Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
One common way of using config will be:
- Site Builder A: Export files to a directory
- Server: Import the exported files from that directory
As we see, the webserver never needs the staging directory to the writeable, but Drupal complains about it,
see core/modules/system/system.install:409
Proposed resolution
- System module does not require the staging directory to be writeable
- Config module has a warning if the staging directory is not writeable
- System module requires that the $config_directories has a 'sync' key because config.storage.staging relies on it
- System module requires that all directories listed in $config_directories exist
Note this resolution does not do
Require the active directory writeable, in case the site uses file storage
because that should be the responsibility of who ever swaps out the storage (imo).
Remaining tasks
User interface changes
New UI text
API changes
None
Comment | File | Size | Author |
---|---|---|---|
#67 | interdiff-2466197.txt | 1.98 KB | Crell |
#67 | 2466197-staging-dir.patch | 16.32 KB | Crell |
#55 | 49-55-interdiff.txt | 1.61 KB | alexpott |
#49 | 2466197-49.patch | 16.53 KB | alexpott |
#49 | 48-49-interdiff.txt | 576 bytes | alexpott |
Comments
Comment #1
dawehnerComment #2
xjmAgreed, there is no longer any functionality in the UI that needs to write to the staging directory, so core does not need to require it to be writeable. A contributed module supporting a UI-to-staging workflow could add this requirement if desired.
Comment #3
alexpott+1
Comment #4
alexpottLooking at this issue again. I think we should remove all automatic creation of the directories listed in the $config_directories global and all testing of them in system_requirements.
Also as it is a very debatable security practice store active config in sites/default/files it is questionable whether we should create a $config_directories['sync'] setting during install at all.
Comment #5
alexpottI guess the question is what can we get away with in Drupal 8. And thinking about this some more - actually we do write to the sync directory - we write there if we import a tarball.
Comment #6
alexpottSo if this issue is to proceed is going to need to make the ConfigSync UI detect whether or not the sync directory is writable before trying to upload the tarball.
I think the generic config directory checking beyond existence of directory should be removed from system_requirements. The config module should add a check that the sync directory is writeable - since it provides the UI that requires it. And the import tarball form needs to be tested to ensure it handles this type of error properly.
Comment #7
alexpottComment #8
alexpottComment #10
alexpottComment #11
alexpottHere's tests.
Comment #12
alexpottUpdated IS to reflect solution in #11.
Comment #14
alexpottComment #15
dawehnerIt is weird, that we don't have a more specific exception, but well, this is how it is.
Do we check before the import from a tarball whether the folder is writeable already?
Should we explain why this directory has to be writeable?
Comment #16
alexpottThanks for the review @dawehner.
Comment #17
dawehnerYeah sure.
Cool, thank you alex
Comment #18
catchThe issue summary talks about not warning about this - because you can run a site fine without it. But this is still warning about it - should it just be a notice?
What about doing this check in the form builder itself too, and warning there?
Comment #19
alexpottre #18.1 This warning only occurs if you have the config module installed which I think is the desired behaviour as this is the only place that can write to this directory - updated IS to just describe the current resolution.
Comment #20
alexpottPatch addresses #18.2 - we now check and display a message is the folder is not writable before uploading. Seems polite.
Comment #21
tstoecklerCouldn't this just be:
?
Edit: Or do we want to support people actively setting the directory to FALSE?
Comment #23
alexpott@tstoeckler because \Exception is such a general exception I didn't want to falsely catch anything coming form that.
Comment #24
alexpottDrupal\system\Tests\Routing\RouterTest::testControllerResolutionPage
failed... nothing to do with this.Comment #25
tstoecklerAhh, that's smart!
Comment #26
alexpott@tstoeckler I've created #2696103: \Drupal\Core\Config\FileStorageFactory::getSync() should throw a more specific exception to address this and added a comment.
Comment #27
alexpottSo if the directory is not writable what should we do here? At the moment this is going to break - I think we should eat this error. `if staging is not writable you're not doing a standard install of drupal with config in the files directory - therefore it is up to you to secure it. You might not even be using apache so this could be pointless.
Comment #28
pjcdawkins CreditAttribution: pjcdawkins at Platform.sh commentedif ($staging && is_dir($staging) && is_writable($staging)) {
file_save_htaccess()
defaults to TRUE anyway, so that could be removed.Little typo here
This comment could be a bit more descriptive!
Can we change "
the name of a directories in which configuration files can be written.
" to "the names of directories in which configuration files can be found.
" ?Comment #29
alexpottThanks for the review @pjcdawkins. Fixed 2-4.
Point 1 is super tricky. I think we should err on the side of caution and if the staging directory is not writable and does not have an .htaccess file just let it log the security warning. Because if the directory is web accessible then this security warning is a good idea.
I was wrong in #27 - nothing is going to break if the directory does not exist or is not writable we're just going to log a warning.
Comment #30
alexpottGiving @pjcdawkins credit on this issue because of the work on #2607352: The installer, updater and status report needlessly require $config_directories to be writable
Comment #31
Crell CreditAttribution: Crell at Platform.sh commentedThe flag is unnecessary. Put the file_save_htaccess() in the try block, and then an empty catch (with comment saying why it's empty). Same result, but cleaner and shorter.
Comment #32
alexpott@Crell see #23/#2696103: \Drupal\Core\Config\FileStorageFactory::getSync() should throw a more specific exception - I'd agree if the exception caught was more specific.
Comment #33
alexpottAnd there's a @todo about this already :)
Comment #34
heddnThe tests must not be testing every scenario. This currently is causing my platformsh build to fail because the filesystem is mounted as read-only and I'm getting following error. I'm running 8.1.1.
Comment #35
rachel_norfolkOh? With reference to #34 I have the following
In my composer.json and platform.sh seems happy?
Comment #36
heddnRe-roll is needed. Next up, is a patch that should get things working again.
re #35, it could be that the difference here is that I'm using config_installer and/or 8.1.1?
Comment #37
heddnLet's see if this fixes the problem on platform.
Comment #38
heddnComment #39
heddnComment #40
heddnComment #41
heddnDropped a test since it doesn't apply cleanly on 8.1.1.
Comment #43
heddnComment #45
heddnComment #46
alexpottCreated #2723411: Test the .htaccess added config sync directory to make this even simpler.
Comment #47
alexpott@heddn I'm not sure what you been trying to do in the patches from #37 onwards however I'm aware that there still is a problem during installation so what I'm going to do is work from #36 and rebase this on top of #2723411: Test the .htaccess added config sync directory and then add test coverage of having a read-only sync directory during install. I believe doing this will resolve the issues on platform.sh and will the config_installer.
Comment #48
alexpottWow we really want the sync directory to be writable!
Comment #49
alexpottSo we can actually deprecate
install_ensure_config_directory()
because its only usage is the deprecated version of KernelTestBase.Comment #51
heddnComment #52
heddnLinking #2156401: Write install_profile value to configuration and only to settings.php if it is writeable
Comment #53
pjcdawkins CreditAttribution: pjcdawkins at Platform.sh commentedLooks like this should still be Needs review for #49
Comment #54
alexpott@pjcdawkins #2723411: Test the .htaccess added config sync directory needs review before this one.
Comment #55
alexpottI've backtracked on #2723411: Test the .htaccess added config sync directory because @neclimdul had valid security concerns and turned it into a test only patch. Here's an updated patch that removes the requirement to be writable but leaves the htaccess thing alone and documents it. I think it is acceptable to write an error to the log if a .htaccess is missing since this is the safest thing to do. Even if the sync directory is not served by apache or not available to the server it might be moved in the future and future-yous could assume it is safe when it's not because the usual htaccess is missing.
As much as I'd love to see this 8.1.x there are string changes so I think this should only be for 8.2.x.
Comment #57
alexpottComment #58
dawehnerShould we stop setting up the the setting, if we could not write in the first place?
Its weird to replace one of the few actual usages of install_ensure_config_directory and replace it with something else. Can't we have an api function which does what you need?
I'm wondering whether conceptually this totally belongs into config module, given that config is really just config UI. You can sync with just drush easily.
Mh, its not entirely obvious why we cannot import a from a tar when the folder is not writeable ... one could extract the file in memory and do everything in memory, or store things temporarily somewhere else. I think this is more of a temporary workaround?
Comment #59
alexpottThanks for the review @dawehner
\Drupal::service('site.path') . '/files/config_' . $config_directories_hash . '/sync',
- this has to be writable. Slightly altered the code flow to make this more obvious.Comment #60
alexpottMore on the config_requirements() - here we are testing that the webserver has write access. And as said before, the only place in core this is required is the Config UI module.
Comment #61
dawehnerGotcha!
Comment #62
Crell CreditAttribution: Crell at Platform.sh commentedThis does apply to 8.1 and works currently. It's also required for D8 running properly on Platform.sh. Is there any way we could manage an 8.1 backport? (I'm happy to do the reroll for it if so.) We'd really hate to require a patch file for the next 5 months. :-(
Comment #63
alexpottSo there's no API change here really. The changes that block this going in to 8.1.x are all translatable string changes or additions. In mitigation all of these strings are completely admin facing and not just regular admin - they are sitebuilder/siteowner facing whilst doing config operations or viewing the site report. Also existing sites should never see these messages because they all have had to had writable config directories.
I can't make the call on whether to put this in 8.1.x - that needs to be a release manager - either @catch or @xjm.
Comment #64
tstoecklerObviously I can't make a decision either way here, but:
This is an important point, I didn't realize that so far. Thanks for pointing that out, just wanted to basically restate that.
Comment #66
catchCommitted 83fce77 and pushed to 8.2.x. Thanks!
Had a look at the strings for 8.1.x, I agree it's not too bad, notes below:
Would it kill us if this error message didn't change in 8.1.x? This seems the most likely message of all of them that new installers will hit, the current information will get you past the error message, and it's only telling you that you might need something that's no longer a requirement.
This is actually a new string, a quick grep didn't find a good 8.1.x equivalent, it's also short though. But could maybe use the error message as the heading at a stretch to have zero string changes.
core/modules/system/system.install: $error = t('The directory %directory is not writable.', array('%directory' => $directory));
This is in 8.1.x already so not actually a new string.
ules/system/system.install: $error = t('The directory %directory does not exist.', array('%directory' => $directory));
Also not a new string.
Comment #67
Crell CreditAttribution: Crell at Platform.sh commentedHere's a reroll of #59, applied against 8.1.x, with the two string changes requested in #66. Interdiff is just the string changes, against the reroll.
Something else we noticed in testing is that while this patch lets the site install cleanly (yay!), there's still a warning on the site status page that the sync directory is not writeable. That's a problem on a development instance, but in production is not necessarily a problem and in Platform.sh's case will always be the case, unconditionally, and it's not a problem by design. Should we (in a follow-up, probably) remove or somehow demote that message? (I think it would be fine to do that in 8.2 only, since it doesn't actually prevent functionality it just is annoying and misleading.)
Comment #68
alexpott@Crell I think it is perfectly reasonable for the Config module to add this warning to the reports page. This module requires it to be writable in order to work. It only provides a UI for importing and exporting config. If it can't write there it can't do one of it's main tasks.
And it is only a warning - not an error.
Comment #69
Crell CreditAttribution: Crell at Platform.sh commentedMm, fair. It's just that on Platform that message will then always and forever be there, because the whole disk is read-only. (We can't make the sync dir both writeable and git-pushable at the same time, as that defeats the whole purpose.)
How is the reroll otherwise?
Comment #70
rachel_norfolkAnd, even outside of platform.sh, surely "good practice" on a production system should be the only writeable files are things that users need to upload etc, certainly not the intended configuration of the website.
We shouldn't be giving a warning message when people are doings things "right".
Comment #71
Crell CreditAttribution: Crell at Platform.sh commentedSomeone want to RTBC #67? The discussion after that is essentially off topic, sorry for bringing it up. :-)
Comment #72
jonathanshawRTBC per #61 and #66
Comment #73
alexpottOnly if they have the config module enabled - which tbh doesn't make a lot of sense if you are using git to do deployments since you probably want to automate config synchronisation with you release process.
Comment #74
xjmAssigning to catch since he committed the patch to 8.2.x and the 8.1.x version is intended to address his feedback.
Comment #75
catchCommitted e5a9806 and pushed to 8.1.x. Thanks!
Comment #79
webchickWhen I install 8.1.8, I'm now getting:
and:
This wasn't an issue on 8.1.7. Any ideas on how to workaround?
Comment #80
webchickSpun-off #2782811: [regression] 8.1.8 newly tries to write to settings.php during install because $settings['install_profile'] gets unset.
Comment #81
webchickPreliminary testing shows that if we adjust our site set-up scripts to pre-create the config sync directory, we can get around this issue, at least on one of our hosting products. So it's looking like it was indeed this patch that caused the breakage compared to 8.1.7. :\
Comment #82
gelierb CreditAttribution: gelierb as a volunteer commentedI've been dealing with this for a day or two. Tried the "upgrade" forum for help. Thought it must be something I was doing. Upgrades have seemed so solid up to now. Why is 8.1.8 still available for download if it's causing these problems? Sorry if this is not the correct place to comment.
Comment #83
alexpottI've confirmed the first part of #79. When a user has a settings.php with database settings and config directories configured but not writable the installer was able to continue before this patch and create the config directories. Now that does not occur - you get the reported installation error. This is quite different from the reported error in #80 so I'm going to file a separate issue for it.
Comment #84
alexpottCreated #2783749: [regression] Config directories should be created by installer if present in setings.php and if possible
Comment #85
mikey_p CreditAttribution: mikey_p commentedUnfortunately there is still a drawback to this approach, and that is while the hook_requirements() requirement has been removed file_ensure_htaccess() still expects it to be writable:
This doesn't check to see if the directory is writable and file_save_htaccess logs an error if it can't write the .htaccess. This is filling up our logs as this happens for ALOT of file operations, sometimes we see dozens of "Security warning: Couldn't write .htaccess file" errors logged per request.
I would suggest either adding a check here to make sure that the config staging directory is writable first, or adding a setting that can be added to settings.php to skip this check. In an unrelated issue, I would suggest that file_ensure_htaccess() include a static check to be sure that it is only run once per request, unless there is a reason to check this on every file operation.
Should I reopen this issue for a followup, or should I create a new issue?
Comment #86
alexpott@mikey_p - new issue.
Comment #88
Dane Powell CreditAttribution: Dane Powell at Acquia commentedIf you are interested in suppressing the "not writable" warning on the status report, and assuming you can't simply disable the config module, I think this might be the best solution: #2877128: [META] Evaluate status report warnings and determine which should be reduced to info, removed, etc.
Also it was surprising to me to learn that the config module is strictly an administrative interface; I assumed it couldn't be disabled if you wanted to do any sort of configuration management. I opened another issue to address this: #2877111: Rename Config module to "Config UI"
Comment #89
xjm