Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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