Merge pull request #14603 from nextcloud/fix/noid/add-setup-check-for-s3-temp-path

Show a setup warning in case S3 object storage is used as primary storage
This commit is contained in:
Morris Jobke 2019-03-08 18:03:49 +01:00 committed by GitHub
commit d40b21ac81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 182 additions and 14 deletions

View File

@ -450,6 +450,18 @@
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
})
}
if (!data.isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed) {
messages.push({
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.',
{
docLink: oc_defaults.docPlaceholderUrl.replace('PLACEHOLDER', 'admin-mysql-utf8mb4'),
}
),
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
})
}
} else {
messages.push({

View File

@ -248,7 +248,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -299,7 +300,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -351,7 +353,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -401,7 +404,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -449,7 +453,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -499,7 +504,8 @@ describe('OC.SetupChecks tests', function() {
],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -547,7 +553,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -595,7 +602,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -643,7 +651,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -712,7 +721,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -761,7 +771,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -810,7 +821,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -859,7 +871,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -907,7 +920,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: true
isMysqlUsedWithoutUTF8MB4: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true
})
);
@ -919,6 +933,55 @@ describe('OC.SetupChecks tests', function() {
done();
});
});
it('should return an error if there is not enough free space in the temp directory', function(done) {
var async = OC.SetupChecks.checkSetup();
suite.server.requests[0].respond(
200,
{
'Content-Type': 'application/json',
},
JSON.stringify({
hasFileinfoInstalled: true,
isGetenvServerWorking: true,
isReadOnlyConfig: false,
hasWorkingFileLocking: true,
hasValidTransactionIsolationLevel: true,
suggestedOverwriteCliURL: '',
isRandomnessSecure: true,
securityDocs: 'https://docs.owncloud.org/myDocs.html',
serverHasInternetConnection: true,
isMemcacheConfigured: true,
forwardedForHeadersWorking: true,
isCorrectMemcachedPHPModuleInstalled: true,
hasPassedCodeIntegrityCheck: true,
isOpcacheProperlySetup: true,
hasOpcacheLoaded: true,
isSettimelimitAvailable: true,
hasFreeTypeSupport: true,
missingIndexes: [],
cronErrors: [],
cronInfo: {
diffInSeconds: 0
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: false
})
);
async.done(function( data, s, x ){
expect(data).toEqual([{
msg: '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.',
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
}]);
done();
});
});
});
describe('checkGeneric', function() {

View File

@ -628,6 +628,42 @@ Raw output
return $pendingColumns;
}
protected function isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(): bool {
$objectStore = $this->config->getSystemValue('objectstore', null);
$objectStoreMultibucket = $this->config->getSystemValue('objectstore_multibucket', null);
if (!isset($objectStoreMultibucket) && !isset($objectStore)) {
return true;
}
if (isset($objectStoreMultibucket['class']) && $objectStoreMultibucket['class'] !== 'OC\\Files\\ObjectStore\\S3') {
return true;
}
if (isset($objectStore['class']) && $objectStore['class'] !== 'OC\\Files\\ObjectStore\\S3') {
return true;
}
$tempPath = sys_get_temp_dir();
if (!is_dir($tempPath)) {
$this->logger->error('Error while checking the temporary PHP path - it was not properly set to a directory. value: ' . $tempPath);
return false;
}
$freeSpaceInTemp = disk_free_space($tempPath);
if ($freeSpaceInTemp === false) {
$this->logger->error('Error while checking the available disk space of temporary PHP path - no free disk space returned. temporary path: ' . $tempPath);
return false;
}
$freeSpaceInTempInGB = $freeSpaceInTemp / 1024 / 1024 / 1024;
if ($freeSpaceInTempInGB > 50) {
return true;
}
$this->logger->warning('Checking the available space in the temporary path resulted in ' . round($freeSpaceInTempInGB, 1) . ' GB instead of the recommended 50GB. Path: ' . $tempPath);
return false;
}
/**
* @return DataResponse
*/
@ -669,6 +705,7 @@ Raw output
'recommendedPHPModules' => $this->hasRecommendedPHPModules(),
'pendingBigIntConversionColumns' => $this->hasBigIntConversionPendingColumns(),
'isMysqlUsedWithoutUTF8MB4' => $this->isMysqlUsedWithoutUTF8MB4(),
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => $this->isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(),
]
);
}

View File

@ -160,6 +160,7 @@ class CheckSetupControllerTest extends TestCase {
'hasRecommendedPHPModules',
'hasBigIntConversionPendingColumns',
'isMysqlUsedWithoutUTF8MB4',
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed',
])->getMock();
}
@ -526,6 +527,11 @@ class CheckSetupControllerTest extends TestCase {
->method('isMysqlUsedWithoutUTF8MB4')
->willReturn(false);
$this->checkSetupController
->expects($this->once())
->method('isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed')
->willReturn(true);
$expected = new DataResponse(
[
'isGetenvServerWorking' => true,
@ -570,6 +576,7 @@ class CheckSetupControllerTest extends TestCase {
'recommendedPHPModules' => [],
'pendingBigIntConversionColumns' => [],
'isMysqlUsedWithoutUTF8MB4' => false,
'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed' => true,
]
);
$this->assertEquals($expected, $this->checkSetupController->check());
@ -1400,4 +1407,53 @@ Array
$this->assertSame($expected, $this->invokePrivate($checkSetupController, 'isMysqlUsedWithoutUTF8MB4'));
}
public function dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed() {
return [
['singlebucket', 'OC\\Files\\ObjectStore\\Swift', true],
['multibucket', 'OC\\Files\\ObjectStore\\Swift', true],
['singlebucket', 'OC\\Files\\ObjectStore\\Custom', true],
['multibucket', 'OC\Files\\ObjectStore\\Custom', true],
['singlebucket', 'OC\Files\ObjectStore\Swift', true],
['multibucket', 'OC\Files\ObjectStore\Swift', true],
['singlebucket', 'OC\Files\ObjectStore\Custom', true],
['multibucket', 'OC\Files\ObjectStore\Custom', true],
];
}
/**
* @dataProvider dataForIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed
*/
public function testIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(string $mode, string $className, bool $expected) {
$this->config->method('getSystemValue')
->will($this->returnCallback(function($key, $default) use ($mode, $className) {
if ($key === 'objectstore' && $mode === 'singlebucket') {
return ['class' => $className];
}
if ($key === 'objectstore_multibucket' && $mode === 'multibucket') {
return ['class' => $className];
}
return $default;
}));
$checkSetupController = new CheckSetupController(
'settings',
$this->request,
$this->config,
$this->clientService,
$this->urlGenerator,
$this->util,
$this->l10n,
$this->checker,
$this->logger,
$this->dispatcher,
$this->db,
$this->lockingProvider,
$this->dateTimeFormatter,
$this->memoryInfo,
$this->secureRandom
);
$this->assertSame($expected, $this->invokePrivate($checkSetupController, 'isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed'));
}
}