Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * This script creates config.php file and prepares database. 20 * 21 * This script is not intended for beginners! 22 * Potential problems: 23 * - su to apache account or sudo before execution 24 * - not compatible with Windows platform 25 * 26 * @package core 27 * @subpackage cli 28 * @copyright 2009 Petr Skoda (http://skodak.org) 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 32 // Force OPcache reset if used, we do not want any stale caches 33 // when detecting if upgrade necessary or when running upgrade. 34 if (function_exists('opcache_reset') and !isset($_SERVER['REMOTE_ADDR'])) { 35 opcache_reset(); 36 } 37 38 define('CLI_SCRIPT', true); 39 define('CACHE_DISABLE_ALL', true); 40 41 require(__DIR__.'/../../config.php'); 42 require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions 43 require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions 44 require_once($CFG->libdir.'/clilib.php'); // cli only functions 45 require_once($CFG->libdir.'/environmentlib.php'); 46 47 // now get cli options 48 $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; 49 list($options, $unrecognized) = cli_get_params( 50 array( 51 'allow-unstable' => false, 52 'help' => false, 53 'is-maintenance-required' => false, 54 'is-pending' => false, 55 'lang' => $lang, 56 'maintenance' => true, 57 'non-interactive' => false, 58 'set-ui-upgrade-lock' => false, 59 'unset-ui-upgrade-lock' => false, 60 'verbose-settings' => false, 61 ), 62 array( 63 'h' => 'help' 64 ) 65 ); 66 67 if ($options['lang']) { 68 $SESSION->lang = $options['lang']; 69 } 70 71 $interactive = empty($options['non-interactive']); 72 73 if ($unrecognized) { 74 $unrecognized = implode("\n ", $unrecognized); 75 cli_error(get_string('cliunknowoption', 'admin', $unrecognized)); 76 } 77 78 if ($options['help']) { 79 $help = 80 "Command line Moodle upgrade. 81 Please note you must execute this script with the same uid as apache! 82 83 Site defaults may be changed via local/defaults.php. 84 85 Options: 86 --allow-unstable Upgrade even if the version is not marked as stable yet, 87 required in non-interactive mode. 88 -h, --help Print out this help. 89 --is-maintenance-required Returns exit code 2 if the upgrade requires maintenance mode. 90 Returns exit code 3 if no maintenance is required for the upgrade. 91 --is-pending Exit with error code 2 if an upgrade is required. 92 --lang=CODE Set preferred language for CLI output. Defaults to the 93 site language if not set. Defaults to 'en' if the lang 94 parameter is invalid or if the language pack is not 95 installed. 96 --maintenance Sets whether this upgrade will use maintenance mode. 97 If not possible, the upgrade will not happen and the script will exit. 98 WARNING: Caches (except theme) will be STALE and MUST be purged after upgrading. 99 DO NOT USE if the upgrade contains known breaking changes to the way data 100 and the database interact. 101 RECOMMENDED for lightweight deployments, to allow for a graceful purge and 102 rebuild of the cache. 103 --non-interactive No interactive questions or confirmations. 104 --set-ui-upgrade-lock Sets the upgrade to CLI only and unable to be triggered from the frontend. 105 If called with --maintenance=false, the lock WILL NOT be released when the 106 upgrade finishes, and MUST be manually removed. 107 If called with --is-maintenance-required before an upgrade, 108 The lock WILL be released when the upgrade finishes. 109 --unset-ui-upgrade-lock Removes the frontend upgrade lock, if the lock exists. 110 Useful when an error during the upgrade leaves the upgrade locked, 111 or there is need to control the time where the unlock happens. 112 --verbose-settings Show new settings values. By default only the name of 113 new core or plugin settings are displayed. This option 114 outputs the new values as well as the setting name. 115 116 Example: 117 \$sudo -u www-data /usr/bin/php admin/cli/upgrade.php 118 "; //TODO: localize - to be translated later when everything is finished 119 120 echo $help; 121 die; 122 } 123 124 if (empty($CFG->version)) { 125 cli_error(get_string('missingconfigversion', 'debug')); 126 } 127 128 require("$CFG->dirroot/version.php"); // defines $version, $release, $branch and $maturity 129 $CFG->target_release = $release; // used during installation and upgrades 130 131 if ($version < $CFG->version) { 132 cli_error(get_string('downgradedcore', 'error')); 133 } 134 135 $oldversion = "$CFG->release ($CFG->version)"; 136 $newversion = "$release ($version)"; 137 138 if ($options['unset-ui-upgrade-lock']) { 139 // Unconditionally unset this config if requested. 140 set_config('outagelessupgrade', false); 141 cli_writeln(get_string('cliupgradeunsetlock', 'admin')); 142 } 143 144 $allhash = core_component::get_all_component_hash(); 145 146 // Initialise allcomponent hash if not set. It will be correctly set after upgrade. 147 $CFG->allcomponenthash = $CFG->allcomponenthash ?? ''; 148 if (!$options['maintenance']) { 149 if ($allhash !== $CFG->allcomponenthash) { 150 // Throw an error here, we can't proceed, this needs to set maintenance. 151 cli_error(get_string('cliupgrademaintenancerequired', 'core_admin'), 2); 152 } 153 154 // Set a constant to stop any upgrade var from being set during processing. 155 // This protects against the upgrade setting timeouts and maintenance during the upgrade. 156 define('CLI_UPGRADE_RUNNING', true); 157 158 // This database control is the control to block the GUI from doing upgrade related actions. 159 set_config('outagelessupgrade', true); 160 } 161 162 // We should ignore all upgrade locks here. 163 if (!moodle_needs_upgrading(false)) { 164 cli_error(get_string('cliupgradenoneed', 'core_admin', $newversion), 0); 165 } 166 167 // Handle exit based options for outputting upgrade state. 168 if ($options['is-pending'] || $options['is-maintenance-required']) { 169 // If we aren't doing a maintenance check, plain pending check. 170 if (!$options['is-maintenance-required']) { 171 cli_error(get_string('cliupgradepending', 'core_admin'), 2); 172 } 173 174 // Can we do this safely with no maintenance/outage? Detect if there is a schema or other application state change. 175 if ($allhash !== $CFG->allcomponenthash) { 176 // State change here, we need to do this in maintenance. 177 cli_writeln(get_string('cliupgradepending', 'core_admin')); 178 cli_error(get_string('cliupgrademaintenancerequired', 'core_admin'), 2); 179 } 180 181 // If requested, we should always set the upgrade lock here, so this cannot be run from frontend. 182 if ($options['set-ui-upgrade-lock']) { 183 set_config('outagelessupgrade', true); 184 cli_writeln(get_string('cliupgradesetlock', 'admin')); 185 } 186 187 // We can do an upgrade without maintenance! 188 cli_writeln(get_string('cliupgradepending', 'core_admin')); 189 cli_error(get_string('cliupgrademaintenancenotrequired', 'core_admin'), 3); 190 } 191 192 // Test environment first. 193 list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE); 194 if (!$envstatus) { 195 $errors = environment_get_errors($environment_results); 196 cli_heading(get_string('environment', 'admin')); 197 foreach ($errors as $error) { 198 list($info, $report) = $error; 199 echo "!! $info !!\n$report\n\n"; 200 } 201 exit(1); 202 } 203 204 // Make sure there are no files left over from previous versions. 205 if (upgrade_stale_php_files_present()) { 206 cli_problem(get_string('upgradestalefiles', 'admin')); 207 208 // Stale file info contains HTML elements which aren't suitable for CLI. 209 $upgradestalefilesinfo = get_string('upgradestalefilesinfo', 'admin', get_docs_url('Upgrading')); 210 cli_error(strip_tags($upgradestalefilesinfo)); 211 } 212 213 // Test plugin dependencies. 214 $failed = array(); 215 if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) { 216 cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed))))); 217 cli_error(get_string('pluginschecktodo', 'admin')); 218 } 219 220 $a = new stdClass(); 221 $a->oldversion = $oldversion; 222 $a->newversion = $newversion; 223 224 if ($interactive) { 225 echo cli_heading(get_string('databasechecking', '', $a)) . PHP_EOL; 226 } 227 228 // make sure we are upgrading to a stable release or display a warning 229 if (isset($maturity)) { 230 if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) { 231 $maturitylevel = get_string('maturity'.$maturity, 'admin'); 232 233 if ($interactive) { 234 cli_separator(); 235 cli_heading(get_string('notice')); 236 echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL; 237 echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL; 238 cli_separator(); 239 } else { 240 cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel)); 241 cli_error(get_string('maturityallowunstable', 'admin')); 242 } 243 } 244 } 245 246 if ($interactive) { 247 echo html_to_text(get_string('upgradesure', 'admin', $newversion))."\n"; 248 $prompt = get_string('cliyesnoprompt', 'admin'); 249 $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin'))); 250 if ($input == get_string('clianswerno', 'admin')) { 251 exit(1); 252 } 253 } 254 255 if ($version > $CFG->version) { 256 257 // Only purge caches if this is a plain upgrade. 258 // In the case of a no-outage upgrade, we will gracefully roll caches after upgrade. 259 if ($options['maintenance']) { 260 // We purge all of MUC's caches here. 261 // Caches are disabled for upgrade by CACHE_DISABLE_ALL so we must set the first arg to true. 262 // This ensures a real config object is loaded and the stores will be purged. 263 // This is the only way we can purge custom caches such as memcache or APC. 264 // Note: all other calls to caches will still used the disabled API. 265 cache_helper::purge_all(true); 266 } 267 268 upgrade_core($version, true); 269 } 270 set_config('release', $release); 271 set_config('branch', $branch); 272 273 // unconditionally upgrade 274 upgrade_noncore(true); 275 276 // log in as admin - we need doanything permission when applying defaults 277 \core\session\manager::set_user(get_admin()); 278 279 // Apply default settings and output those that have changed. 280 cli_heading(get_string('cliupgradedefaultheading', 'admin')); 281 $settingsoutput = admin_apply_default_settings(null, false); 282 283 foreach ($settingsoutput as $setting => $value) { 284 285 if ($options['verbose-settings']) { 286 $stringvlaues = array( 287 'name' => $setting, 288 'defaultsetting' => var_export($value, true) // Expand objects. 289 ); 290 echo get_string('cliupgradedefaultverbose', 'admin', $stringvlaues) . PHP_EOL; 291 292 } else { 293 echo get_string('cliupgradedefault', 'admin', $setting) . PHP_EOL; 294 295 } 296 } 297 298 // This needs to happen at the end to ensure it occurs after all caches 299 // have been purged for the last time. 300 // This will build a cached version of the current theme for the user 301 // to immediately start browsing the site. 302 upgrade_themes(); 303 304 echo get_string('cliupgradefinished', 'admin', $a)."\n"; 305 306 if (!$options['maintenance']) { 307 cli_writeln(get_string('cliupgradecompletenomaintenanceupgrade', 'admin')); 308 309 // Here we check if upgrade lock has not been specifically set during this upgrade run. 310 // This supports wider server orchestration actions happening, which should call with no-maintenance AND set-ui-upgrade-lock, 311 // such as a new docker container deployment, of which the moodle upgrade is only a component. 312 if (!$options['set-ui-upgrade-lock']) { 313 // In this case we should release the lock now, as the upgrade is finished. 314 // We weren't told to keep the lock with set-ui-upgrade-lock, so release. 315 set_config('outagelessupgrade', false); 316 } 317 } 318 319 exit(0); // 0 means success
title
Description
Body
title
Description
Body
title
Description
Body
title
Body