d7694e6f68a50370b3e77263425a5fb4891f140b
1 <?php
3 class InstallRecipe extends plugin
4 {
6 public $rpcErrorMessage = "";
7 public $deviceUUID = "";
9 // Template options
10 public $installTemplate = "";
11 public $installationTemplateNames = array();
12 public $templateToRelease = array();
13 public $installationTemplates = array();
15 // The selected installation release
16 public $installRelease = "";
18 // Selected config management variant
19 public $installConfigManagement = '';
20 public $installConfigManagementList = array();
22 // Bootstrap method
23 public $installBootstrapMethod = '';
24 public $installBootstrapMethodList = array();
26 // Timezone settings
27 public $installTimezone = "";
28 public $installTimeUTC = "";
30 // Kernel packages
31 public $installKernelPackage = "";
32 public $installKernelPackageList = array();
34 // System Locale
35 public $installSystemLocale = "";
36 public $installSystemLocaleList = array();
38 // Selected NTP Server
39 public $installNTPServer = array();
40 public $installNTPServerList = NULL;
42 // Root password
43 public $installRootEnabled = "";
44 public $installRootPasswordHash = "";
45 public $setPasswordHash = FALSE;
47 // Partition table variables
48 public $installPartitionTable = "";
49 private $partitionEdit = NULL;
51 // Keyboard-layout attribute
52 public $installKeyboardlayout = "";
53 public $installKeyboardlayoutList = array();
55 // Mirror related attribute
56 public $installMirror = "";
57 public $installMirrorList = array();
59 public $objectclasses = array();
60 public $attributes = array("installRelease", "installTemplate","installKeyboardlayout","installSystemLocale",
61 "installTimezone","installTimeUTC","installNTPServer","installMirror",
62 "installRootEnabled","installRootPasswordHash","installKernelPackage",
63 "installPartitionTable","installConfigManagement","installBootstrapMethod");
66 /* Some plugin management related attributes
67 * See class plugin for details.
68 */
69 public $view_logged = FALSE;
70 public $ignore_account = FALSE;
71 public $parent = NULL;
73 /*! \brief Initialize the plugin and its widgets.
74 * Finally call init() to load values from the backend.
75 */
76 function __construct(&$config, $dn, $parent)
77 {
78 plugin::plugin($config, $dn);
80 $this->is_account = $this->initially_was_account = FALSE;
82 $this->_device = &$parent;
83 $this->deviceUUID = $parent->deviceUUID;
85 // Set default password hash
86 $this->hash = $this->config->get_cfg_value("core","passwordDefaultHash");
88 // Get list of password hashes
89 $tmp = passwordMethod::get_available_methods();
90 $this->hashes = array();
91 foreach($tmp['name'] as $name){
92 $this->hashes[$name] = $name;
93 }
95 // Initialize plugin
96 $this->init_static_info();
97 $this->init($initially = TRUE);
98 }
100 function init($initially = FALSE)
101 {
102 // Init the object values.
103 $this->init_client_info();
105 // Prepare NTP servers list
106 $this->installNTPServerList= new sortableListing($this->installNTPServer);
107 $this->installNTPServerList->setDeleteable(true);
108 $this->installNTPServerList->setEditable(false);
109 $this->installNTPServerList->setColspecs(array('*'));
110 $this->installNTPServerList->setWidth("100%");
111 $this->installNTPServerList->setHeight("70px");
113 // Preset values for new devices
114 if(!$this->is_account){
115 $this->installTemplate = key($this->installationTemplates);
116 $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
117 }else{
119 if(!isset($this->installationTemplates[$this->installTemplate])){
121 // The selected template is no longer available, select the next selectable template.
122 $new = key($this->installationTemplates);
124 if($initially){
125 $message = sprintf(_("The selected template '%s' is no longer available. Selecting '%s' as replacement!"),
126 $this->installTemplate, $new);
127 msg_dialog::display(_("Warning"), $message, WARNING_DIALOG);
128 }
129 $this->installTemplate = $new;
130 $installRelease = key($this->templateToRelease[$this->installTemplate]);
132 }elseif(!isset($this->installationTemplates[$this->installTemplate]['method'])){
134 // Not necessary to warn the user here, the input fields will be empty and thus
135 // avoid saving.
137 }elseif(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
139 // The selected release is no longer available for the current template
140 // Warn the user and select the next selectable release.
141 $new = key($this->templateToRelease[$this->installTemplate]);
142 if($initially){
143 $message = sprintf(_("The selected release '%s' is no longer available. Selecting '%s' as replacement!"),
144 $this->installRelease, $new);
145 }
146 $this->installRelease = $new;
147 msg_dialog::display(_("Warning"), $message, WARNING_DIALOG);
148 }
149 }
151 // Update selectable items like kernels and mirrors depending on the current setup (relase)
152 $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
153 $this->reloadInstallationKernelPackages($initially);
154 $this->reloadInstallationMirrors($initially);
156 // Preset the config management method.
157 if(!isset($this->installConfigManagementList[$this->installBootstrapMethod][$this->installConfigManagement])){
158 if(isset($this->installConfigManagementList[$this->installBootstrapMethod]) &&
159 count($this->installConfigManagementList[$this->installBootstrapMethod])){
160 $this->installConfigManagement = key($this->installConfigManagementList[$this->installBootstrapMethod]);
161 }
162 }
163 }
166 /*! \brief Loads client-information values from the GOsa-backend using jsonRPC
167 */
168 function init_client_info()
169 {
170 if(empty($this->deviceUUID)){
171 return;
172 }
174 $rpc = $this->config->getRpcHandle();
175 $res = $rpc->systemGetBaseInstallParameters($this->deviceUUID);
177 // Failed to load backend values, keep reported error and return with FALSE;
178 $this->rpcError = !$rpc->success();
179 if(!$rpc->success()){
180 $this->rpcErrorMessage = $rpc->get_error();
181 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
182 return(NULL);
183 }
185 // Apply received options
186 $this->is_account = $res == True;
187 if($this->is_account){
189 $map = array(
190 'ntp-servers' => "installNTPServer",
191 'template' => "installTemplate",
192 'keyboard-layout' => "installKeyboardlayout");
194 // We receive an array for these attributes, but require a string instead
195 // we just use the first element of the array.
196 $mapArray = array(
197 'release' => "installRelease",
198 'timezone' => "installTimezone",
199 'utc' => "installTimeUTC",
200 'kernel' => "installKernelPackage",
201 'system-locale' => "installSystemLocale",
202 'root-user' => "installRootEnabled",
203 'root-hash' => "installRootPasswordHash",
204 'disk-setup' => "installPartitionTable");
206 foreach($res as $name => $data){
207 if(isset($map[$name])){
208 $target = $map[$name];
209 $value = $res[$name];
210 }elseif(isset($mapArray[$name])){
211 $target = $mapArray[$name];
212 $value = $res[$name][0];
213 }
214 $this->$target = $value;
215 }
217 // Convert Bool values to Bool.
218 $boolean = array("installRootEnabled", "installTimeUTC");
219 foreach($boolean as $attr){
220 $this->$attr = ($this->$attr != FALSE && !preg_match("/false/i", $this->$attr));
221 }
222 }
224 return;
225 }
228 function init_static_info()
229 {
230 // Load static values.
231 foreach(array(
232 "timeozones" => "getTimezones",
233 "distributions" => "loadDistributions",
234 "keyboardLayouts" => "loadInstallationKeyboardLayouts",
235 "installationTemplates" => "loadInstallationTemplates",
236 "installationMethods" => "loadInstallationMethods",
237 "locales" => "getSystemLocales" ) as $target => $func){
238 $$target = $this->$func();
239 if($$target == NULL){
240 $this->initFailed = TRUE;
241 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
242 return;
243 }
244 }
246 // Assign fetchted values
247 $this->timezones = $timeozones;
248 $this->installBootstrapMethodList = $installationMethods['installBootstrapMethodList'];
249 $this->installConfigManagementList = $installationMethods['installConfigManagementList'];
250 $this->installSystemLocaleList = $locales;
251 $this->installKeyboardlayoutList = $keyboardLayouts;
252 $this->distributions = $distributions;
254 # Create template to relase map
255 $this->templateToRelease = array();
257 // Walk through installation templates and use the 'repositories' attribute
258 // to supported releases.
259 foreach($installationTemplates as $name => $tdata){
261 $mName = isset($this->installBootstrapMethodList[$tdata['method']]) ?
262 $this->installBootstrapMethodList[$tdata['method']]: $tdata['method'];
264 $this->installationTemplateNames[$name] = $tdata['description']." (".$mName.")";
265 $this->installationTemplates[$name] = $tdata;
266 $this->templateToRelease[$name] = array();
268 // Check if the 'repository'-category of the template can be found in any
269 // received release list.
270 if(isset($installationMethods[$tdata['method']]['repositories'])){
271 $repos = $installationMethods[$tdata['method']]['repositories'];
272 foreach($distributions as $dist){
273 if(in_array($dist['type']['name'],$repos) && isset($dist['releases'])){
274 foreach($dist['releases'] as $release){
275 $rname = $dist['name'].'/'.$release['name'];
276 $this->templateToRelease[$name][$rname] = $rname;
277 }
278 }
279 }
280 }
281 }
282 }
285 function check()
286 {
287 // Check if the parents deviceUUID has changed
288 if($this->deviceUUID != $this->_device->deviceUUID){
289 $this->deviceUUID = $this->_device->deviceUUID;
290 print "The device uuid has changed.";
291 }
292 }
295 function execute()
296 {
297 // Log account access
298 if($this->is_account && !$this->view_logged){
299 $this->view_logged = TRUE;
300 new log("view","Device/".get_class($this),$this->dn);
301 }
303 /***************
304 Handle account state
305 ***************/
307 // Allow to add or remove the distribution list extension
308 if(isset($_POST['modify_state'])){
309 if($this->is_account && $this->acl_is_removeable()){
310 $this->is_account= FALSE;
311 }elseif(!$this->is_account && $this->acl_is_createable()){
312 $this->is_account= TRUE;
313 }
314 }
316 // Show account status-changer
317 $display = "";
318 if ($this->parent !== NULL){
319 if ($this->is_account){
320 $display= $this->show_disable_header(_("Remove base installation"),
321 msgPool::featuresEnabled(_("Base installation")));
322 } else {
323 $display= $this->show_enable_header(_("Add base installation"),
324 msgPool::featuresDisabled(_("Base installation")));
325 return ($display);
326 }
327 }
329 /***************
330 Root password hash dialog
331 ***************/
333 $this->dialog = FALSE;
334 if($this->setPasswordHash){
335 $this->dialog = TRUE;
336 $smarty = get_smarty();
337 $smarty->assign('hashes', set_post($this->hashes));
338 $smarty->assign('hash', set_post($this->hash));
339 return($smarty->fetch(get_template_path('goto/Device/SetPassword.tpl', TRUE)));
340 }
342 /***************
343 Partition dialog
344 ***************/
346 if(isset($_POST['partition_finish']) && $this->partitionEdit){
347 $this->installPartitionTable = $this->partitionEdit->save();
348 $this->partitionEdit = NULL;
349 }
350 if(isset($_POST['partition_cancel']) && $this->partitionEdit){
351 $this->partitionEdit = NULL;
352 }
353 if(isset($_POST['edit_installPartitionTable'])){
354 $this->partitionEdit = new DevicePartition($this->config, $this->installPartitionTable);
355 }
356 if($this->partitionEdit){
357 $this->partitionEdit->save_object();
358 $this->dialog = TRUE;
359 return($this->partitionEdit->execute());
360 }
364 /***************
365 Generate HTML content
366 ***************/
368 $this->installNTPServerList->setAcl($this->getacl('installNTPServer'));
369 $this->installNTPServerList->update();
371 plugin::execute();
372 $smarty = get_smarty();
373 $smarty->assign('installTemplateList', $this->installationTemplateNames);
374 $smarty->assign('installReleaseList', $this->templateToRelease[$this->installTemplate]);
377 $smarty->assign('timezones', $this->timezones);
378 $smarty->assign('installKeyboardlayoutList', $this->installKeyboardlayoutList);
379 $smarty->assign('installKernelPackageList', $this->installKernelPackageList);
380 $smarty->assign('installMirrorList', $this->installMirrorList);
381 $smarty->assign('installSystemLocaleList', $this->installSystemLocaleList);
382 $smarty->assign('installNTPServerList', $this->installNTPServerList->render());
384 $smarty->assign('installBootstrapMethod', $this->installBootstrapMethod);
385 $smarty->assign('installBootstrapMethodList', $this->installBootstrapMethodList);
386 $smarty->assign('installConfigManagement', $this->installConfigManagement);
388 // Assign list of available config-management types.
389 if(isset($this->installConfigManagementList[$this->installBootstrapMethod])){
390 $smarty->assign('installConfigManagementList', $this->installConfigManagementList[$this->installBootstrapMethod]);
391 }else{
392 $smarty->assign('installConfigManagementList', array());
393 }
395 foreach($this->attributes as $attr){
396 $smarty->assign($attr, $this->$attr);
397 }
398 $this->dialog = false;
399 return($display.$smarty->fetch(get_template_path('goto/Device/InstallRecipe.tpl', TRUE)));
400 }
403 function save_object()
404 {
405 if(isset($_POST['InstallRecipePosted'])){
407 $currentInstallMethod = $this->installConfigManagement;
409 $oldRelease = $this->installRelease;
410 plugin::save_object();
411 $this->installRootEnabled = isset($_POST['installRootEnabled']);
412 $this->installTimeUTC = isset($_POST['installTimeUTC']);
415 if(isset($_POST['setPasswordHash'])){
416 $this->setPasswordHash = true;
417 }
419 $this->installNTPServerList->save_object();
420 $this->installNTPServer = $this->installNTPServerList->getMaintainedData();
421 if(isset($_POST['installNTPServer_Input']) && isset($_POST['installNTPServer_Add'])){
422 $add = get_post('installNTPServer_Input');
423 if(!in_array($add, $this->installNTPServer) && !empty($add)){
424 $this->installNTPServer[] = $add;
425 }
426 }
427 $this->installNTPServerList->setListData($this->installNTPServer);
428 $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
430 // The selected release is no longer available for the current template
431 if(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
432 $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
433 }
435 // Reload list of kernel packages and mirrors
436 if($oldRelease != $this->installRelease){
437 $this->reloadInstallationKernelPackages();
438 $this->reloadInstallationMirrors();
439 }
440 }
442 if(isset($_POST['cancelPassword'])) $this->setPasswordHash =false;
443 if(isset($_POST['setPassword'])) {
444 $this->setPasswordHash =false;
445 $hash = get_post('passwordHash');
447 // Not sure, why this is here, but maybe some encryption methods require it.
448 mt_srand((double) microtime()*1000000);
450 // Generate the requested hash
451 $methods = new passwordMethod($this->config, $this->dn);
452 $available = $methods->get_available_methods();
453 $test = new $available[$hash]($this->config,$this->dn);
454 $this->installRootPasswordHash = @$test->generate_hash(get_post('rootPassword'));
455 }
456 }
459 function save()
460 {
461 if(!$this->installRootEnabled) $this->installRootPasswordHash = "";
463 $map = array(
464 "installNTPServer"=>'ntp-servers',
465 "installTemplate"=>'template',
466 "installRelease"=>'release',
467 "installTimezone"=>'timezone',
468 "installTimeUTC"=>'utc',
469 "installKernelPackage"=>'kernel',
470 "installSystemLocale"=>'system-locale',
471 "installRootEnabled"=>'root-user',
472 "installRootPasswordHash"=>'root-hash',
473 "installPartitionTable"=>'disk-setup',
474 "installKeyboardlayout"=>'keyboard-layout',
475 );
477 // Collect values to be saved.
478 $data = array();
479 foreach($map as $source => $dest){
480 if(!empty($this->$source)){
481 $data[$dest] = $this->$source;
482 }
483 }
485 // Enforce an array for ntp-servers
486 $data['ntp-servers'] = array_values($data['ntp-servers']);
488 // Save Boolean like a String
489 $boolean = array("root-user" => "installRootEnabled", "utc" => "installTimeUTC");
490 foreach($boolean as $attr => $source){
491 $data[$attr] = ($this->$source) ? $data[$attr] = "TRUE" : $data[$attr] = "FALSE";
492 }
494 $rpc = $this->config->getRpcHandle();
495 $res = $rpc->systemSetBaseInstallParameters($this->deviceUUID, $data);
497 // Failed to load backend values, keep reported error and return with FALSE;
498 $this->rpcError = !$rpc->success();
499 if(!$rpc->success()){
500 $this->rpcErrorMessage = $rpc->get_error();
501 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
502 return(NULL);
503 }
505 }
508 function remove_from_parent()
509 {
510 print "Missing";
511 }
514 /*! \brief Refreshes the list of selectable kernel packages.
515 */
516 function reloadInstallationKernelPackages($initially = FALSE)
517 {
518 // Do nothing if no release is given.
519 if(empty($this->installRelease)){
520 $this->installKernelPackageList = array();
521 return;
522 }
524 $rpc = $this->config->getRpcHandle();
525 $res = $rpc->getKernelPackages($this->installRelease);
527 // Failed to load backend values, keep reported error and return with FALSE;
528 $this->rpcError = !$rpc->success();
529 if(!$rpc->success()){
530 $this->rpcErrorMessage = $rpc->get_error();
531 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
532 }else{
533 $this->installKernelPackageList = array();
534 foreach($res as $name){
535 $this->installKernelPackageList[$name] = $name;
536 }
538 if(!isset($this->installKernelPackageList[$this->installKernelPackage])){
539 $new = key($this->installKernelPackageList);
540 if($initially){
541 msg_dialog::display(_("Warning"), sprintf(_("The selected kernel package '%s' is no longer available! The kernel package '%s' was selected as replacement!"), $this->installKernelPackage, $new), WARNING_DIALOG);
542 }
543 $this->installKernelPackage = $new;
544 }
545 }
546 }
549 /*! \brief Returns a list of distributions on success.
550 * In case of an error, it returns NULL.
551 */
552 function loadDistributions()
553 {
554 $rpc = $this->config->getRpcHandle();
555 $res = $rpc->getDistributions();
557 // Failed to load backend values, keep reported error and return with FALSE;
558 $this->rpcError = !$rpc->success();
559 if(!$rpc->success()){
560 $this->rpcErrorMessage = $rpc->get_error();
561 return(NULL);
562 }
563 return($res);
564 }
567 /*! \brief Returns a list of timezones on success.
568 * In case of an error, it returns NULL.
569 */
570 function getTimezones()
571 {
572 $rpc = $this->config->getRpcHandle();
573 $res = $rpc->getTimezones();
575 // Failed to load backend values, keep reported error and return with FALSE;
576 $this->rpcError = !$rpc->success();
577 if(!$rpc->success()){
578 $this->rpcErrorMessage = $rpc->get_error();
579 return(NULL);
580 }
581 return($res);
582 }
585 /*! \brief Returns a list of installation mirrors on success.
586 * In case of an error, it returns NULL.
587 */
588 function reloadInstallationMirrors($initially = FALSE)
589 {
590 $res = array(
591 'dc=intranet,dc=gonicus,dc=de' => 'Intranet',
592 'ou=systems,dc=intranet,dc=gonicus,dc=de' => 'System');
593 $this->installMirrorList =$res;
594 }
597 /*! \brief Returns a list of installation templates on success.
598 * In case of an error, it returns NULL.
599 */
600 function loadInstallationTemplates()
601 {
602 $rpc = $this->config->getRpcHandle();
603 $res = $rpc->installListTemplates();
605 // Failed to load backend values, keep reported error and return with FALSE;
606 $this->rpcError = !$rpc->success();
607 if(!$rpc->success()){
608 $this->rpcErrorMessage = $rpc->get_error();
609 return(NULL);
610 }
611 return($res);
612 }
615 /*! \brief Returns a list of keyboard layouts on success.
616 * In case of an error, it returns NULL.
617 */
618 function loadInstallationKeyboardLayouts()
619 {
620 $rpc = $this->config->getRpcHandle();
621 $res = $rpc->getKeyboardModels();
623 // Failed to load backend values, keep reported error and return with FALSE;
624 $this->rpcError = !$rpc->success();
625 if(!$rpc->success()){
626 $this->rpcErrorMessage = $rpc->get_error();
627 return(NULL);
628 }
629 $lay = array();
630 foreach($res as $key => $data){
631 $lay[$key] = "{$data[0]} - {$data[2]}";
632 }
633 asort($lay);
634 return($lay);
635 }
638 /*! \brief Returns a list of system locales on success.
639 * In case of an error, it returns NULL.
640 */
641 function getSystemLocales()
642 {
643 $rpc = $this->config->getRpcHandle();
644 $res = $rpc->getSystemLocales();
646 // Failed to load backend values, keep reported error and return with FALSE;
647 $this->rpcError = !$rpc->success();
648 if(!$rpc->success()){
649 $this->rpcErrorMessage = $rpc->get_error();
650 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
651 return(NULL);
652 }
654 return($res);
655 }
658 /*! \brief Try to load install and bootstrap methods from the GOsa-backend
659 * This is done via jsonRPC, if calling the backend method fails,
660 * this method returns FALSE, in case of success it return TRUE;
661 */
662 function loadInstallationMethods()
663 {
664 $rpc = $this->config->getRpcHandle();
665 $res = $rpc->getSupportedBaseInstallMethods();
667 // Failed to load backend values, keep reported error and return with FALSE;
668 $this->rpcError = !$rpc->success();
669 if(!$rpc->success()){
670 $this->rpcErrorMessage = $rpc->get_error();
671 return(NULL);
672 }
674 // Walk through result and set bootstrap methods.
675 foreach($res as $name => $method){
676 $res['installBootstrapMethodList'][$name] = $method['name'];
677 foreach($method['methods'] as $m){
678 $res['installConfigManagementList'][$name][$m] = $m;
679 }
680 }
681 return($res);
682 }
685 static function plInfo()
686 {
687 return (array(
688 "plShortName" => _("Device"),
689 "plDescription" => _("Registered device"),
690 "plSelfModify" => FALSE,
691 "plDepends" => array(),
692 "plPriority" => 1,
693 "plSection" => array("administration"),
694 "plCategory" => array("Device"),
695 "plProvidedAcls" => array(
696 "member" => _("Member"),
697 "installTemplate" => _("Installation template"),
698 "installRelease" => _("Installation release"),
700 "installBootstrapMethod" => _("Bootstrap method"),
701 "installConfigManagement" => _("Config management"),
702 "installKeyboardlayout" => _("Keyboard layout"),
703 "installSystemLocale" => _("System locale"),
704 "installTimezone" => _("Timezone"),
705 "installTimeUTC" => _("Time"),
706 "installNTPServer" => _("NTP-Server"),
707 "installMirror" => _("Mirror"),
708 "installRootEnabled" => _("Root login enabled"),
709 "installRootPasswordHash" => _("Root password hash"),
710 "installKernelPackage" => _("Kernel package"),
711 "installPartitionTable" => _("Partition table")
712 )
713 )
714 );
715 }
716 }
717 ?>