Currently, it is not possible to perform a Drupal core update in-browser.
One of the substantial technical roadblocks to achieving this, to highlight a point raised in older issues / feature requests, is the fact that any sort of in-browser updates are best done incrementally as a batch of smaller work units, to avoid potential timeout issues. The existing module update manager works this way, for example. But, if you use core's facilities such as its batch api, authentication, ftp file writer, etc. to update itself, you run the risk of trying to use those facilities while they are partially updated and in an inconsistent state, leaving a site in a permanently broken state.
I have created a solution to this by developing a separate set of facilities for updating code through a browser, totally independent of Drupal core during the time the updates are being applied, as demoed at MWDS 2018, or below:
https://youtu.be/4yhO442LyII Oh look, now it looks all drupally: https://youtu.be/r3H-KzfV5sk
Code behind aforementioned demo:
- Standalone project decoupled from core, where all the real work is: https://github.com/curator-wik/curator
- Drupal 7 module that creates the Update Core button, authorizes that the user has the administer software updates permission before handing off control, etc: https://www.drupal.org/project/core_update
This work is getting to the point where it could be used fairly readily to fulfill an initial objective of the automatic updates initiative (https://www.drupal.org/project/ideas/issues/2940731) -- providing manually installed, but via the browser core security updates. Because the code doing the heavy lifting is independent of Drupal core, it is approximately equally applicable to Drupal 7 and 8.
To use this successfully with Drupal, there are a few important requirements that would need support / buy-in from key Drupal and Drupal infrastructure stakeholders. There will hopefully be a future targeted srpint in which those issues can be discussed in person as well, but my motivation for writing this issue is mostly to raise awareness now and in hopes it creates a venue for some initial discussions / documentation about that. And also @xjm asked me to write an issue for it :)
The biggest of these requirements is that the release artifact my code downloads and consumes is not the full .tar.gz of the release. The reason is that it's advantageous to do the minimum work necessary to transform release n-1 to n, instead of blowing away the whole old release n-1 and then writing out the whole new one. This dramatically reduces tne amount of work the updater must perform, makes the update process run much faster / reduces site downtime, and probably reduces the number of things that can go wrong during the update. A better way to do it is to precompute the differences between release n-1 and n once as part of the release process and capture those differences in a release artifact that Curator downloads and replays to transform an n-1 release to n. The work to identify the differences between two arbitrary directory trees and suck them into a .zip file in the format Curator is looking for is over here, see https://github.com/curator-wik/makeup. So running this to generate the update-centric release artifacts would just need to be added to the Drupal release scripts, and the resulting static files would need to be hosted somewhere, presumably on the same infrastructure that hosts the full release archives. (Note it wouldn't make much sense to publicize these files as another download option for those who choose to update the traditional way; they'd hang out on your CDN but not be linked from webpages.)
-> For simplicity of evaluation purposes I'll stick some of these up on the Internet somewhere for now, and point the updater at that location for now.
A hopefully more minor issue that would need some review is that since there's no dependency on Drupal core during the update, the front controller / "index.php" that is serving the batch runner API is not Drupal's index.php. In the current D7 module manifestation of this, it is an alternative .php file that ships in the module, and I would expect that this works for most people on D7 because the default .htaccess in D7 doesn't prevent you from running .php files other than Drupal's index.php. However, in D8, the default is that you cannot run php scripts directly out of contrib. The likely / obvious solution to this would be a patch to `authorize.php` that hands over control to the Curator phar instead of bootstrapping Drupal and doing its usual thing if some request property exists like presence of a cookie that looks like a Curator session cookie.
I'm also happy to answer any specific questions folks have about design, implementation, approach to security concerns, etc. Code reviews and comments are even better! ;)
Comments
Comment #2
mbayntonComment #3
mbayntonLink to new demo vid. Now it looks just like a job being run in Drupal's batch api while the update is being applied, for optimal UX. That's not actually what's going on, at all...
Comment #4
mbayntonAs promised by labor day, here's the Drupal 7 module part of it, as a sandbox project: https://www.drupal.org/sandbox/mbaynton/2997009. Please try it out!
Comment #5
arlingtonvoicellc commentedmbaynton, you've done impressive work solving a problem that has plagued Drupal forever. Thank you for the time you've invested. I hope stakeholders are paying close attention. To have any chance at surviving as a serious CMS, this issue needs to be solved. I hope the community gets behind your initiative. As I've alluded in a comment on another thread, I am finished building any new websites in Drupal until this issue has been solved in core or with a stable module. Best of luck moving ahead on this project. I'll check back occasionally to see if there's been progress on its adoption.
Comment #6
mbayntonI've just added a rollback capability to the sandbox project. Now, if an error occurs while it is updating a site to a newer version, it stops and performs the opposite of all filesystem changes it had performed up until that point. That way, if e.g. one file has weird permissions, the site won't end up in an inconsistent, partially-updated state.
I'll start focusing on Drupal 8 next. I'm also getting closer to being comfortable un-sandboxing this for D7, but since failure has the potential to take down the sites of users who may lack the skills to easily recover, I would still like to see these additional things in place first:
Comment #8
mbayntonUpdate link from sandbox to official contrib project