From 4a04c07f94b38cbba83d375222169d192dd2fba9 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Wed, 18 Sep 2024 18:07:00 +0200 Subject: [PATCH] feat(developer): Add documentation for `SetupChecks` Signed-off-by: Ferdinand Thiessen --- Makefile | 2 +- .../app_upgrade_guide/upgrade_to_31.rst | 2 +- developer_manual/digging_deeper/index.rst | 1 + .../digging_deeper/setup_checks.rst | 172 ++++++++++++++++++ 4 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 developer_manual/digging_deeper/setup_checks.rst diff --git a/Makefile b/Makefile index 65ee0167d11..d532a2fc4de 100644 --- a/Makefile +++ b/Makefile @@ -42,4 +42,4 @@ openapi-spec: get-server-sources clean: - rm -r admin_manual/_build developer_manual/_build user_manual/_build user_manual_de_/_build + rm -vrf admin_manual/_build developer_manual/_build user_manual/_build user_manual_de_/_build diff --git a/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.rst b/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.rst index 7f57564716b..8142f7275aa 100644 --- a/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.rst +++ b/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.rst @@ -68,7 +68,7 @@ Back-end changes Added APIs ^^^^^^^^^^ -- TBD +- ``OCP\SetupCheck\CheckServerResponseTrait`` was added to ease implementing custom :ref:`setup checks` which need to check HTTP calls to the the server itself. Changed APIs ^^^^^^^^^^^^ diff --git a/developer_manual/digging_deeper/index.rst b/developer_manual/digging_deeper/index.rst index 368a2515fb5..277b5c441f3 100644 --- a/developer_manual/digging_deeper/index.rst +++ b/developer_manual/digging_deeper/index.rst @@ -39,6 +39,7 @@ Digging deeper web_host_metadata status security + setup_checks profile user_migration profiler diff --git a/developer_manual/digging_deeper/setup_checks.rst b/developer_manual/digging_deeper/setup_checks.rst new file mode 100644 index 00000000000..0d4b64db31a --- /dev/null +++ b/developer_manual/digging_deeper/setup_checks.rst @@ -0,0 +1,172 @@ +.. _setup-checks: + +============ +Setup checks +============ + +Setup checks allow to test specific functionality of the server and report issues with configuration +early to the administrators to prevent run time issues. + +One example for setup checks is the JavaScript Modules test that ensures the server is able to +serve ``.mjs`` files correctly, which is needed for apps that use modern JavaScript for their UI. +Any issue with the configuration would be reported to the administrator, either on the web interface (admin setting), +or when running the ``occ setupchecks`` command, before a user experience the issue. + +Register a setup check +---------------------- + +Setup checks are registered within the registration context of the app bootstrap: + +.. code-block:: php + + registerSetupCheck(JavaScriptModules::class); + } + + // ... + + } + +Define a setup check +-------------------- + +Defining a custom setup check is done by simply implementing ``OCP\SetupCheck\SetupResult``, +for this example we will create a check that ensures the Nextcloud instance is not running in debug mode. + +.. code-block:: php + + l10n->t('Debug mode'); + } + + public function getCategory(): string { + return 'system'; + } + + public function run(): SetupResult { + if ($this->config->getSystemValueBool('debug', false)) { + return SetupResult::warning($this->l10n->t('This instance is running in debug mode. Only enable this for local development and not in production environments.')); + } else { + return SetupResult::success($this->l10n->t('Debug mode is disabled.')); + } + } + } + + +First it is required to provide a name, the name which should summarize the check and should be provided as a user visible, thus translated string. + +.. code-block:: php + + public function getName(): string { + // This is user visible and thus should be translated + return $this->l10n->t('Debug mode'); + } + + +Setup checks are grouped by category, the category should be one of + +- ``security``: Related to the security of the instance +- ``accounts``: Related to user accounts +- ``system``: System status Related +- Custom category: Will be merged into system. Examples for existing custom categories are ``network`` and ``database``. + +.. code-block:: php + + public function getCategory(): string { + return 'system'; + } + + +The most important part is the ``run`` function. +This function should perform the test and report the result as a ``OCP\SetupCheck\SetupResult``. +Available severity level are: + +- ``SetupResult::success``: Test succeeded no action needed. +- ``SetupResult::info``: No action required but it can not be guaranteed that the check passed (e.g. missing precondition for running the test). +- ``SetupResult::warning``: The test failed but the result is not fatal, yet the administrator should be warned about this. +- ``SetupResult::error``: The test failed and some functionality is not available or might be broken. + +It is also possible to add a link to documentation to ease administrators solving the issue. +The link is simply passed as the second parameter to the ``SetupResult``. + +Additionally it is also possible to use rich objects (``OCP\RichObjectStrings``) for formatting the message, +in this case the third parameter should contain the rich object parameters. + +.. note:: + Please be aware that setup checks could be ran from both, + the web frontend and from the CLI. Meaning they might use different ``php.ini`` files. + +.. code-block:: php + + public function run(): SetupResult { + if ($this->config->getSystemValueBool('debug', false)) { + return SetupResult::warning($this->l10n->t('This instance is running in debug mode. Only enable this for local development and not in production environments.')); + } else { + return SetupResult::success($this->l10n->t('Debug mode is disabled.')); + } + } + + +Running HTTP requests against the server +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As mentioned in the initial example it is sometimes needed to run HTTP requests +for a setup check, to ensure configuration is working correctly. +To ease writing tests like that we provide the ``CheckServerResponseTrait`` trait. + +The ``run`` function of the JavaScript modules setup check could look like: + +.. code-block:: php + + public function run(): SetupResult { + // This is a real existing file + $testFile = $this->urlGenerator->linkTo('settings', 'js/esm-test.mjs'); + + $noResponse = true; + foreach ($this->runRequest('HEAD', $testFile) as $response) { + $noResponse = false; + if (preg_match('/(text|application)\/javascript/i', $response->getHeader('Content-Type'))) { + return SetupResult::success(); + } + } + + if ($noResponse) { + return SetupResult::warning($this->l10n->t('Unable to run check for JavaScript support.') . "\n" . $this->serverConfigHelp()); + } + return SetupResult::error($this->l10n->t('Your webserver does not serve `.mjs` files using the JavaScript MIME type. This will break some apps by preventing browsers from executing the JavaScript files.')); + } + +The ``runRequest`` is provided by the ``CheckServerResponseTrait``, it accepts a HTTP request method +as the first parameter (in this example ``HEAD``) and an URL with an absolute path, so meaning +the full path but no host set, like provided when using the URL generator. One example string would be ``nextcloud/apps/settings/js/esm-test.mjs``. +Internally the function requests that URL on all possible URLs (using the current host, the trusted domains and the cli overwrite URL), +and then yields a result for each request. + +``CheckServerResponseTrait::serverConfigHelp`` provides information about +common pitfalls that prevent HTTP requests against the current server. +If no response is yielded from the ``runRequest`` method then this information should be included.