Bug #66341
closedprocessing folders are not created by upgrade wizard, forcing specific workflow during migration
100%
Description
When migrating a website from 4.5 to 6.2, the upgrade wizard does not fully initialize the automatically created FAL storage as it does not create any processing folders. This becomes an issue if getFile
is called on an instance of ResourceStorage
which has evaluatePermissions
set to true
, which is the case if e.g. dam_falmigration is being run from CLI with command php typo3/cli_dispatch.phpsh extbase dammigration:migratedamrecords
. This results in a loop inside ResourceStorage
; with custom debugging output to trace the loop (each number corresponds to a specific function, described on the a
-line, each character to another line in that function):
1a entry TYPO3\CMS\Core\Resource\ResourceStorage::getFile, uid 1, identifier user_upload/folder/file.jpg 2a entry TYPO3\CMS\Core\Resource\ResourceFactory::getFileObjectByStorageAndIdentifier, uid 1 file identifier user_upload/folder/file.jpg 2b checking $storage->isWithinProcessingFolder($fileIdentifier) 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier user_upload/folder/file.jpg 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / 7c folder === null? 7e read check 7g write check 7h $isWriteCheck = TRUE 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8c $this->evaluatePermissions true 8e get identifier 8f identifier: /, next call is isWithinProcessingFolder 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier / 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / ...
What happens is that TYPO3\CMS\Core\Resource\ResourceStorage::getFile
implicitely checks if processing folders have already been created but they haven't yet. Using isWithinProcessingFolder
, TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission
then checks if the storage's root folder /
belongs to the processing folder. Since evaluatePermissions
is true
, this results in getting the processing folders yet again in an inifinite recursion as the processing folder still not exists, permissions are being checked again and everything repeats.
When the filelist module is being called for the first time by a backend user, the same debugging code produces a partial (incompletely commented) output of:
7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: / 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /templates/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /user_upload/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /_temp_/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action add, folder identifier: / 7c folder === null? 7e read check 7g write check 7h $isWriteCheck = TRUE 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6f permitted 6g creating folder $this->getDriver()->createFolder($folderName = "_processed_", $parentFolder->getIdentifier() = "/", TRUE) 6h now getting folder /_processed_/ 7a entry TYPO3\CMS\Core\Resource\ResourceStorage::checkFolderActionPermission; checking folder action read, folder identifier: /_processed_/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6i emitting post folder add signal 6j done
It's visible that certain folders are initially created only when first checked by the filelist module. Note that there is no line 8c $this->evaluatePermissions true
if filelist is called, so evaluatePermissions
is false
. This prevents the loop that's happening on CLI.
Afterwards, dam_falmigration
does work as expected as the processing folder has already been created and the looping check is no longer performed:
1a entry TYPO3\CMS\Core\Resource\ResourceStorage::getFile, uid 1, identifier user_upload/folder/file.jpg 2a entry TYPO3\CMS\Core\Resource\ResourceFactory::getFileObjectByStorageAndIdentifier, uid 1 file identifier user_upload/folder/file.jpg 2b checking $storage->isWithinProcessingFolder($fileIdentifier) 3a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinProcessingFolder with identifier user_upload/folder/file.jpg 3b starting iteration over getProcessingFolders() 4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5i folder already exists 5j got data
dam_falmigration
does not manipulate evaluatePermissions
, so this appears to be a bug in Core...
I could imagine two ways to fix this:
- When the upgrade wizard is creating a FAL storage for the first time, it should initialize all folders that would otherwise only be created upon entering filelist module for the first time. Or:
checkFolderActionPermission
should skip theisWithinProcessingFolder
check if the storage root folder/
is being checked as the expected result should always befalse
? Note that this assumption should be verified by the FAL/Core team; I'm primarily a user and don't know much about those internals of TYPO3. :)
A workaround, obviously, is to call the BE module filelist immediately upon migration, before trying to do anything else. But that shouldn't be necessary in my opinion - what's the upgrade wizard for?
Files
Updated by Frans Saris over 9 years ago
- Status changed from New to Needs Feedback
What version of 6.2 are you using? The processed folder is part of the required folders since last release and should show if you open the install tool. Not sure if creating the required folders is part of a upgrade wizard.
Updated by Daniel Neugebauer over 9 years ago
6.2.11, which is the latest released version.
In "Folder structure" the install tool only lists /typo3temp/_processed_
but apparently /fileadmin/_processed_
is needed? It does list /fileadmin/_temp_
however, as well as /fileadmin/user_upload/_temp_
. The following special (_*_
) directories exist after auto-creation succeeded:
htdocs # find . -type d -name _\*_ ./fileadmin/_temp_ ./fileadmin/_processed_ ./fileadmin/user_upload/_temp_ ./typo3temp/_processed_ ./typo3_src/typo3/sysext/impexp/Tests/Functional/Fixtures/Folders/fileadmin/_processed_
Tomorrow, I'll reset the webspace to the last state before migration and check again what it looks like if only the install tool has completed (both after folder structure check and after fileadmin storage creation). I did however run all folder checks before and let the install tool fix what it wanted to change (all changes succeeded, another check saying all folders exist and are writable), so it looks like some folders simply are not part of those checks and also missed by the upgrade tool.
Updated by Daniel Neugebauer over 9 years ago
- File install-tool-before.png install-tool-before.png added
- File install-tool-after.png install-tool-after.png added
- File FilemountUpdateWizard_create_processing_folders.patch FilemountUpdateWizard_create_processing_folders.patch added
I checked again and attached screenshots from before and after clicking "try to fix file and folder permissions" on the "folder structure" module.
On 4.5 special folders were only:
htdocs # find . -type d -name _\*_ ./fileadmin/_temp_ ./fileadmin/user_upload/_temp_
After 6.2's folder structure module fixed what it wanted and before running anything in "Important actions" and "Upgrade Wizard":
htdocs # find . -type d -name _\*_ ./fileadmin/_temp_ ./fileadmin/user_upload/_temp_ ./typo3temp/_processed_ ./typo3_src/typo3/sysext/impexp/Tests/Functional/Fixtures/Folders/fileadmin/_processed_
I then ran all points on "Important Actions" top-to-bottom.
When running the upgrade wizard afterwards, I let it print all queries:
Migrate existing filemounts to be file abstraction layer compatible. UPDATE sys_filemounts SET base='1',path='/user_upload' WHERE uid=1
The file system remains unchanged:
htdocs # find . -type d -name _\*_ ./fileadmin/_temp_ ./fileadmin/user_upload/_temp_ ./typo3temp/_processed_ ./typo3_src/typo3/sysext/impexp/Tests/Functional/Fixtures/Folders/fileadmin/_processed_
None of the code I added tracing output to debug the loop got called up to that point.
I'm also attaching a patch for the FilemountUpdateWizard
which simply runs getProcessingFolders
on all storages to implicitely create those folders after the database update, resulting in the following calls being made:
4a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolders 4b instantiation of TYPO3\CMS\Core\Resource\StorageRepository 4c find all on storage repository 4d iterate over all storages 4e storage uid 1, name fileadmin/ (auto-created) 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5b processing folder is not set 5c default set 5e processingfolder is _processed_ 5g checking processing folder _processed_ 5h creating folder 6a entry TYPO3\CMS\Core\Resource\ResourceStorage::createFolder 6b parent folder is null => using root level folder 6d going to check if add is a permitted folder action 7c folder === null? 7e read check 7g write check 7h $isWriteCheck = TRUE 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6f permitted 6g creating folder $this->getDriver()->createFolder($folderName = "_processed_", $parentFolder->getIdentifier() = "/", TRUE) 6h now getting folder /_processed_/ 7c folder === null? 7e read check 7f $isReadCheck = TRUE 7g write check 7i Check 2: Does the user has the right to perform the action? 8a entry TYPO3\CMS\Core\Resource\ResourceStorage::isWithinFileMountBoundaries 8b !$this->evaluatePermissions 7k 7m 7o 7p 7r 7t 6i emitting post folder add signal 6j done 5k done getting processing folder 4f $storage->getProcessingFolder()->getStorage() is $this, adding $this->getProcessingFolder() to array 5a entry TYPO3\CMS\Core\Resource\ResourceStorage::getProcessingFolder 5k done getting processing folder 4g done getting processing folders
Running damfalmigration
via CLI then works fine without having to call the "Filelist" module on BE first.
Updated by Frans Saris over 9 years ago
- Status changed from Needs Feedback to Accepted
Your patch seems valid. Could you maybe push it to review.typo3.org?
Updated by Gerrit Code Review over 9 years ago
- Status changed from Accepted to Under Review
Patch set 1 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/38622
Updated by Gerrit Code Review about 9 years ago
Patch set 2 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/38622
Updated by Gerrit Code Review almost 9 years ago
Patch set 3 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/38622
Updated by Gerrit Code Review almost 9 years ago
Patch set 4 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/38622
Updated by Anonymous almost 9 years ago
- Status changed from Under Review to Resolved
- % Done changed from 0 to 100
Applied in changeset 5046f6e648a28cb9212cf0f9a99a8a385c54c959.