Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / web / public_php / setup / install.php
blob67f27f5c0ced5c4cbcfa20a5b0888b2717bd801a
1 <?php
3 error_reporting(E_ALL);
4 ini_set('display_errors', 'on');
6 class SystemExit extends Exception {}
7 try {
9 $pageTitle = "Install";
10 include('header.php');
12 require_once('setup/version.php');
16 <?php if (file_exists('config.php')) { ?>
18 <div class="alert alert-danger" role="alert">
19 Already installed.
20 </div>
22 <?php } else if ($_POST) { ?>
24 <div class="alert alert-info" role="alert">
25 <?php var_dump($_POST); ?>
26 </div>
28 <?php
30 $roleService = isset($_POST["roleService"]) && $_POST["roleService"] == "on";
31 $roleSupport = isset($_POST["roleSupport"]) && $_POST["roleSupport"] == "on";
32 $roleDomain = isset($_POST["roleDomain"]) && $_POST["roleDomain"] == "on";
34 if (!$roleService && !$roleSupport && !$roleDomain) {
35 printalert("danger", "No server roles selected");
36 $continue = false;
39 if ($continue) {
40 try {
41 if (!in_array("mysql",PDO::getAvailableDrivers(),TRUE))
43 throw new PDOException ("Cannot work without a proper database setting up");
46 catch (PDOException $pdoEx)
48 printalert("danger", "PHP PDO seems to be missing the mysql driver");
49 $continue = false;
53 // Validate basics
54 if ($continue) {
55 if (file_exists($_POST["privatePhpDirectory"])) {
56 printalert("success", "Private PHP Directory found");
57 } else {
58 printalert("danger", "Private PHP Directory not found (NOTE: This directory is relative to the root of the public PHP directory)");
59 $continue = false;
62 if ($continue) {
63 if ($roleService) {
64 $continue = validate_writable($continue, "login/logs/");
65 $continue = validate_writable($continue, "admin/graphs_output/");
66 $continue = validate_writable($continue, "admin/templates/default_c/");
68 if ($roleSupport) {
69 $continue = validate_writable($continue, "ams/cache/");
70 $continue = validate_writable($continue, "ams/templates_c/");
72 $continue = validate_writable($continue, "./");
73 if ($continue) {
74 printalert("success", "Paths are writable");
78 $con = null;
79 if ($continue) { // NOTE: Also test if this is reachable when not Service role
80 $con = mysqli_connect($_POST["nelSqlHostname"], $_POST["nelSqlUsername"], $_POST["nelSqlPassword"]);
81 if (mysqli_connect_errno()) {
82 printalert("danger", "Failed to connect to Service SQL: " . mysqli_connect_error());
83 $continue = false;
84 $con = null;
85 } else {
86 printalert("success", "Connected to the Service SQL server");
90 if ($roleService) {
91 // Create NeL database
92 $continue = create_use_database($continue, $con, $_POST["nelDatabase"]);
94 // Create NeL Tools database
95 $continue = create_use_database($continue, $con, $_POST["toolDatabase"]);
98 if ($roleDomain) {
99 // Create Ring database
100 $continue = create_use_database($continue, $con, $_POST["domainDatabase"]);
103 if ($con) {
104 mysqli_close($con);
105 printalert("info", "Disconnected from the Service SQL server");
108 if ($roleSupport) {
109 if ($continue) {
110 $con = mysqli_connect($_POST["amsSqlHostname"], $_POST["amsSqlUsername"], $_POST["amsSqlPassword"]);
111 if (mysqli_connect_errno()) {
112 printalert("danger", "Failed to connect to Support SQL: " . mysqli_connect_error());
113 $continue = false;
114 $con = null;
115 } else {
116 printalert("success", "Connected to the Support SQL server");
120 // Create AMS database
121 $continue = create_use_database($continue, $con, $_POST["amsDatabase"]);
123 // Create AMS Library database
124 $continue = create_use_database($continue, $con, $_POST["amsLibDatabase"]);
126 if ($con) {
127 mysqli_close($con);
128 printalert("info", "Disconnected from the Support SQL server");
132 // Write config.php
133 if ($continue) {
134 $config = file_get_contents($_POST["privatePhpDirectory"] . "/setup/config/config.php");
135 if (!$config) {
136 printalert("danger", "Cannot read <em>config.php</em>");
137 $continue = false;
138 } else {
139 $cwd = getcwd();
140 $config = str_replace("%privatePhpDirectory%", addslashes(realpath($cwd . "/" . $_POST["privatePhpDirectory"])), $config);
141 $config = str_replace("%publicPhpDirectory%", addslashes(realpath($cwd)), $config);
142 $config = str_replace("%nelSqlHostname%", addslashes($_POST["nelSqlHostname"]), $config);
143 $config = str_replace("%nelSqlUsername%", addslashes($_POST["nelSqlUsername"]), $config);
144 $config = str_replace("%nelSqlPassword%", addslashes($_POST["nelSqlPassword"]), $config);
145 $config = str_replace("%nelDatabase%", addslashes($_POST["nelDatabase"]), $config);
146 $config = str_replace("%toolDatabase%", addslashes($_POST["toolDatabase"]), $config);
147 $config = str_replace("%amsSqlHostname%", addslashes($_POST["amsSqlHostname"]), $config);
148 $config = str_replace("%amsSqlUsername%", addslashes($_POST["amsSqlUsername"]), $config);
149 $config = str_replace("%amsSqlPassword%", addslashes($_POST["amsSqlPassword"]), $config);
150 $config = str_replace("%amsDatabase%", addslashes($_POST["amsDatabase"]), $config);
151 $config = str_replace("%amsLibDatabase%", addslashes($_POST["amsLibDatabase"]), $config);
152 $config = str_replace("%nelSetupPassword%", addslashes($_POST["nelSetupPassword"]), $config);
153 $config = str_replace("%domainDatabase%", addslashes($_POST["domainDatabase"]), $config);
154 $config = str_replace("%nelDomainName%", addslashes($_POST["nelDomainName"]), $config);
155 $config = str_replace("%nelSetupVersion%", addslashes($NEL_SETUP_VERSION), $config);
156 $cryptKeyLength = 16;
157 $cryptKey = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes($cryptKeyLength * 2))), 0, $cryptKeyLength);
158 $cryptKeyIMAP = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes($cryptKeyLength * 2))), 0, $cryptKeyLength);
159 $config = str_replace("%cryptKey%", addslashes($cryptKey), $config);
160 $config = str_replace("%cryptKeyIMAP%", addslashes($cryptKeyIMAP), $config);
161 if (file_put_contents("config.php", $config)) {
162 printalert("success", "Generated <em>config.php</em>");
163 } else {
164 printalert("danger", "Cannot write to <em>config.php</em>");
165 $continue = false;
170 if ($continue) {
171 $configUser = file_get_contents($_POST["privatePhpDirectory"] . "/setup/config/config_user.php");
172 if (!$configUser) {
173 printalert("danger", "Cannot read <em>config_user.php</em>");
174 $continue = false;
175 } else {
176 if (file_put_contents("config_user.php", $configUser)) {
177 printalert("success", "Copied <em>config_user.php</em>");
178 } else {
179 printalert("danger", "Cannot write to <em>config.php</em>");
180 $continue = false;
185 // Load config
186 if ($continue) {
187 try {
188 require_once('config.php');
189 } catch (Exception $e) {
190 printalert("danger", "Failed to include <em>config.php</em>");
191 $continue = false;
195 require_once('database.php');
197 if ($roleSupport) {
198 $continue = upgrade_support_databases($continue);
201 if ($roleService) {
202 $continue = upgrade_service_databases($continue);
205 if ($roleDomain) {
206 $continue = upgrade_domain_databases($continue);
209 if ($roleService) {
210 // Create the default shard admin user
211 if (!chdir("admin/")) {
212 printalert("danger", "Cannot change to admin tools directory");
213 $continue = false;
215 if ($continue) {
216 try {
217 require_once('common.php');
218 } catch (Exception $e) {
219 printalert("danger", "Failed to include NeL <em>admin/common.php</em>");
220 $continue = false;
223 if ($continue) {
224 try {
225 require_once('functions_tool_administration.php');
226 } catch (Exception $e) {
227 printalert("danger", "Failed to include NeL <em>admin/functions_tool_administration.php</em>");
228 $continue = false;
231 if ($continue) {
232 $adminGroup = 1;
233 $result = tool_admin_users_add($_POST["toolsAdminUsername"], $_POST["toolsAdminPassword"], (string)$adminGroup, (string)1);
234 if ($result == "") {
235 printalert("success", "Added shard admin to NeL tools database");
236 } else {
237 printalert("danger", "Failed to add shard admin to NeL tools database<br>" . htmlentities($result));
238 $continue = false;
241 if (!chdir("../")) {
242 printalert("danger", "Cannot change to public PHP root directory");
243 $continue = false;
247 if ($roleSupport) {
248 // Load AMS Library
249 if ($continue) {
250 try {
251 require_once($AMS_LIB . '/libinclude.php');
252 } catch (Exception $e) {
253 printalert("danger", "Failed to include AMS <em>libinclude.php</em>");
254 $continue = false;
258 // Create AMS Admin user
259 if ($continue) {
260 $hashpass = crypt($_POST["amsAdminPassword"], Users::generateSALT());
261 $params = array(
262 'Login' => $_POST["amsAdminUsername"],
263 'Password' => $hashpass,
264 'Email' => "localhost@localhost", // TODO
266 try {
267 $user_id = WebUsers::createWebuser($params['Login'], $params['Password'],$params['Email']);
268 $result = Webusers::createUser($params, $user_id);
269 Users::createPermissions(array($params['Login']));
270 $dbl = new DBLayer("lib");
271 $dbl->execute("UPDATE ticket_user SET Permission = 3 WHERE TUserId = :user_id",array('user_id' => $user_id));
272 printalert("success", "AMS Admin account <em>" . htmlentities($_POST["amsAdminUsername"]) . "</em> created");
273 } catch (PDOException $e) {
274 printalert("danger", "Failed to create AMS Admin account");
275 $continue = false;
280 if ($roleDomain) {
281 // TODO: Register the domain with the nel database etc
284 if ($continue && $roleService) {
285 if (file_put_contents("role_service", "1")) {
286 printalert("success", "Service role successfully installed");
287 } else {
288 printalert("danger", "Failed to flag installation success");
289 $continue = false;
293 if ($continue && $roleSupport) {
294 if (file_put_contents("role_support", "1")) {
295 printalert("success", "Support role successfully installed");
296 } else {
297 printalert("danger", "Failed to flag installation success");
298 $continue = false;
302 if ($continue && $roleDomain) {
303 if (file_put_contents("role_domain", "1")) {
304 printalert("success", "Domain role successfully installed");
305 } else {
306 printalert("danger", "Failed to flag installation success");
307 $continue = false;
313 <a class="btn btn-primary" href="index.php">Continue</a>
314 </p>
316 <?php } /* ENDOF: if (isset($_POST)) { */ else { /* TODO: Refill form on failure */ ?>
318 <script>
320 var visiblePanelClass = "panel panel-default";
321 var hiddenPanelClass = "panel panel-default hide";
323 function checkService() {
324 var panelClass = document.getElementById('roleService').checked
325 ? visiblePanelClass
326 : hiddenPanelClass;
327 document.getElementById("panelAdmin").className = panelClass;
330 function checkSupport() {
331 var panelClass = document.getElementById('roleSupport').checked
332 ? visiblePanelClass
333 : hiddenPanelClass;
334 document.getElementById("panelAMS").className = panelClass;
337 function checkDomain() {
338 var panelClass = document.getElementById('roleDomain').checked
339 ? visiblePanelClass
340 : hiddenPanelClass;
341 document.getElementById("panelDomain").className = panelClass;
344 </script>
346 <form class="form-horizontal" role="form" method="POST" action="" enctype="application/x-www-form-urlencoded">
347 <div class="panel panel-default">
348 <div class="panel-heading">
349 <h2 class="panel-title">Roles</h2>
350 </div>
351 <div class="panel-body">
352 <div class="form-group">
353 <div class="col-sm-offset-3 col-sm-8">
354 <div class="checkbox">
355 <label>
356 <input id="roleService" name="roleService" type="checkbox" onclick="checkService();" checked> Service <small>(NeL Login, Shard Admin, Domain Database, ...)</small>
357 </label>
358 </div>
359 </div>
360 </div>
361 <div class="form-group">
362 <div class="col-sm-offset-3 col-sm-8">
363 <div class="checkbox">
364 <label>
365 <input id="roleSupport" name="roleSupport" type="checkbox" onclick="checkSupport();" checked> Support <small>(AMS, ...)</small>
366 </label>
367 </div>
368 </div>
369 </div>
370 <div class="form-group">
371 <div class="col-sm-offset-3 col-sm-8">
372 <div class="checkbox">
373 <label>
374 <input id="roleDomain" name="roleDomain" type="checkbox" onclick="checkDomain();" checked> Domain <small>(Ring Database, ...)</small>
375 </label>
376 </div>
377 </div>
378 </div>
379 </div>
380 </div>
381 <div class="panel panel-default">
382 <div class="panel-heading">
383 <h2 class="panel-title">Basics <small>(Paths relative to the public root directory)</small></h2>
384 </div>
385 <div class="panel-body">
386 <div class="form-group">
387 <label for="privatePhpDirectory" class="col-sm-3 control-label">Private PHP Directory</label>
388 <div class="col-sm-6">
389 <input type="text" class="form-control" id="privatePhpDirectory" name="privatePhpDirectory" value="../private_php/">
390 </div>
391 </div>
392 <div class="form-group">
393 <label for="nelSetupPassword" class="col-sm-3 control-label">Setup Password</label>
394 <div class="col-sm-6">
395 <input type="password" class="form-control" id="nelSetupPassword" name="nelSetupPassword" value="admin">
396 </div>
397 </div>
398 </div>
399 </div>
400 <div class="panel panel-default">
401 <div class="panel-heading">
402 <h2 class="panel-title">Service Database <small>(Used for NeL login, admin tools and domain databases)</small></h2>
403 </div>
404 <div class="panel-body">
405 <div class="form-group">
406 <label for="nelSqlHostname" class="col-sm-3 control-label">SQL Hostname</label>
407 <div class="col-sm-6">
408 <input type="text" class="form-control" id="nelSqlHostname" name="nelSqlHostname" value="localhost">
409 </div>
410 </div>
411 <div class="form-group">
412 <label for="nelSqlUsername" class="col-sm-3 control-label">SQL Username</label>
413 <div class="col-sm-6">
414 <input type="text" class="form-control" id="nelSqlUsername" name="nelSqlUsername" value="root">
415 </div>
416 </div>
417 <div class="form-group">
418 <label for="nelSqlPassword" class="col-sm-3 control-label">SQL Password</label>
419 <div class="col-sm-6">
420 <input type="password" class="form-control" id="nelSqlPassword" name="nelSqlPassword" value="">
421 </div>
422 </div>
423 <div class="form-group">
424 <label for="nelDatabase" class="col-sm-3 control-label">NeL Database</label>
425 <div class="col-sm-6">
426 <input type="text" class="form-control" id="nelDatabase" name="nelDatabase" value="nel">
427 </div>
428 </div>
429 </div>
430 </div>
431 <div id="panelAdmin" class="panel panel-default">
432 <div class="panel-heading">
433 <h2 class="panel-title">Shard Admin</h2>
434 </div>
435 <div class="panel-body">
436 <div class="form-group">
437 <label for="toolDatabase" class="col-sm-3 control-label">NeL Tools Database</label>
438 <div class="col-sm-6">
439 <input type="text" class="form-control" id="toolDatabase" name="toolDatabase" value="nel_tool">
440 </div>
441 </div>
442 <div class="form-group">
443 <label for="toolsAdminUsername" class="col-sm-3 control-label">Admin Username</label>
444 <div class="col-sm-6">
445 <input type="text" class="form-control" id="toolsAdminUsername" name="toolsAdminUsername" value="admin">
446 </div>
447 </div>
448 <div class="form-group">
449 <label for="toolsAdminPassword" class="col-sm-3 control-label">Admin Password</label>
450 <div class="col-sm-6">
451 <input type="password" class="form-control" id="toolsAdminPassword" name="toolsAdminPassword" value="admin">
452 </div>
453 </div>
454 </div>
455 </div>
456 <div id="panelAMS" class="panel panel-default">
457 <div class="panel-heading">
458 <h2 class="panel-title">AMS <small>(Account Management System)</small></h2>
459 </div>
460 <div class="panel-body">
461 <div class="form-group">
462 <label for="amsSqlHostname" class="col-sm-3 control-label">SQL Hostname</label>
463 <div class="col-sm-6">
464 <input type="text" class="form-control" id="amsSqlHostname" name="amsSqlHostname" value="localhost">
465 </div>
466 </div>
467 <div class="form-group">
468 <label for="amsSqlUsername" class="col-sm-3 control-label">SQL Username</label>
469 <div class="col-sm-6">
470 <input type="text" class="form-control" id="amsSqlUsername" name="amsSqlUsername" value="root">
471 </div>
472 </div>
473 <div class="form-group">
474 <label for="amsSqlPassword" class="col-sm-3 control-label">SQL Password</label>
475 <div class="col-sm-6">
476 <input type="password" class="form-control" id="amsSqlPassword" name="amsSqlPassword" value="">
477 </div>
478 </div>
479 <div class="form-group">
480 <label for="amsDatabase" class="col-sm-3 control-label">CMS Database</label>
481 <div class="col-sm-6">
482 <input type="text" class="form-control" id="amsDatabase" name="amsDatabase" value="nel_ams">
483 </div>
484 </div>
485 <div class="form-group">
486 <label for="amsLibDatabase" class="col-sm-3 control-label">Library Database</label>
487 <div class="col-sm-6">
488 <input type="text" class="form-control" id="amsLibDatabase" name="amsLibDatabase" value="nel_ams_lib">
489 </div>
490 </div>
491 <div class="form-group">
492 <label for="amsAdminUsername" class="col-sm-3 control-label">Admin Username</label>
493 <div class="col-sm-6">
494 <input type="text" class="form-control" id="amsAdminUsername" name="amsAdminUsername" value="admin">
495 </div>
496 </div>
497 <div class="form-group">
498 <label for="amsAdminPassword" class="col-sm-3 control-label">Admin Password</label>
499 <div class="col-sm-6">
500 <input type="password" class="form-control" id="amsAdminPassword" name="amsAdminPassword" value="admin">
501 </div>
502 </div>
503 </div>
504 </div>
505 <div id="panelDomain" class="panel panel-default hide">
506 <div class="panel-heading">
507 <h2 class="panel-title">Domain <small>(Multiple domains require separate installations, as they may run different versions)</small></h2>
508 </div>
509 <div class="panel-body">
510 <div class="panel panel-danger">
511 <div class="panel-heading"><span class="glyphicon glyphicon-info-sign"></span> Database Only</div>
512 <div class="panel-body">
513 <p>The setup script is intended only for installation and upgrade of the domain specific database.</p>
514 <p>This will only configure the database for a single domain. It will not register the domain in the domain configuration.</p>
515 <p>The domain must be manually configured in the databases according to the procedure for configuring your server park with patchman, as it depends on several values defined within the patchman configuration.</p>
516 <!-- NOTE: For future implementation, it would be practical to configure the nel database directly from the patchman configuration script, as this has all the required values ready. -->
517 <!-- IMPORTANT: This setup must NEVER be modified to configure the domains, it is not it's responsibility. -->
518 <p>It is required to use separate virtual hosts for multiple domains, in order to allow domain-specific script to run at different versions.</p>
519 <p>It is recommended, when planning to use multiple domains, to use a separate virtual host for each web service role.</p>
520 <p>There can be multiple instances of the domain role, there can only be one support and one service role setup.</p>
521 </div>
522 </div>
523 <div class="form-group">
524 <label for="nelDomainName" class="col-sm-3 control-label">Name</label>
525 <div class="col-sm-6">
526 <input type="text" class="form-control" id="nelDomainName" name="nelDomainName" value="mini01">
527 </div>
528 </div>
529 <div class="form-group">
530 <label for="domainDatabase" class="col-sm-3 control-label">Database</label>
531 <div class="col-sm-6">
532 <input type="text" class="form-control" id="domainDatabase" name="domainDatabase" value="ring_mini01">
533 </div>
534 </div>
535 </div>
536 </div>
537 <input name="submit" type="submit" value="Configure" class="btn btn-primary">
538 </form>
540 <script>
542 checkService();
543 checkSupport();
544 checkDomain();
546 </script>
548 <?php } ?>
550 <?php
552 include('footer.php');
555 catch (SystemExit $e) { /* do nothing */ }