Skip to content

Commit 7c79521

Browse files
Merge pull request #42839 from nextcloud/enh/migrate-s3tempspace-setupcheck
Migrate available temp space check to new SetupCheck API
2 parents 723b9f4 + 9add64f commit 7c79521

8 files changed

Lines changed: 130 additions & 206 deletions

File tree

apps/settings/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => $baseDir . '/../lib/SetupChecks/ReadOnlyConfig.php',
111111
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => $baseDir . '/../lib/SetupChecks/SupportedDatabase.php',
112112
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => $baseDir . '/../lib/SetupChecks/SystemIs64bit.php',
113+
'OCA\\Settings\\SetupChecks\\TempSpaceAvailable' => $baseDir . '/../lib/SetupChecks/TempSpaceAvailable.php',
113114
'OCA\\Settings\\SetupChecks\\TransactionIsolation' => $baseDir . '/../lib/SetupChecks/TransactionIsolation.php',
114115
'OCA\\Settings\\UserMigration\\AccountMigrator' => $baseDir . '/../lib/UserMigration/AccountMigrator.php',
115116
'OCA\\Settings\\UserMigration\\AccountMigratorException' => $baseDir . '/../lib/UserMigration/AccountMigratorException.php',

apps/settings/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class ComposerStaticInitSettings
125125
'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => __DIR__ . '/..' . '/../lib/SetupChecks/ReadOnlyConfig.php',
126126
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => __DIR__ . '/..' . '/../lib/SetupChecks/SupportedDatabase.php',
127127
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => __DIR__ . '/..' . '/../lib/SetupChecks/SystemIs64bit.php',
128+
'OCA\\Settings\\SetupChecks\\TempSpaceAvailable' => __DIR__ . '/..' . '/../lib/SetupChecks/TempSpaceAvailable.php',
128129
'OCA\\Settings\\SetupChecks\\TransactionIsolation' => __DIR__ . '/..' . '/../lib/SetupChecks/TransactionIsolation.php',
129130
'OCA\\Settings\\UserMigration\\AccountMigrator' => __DIR__ . '/..' . '/../lib/UserMigration/AccountMigrator.php',
130131
'OCA\\Settings\\UserMigration\\AccountMigratorException' => __DIR__ . '/..' . '/../lib/UserMigration/AccountMigratorException.php',

apps/settings/lib/AppInfo/Application.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
use OCA\Settings\SetupChecks\ReadOnlyConfig;
8383
use OCA\Settings\SetupChecks\SupportedDatabase;
8484
use OCA\Settings\SetupChecks\SystemIs64bit;
85+
use OCA\Settings\SetupChecks\TempSpaceAvailable;
8586
use OCA\Settings\SetupChecks\TransactionIsolation;
8687
use OCA\Settings\UserMigration\AccountMigrator;
8788
use OCA\Settings\WellKnown\ChangePasswordHandler;
@@ -206,6 +207,7 @@ public function register(IRegistrationContext $context): void {
206207
$context->registerSetupCheck(ReadOnlyConfig::class);
207208
$context->registerSetupCheck(SupportedDatabase::class);
208209
$context->registerSetupCheck(SystemIs64bit::class);
210+
$context->registerSetupCheck(TempSpaceAvailable::class);
209211
$context->registerSetupCheck(TransactionIsolation::class);
210212

211213
$context->registerUserMigrator(AccountMigrator::class);

apps/settings/lib/Controller/CheckSetupController.php

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
use OCP\IConfig;
5656
use OCP\IL10N;
5757
use OCP\IRequest;
58-
use OCP\ITempManager;
5958
use OCP\IURLGenerator;
6059
use OCP\Notification\IManager;
6160
use OCP\SetupCheck\ISetupCheckManager;
@@ -73,8 +72,6 @@ class CheckSetupController extends Controller {
7372
private $checker;
7473
/** @var LoggerInterface */
7574
private $logger;
76-
/** @var ITempManager */
77-
private $tempManager;
7875
/** @var IManager */
7976
private $manager;
8077
private ISetupCheckManager $setupCheckManager;
@@ -86,7 +83,6 @@ public function __construct($AppName,
8683
IL10N $l10n,
8784
Checker $checker,
8885
LoggerInterface $logger,
89-
ITempManager $tempManager,
9086
IManager $manager,
9187
ISetupCheckManager $setupCheckManager,
9288
) {
@@ -96,7 +92,6 @@ public function __construct($AppName,
9692
$this->l10n = $l10n;
9793
$this->checker = $checker;
9894
$this->logger = $logger;
99-
$this->tempManager = $tempManager;
10095
$this->manager = $manager;
10196
$this->setupCheckManager = $setupCheckManager;
10297
}
@@ -192,52 +187,6 @@ public function getFailedIntegrityCheckFiles(): DataDisplayResponse {
192187
);
193188
}
194189

195-
private function isTemporaryDirectoryWritable(): bool {
196-
try {
197-
if (!empty($this->tempManager->getTempBaseDir())) {
198-
return true;
199-
}
200-
} catch (\Exception $e) {
201-
}
202-
return false;
203-
}
204-
205-
protected function isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(): bool {
206-
$objectStore = $this->config->getSystemValue('objectstore', null);
207-
$objectStoreMultibucket = $this->config->getSystemValue('objectstore_multibucket', null);
208-
209-
if (!isset($objectStoreMultibucket) && !isset($objectStore)) {
210-
return true;
211-
}
212-
213-
if (isset($objectStoreMultibucket['class']) && $objectStoreMultibucket['class'] !== 'OC\\Files\\ObjectStore\\S3') {
214-
return true;
215-
}
216-
217-
if (isset($objectStore['class']) && $objectStore['class'] !== 'OC\\Files\\ObjectStore\\S3') {
218-
return true;
219-
}
220-
221-
$tempPath = sys_get_temp_dir();
222-
if (!is_dir($tempPath)) {
223-
$this->logger->error('Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: ' . $tempPath);
224-
return false;
225-
}
226-
$freeSpaceInTemp = function_exists('disk_free_space') ? disk_free_space($tempPath) : false;
227-
if ($freeSpaceInTemp === false) {
228-
$this->logger->error('Error while checking the available disk space of temporary PHP path or no free disk space returned. Temporary path: ' . $tempPath);
229-
return false;
230-
}
231-
232-
$freeSpaceInTempInGB = $freeSpaceInTemp / 1024 / 1024 / 1024;
233-
if ($freeSpaceInTempInGB > 50) {
234-
return true;
235-
}
236-
237-
$this->logger->warning('Checking the available space in the temporary path resulted in ' . round($freeSpaceInTempInGB, 1) . ' GB instead of the recommended 50GB. Path: ' . $tempPath);
238-
return false;
239-
}
240-
241190
/**
242191
* @return DataResponse
243192
* @AuthorizedAdminSetting(settings=OCA\Settings\Settings\Admin\Overview)
@@ -247,9 +196,7 @@ public function check() {
247196
[
248197
'isFairUseOfFreePushService' => $this->isFairUseOfFreePushService(),
249198
'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
250-
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => $this->isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(),
251199
'reverseProxyGeneratedURL' => $this->urlGenerator->getAbsoluteURL('index.php'),
252-
'temporaryDirectoryWritable' => $this->isTemporaryDirectoryWritable(),
253200
'generic' => $this->setupCheckManager->runAll(),
254201
]
255202
);
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com>
7+
*
8+
* @author Côme Chilliet <come.chilliet@nextcloud.com>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*
25+
*/
26+
namespace OCA\Settings\SetupChecks;
27+
28+
use OCP\IConfig;
29+
use OCP\IL10N;
30+
use OCP\ITempManager;
31+
use OCP\IURLGenerator;
32+
use OCP\SetupCheck\ISetupCheck;
33+
use OCP\SetupCheck\SetupResult;
34+
35+
class TempSpaceAvailable implements ISetupCheck {
36+
public function __construct(
37+
private IL10N $l10n,
38+
private IConfig $config,
39+
private IURLGenerator $urlGenerator,
40+
private ITempManager $tempManager,
41+
) {
42+
}
43+
44+
public function getName(): string {
45+
return $this->l10n->t('Temporary space available');
46+
}
47+
48+
public function getCategory(): string {
49+
return 'system';
50+
}
51+
52+
private function isPrimaryStorageS3(): bool {
53+
$objectStore = $this->config->getSystemValue('objectstore', null);
54+
$objectStoreMultibucket = $this->config->getSystemValue('objectstore_multibucket', null);
55+
56+
if (!isset($objectStoreMultibucket) && !isset($objectStore)) {
57+
return false;
58+
}
59+
60+
if (isset($objectStoreMultibucket['class']) && $objectStoreMultibucket['class'] !== 'OC\\Files\\ObjectStore\\S3') {
61+
return false;
62+
}
63+
64+
if (isset($objectStore['class']) && $objectStore['class'] !== 'OC\\Files\\ObjectStore\\S3') {
65+
return false;
66+
}
67+
68+
return true;
69+
}
70+
71+
public function run(): SetupResult {
72+
$phpTempPath = sys_get_temp_dir();
73+
$nextcloudTempPath = '';
74+
try {
75+
$nextcloudTempPath = $this->tempManager->getTempBaseDir();
76+
} catch (\Exception $e) {
77+
}
78+
79+
if (empty($nextcloudTempPath)) {
80+
return SetupResult::error('The temporary directory of this instance points to an either non-existing or non-writable directory.');
81+
}
82+
83+
if (!is_dir($phpTempPath)) {
84+
return SetupResult::error($this->l10n->t('Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s', [$phpTempPath]));
85+
}
86+
87+
$freeSpaceInTemp = function_exists('disk_free_space') ? disk_free_space($phpTempPath) : false;
88+
if ($freeSpaceInTemp === false) {
89+
return SetupResult::error($this->l10n->t('Error while checking the available disk space of temporary PHP path or no free disk space returned. Temporary path: %s', [$phpTempPath]));
90+
}
91+
92+
/** Build details data about temporary directory, either one or two of them */
93+
$freeSpaceInTempInGB = $freeSpaceInTemp / 1024 / 1024 / 1024;
94+
$spaceDetail = $this->l10n->t('- %.1f GiB available in %s (PHP temporary directory)', [round($freeSpaceInTempInGB, 1),$phpTempPath]);
95+
if ($nextcloudTempPath !== $phpTempPath) {
96+
$freeSpaceInNextcloudTemp = function_exists('disk_free_space') ? disk_free_space($nextcloudTempPath) : false;
97+
if ($freeSpaceInNextcloudTemp === false) {
98+
return SetupResult::error($this->l10n->t('Error while checking the available disk space of temporary PHP path or no free disk space returned. Temporary path: %s', [$nextcloudTempPath]));
99+
}
100+
$freeSpaceInNextcloudTempInGB = $freeSpaceInNextcloudTemp / 1024 / 1024 / 1024;
101+
$spaceDetail .= "\n".$this->l10n->t('- %.1f GiB available in %s (Nextcloud temporary directory)', [round($freeSpaceInNextcloudTempInGB, 1),$nextcloudTempPath]);
102+
}
103+
104+
if (!$this->isPrimaryStorageS3()) {
105+
return SetupResult::success(
106+
$this->l10n->t("Temporary directory is correctly configured:\n%s", [$spaceDetail])
107+
);
108+
}
109+
110+
if ($freeSpaceInTempInGB > 50) {
111+
return SetupResult::success(
112+
$this->l10n->t(
113+
"This instance uses an S3 based object store as primary storage, and has enough space in the temporary directory.\n%s",
114+
[$spaceDetail]
115+
)
116+
);
117+
}
118+
119+
return SetupResult::warning(
120+
$this->l10n->t(
121+
"This instance uses an S3 based object store as primary storage. The uploaded files are stored temporarily on the server and thus it is recommended to have 50 GiB of free space available in the temp directory of PHP. To improve this please change the temporary directory in the php.ini or make more space available in that path. \nChecking the available space in the temporary path resulted in %.1f GiB instead of the recommended 50 GiB. Path: %s",
122+
[round($freeSpaceInTempInGB, 1),$phpTempPath]
123+
)
124+
);
125+
}
126+
}

apps/settings/tests/Controller/CheckSetupControllerTest.php

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
use OCP\IConfig;
4444
use OCP\IL10N;
4545
use OCP\IRequest;
46-
use OCP\ITempManager;
4746
use OCP\IURLGenerator;
4847
use OCP\Notification\IManager;
4948
use OCP\SetupCheck\ISetupCheckManager;
@@ -72,8 +71,6 @@ class CheckSetupControllerTest extends TestCase {
7271
private $logger;
7372
/** @var Checker|\PHPUnit\Framework\MockObject\MockObject */
7473
private $checker;
75-
/** @var ITempManager|\PHPUnit\Framework\MockObject\MockObject */
76-
private $tempManager;
7774
/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
7875
private $notificationManager;
7976
/** @var ISetupCheckManager|MockObject */
@@ -98,7 +95,6 @@ protected function setUp(): void {
9895
$this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker')
9996
->disableOriginalConstructor()->getMock();
10097
$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
101-
$this->tempManager = $this->getMockBuilder(ITempManager::class)->getMock();
10298
$this->notificationManager = $this->getMockBuilder(IManager::class)->getMock();
10399
$this->setupCheckManager = $this->createMock(ISetupCheckManager::class);
104100
$this->checkSetupController = $this->getMockBuilder(CheckSetupController::class)
@@ -110,15 +106,13 @@ protected function setUp(): void {
110106
$this->l10n,
111107
$this->checker,
112108
$this->logger,
113-
$this->tempManager,
114109
$this->notificationManager,
115110
$this->setupCheckManager,
116111
])
117112
->setMethods([
118113
'getCurlVersion',
119114
'isPhpOutdated',
120115
'isPHPMailerUsed',
121-
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed',
122116
])->getMock();
123117
}
124118

@@ -141,11 +135,6 @@ public function testCheck() {
141135
$this->request->expects($this->never())
142136
->method('getHeader');
143137

144-
$this->checkSetupController
145-
->expects($this->once())
146-
->method('isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed')
147-
->willReturn(true);
148-
149138
$this->urlGenerator->method('linkToDocs')
150139
->willReturnCallback(function (string $key): string {
151140
if ($key === 'admin-performance') {
@@ -180,10 +169,8 @@ public function testCheck() {
180169
$expected = new DataResponse(
181170
[
182171
'reverseProxyDocs' => 'reverse-proxy-doc-link',
183-
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => true,
184172
'reverseProxyGeneratedURL' => 'https://server/index.php',
185173
'isFairUseOfFreePushService' => false,
186-
'temporaryDirectoryWritable' => false,
187174
'generic' => [],
188175
]
189176
);
@@ -645,48 +632,4 @@ public function testGetFailedIntegrityCheckFilesWithSomeErrorsFound() {
645632
);
646633
$this->assertEquals($expected, $this->checkSetupController->getFailedIntegrityCheckFiles());
647634
}
648-
649-
public function dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed() {
650-
return [
651-
['singlebucket', 'OC\\Files\\ObjectStore\\Swift', true],
652-
['multibucket', 'OC\\Files\\ObjectStore\\Swift', true],
653-
['singlebucket', 'OC\\Files\\ObjectStore\\Custom', true],
654-
['multibucket', 'OC\Files\\ObjectStore\\Custom', true],
655-
['singlebucket', 'OC\Files\ObjectStore\Swift', true],
656-
['multibucket', 'OC\Files\ObjectStore\Swift', true],
657-
['singlebucket', 'OC\Files\ObjectStore\Custom', true],
658-
['multibucket', 'OC\Files\ObjectStore\Custom', true],
659-
];
660-
}
661-
662-
/**
663-
* @dataProvider dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed
664-
*/
665-
public function testIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(string $mode, string $className, bool $expected) {
666-
$this->config->method('getSystemValue')
667-
->willReturnCallback(function ($key, $default) use ($mode, $className) {
668-
if ($key === 'objectstore' && $mode === 'singlebucket') {
669-
return ['class' => $className];
670-
}
671-
if ($key === 'objectstore_multibucket' && $mode === 'multibucket') {
672-
return ['class' => $className];
673-
}
674-
return $default;
675-
});
676-
677-
$checkSetupController = new CheckSetupController(
678-
'settings',
679-
$this->request,
680-
$this->config,
681-
$this->urlGenerator,
682-
$this->l10n,
683-
$this->checker,
684-
$this->logger,
685-
$this->tempManager,
686-
$this->notificationManager,
687-
$this->setupCheckManager,
688-
);
689-
690-
$this->assertSame($expected, $this->invokePrivate($checkSetupController, 'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed'));
691-
}
692635
}

core/js/setupchecks.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,6 @@
189189
});
190190
}
191191

192-
if (!data.isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed) {
193-
messages.push({
194-
msg: t('core', 'This instance uses an S3 based object store as primary storage. The uploaded files are stored temporarily on the server and thus it is recommended to have 50 GB of free space available in the temp directory of PHP. Check the logs for full details about the path and the available space. To improve this please change the temporary directory in the php.ini or make more space available in that path.'),
195-
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
196-
})
197-
}
198-
if (!data.temporaryDirectoryWritable) {
199-
messages.push({
200-
msg: t('core', 'The temporary directory of this instance points to an either non-existing or non-writable directory.'),
201-
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
202-
})
203-
}
204192
if (window.location.protocol === 'https:' && data.reverseProxyGeneratedURL.split('/')[0] !== 'https:') {
205193
messages.push({
206194
msg: t('core', 'You are accessing your instance over a secure connection, however your instance is generating insecure URLs. This most likely means that you are behind a reverse proxy and the overwrite config variables are not set correctly. Please read {linkstart}the documentation page about this ↗{linkend}.')

0 commit comments

Comments
 (0)