Upgrade/install: Revert upgrader rollback features.

Revert the rollback features introduced for theme and plugin upgrades during the WordPress 5.9 cycle. A bug (suspected to be in third party virtualisation software) causes the upgrades to fail consistently on some set ups. The revert is to allow contributors further time to investigate mitigation options.

Reverts [52337], [52289], [52284], [51951], [52192], [51902], [51899], [51898], [51815].

Props pbiron, dlh, peterwilsoncc, galbaras, SergeyBiryukov, afragen, costdev, bronsonquick, aristath, noisysocks, desrosj, TobiasBg, hellofromTonya, francina, Boniu91.
See #54543, #54166, #51857.



Built from https://develop.svn.wordpress.org/trunk@52351


git-svn-id: http://core.svn.wordpress.org/trunk@51943 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Peter Wilson 2021-12-10 00:06:04 +00:00
parent 852fad7531
commit 88b1019dc3
7 changed files with 28 additions and 516 deletions

View File

@ -226,14 +226,9 @@ class Plugin_Upgrader extends WP_Upgrader {
'clear_destination' => true,
'clear_working' => true,
'hook_extra' => array(
'plugin' => $plugin,
'type' => 'plugin',
'action' => 'update',
'temp_backup' => array(
'slug' => dirname( $plugin ),
'src' => WP_PLUGIN_DIR,
'dir' => 'plugins',
),
'plugin' => $plugin,
'type' => 'plugin',
'action' => 'update',
),
)
);
@ -347,12 +342,7 @@ class Plugin_Upgrader extends WP_Upgrader {
'clear_working' => true,
'is_multi' => true,
'hook_extra' => array(
'plugin' => $plugin,
'temp_backup' => array(
'slug' => dirname( $plugin ),
'src' => WP_PLUGIN_DIR,
'dir' => 'plugins',
),
'plugin' => $plugin,
),
)
);

View File

@ -328,14 +328,9 @@ class Theme_Upgrader extends WP_Upgrader {
'clear_destination' => true,
'clear_working' => true,
'hook_extra' => array(
'theme' => $theme,
'type' => 'theme',
'action' => 'update',
'temp_backup' => array(
'slug' => $theme,
'src' => get_theme_root( $theme ),
'dir' => 'themes',
),
'theme' => $theme,
'type' => 'theme',
'action' => 'update',
),
)
);
@ -448,12 +443,7 @@ class Theme_Upgrader extends WP_Upgrader {
'clear_working' => true,
'is_multi' => true,
'hook_extra' => array(
'theme' => $theme,
'temp_backup' => array(
'slug' => $theme,
'src' => get_theme_root( $theme ),
'dir' => 'themes',
),
'theme' => $theme,
),
)
);

View File

@ -1882,196 +1882,6 @@ class WP_Site_Health {
return $result;
}
/**
* Test available disk space for updates.
*
* @since 5.9.0
*
* @return array The test results.
*/
public function get_test_available_updates_disk_space() {
$available_space = function_exists( 'disk_free_space' ) ? (int) @disk_free_space( WP_CONTENT_DIR . '/upgrade/' ) : 0;
$available_space_in_mb = $available_space / MB_IN_BYTES;
$result = array(
'label' => __( 'Disk space available to safely perform updates' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Security' ),
'color' => 'blue',
),
'description' => sprintf(
/* translators: %s: Available disk space in MB or GB. */
'<p>' . __( '%s available disk space was detected, update routines can be performed safely.' ),
size_format( $available_space )
),
'actions' => '',
'test' => 'available_updates_disk_space',
);
if ( $available_space_in_mb < 100 ) {
$result['description'] = __( 'Available disk space is low, less than 100 MB available.' );
$result['status'] = 'recommended';
}
if ( $available_space_in_mb < 20 ) {
$result['description'] = __( 'Available disk space is critically low, less than 20 MB available. Proceed with caution, updates may fail.' );
$result['status'] = 'critical';
}
if ( ! $available_space ) {
$result['description'] = __( 'Could not determine available disk space for updates.' );
$result['status'] = 'recommended';
}
return $result;
}
/**
* Test if plugin and theme updates temp-backup directories are writable or can be created.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @return array The test results.
*/
public function get_test_update_temp_backup_writable() {
global $wp_filesystem;
$result = array(
'label' => sprintf(
/* translators: %s: temp-backup */
__( 'Plugin and theme update %s directory is writable' ),
'temp-backup'
),
'status' => 'good',
'badge' => array(
'label' => __( 'Security' ),
'color' => 'blue',
),
'description' => sprintf(
/* translators: %s: wp-content/upgrade/temp-backup */
'<p>' . __( 'The %s directory used to improve the stability of plugin and theme updates is writable.' ),
'<code>wp-content/upgrade/temp-backup</code>'
),
'actions' => '',
'test' => 'update_temp_backup_writable',
);
if ( ! $wp_filesystem ) {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
}
WP_Filesystem();
}
$wp_content = $wp_filesystem->wp_content_dir();
$upgrade_dir_exists = $wp_filesystem->is_dir( "$wp_content/upgrade" );
$upgrade_dir_is_writable = $wp_filesystem->is_writable( "$wp_content/upgrade" );
$backup_dir_exists = $wp_filesystem->is_dir( "$wp_content/upgrade/temp-backup" );
$backup_dir_is_writable = $wp_filesystem->is_writable( "$wp_content/upgrade/temp-backup" );
$plugins_dir_exists = $wp_filesystem->is_dir( "$wp_content/upgrade/temp-backup/plugins" );
$plugins_dir_is_writable = $wp_filesystem->is_writable( "$wp_content/upgrade/temp-backup/plugins" );
$themes_dir_exists = $wp_filesystem->is_dir( "$wp_content/upgrade/temp-backup/themes" );
$themes_dir_is_writable = $wp_filesystem->is_writable( "$wp_content/upgrade/temp-backup/themes" );
if ( $plugins_dir_exists && ! $plugins_dir_is_writable && $themes_dir_exists && ! $themes_dir_is_writable ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: temp-backup */
__( 'Plugins and themes %s directories exist but are not writable' ),
'temp-backup'
);
$result['description'] = sprintf(
/* translators: 1: wp-content/upgrade/temp-backup/plugins, 2: wp-content/upgrade/temp-backup/themes. */
'<p>' . __( 'The %1$s and %2$s directories exist but are not writable. These directories are used to improve the stability of plugin updates. Please make sure the server has write permissions to these directories.' ) . '</p>',
'<code>wp-content/upgrade/temp-backup/plugins</code>',
'<code>wp-content/upgrade/temp-backup/themes</code>'
);
return $result;
}
if ( $plugins_dir_exists && ! $plugins_dir_is_writable ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: temp-backup */
__( 'Plugins %s directory exists but is not writable' ),
'temp-backup'
);
$result['description'] = sprintf(
/* translators: %s: wp-content/upgrade/temp-backup/plugins */
'<p>' . __( 'The %s directory exists but is not writable. This directory is used to improve the stability of plugin updates. Please make sure the server has write permissions to this directory.' ) . '</p>',
'<code>wp-content/upgrade/temp-backup/plugins</code>'
);
return $result;
}
if ( $themes_dir_exists && ! $themes_dir_is_writable ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: temp-backup */
__( 'Themes %s directory exists but is not writable' ),
'temp-backup'
);
$result['description'] = sprintf(
/* translators: %s: wp-content/upgrade/temp-backup/themes */
'<p>' . __( 'The %s directory exists but is not writable. This directory is used to improve the stability of theme updates. Please make sure the server has write permissions to this directory.' ) . '</p>',
'<code>wp-content/upgrade/temp-backup/themes</code>'
);
return $result;
}
if ( ( ! $plugins_dir_exists || ! $themes_dir_exists ) && $backup_dir_exists && ! $backup_dir_is_writable ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: temp-backup */
__( 'The %s directory exists but is not writable' ),
'temp-backup'
);
$result['description'] = sprintf(
/* translators: %s: wp-content/upgrade/temp-backup */
'<p>' . __( 'The %s directory exists but is not writable. This directory is used to improve the stability of plugin and theme updates. Please make sure the server has write permissions to this directory.' ) . '</p>',
'<code>wp-content/upgrade/temp-backup</code>'
);
return $result;
}
if ( ! $backup_dir_exists && $upgrade_dir_exists && ! $upgrade_dir_is_writable ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: upgrade */
__( 'The %s directory exists but is not writable' ),
'upgrade'
);
$result['description'] = sprintf(
/* translators: %s: wp-content/upgrade */
'<p>' . __( 'The %s directory exists but is not writable. This directory is used for plugin and theme updates. Please make sure the server has write permissions to this directory.' ) . '</p>',
'<code>wp-content/upgrade</code>'
);
return $result;
}
if ( ! $upgrade_dir_exists && ! $wp_filesystem->is_writable( $wp_content ) ) {
$result['status'] = 'critical';
$result['label'] = sprintf(
/* translators: %s: upgrade */
__( 'The %s directory cannot be created' ),
'upgrade'
);
$result['description'] = sprintf(
/* translators: 1: wp-content/upgrade, 2: wp-content. */
'<p>' . __( 'The %1$s directory does not exist, and the server does not have write permissions in %2$s to create it. This directory is used for plugin and theme updates. Please make sure the server has write permissions in %2$s.' ) . '</p>',
'<code>wp-content/upgrade</code>',
'<code>wp-content</code>'
);
return $result;
}
return $result;
}
/**
* Test if loopbacks work as expected.
*
@ -2456,80 +2266,71 @@ class WP_Site_Health {
public static function get_tests() {
$tests = array(
'direct' => array(
'wordpress_version' => array(
'wordpress_version' => array(
'label' => __( 'WordPress Version' ),
'test' => 'wordpress_version',
),
'plugin_version' => array(
'plugin_version' => array(
'label' => __( 'Plugin Versions' ),
'test' => 'plugin_version',
),
'theme_version' => array(
'theme_version' => array(
'label' => __( 'Theme Versions' ),
'test' => 'theme_version',
),
'php_version' => array(
'php_version' => array(
'label' => __( 'PHP Version' ),
'test' => 'php_version',
),
'php_extensions' => array(
'php_extensions' => array(
'label' => __( 'PHP Extensions' ),
'test' => 'php_extensions',
),
'php_default_timezone' => array(
'php_default_timezone' => array(
'label' => __( 'PHP Default Timezone' ),
'test' => 'php_default_timezone',
),
'php_sessions' => array(
'php_sessions' => array(
'label' => __( 'PHP Sessions' ),
'test' => 'php_sessions',
),
'sql_server' => array(
'sql_server' => array(
'label' => __( 'Database Server version' ),
'test' => 'sql_server',
),
'utf8mb4_support' => array(
'utf8mb4_support' => array(
'label' => __( 'MySQL utf8mb4 support' ),
'test' => 'utf8mb4_support',
),
'ssl_support' => array(
'ssl_support' => array(
'label' => __( 'Secure communication' ),
'test' => 'ssl_support',
),
'scheduled_events' => array(
'scheduled_events' => array(
'label' => __( 'Scheduled events' ),
'test' => 'scheduled_events',
),
'http_requests' => array(
'http_requests' => array(
'label' => __( 'HTTP Requests' ),
'test' => 'http_requests',
),
'rest_availability' => array(
'rest_availability' => array(
'label' => __( 'REST API availability' ),
'test' => 'rest_availability',
'skip_cron' => true,
),
'debug_enabled' => array(
'debug_enabled' => array(
'label' => __( 'Debugging enabled' ),
'test' => 'is_in_debug_mode',
),
'file_uploads' => array(
'file_uploads' => array(
'label' => __( 'File uploads' ),
'test' => 'file_uploads',
),
'plugin_theme_auto_updates' => array(
'plugin_theme_auto_updates' => array(
'label' => __( 'Plugin and theme auto-updates' ),
'test' => 'plugin_theme_auto_updates',
),
'update_temp_backup_writable' => array(
/* translators: %s: temp-backup */
'label' => sprintf( __( 'Updates %s directory access' ), 'temp-backup' ),
'test' => 'update_temp_backup_writable',
),
'available_updates_disk_space' => array(
'label' => __( 'Available disk space' ),
'test' => 'available_updates_disk_space',
),
),
'async' => array(
'dotorg_communication' => array(

View File

@ -133,29 +133,11 @@ class WP_Upgrader {
* This will set the relationship between the skin being used and this upgrader,
* and also add the generic strings to `WP_Upgrader::$strings`.
*
* Additionally, it will schedule a weekly task to clean up the temp-backup directory.
*
* @since 2.8.0
* @since 5.9.0 Added the `schedule_temp_backup_cleanup()` task.
*/
public function init() {
$this->skin->set_upgrader( $this );
$this->generic_strings();
if ( ! wp_installing() ) {
$this->schedule_temp_backup_cleanup();
}
}
/**
* Schedule cleanup of the temp-backup directory.
*
* @since 5.9.0
*/
protected function schedule_temp_backup_cleanup() {
if ( false === wp_next_scheduled( 'wp_delete_temp_updater_backups' ) ) {
wp_schedule_event( time(), 'weekly', 'wp_delete_temp_updater_backups' );
}
}
/**
@ -184,13 +166,6 @@ class WP_Upgrader {
$this->strings['maintenance_start'] = __( 'Enabling Maintenance mode&#8230;' );
$this->strings['maintenance_end'] = __( 'Disabling Maintenance mode&#8230;' );
/* translators: %s: temp-backup */
$this->strings['temp_backup_mkdir_failed'] = sprintf( __( 'Could not create the %s directory.' ), 'temp-backup' );
/* translators: %s: temp-backup */
$this->strings['temp_backup_move_failed'] = sprintf( __( 'Could not move old version to the %s directory.' ), 'temp-backup' );
$this->strings['temp_backup_restore_failed'] = __( 'Could not restore original version.' );
}
/**
@ -338,9 +313,6 @@ class WP_Upgrader {
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
if ( ! empty( $upgrade_files ) ) {
foreach ( $upgrade_files as $file ) {
if ( 'temp-backup' === $file['name'] ) {
continue;
}
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
}
}
@ -521,13 +493,6 @@ class WP_Upgrader {
return $res;
}
if ( ! empty( $args['hook_extra']['temp_backup'] ) ) {
$temp_backup = $this->move_to_temp_backup_dir( $args['hook_extra']['temp_backup'] );
if ( is_wp_error( $temp_backup ) ) {
return $temp_backup;
}
}
// Retain the original source and destinations.
$remote_source = $args['source'];
$local_destination = $destination;
@ -627,8 +592,8 @@ class WP_Upgrader {
}
}
// Move new version of item into place.
$result = move_dir( $source, $remote_destination, $remote_source );
// Copy new version of item into place.
$result = copy_dir( $source, $remote_destination );
if ( is_wp_error( $result ) ) {
if ( $args['clear_working'] ) {
$wp_filesystem->delete( $remote_source, true );
@ -636,7 +601,7 @@ class WP_Upgrader {
return $result;
}
// Clear the working directory?
// Clear the working folder?
if ( $args['clear_working'] ) {
$wp_filesystem->delete( $remote_source, true );
}
@ -846,20 +811,6 @@ class WP_Upgrader {
$this->skin->set_result( $result );
if ( is_wp_error( $result ) ) {
if ( ! empty( $options['hook_extra']['temp_backup'] ) ) {
/*
* Restore the backup on shutdown.
* Actions running on `shutdown` are immune to PHP timeouts,
* so in case the failure was due to a PHP timeout,
* we'll still be able to properly restore the previous version.
*/
add_action(
'shutdown',
function() use ( $options ) {
$this->restore_temp_backup( $options['hook_extra']['temp_backup'] );
}
);
}
$this->skin->error( $result );
if ( ! method_exists( $this->skin, 'hide_process_failed' ) || ! $this->skin->hide_process_failed( $result ) ) {
@ -872,17 +823,6 @@ class WP_Upgrader {
$this->skin->after();
// Clean up the backup kept in the temp-backup directory.
if ( ! empty( $options['hook_extra']['temp_backup'] ) ) {
// Delete the backup on `shutdown` to avoid a PHP timeout.
add_action(
'shutdown',
function() use ( $options ) {
$this->delete_temp_backup( $options['hook_extra']['temp_backup'] );
}
);
}
if ( ! $options['is_multi'] ) {
/**
@ -1007,121 +947,6 @@ class WP_Upgrader {
public static function release_lock( $lock_name ) {
return delete_option( $lock_name . '.lock' );
}
/**
* Moves the plugin/theme being updated into a temp-backup directory.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @param array $args Array of data for the temp-backup. Must include a slug, the source, and directory.
* @return bool|WP_Error
*/
public function move_to_temp_backup_dir( $args ) {
global $wp_filesystem;
if ( empty( $args['slug'] ) || empty( $args['src'] ) || empty( $args['dir'] ) ) {
return false;
}
/**
* Skip any plugin that has "." as its slug.
* A slug of "." will result in a `$src` value ending in a period.
*
* On Windows, this will cause the 'plugins' folder to be moved,
* and will cause a failure when attempting to call `mkdir()`.
*/
if ( '.' === $args['slug'] ) {
return false;
}
$dest_dir = $wp_filesystem->wp_content_dir() . 'upgrade/temp-backup/';
// Create the temp-backup directory if it doesn't exist.
if ( (
! $wp_filesystem->is_dir( $dest_dir )
&& ! $wp_filesystem->mkdir( $dest_dir )
) || (
! $wp_filesystem->is_dir( $dest_dir . $args['dir'] . '/' )
&& ! $wp_filesystem->mkdir( $dest_dir . $args['dir'] . '/' )
)
) {
return new WP_Error( 'fs_temp_backup_mkdir', $this->strings['temp_backup_mkdir_failed'] );
}
$src = trailingslashit( $args['src'] ) . $args['slug'];
$dest = $dest_dir . $args['dir'] . '/' . $args['slug'];
// Delete the temp-backup directory if it already exists.
if ( $wp_filesystem->is_dir( $dest ) ) {
$wp_filesystem->delete( $dest, true );
}
// Move to the temp-backup directory.
if ( ! move_dir( $src, $dest ) ) {
return new WP_Error( 'fs_temp_backup_move', $this->strings['temp_backup_move_failed'] );
}
return true;
}
/**
* Restores the plugin/theme from the temp-backup directory.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @param array $args Array of data for the temp-backup. Must include a slug, the source, and directory.
* @return bool|WP_Error
*/
public function restore_temp_backup( $args ) {
global $wp_filesystem;
if ( empty( $args['slug'] ) || empty( $args['src'] ) || empty( $args['dir'] ) ) {
return false;
}
$src = $wp_filesystem->wp_content_dir() . 'upgrade/temp-backup/' . $args['dir'] . '/' . $args['slug'];
$dest = trailingslashit( $args['src'] ) . $args['slug'];
if ( $wp_filesystem->is_dir( $src ) ) {
// Cleanup.
if ( $wp_filesystem->is_dir( $dest ) && ! $wp_filesystem->delete( $dest, true ) ) {
return new WP_Error( 'fs_temp_backup_delete', $this->strings['temp_backup_restore_failed'] );
}
// Move it.
if ( ! move_dir( $src, $dest ) ) {
return new WP_Error( 'fs_temp_backup_delete', $this->strings['temp_backup_restore_failed'] );
}
}
return true;
}
/**
* Deletes a temp-backup.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @param array $args Array of data for the temp-backup. Must include a slug, the source, and directory.
* @return bool
*/
public function delete_temp_backup( $args ) {
global $wp_filesystem;
if ( empty( $args['slug'] ) || empty( $args['dir'] ) ) {
return false;
}
return $wp_filesystem->delete(
$wp_filesystem->wp_content_dir() . "upgrade/temp-backup/{$args['dir']}/{$args['slug']}",
true
);
}
}
/** Plugin_Upgrader class */

View File

@ -1943,53 +1943,6 @@ function copy_dir( $from, $to, $skip_list = array() ) {
return true;
}
/**
* Moves a directory from one location to another via the rename() PHP function.
* If the renaming failed, falls back to copy_dir().
*
* Assumes that WP_Filesystem() has already been called and setup.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @param string $from Source directory.
* @param string $to Destination directory.
* @param string $working_dir Optional. Remote file source directory.
* Default empty string.
* @return true|WP_Error True on success, WP_Error on failure.
*/
function move_dir( $from, $to, $working_dir = '' ) {
global $wp_filesystem;
if ( 'direct' === $wp_filesystem->method ) {
$wp_filesystem->rmdir( $to );
if ( @rename( $from, $to ) ) {
return true;
}
}
if ( ! $wp_filesystem->is_dir( $to ) ) {
if ( ! $wp_filesystem->mkdir( $to, FS_CHMOD_DIR ) ) {
// Clear the working directory?
if ( ! empty( $working_dir ) ) {
$wp_filesystem->delete( $working_dir, true );
}
return new WP_Error( 'mkdir_failed_move_dir', __( 'Could not create directory.' ), $to );
}
}
$result = copy_dir( $from, $to );
// Clear the working directory?
if ( ! empty( $working_dir ) ) {
$wp_filesystem->delete( $working_dir, true );
}
return $result;
}
/**
* Initializes and connects the WordPress Filesystem Abstraction classes.
*

View File

@ -956,51 +956,6 @@ function wp_clean_update_cache() {
delete_site_transient( 'update_core' );
}
/**
* Deletes all contents of the temp-backup directory.
*
* @since 5.9.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*/
function wp_delete_all_temp_backups() {
/*
* Check if there's a lock, or if currently performing an Ajax request,
* in which case there's a chance we're doing an update.
* Reschedule for an hour from now and exit early.
*/
if ( get_option( 'core_updater.lock' ) || get_option( 'auto_updater.lock' ) || wp_doing_ajax() ) {
wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'wp_delete_temp_updater_backups' );
return;
}
add_action(
'shutdown',
/*
* This action runs on shutdown to make sure there's no plugin updates currently running.
* Using a closure in this case is OK since the action can be removed by removing the parent hook.
*/
function() {
global $wp_filesystem;
if ( ! $wp_filesystem ) {
include_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
$dirlist = $wp_filesystem->dirlist( $wp_filesystem->wp_content_dir() . 'upgrade/temp-backup/' );
foreach ( array_keys( $dirlist ) as $dir ) {
if ( '.' === $dir || '..' === $dir ) {
continue;
}
$wp_filesystem->delete( $wp_filesystem->wp_content_dir() . 'upgrade/temp-backup/' . $dir, true );
}
}
);
}
if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) {
return;
}
@ -1025,5 +980,3 @@ add_action( 'update_option_WPLANG', 'wp_clean_update_cache', 10, 0 );
add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
add_action( 'init', 'wp_schedule_update_checks' );
add_action( 'wp_delete_temp_updater_backups', 'wp_delete_all_temp_backups' );

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.9-beta2-52350';
$wp_version = '5.9-beta2-52351';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.