Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4a04c07

Browse files
committedSep 18, 2024··
feat(developer): Add documentation for SetupChecks
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 9e09785 commit 4a04c07

File tree

4 files changed

+175
-2
lines changed

4 files changed

+175
-2
lines changed
 

‎Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ openapi-spec: get-server-sources
4242

4343

4444
clean:
45-
rm -r admin_manual/_build developer_manual/_build user_manual/_build user_manual_de_/_build
45+
rm -vrf admin_manual/_build developer_manual/_build user_manual/_build user_manual_de_/_build

‎developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Back-end changes
6868
Added APIs
6969
^^^^^^^^^^
7070

71-
- TBD
71+
- ``OCP\SetupCheck\CheckServerResponseTrait`` was added to ease implementing custom :ref:`setup checks<setup-checks>` which need to check HTTP calls to the the server itself.
7272

7373
Changed APIs
7474
^^^^^^^^^^^^

‎developer_manual/digging_deeper/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Digging deeper
3939
web_host_metadata
4040
status
4141
security
42+
setup_checks
4243
profile
4344
user_migration
4445
profiler
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
.. _setup-checks:
2+
3+
============
4+
Setup checks
5+
============
6+
7+
Setup checks allow to test specific functionality of the server and report issues with configuration
8+
early to the administrators to prevent run time issues.
9+
10+
One example for setup checks is the JavaScript Modules test that ensures the server is able to
11+
serve ``.mjs`` files correctly, which is needed for apps that use modern JavaScript for their UI.
12+
Any issue with the configuration would be reported to the administrator, either on the web interface (admin setting),
13+
or when running the ``occ setupchecks`` command, before a user experience the issue.
14+
15+
Register a setup check
16+
----------------------
17+
18+
Setup checks are registered within the registration context of the app bootstrap:
19+
20+
.. code-block:: php
21+
22+
<?php
23+
declare(strict_types=1);
24+
25+
namespace OCA\MyApp\AppInfo;
26+
27+
class Application extends App implements IBootstrap {
28+
29+
public function register(IRegistrationContext $context): void {
30+
// Other registration
31+
$context->registerSetupCheck(JavaScriptModules::class);
32+
}
33+
34+
// ...
35+
36+
}
37+
38+
Define a setup check
39+
--------------------
40+
41+
Defining a custom setup check is done by simply implementing ``OCP\SetupCheck\SetupResult``,
42+
for this example we will create a check that ensures the Nextcloud instance is not running in debug mode.
43+
44+
.. code-block:: php
45+
46+
<?php
47+
declare(strict_types=1);
48+
49+
namespace OCA\MyApp\SetupChecks;
50+
51+
use OCP\IConfig;
52+
use OCP\IL10N;
53+
use OCP\SetupCheck\ISetupCheck;
54+
use OCP\SetupCheck\SetupResult;
55+
56+
class DebugModeSetupCheck implements ISetupCheck {
57+
public function __construct(
58+
private IL10N $l10n,
59+
private IConfig $config,
60+
) {
61+
}
62+
63+
public function getName(): string {
64+
return $this->l10n->t('Debug mode');
65+
}
66+
67+
public function getCategory(): string {
68+
return 'system';
69+
}
70+
71+
public function run(): SetupResult {
72+
if ($this->config->getSystemValueBool('debug', false)) {
73+
return SetupResult::warning($this->l10n->t('This instance is running in debug mode. Only enable this for local development and not in production environments.'));
74+
} else {
75+
return SetupResult::success($this->l10n->t('Debug mode is disabled.'));
76+
}
77+
}
78+
}
79+
80+
81+
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.
82+
83+
.. code-block:: php
84+
85+
public function getName(): string {
86+
// This is user visible and thus should be translated
87+
return $this->l10n->t('Debug mode');
88+
}
89+
90+
91+
Setup checks are grouped by category, the category should be one of
92+
93+
- ``security``: Related to the security of the instance
94+
- ``accounts``: Related to user accounts
95+
- ``system``: System status Related
96+
- Custom category: Will be merged into system. Examples for existing custom categories are ``network`` and ``database``.
97+
98+
.. code-block:: php
99+
100+
public function getCategory(): string {
101+
return 'system';
102+
}
103+
104+
105+
The most important part is the ``run`` function.
106+
This function should perform the test and report the result as a ``OCP\SetupCheck\SetupResult``.
107+
Available severity level are:
108+
109+
- ``SetupResult::success``: Test succeeded no action needed.
110+
- ``SetupResult::info``: No action required but it can not be guaranteed that the check passed (e.g. missing precondition for running the test).
111+
- ``SetupResult::warning``: The test failed but the result is not fatal, yet the administrator should be warned about this.
112+
- ``SetupResult::error``: The test failed and some functionality is not available or might be broken.
113+
114+
It is also possible to add a link to documentation to ease administrators solving the issue.
115+
The link is simply passed as the second parameter to the ``SetupResult``.
116+
117+
Additionally it is also possible to use rich objects (``OCP\RichObjectStrings``) for formatting the message,
118+
in this case the third parameter should contain the rich object parameters.
119+
120+
.. note::
121+
Please be aware that setup checks could be ran from both,
122+
the web frontend and from the CLI. Meaning they might use different ``php.ini`` files.
123+
124+
.. code-block:: php
125+
126+
public function run(): SetupResult {
127+
if ($this->config->getSystemValueBool('debug', false)) {
128+
return SetupResult::warning($this->l10n->t('This instance is running in debug mode. Only enable this for local development and not in production environments.'));
129+
} else {
130+
return SetupResult::success($this->l10n->t('Debug mode is disabled.'));
131+
}
132+
}
133+
134+
135+
Running HTTP requests against the server
136+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137+
138+
As mentioned in the initial example it is sometimes needed to run HTTP requests
139+
for a setup check, to ensure configuration is working correctly.
140+
To ease writing tests like that we provide the ``CheckServerResponseTrait`` trait.
141+
142+
The ``run`` function of the JavaScript modules setup check could look like:
143+
144+
.. code-block:: php
145+
146+
public function run(): SetupResult {
147+
// This is a real existing file
148+
$testFile = $this->urlGenerator->linkTo('settings', 'js/esm-test.mjs');
149+
150+
$noResponse = true;
151+
foreach ($this->runRequest('HEAD', $testFile) as $response) {
152+
$noResponse = false;
153+
if (preg_match('/(text|application)\/javascript/i', $response->getHeader('Content-Type'))) {
154+
return SetupResult::success();
155+
}
156+
}
157+
158+
if ($noResponse) {
159+
return SetupResult::warning($this->l10n->t('Unable to run check for JavaScript support.') . "\n" . $this->serverConfigHelp());
160+
}
161+
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.'));
162+
}
163+
164+
The ``runRequest`` is provided by the ``CheckServerResponseTrait``, it accepts a HTTP request method
165+
as the first parameter (in this example ``HEAD``) and an URL with an absolute path, so meaning
166+
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``.
167+
Internally the function requests that URL on all possible URLs (using the current host, the trusted domains and the cli overwrite URL),
168+
and then yields a result for each request.
169+
170+
``CheckServerResponseTrait::serverConfigHelp`` provides information about
171+
common pitfalls that prevent HTTP requests against the current server.
172+
If no response is yielded from the ``runRequest`` method then this information should be included.

0 commit comments

Comments
 (0)
Please sign in to comment.