From 6f36c1392ba89a1ac64a523edd21e6e961bafd54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 19:57:33 +0000 Subject: [PATCH 01/14] chore: bump next from 11.1.0 to 11.1.1 in /striker-ui Bumps [next](https://github.com/vercel/next.js) from 11.1.0 to 11.1.1. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v11.1.0...v11.1.1) --- updated-dependencies: - dependency-name: next dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- striker-ui/package-lock.json | 130 +++++++++++++++++++++-------------- striker-ui/package.json | 2 +- 2 files changed, 80 insertions(+), 52 deletions(-) diff --git a/striker-ui/package-lock.json b/striker-ui/package-lock.json index 3abf5bbc..c1c49d7f 100644 --- a/striker-ui/package-lock.json +++ b/striker-ui/package-lock.json @@ -429,9 +429,9 @@ } }, "@hapi/boom": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.3.tgz", - "integrity": "sha512-RlrGyZ603hE/eRTZtTltocRm50HHmrmL3kGOP0SQ9MasazlW1mt/fkv4C5P/6rnpFXjwld/POFX1C8tMZE3ldg==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.4.tgz", + "integrity": "sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==", "requires": { "@hapi/hoek": "9.x.x" } @@ -523,9 +523,9 @@ "integrity": "sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA==" }, "@next/env": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-11.1.0.tgz", - "integrity": "sha512-zPJkMFRenSf7BLlVee8987G0qQXAhxy7k+Lb/5hLAGkPVHAHm+oFFeL+2ipbI2KTEFlazdmGY0M+AlLQn7pWaw==" + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-11.1.1.tgz", + "integrity": "sha512-UEAzlfKofotLmj9LIgNixAfXpRck9rt/1CU9Q4ZtNDueGBJQP3HUzPHlrLChltWY2TA5MOzDQGL82H0a3+i5Ag==" }, "@next/eslint-plugin-next": { "version": "11.1.0", @@ -537,14 +537,14 @@ } }, "@next/polyfill-module": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-11.1.0.tgz", - "integrity": "sha512-64EgW8SzJRQls2yJ5DkuljRxgE24o2kYtX/ghTkPUJYsfidHMWzQGwg26IgRbb/uHqTd1G0W5UkKag+Nt8TWaQ==" + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-11.1.1.tgz", + "integrity": "sha512-9FyVSnz00WGdlLsgc2w1xL1Lm/Q25y6FYIyA+1WlJvT6LA2lbR78GKiHgedzUvrAatVGAcg/Og+d0d7B4tsJOg==" }, "@next/react-dev-overlay": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-11.1.0.tgz", - "integrity": "sha512-h+ry0sTk1W3mJw+TwEf91aqLbBJ5oqAsxfx+QryqEItNtfW6zLSSjxkyTYTqX8DkgSssQQutQfATkzBVgOR+qQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-11.1.1.tgz", + "integrity": "sha512-CXc/A0DbSk5VXYu4+zr0fHm52Zh/LhPlLyVPEctJOZL64ccxkls5xGoXvgolJCku9L0pLjJzvdfAmhNLOp5dyw==", "requires": { "@babel/code-frame": "7.12.11", "anser": "1.4.9", @@ -592,9 +592,33 @@ } }, "@next/react-refresh-utils": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-11.1.0.tgz", - "integrity": "sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog==" + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-11.1.1.tgz", + "integrity": "sha512-j186y+lWc8BHAuysAWvlOqO9Bp7E3BLK/d/Ju3W2sP5BCH5ZLyLG/p308zSy/O0MGTag0B038ZA1dCy/msouRQ==" + }, + "@next/swc-darwin-arm64": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.1.tgz", + "integrity": "sha512-KyB0aLpfQ+B2dsyGYpkM0ZwK3PV0t4C4b9yjgQc1VoTVnIjzXdDPnNOuVvmD849ZNOHfj3x8e2rlbxkj0lPm3A==", + "optional": true + }, + "@next/swc-darwin-x64": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.1.tgz", + "integrity": "sha512-B3ZXgrGx0bQplbrk2oggPjKPPsmyg8Fl0PJLMTVQ+erQ8g1m5QzyS9P6tB3SiIZa180JgENuguTHlVK5qEj4UA==", + "optional": true + }, + "@next/swc-linux-x64-gnu": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.1.tgz", + "integrity": "sha512-qvZL7gSKF+E+GZ3L1XiTnE3cOh9rk0wkqimT/q+wwcZA4E720Lu4lrT79I3HPuj6i/JPgGvmNskcnYrDeaoFaw==", + "optional": true + }, + "@next/swc-win32-x64-msvc": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.1.tgz", + "integrity": "sha512-jhnCiA1De1L+kA0gmHG1AJijHoxOcrETWziDWy8fcqSrM1NlC4aJ5Mnu6k0QMcM9MnmXTA4TQZOEv3kF7vhJUQ==", + "optional": true }, "@node-rs/helper": { "version": "1.2.1", @@ -1082,9 +1106,9 @@ "dev": true }, "available-typed-arrays": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "axe-core": { "version": "4.1.3", @@ -1283,9 +1307,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==" + "version": "1.0.30001252", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001252.tgz", + "integrity": "sha512-I56jhWDGMtdILQORdusxBOH+Nl/KgQSdDmpJezYddnAkVOmnoU8zwjTV9xAjMIYxr0iPreEAVylCGcmHCjfaOw==" }, "chalk": { "version": "2.4.2", @@ -1570,9 +1594,9 @@ "dev": true }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cosmiconfig": { "version": "7.0.0", @@ -1847,9 +1871,9 @@ } }, "electron-to-chromium": { - "version": "1.3.812", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.812.tgz", - "integrity": "sha512-7KiUHsKAWtSrjVoTSzxQ0nPLr/a+qoxNZwkwd9LkylTOgOXSVXkQbpIVT0WAUQcI5gXq3SwOTCrK+WfINHOXQg==" + "version": "1.3.826", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.826.tgz", + "integrity": "sha512-bpLc4QU4B8PYmdO4MSu2ZBTMD8lAaEXRS43C09lB31BvYwuk9UxgBRXbY5OJBw7VuMGcg2MZG5FyTaP9u4PQnw==" }, "elliptic": { "version": "6.5.4", @@ -3345,11 +3369,11 @@ } }, "is-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.7.tgz", - "integrity": "sha512-VxlpTBGknhQ3o7YiVjIhdLU6+oD8dPz/79vvvH4F+S/c8608UCVa9fgDpa1kZgFoUST2DCgacc70UszKgzKuvA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", "requires": { - "available-typed-arrays": "^1.0.4", + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-abstract": "^1.18.5", "foreach": "^2.0.5", @@ -4087,16 +4111,20 @@ "dev": true }, "next": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/next/-/next-11.1.0.tgz", - "integrity": "sha512-GHBk/c7Wyr6YbFRFZF37I0X7HKzkHHI8pur/loyXo5AIE8wdkbGPGO0ds3vNAO6f8AxZAKGCRYtAzoGlVLoifA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/next/-/next-11.1.1.tgz", + "integrity": "sha512-vfLJDkwAHsZUho5R1K4w49nfYhftUMWNmeNSjCtulOvnRBuEFb7ROyRZOQk7f29rMz02eLQrPZ9yiAmPsexL2g==", "requires": { - "@babel/runtime": "7.12.5", + "@babel/runtime": "7.15.3", "@hapi/accept": "5.0.2", - "@next/env": "11.1.0", - "@next/polyfill-module": "11.1.0", - "@next/react-dev-overlay": "11.1.0", - "@next/react-refresh-utils": "11.1.0", + "@next/env": "11.1.1", + "@next/polyfill-module": "11.1.1", + "@next/react-dev-overlay": "11.1.1", + "@next/react-refresh-utils": "11.1.1", + "@next/swc-darwin-arm64": "11.1.1", + "@next/swc-darwin-x64": "11.1.1", + "@next/swc-linux-x64-gnu": "11.1.1", + "@next/swc-win32-x64-msvc": "11.1.1", "@node-rs/helper": "1.2.1", "assert": "2.0.0", "ast-types": "0.13.2", @@ -4138,15 +4166,15 @@ "timers-browserify": "2.0.12", "tty-browserify": "0.0.1", "use-subscription": "1.5.1", - "util": "0.12.3", + "util": "0.12.4", "vm-browserify": "1.1.2", "watchpack": "2.1.1" }, "dependencies": { "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", + "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -5906,9 +5934,9 @@ } }, "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -5990,16 +6018,16 @@ } }, "which-typed-array": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.6.tgz", - "integrity": "sha512-DdY984dGD5sQ7Tf+x1CkXzdg85b9uEel6nr4UkFg1LoE9OXv3uRuZhe5CoWdawhGACeFpEZXH8fFLQnDhbpm/Q==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", "requires": { - "available-typed-arrays": "^1.0.4", + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-abstract": "^1.18.5", "foreach": "^2.0.5", "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.6" + "is-typed-array": "^1.1.7" }, "dependencies": { "es-abstract": { diff --git a/striker-ui/package.json b/striker-ui/package.json index a14df2e5..aec5d45b 100644 --- a/striker-ui/package.json +++ b/striker-ui/package.json @@ -17,7 +17,7 @@ "@material-ui/icons": "^4.11.2", "@material-ui/styles": "^4.11.4", "@novnc/novnc": "^1.2.0", - "next": "^11.1.0", + "next": "^11.1.1", "pretty-bytes": "^5.6.0", "react": "17.0.2", "react-dom": "17.0.2", From f97a820b4830862f1c170ba66c161df8fc4a20a6 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Wed, 4 Aug 2021 20:41:54 -0400 Subject: [PATCH 02/14] feat(tools): add script to take screenshot of server VM --- tools/anvil-get-server-screenshot | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 tools/anvil-get-server-screenshot diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot new file mode 100755 index 00000000..d7f5e1e9 --- /dev/null +++ b/tools/anvil-get-server-screenshot @@ -0,0 +1,88 @@ +#!/usr/bin/perl +# +# +# + +use strict; +use warnings; +use Anvil::Tools; + +$| = 1; + +my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; +my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; +if (($running_directory =~ /^\./) && ($ENV{PWD})) +{ + $running_directory =~ s/^\./$ENV{PWD}/; +} + +my $anvil = Anvil::Tools->new(); + +$anvil->Get->switches; + +$anvil->Database->connect; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); +if (not $anvil->data->{sys}{database}{connections}) +{ + # No databases, exit. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"}); + $anvil->nice_exit({exit_code => 1}); +} + +sub system_call +{ + my $parameters = shift; + my $shell_call = $parameters->{shell_call}; + + my ($shell_output, $shell_return_code) = $anvil->System->call({ shell_call => $shell_call }); + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { + shell_call => $shell_call, + shell_output => $shell_output, + shell_return_code => $shell_return_code + } }); + + return ($shell_output, $shell_return_code); +} + +sub get_server_screenshot +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + + my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//' | base64"; + my ($shell_output, $shell_return_code) = system_call({ shell_call => $shell_call }); + + return $shell_return_code == 0 ? $shell_output : undef; +} + +sub insert_server_screenshot +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + my $encoded_image = $parameters->{encoded_image}; + + $anvil->Database->insert_or_update_variables({ + variable_name => "server_screenshot::".$server_uuid, + variable_value => $encoded_image + }); +} + +my $server_uuid = $anvil->data->{switches}{'server-uuid'}; +my $is_stdout = $anvil->data->{switches}{'stdout'}; + +if ($server_uuid) +{ + my $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + + if ($is_stdout) + { + print($encoded_image); + } + else + { + insert_server_screenshot({ + server_uuid => $server_uuid, + encoded_image => $encoded_image + }); + } +} From 1014299d38c9c8b4492d051721ca558a2804d702 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 5 Aug 2021 18:46:42 -0400 Subject: [PATCH 03/14] fix(tools): enable anvil-get-server-screenshot to be a job --- share/words.xml | 4 ++ tools/anvil-get-server-screenshot | 99 +++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/share/words.xml b/share/words.xml index 5e521616..3e2f71ff 100644 --- a/share/words.xml +++ b/share/words.xml @@ -2256,6 +2256,10 @@ Are you sure that you want to delete the server: [#!variable!server_name!#]? [Ty Finished [#!variable!operation!#] VNC pipe for server UUID [#!variable!server_uuid!#] from host UUID [#!variable!host_uuid!#]. Finished dropping VNC pipes table. Finished managing VNC pipes; no operations happened because requirements not met. + Preparing to get server VM screenshot. + Finished getting server VM screenshot. + Failed to get server VM screenshot; got non-zero return code. + Finished attempting to get server VM screenshot; no operations happened because requirements not met. Saved the mail server information successfully! diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index d7f5e1e9..587edfe2 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -18,17 +18,6 @@ if (($running_directory =~ /^\./) && ($ENV{PWD})) my $anvil = Anvil::Tools->new(); -$anvil->Get->switches; - -$anvil->Database->connect; -$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); -if (not $anvil->data->{sys}{database}{connections}) -{ - # No databases, exit. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"}); - $anvil->nice_exit({exit_code => 1}); -} - sub system_call { my $parameters = shift; @@ -67,22 +56,94 @@ sub insert_server_screenshot }); } -my $server_uuid = $anvil->data->{switches}{'server-uuid'}; -my $is_stdout = $anvil->data->{switches}{'stdout'}; +$anvil->Get->switches; + +$anvil->Database->connect; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); +if (not $anvil->data->{sys}{database}{connections}) +{ + # No databases, exit. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"}); + $anvil->nice_exit({exit_code => 1}); +} + +# Try to get a job UUID if not given. +if (not $anvil->data->{switches}{'job-uuid'}) +{ + $anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({ program => $THIS_FILE }); + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { + "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} + } }); +} + +# Handle this script as a job when job UUID is provided. +if ($anvil->data->{switches}{'job-uuid'}) +{ + $anvil->Job->clear(); + $anvil->Job->get_job_details(); + $anvil->Job->update_progress({ + progress => 1, + job_picked_up_by => $$, + job_picked_up_at => time, + message => "message_0263" + }); + + foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) + { + if ($line =~ /server-uuid=(.*?)$/) + { + $anvil->data->{switches}{'server-uuid'} = $1; + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'switches::server-uuid' => $anvil->data->{switches}{'server-uuid'} + } }); + } + + if ($line =~ /stdout=(.*?)$/) + { + $anvil->data->{switches}{'stdout'} = $1; + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'switches::stdout' => $anvil->data->{switches}{'stdout'} + } }); + } + } +} + +my $server_uuid = $anvil->data->{switches}{'server-uuid'}; +my $is_stdout = $anvil->data->{switches}{'stdout'}; +my $job_uuid = $anvil->data->{switches}{'job-uuid'}; + +$anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { + server_uuid => $server_uuid, + is_stdout => $is_stdout, + job_uuid => $job_uuid +} }); if ($server_uuid) { my $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); - if ($is_stdout) + if (defined $encoded_image) { - print($encoded_image); + if ($is_stdout) + { + print($encoded_image); + } + else + { + insert_server_screenshot({ + server_uuid => $server_uuid, + encoded_image => $encoded_image + }); + } + + $anvil->Job->update_progress({ progress => 100, message => "message_0264" }); } else { - insert_server_screenshot({ - server_uuid => $server_uuid, - encoded_image => $encoded_image - }); + $anvil->Job->update_progress({ progress => 100, message => "message_0265" }); } } +else +{ + $anvil->Job->update_progress({ progress => 100, message => "message_0266" }); +} From d195a53ba2204afbdcd035c1f5b57abb7546fbd7 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 5 Aug 2021 21:35:30 -0400 Subject: [PATCH 04/14] feat(cgi-bin): add endpoint for fetching server screenshot --- Anvil/Tools.pm | 1 + cgi-bin/get_server_screenshot | 124 ++++++++++++++++++++++++++++++++++ share/words.xml | 2 + 3 files changed, 127 insertions(+) create mode 100755 cgi-bin/get_server_screenshot diff --git a/Anvil/Tools.pm b/Anvil/Tools.pm index 168fccb6..f358106e 100644 --- a/Anvil/Tools.pm +++ b/Anvil/Tools.pm @@ -1106,6 +1106,7 @@ sub _set_paths 'anvil-delete-server' => "/usr/sbin/anvil-delete-server", 'anvil-download-file' => "/usr/sbin/anvil-download-file", 'anvil-file-details' => "/usr/sbin/anvil-file-details", + 'anvil-get-server-screenshot' => "/usr/sbin/anvil-get-server-screenshot", 'anvil-join-anvil' => "/usr/sbin/anvil-join-anvil", 'anvil-maintenance-mode' => "/usr/sbin/anvil-maintenance-mode", 'anvil-manage-firewall' => "/usr/sbin/anvil-manage-firewall", diff --git a/cgi-bin/get_server_screenshot b/cgi-bin/get_server_screenshot new file mode 100755 index 00000000..8e212267 --- /dev/null +++ b/cgi-bin/get_server_screenshot @@ -0,0 +1,124 @@ +#!/usr/bin/perl +# +# Gets a server VM's screenshot and convert it to a Base64 string. +# + +use strict; +use warnings; +use Anvil::Tools; +use JSON; + +$| = 1; + +my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; +my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; +if (($running_directory =~ /^\./) && ($ENV{PWD})) +{ + $running_directory =~ s/^\./$ENV{PWD}/; +} + +my $anvil = Anvil::Tools->new(); + +sub is_job_incomplete +{ + my $parameters = shift; + my $job_uuid = $parameters->{job_uuid}; + + my $query = " +SELECT + job_progress +FROM + public.jobs +WHERE + job_uuid = ".$anvil->Database->quote($job_uuid)." +;"; + + my $job_progress = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ })->[0]->[0]; + + return $job_progress == 100 ? 0 : 1; +} + +sub get_server_host_uuid +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + + my $query = " +SELECT + server_host_uuid +FROM + public.servers +WHERE + server_uuid = ".$anvil->Database->quote($server_uuid)." +;"; + + return $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ })->[0]->[0]; +} + +sub get_screenshot +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + my $server_host_uuid = $parameters->{server_host_uuid}; + + my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ + job_command => $anvil->data->{path}{exe}{'anvil-get-server-screenshot'}, + job_data => "server-uuid=".$server_uuid, + job_host_uuid => $server_host_uuid, + job_description => "job_0357", + job_name => "cgi-bin::get_server_screenshot::".$server_uuid, + job_progress => 0, + job_title => "job_0356" + }); + + # Wait until the job is complete before continuing. + while(is_job_incomplete({ job_uuid => $job_uuid })) + { + sleep(2); + } + + my ($encoded_image) = $anvil->Database->read_variable({ variable_name => "server_screenshot::".$server_uuid }); + + return $encoded_image; +} + +$anvil->Get->switches; + +$anvil->Database->connect; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); +if (not $anvil->data->{sys}{database}{connections}) +{ + # No databases, exit. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0003"}); + $anvil->nice_exit({exit_code => 1}); +} + +my $cookie_problem = $anvil->Account->read_cookies(); + +# Don't do anything data-related if the user is not logged in. +if ($cookie_problem) +{ + $anvil->Log->entry({ source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0307" }); + $anvil->nice_exit({ exit_code => 1 }); +} + +# Read in any CGI variables, if needed. +$anvil->Get->cgi(); + +print $anvil->Template->get({ file => "shared.html", name => "json_headers", show_name => 0 })."\n"; + +my $server_uuid = defined $anvil->data->{cgi}{server_uuid}{value} ? $anvil->data->{cgi}{server_uuid}{value} : $anvil->data->{switches}{'server-uuid'}; + +my $response_body = {}; + +if ($server_uuid) +{ + my $encoded_image = get_screenshot({ server_uuid => $server_uuid, server_host_uuid => get_server_host_uuid({ server_uuid => $server_uuid }) }); + + if (defined $encoded_image) + { + $response_body->{image} = $encoded_image; + } +} + +print JSON->new->utf8->encode($response_body)."\n"; diff --git a/share/words.xml b/share/words.xml index 3e2f71ff..368f2463 100644 --- a/share/words.xml +++ b/share/words.xml @@ -1148,6 +1148,8 @@ It should be provisioned in the next minute or two. * Please enter the name of the server you want to manage -=] Servers available to manage on the Anvil! [#!variable!anvil_name!#] [=- -=] Managing the server: [#!variable!server_name!#] on the Anvil!: [#!variable!anvil_name!#] + Get Server VM Screenshot + Fetch a screenshot of the specified server VM and represent it as a Base64 string. Starting: [#!variable!program!#]. From 4ef231b5671aa48941a518312cde694553e20233 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 6 Aug 2021 14:56:26 -0400 Subject: [PATCH 05/14] fix(tools): prevent too frequent inserts of server VM screenshots --- tools/anvil-get-server-screenshot | 44 ++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index 587edfe2..f673a895 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -33,6 +33,18 @@ sub system_call return ($shell_output, $shell_return_code); } +sub is_existing_server_screenshot_outdated +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + + my ($encoded_image, $variable_uuid, $variable_mtime) = $anvil->Database->read_variable({ variable_name => "server_screenshot::".$server_uuid }); + + my $time_difference = time - $variable_mtime; + + return $time_difference > 120 ? 1 : 0; +} + sub get_server_screenshot { my $parameters = shift; @@ -120,27 +132,41 @@ $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, lis if ($server_uuid) { - my $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + my $encoded_image; - if (defined $encoded_image) + if ($is_stdout) { - if ($is_stdout) + $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + + if (defined $encoded_image) { print($encoded_image); + + $anvil->Job->update_progress({ progress => 100, message => "message_0264" }); } else { - insert_server_screenshot({ - server_uuid => $server_uuid, - encoded_image => $encoded_image - }); + $anvil->Job->update_progress({ progress => 100, message => "message_0265" }); } + } + elsif (is_existing_server_screenshot_outdated({ server_uuid => $server_uuid })) + { + $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + + if (defined $encoded_image) + { + insert_server_screenshot({ server_uuid => $server_uuid, encoded_image => $encoded_image }); - $anvil->Job->update_progress({ progress => 100, message => "message_0264" }); + $anvil->Job->update_progress({ progress => 100, message => "message_0264" }); + } + else + { + $anvil->Job->update_progress({ progress => 100, message => "message_0265" }); + } } else { - $anvil->Job->update_progress({ progress => 100, message => "message_0265" }); + $anvil->Job->update_progress({ progress => 100, message => "message_0266" }); } } else From da6b4d39c6a86e090ff8efec2b882ad2101effeb Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 6 Aug 2021 15:17:45 -0400 Subject: [PATCH 06/14] fix(tools): disable line wrap in image Base64 output --- tools/anvil-get-server-screenshot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index f673a895..5ca019f1 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -50,7 +50,7 @@ sub get_server_screenshot my $parameters = shift; my $server_uuid = $parameters->{server_uuid}; - my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//' | base64"; + my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//' | base64 --wrap 0"; my ($shell_output, $shell_return_code) = system_call({ shell_call => $shell_call }); return $shell_return_code == 0 ? $shell_output : undef; From 26d5c60696dd8c240e058c9eacea06852a73cd0b Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 6 Aug 2021 15:36:15 -0400 Subject: [PATCH 07/14] fix(cgi-bin): rename response body screenshot property --- cgi-bin/get_server_screenshot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgi-bin/get_server_screenshot b/cgi-bin/get_server_screenshot index 8e212267..976c0984 100755 --- a/cgi-bin/get_server_screenshot +++ b/cgi-bin/get_server_screenshot @@ -117,7 +117,7 @@ if ($server_uuid) if (defined $encoded_image) { - $response_body->{image} = $encoded_image; + $response_body->{screenshot} = $encoded_image; } } From 256051a6cab239029d9ae9d60888406c36836f20 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 6 Aug 2021 15:37:18 -0400 Subject: [PATCH 08/14] build(cgi-bin): add get_server_screenshot endpoint to build --- cgi-bin/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/cgi-bin/Makefile.am b/cgi-bin/Makefile.am index 5343314e..92fc1a55 100644 --- a/cgi-bin/Makefile.am +++ b/cgi-bin/Makefile.am @@ -7,6 +7,7 @@ dist_cgibin_SCRIPTS = \ get_memory \ get_networks \ get_replicated_storage \ + get_server_screenshot \ get_servers \ get_shared_storage \ get_status \ From 74670360543dab12bee40cb280464e3e1e3616ad Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 6 Aug 2021 15:38:20 -0400 Subject: [PATCH 09/14] build(tools): add anvil-get-server-screenshot script to build --- tools/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/Makefile.am b/tools/Makefile.am index f23aa192..d2b6c074 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -14,6 +14,7 @@ dist_sbin_SCRIPTS = \ anvil-delete-server \ anvil-download-file \ anvil-file-details \ + anvil-get-server-screenshot \ anvil-join-anvil \ anvil-maintenance-mode \ anvil-manage-files \ From 65613f501b20049e39dd75b3fb81b6a571fecd7a Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 12 Aug 2021 14:31:12 -0400 Subject: [PATCH 10/14] fix(tools): add option to resize server screenshot --- cgi-bin/get_server_screenshot | 10 ++++++++-- tools/anvil-get-server-screenshot | 28 +++++++++++++++++++--------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/cgi-bin/get_server_screenshot b/cgi-bin/get_server_screenshot index 976c0984..7a1e071d 100755 --- a/cgi-bin/get_server_screenshot +++ b/cgi-bin/get_server_screenshot @@ -60,10 +60,11 @@ sub get_screenshot my $parameters = shift; my $server_uuid = $parameters->{server_uuid}; my $server_host_uuid = $parameters->{server_host_uuid}; + my $resize_args = defined $parameters->{resize_args} ? $parameters->{resize_args} : "512x512"; my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ job_command => $anvil->data->{path}{exe}{'anvil-get-server-screenshot'}, - job_data => "server-uuid=".$server_uuid, + job_data => "server-uuid=".$server_uuid."\nresize=".$resize_args, job_host_uuid => $server_host_uuid, job_description => "job_0357", job_name => "cgi-bin::get_server_screenshot::".$server_uuid, @@ -108,12 +109,17 @@ $anvil->Get->cgi(); print $anvil->Template->get({ file => "shared.html", name => "json_headers", show_name => 0 })."\n"; my $server_uuid = defined $anvil->data->{cgi}{server_uuid}{value} ? $anvil->data->{cgi}{server_uuid}{value} : $anvil->data->{switches}{'server-uuid'}; +my $resize_args = defined $anvil->data->{cgi}{resize}{value} ? $anvil->data->{cgi}{resize}{value} : $anvil->data->{switches}{'resize'}; my $response_body = {}; if ($server_uuid) { - my $encoded_image = get_screenshot({ server_uuid => $server_uuid, server_host_uuid => get_server_host_uuid({ server_uuid => $server_uuid }) }); + my $encoded_image = get_screenshot({ + server_uuid => $server_uuid, + server_host_uuid => get_server_host_uuid({ server_uuid => $server_uuid }), + resize_args => $resize_args + }); if (defined $encoded_image) { diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index 5ca019f1..16442d89 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -49,8 +49,17 @@ sub get_server_screenshot { my $parameters = shift; my $server_uuid = $parameters->{server_uuid}; + my $resize_args = $parameters->{resize_args}; + + my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//'"; + + if (defined $resize_args) + { + $shell_call .= " | convert - -resize ".$resize_args." png:-"; + } + + $shell_call .= " | base64 --wrap 0"; - my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//' | base64 --wrap 0"; my ($shell_output, $shell_return_code) = system_call({ shell_call => $shell_call }); return $shell_return_code == 0 ? $shell_output : undef; @@ -105,27 +114,28 @@ if ($anvil->data->{switches}{'job-uuid'}) if ($line =~ /server-uuid=(.*?)$/) { $anvil->data->{switches}{'server-uuid'} = $1; - $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'switches::server-uuid' => $anvil->data->{switches}{'server-uuid'} - } }); + } + + if ($line =~ /resize=(.*?)$/) + { + $anvil->data->{switches}{'resize'} = $1; } if ($line =~ /stdout=(.*?)$/) { $anvil->data->{switches}{'stdout'} = $1; - $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'switches::stdout' => $anvil->data->{switches}{'stdout'} - } }); } } } my $server_uuid = $anvil->data->{switches}{'server-uuid'}; +my $resize_args = $anvil->data->{switches}{'resize'}; my $is_stdout = $anvil->data->{switches}{'stdout'}; my $job_uuid = $anvil->data->{switches}{'job-uuid'}; $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { server_uuid => $server_uuid, + resize_args => $resize_args, is_stdout => $is_stdout, job_uuid => $job_uuid } }); @@ -136,7 +146,7 @@ if ($server_uuid) if ($is_stdout) { - $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + $encoded_image = get_server_screenshot({ server_uuid => $server_uuid, resize_args => $resize_args }); if (defined $encoded_image) { @@ -151,7 +161,7 @@ if ($server_uuid) } elsif (is_existing_server_screenshot_outdated({ server_uuid => $server_uuid })) { - $encoded_image = get_server_screenshot({ server_uuid => $server_uuid }); + $encoded_image = get_server_screenshot({ server_uuid => $server_uuid, resize_args => $resize_args }); if (defined $encoded_image) { From c1859bc8d8b9828484e6c149d9c3023794fbe2b6 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 2 Sep 2021 14:07:01 -0400 Subject: [PATCH 11/14] fix(tools): use netpbm tools instead of imagemagick --- tools/anvil-get-server-screenshot | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index 16442d89..e64ef3cb 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -49,13 +49,14 @@ sub get_server_screenshot { my $parameters = shift; my $server_uuid = $parameters->{server_uuid}; - my $resize_args = $parameters->{resize_args}; + my ($resize_x, $resize_y) = split(/x/ , $parameters->{resize_args}); my $shell_call = "virsh screenshot --domain ".$server_uuid." --file /dev/stdout | sed 's/Screenshot.*//'"; - if (defined $resize_args) + if ($resize_x =~ /^\d+$/ && $resize_y =~ /^\d+$/) { - $shell_call .= " | convert - -resize ".$resize_args." png:-"; + $shell_call .= " | pamscale -quiet -xyfit ".$resize_x." ".$resize_y; + $shell_call .= " | pamtopng -quiet"; } $shell_call .= " | base64 --wrap 0"; From f61527edf74653a2980e614bcb1df958b6e91482 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 2 Sep 2021 17:08:36 -0400 Subject: [PATCH 12/14] fix(tools): save screenshots to states table --- cgi-bin/get_server_screenshot | 8 +++++++- tools/anvil-get-server-screenshot | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cgi-bin/get_server_screenshot b/cgi-bin/get_server_screenshot index 7a1e071d..184de9ec 100755 --- a/cgi-bin/get_server_screenshot +++ b/cgi-bin/get_server_screenshot @@ -78,7 +78,13 @@ sub get_screenshot sleep(2); } - my ($encoded_image) = $anvil->Database->read_variable({ variable_name => "server_screenshot::".$server_uuid }); + my $query = " +SELECT state_note +FROM public.states +WHERE state_name = ".$anvil->Database->quote("server_screenshot::".$server_uuid)." +;"; + + my $encoded_image = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ })->[0]->[0]; return $encoded_image; } diff --git a/tools/anvil-get-server-screenshot b/tools/anvil-get-server-screenshot index e64ef3cb..57579c4e 100755 --- a/tools/anvil-get-server-screenshot +++ b/tools/anvil-get-server-screenshot @@ -72,9 +72,9 @@ sub insert_server_screenshot my $server_uuid = $parameters->{server_uuid}; my $encoded_image = $parameters->{encoded_image}; - $anvil->Database->insert_or_update_variables({ - variable_name => "server_screenshot::".$server_uuid, - variable_value => $encoded_image + $anvil->Database->insert_or_update_states({ + state_name => "server_screenshot::".$server_uuid, + state_note => $encoded_image }); } From 089675d4d85e1c41d1a2b15ad92557052d7f54bb Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 3 Sep 2021 16:11:08 -0400 Subject: [PATCH 13/14] build: re-order python3-websockify in anvil specfile --- anvil.spec.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anvil.spec.in b/anvil.spec.in index a7804d62..3cde0a0a 100644 --- a/anvil.spec.in +++ b/anvil.spec.in @@ -159,11 +159,11 @@ Requires: libvirt-daemon-kvm Requires: libvirt-docs Requires: pacemaker Requires: pcs +Requires: python3-websockify Requires: qemu-kvm Requires: qemu-kvm-core Requires: virt-install Requires: virt-top -Requires: python3-websockify # A node is allowed to host servers and be a live migration target. It is not # allowed to host a database or be a DR host. Conflicts: anvil-striker @@ -188,11 +188,11 @@ Requires: libvirt-daemon Requires: libvirt-daemon-driver-qemu Requires: libvirt-daemon-kvm Requires: libvirt-docs +Requires: python3-websockify Requires: qemu-kvm Requires: qemu-kvm-core Requires: virt-install Requires: virt-top -Requires: python3-websockify # A DR host is not allowed to be a live-migration target or host a database. Conflicts: anvil-striker Conflicts: anvil-node From 59ce16f531c9dd16dcf4bb02a769bd88796371ea Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Fri, 3 Sep 2021 16:13:08 -0400 Subject: [PATCH 14/14] build: add netpbm-progs as node and DR dependency --- anvil.spec.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/anvil.spec.in b/anvil.spec.in index 3cde0a0a..d1952b3b 100644 --- a/anvil.spec.in +++ b/anvil.spec.in @@ -157,6 +157,7 @@ Requires: libvirt-daemon Requires: libvirt-daemon-driver-qemu Requires: libvirt-daemon-kvm Requires: libvirt-docs +Requires: netpbm-progs Requires: pacemaker Requires: pcs Requires: python3-websockify @@ -188,6 +189,7 @@ Requires: libvirt-daemon Requires: libvirt-daemon-driver-qemu Requires: libvirt-daemon-kvm Requires: libvirt-docs +Requires: netpbm-progs Requires: python3-websockify Requires: qemu-kvm Requires: qemu-kvm-core