211e33ccda4149ce7bf56b9b4a5e03fd864cd352
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();
374 // Assign ACLs
375 foreach($this->attributes as $attr){
376 $smarty->assign("{$attr}ACL", $this->getacl($attr));
377 }
379 $smarty->assign('installTemplateList', $this->installationTemplateNames);
380 $smarty->assign('installReleaseList', $this->templateToRelease[$this->installTemplate]);
381 $smarty->assign('timezones', $this->timezones);
382 $smarty->assign('installKeyboardlayoutList', $this->installKeyboardlayoutList);
383 $smarty->assign('installKernelPackageList', $this->installKernelPackageList);
384 $smarty->assign('installMirrorList', $this->installMirrorList);
385 $smarty->assign('installSystemLocaleList', $this->installSystemLocaleList);
386 $smarty->assign('installNTPServerList', $this->installNTPServerList->render());
388 $smarty->assign('installBootstrapMethod', $this->installBootstrapMethod);
389 $smarty->assign('installBootstrapMethodList', $this->installBootstrapMethodList);
390 $smarty->assign('installConfigManagement', $this->installConfigManagement);
392 // Assign list of available config-management types.
393 if(isset($this->installConfigManagementList[$this->installBootstrapMethod])){
394 $smarty->assign('installConfigManagementList', $this->installConfigManagementList[$this->installBootstrapMethod]);
395 }else{
396 $smarty->assign('installConfigManagementList', array());
397 }
399 foreach($this->attributes as $attr){
400 $smarty->assign($attr, $this->$attr);
401 }
402 $this->dialog = false;
403 return($display.$smarty->fetch(get_template_path('goto/Device/InstallRecipe.tpl', TRUE)));
404 }
407 function save_object()
408 {
409 if(isset($_POST['InstallRecipePosted'])){
411 $currentInstallMethod = $this->installConfigManagement;
413 $oldRelease = $this->installRelease;
414 plugin::save_object();
415 $this->installRootEnabled = isset($_POST['installRootEnabled']);
416 $this->installTimeUTC = isset($_POST['installTimeUTC']);
419 if(isset($_POST['setPasswordHash'])){
420 $this->setPasswordHash = true;
421 }
423 $this->installNTPServerList->save_object();
424 $this->installNTPServer = $this->installNTPServerList->getMaintainedData();
425 if(isset($_POST['installNTPServer_Input']) && isset($_POST['installNTPServer_Add'])){
426 $add = get_post('installNTPServer_Input');
427 if(!in_array($add, $this->installNTPServer) && !empty($add)){
428 $this->installNTPServer[] = $add;
429 }
430 }
431 $this->installNTPServerList->setListData($this->installNTPServer);
432 $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
434 // The selected release is no longer available for the current template
435 if(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
436 $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
437 }
439 // Reload list of kernel packages and mirrors
440 if($oldRelease != $this->installRelease){
441 $this->reloadInstallationKernelPackages();
442 $this->reloadInstallationMirrors();
443 }
444 }
446 if(isset($_POST['cancelPassword'])) $this->setPasswordHash =false;
447 if(isset($_POST['setPassword'])) {
448 $this->setPasswordHash =false;
449 $hash = get_post('passwordHash');
451 // Not sure, why this is here, but maybe some encryption methods require it.
452 mt_srand((double) microtime()*1000000);
454 // Generate the requested hash
455 $methods = new passwordMethod($this->config, $this->dn);
456 $available = $methods->get_available_methods();
457 $test = new $available[$hash]($this->config,$this->dn);
458 $this->installRootPasswordHash = @$test->generate_hash(get_post('rootPassword'));
459 }
460 }
463 function save()
464 {
465 if(!$this->installRootEnabled) $this->installRootPasswordHash = "";
467 $map = array(
468 "installNTPServer"=>'ntp-servers',
469 "installTemplate"=>'template',
470 "installRelease"=>'release',
471 "installTimezone"=>'timezone',
472 "installTimeUTC"=>'utc',
473 "installKernelPackage"=>'kernel',
474 "installSystemLocale"=>'system-locale',
475 "installRootEnabled"=>'root-user',
476 "installRootPasswordHash"=>'root-hash',
477 "installPartitionTable"=>'disk-setup',
478 "installKeyboardlayout"=>'keyboard-layout',
479 );
481 // Collect values to be saved.
482 $data = array();
483 foreach($map as $source => $dest){
484 if(!empty($this->$source)){
485 $data[$dest] = $this->$source;
486 }
487 }
489 // Enforce an array for ntp-servers
490 $data['ntp-servers'] = array_values($data['ntp-servers']);
492 // Save Boolean like a String
493 $boolean = array("root-user" => "installRootEnabled", "utc" => "installTimeUTC");
494 foreach($boolean as $attr => $source){
495 $data[$attr] = ($this->$source) ? $data[$attr] = "TRUE" : $data[$attr] = "FALSE";
496 }
498 $rpc = $this->config->getRpcHandle();
499 $res = $rpc->systemSetBaseInstallParameters($this->deviceUUID, $data);
501 // Failed to load backend values, keep reported error and return with FALSE;
502 $this->rpcError = !$rpc->success();
503 if(!$rpc->success()){
504 $this->rpcErrorMessage = $rpc->get_error();
505 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
506 return(NULL);
507 }
509 }
512 function remove_from_parent()
513 {
514 print "Missing";
515 }
518 /*! \brief Refreshes the list of selectable kernel packages.
519 */
520 function reloadInstallationKernelPackages($initially = FALSE)
521 {
522 // Do nothing if no release is given.
523 if(empty($this->installRelease)){
524 $this->installKernelPackageList = array();
525 return;
526 }
528 $rpc = $this->config->getRpcHandle();
529 $res = $rpc->getKernelPackages($this->installRelease);
531 // Failed to load backend values, keep reported error and return with FALSE;
532 $this->rpcError = !$rpc->success();
533 if(!$rpc->success()){
534 $this->rpcErrorMessage = $rpc->get_error();
535 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
536 }else{
537 $this->installKernelPackageList = array();
538 foreach($res as $name){
539 $this->installKernelPackageList[$name] = $name;
540 }
542 if(!isset($this->installKernelPackageList[$this->installKernelPackage])){
543 $new = key($this->installKernelPackageList);
544 if($initially){
545 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);
546 }
547 $this->installKernelPackage = $new;
548 }
549 }
550 }
553 /*! \brief Returns a list of distributions on success.
554 * In case of an error, it returns NULL.
555 */
556 function loadDistributions()
557 {
558 $rpc = $this->config->getRpcHandle();
559 $res = $rpc->getDistributions();
561 // Failed to load backend values, keep reported error and return with FALSE;
562 $this->rpcError = !$rpc->success();
563 if(!$rpc->success()){
564 $this->rpcErrorMessage = $rpc->get_error();
565 return(NULL);
566 }
567 return($res);
568 }
571 /*! \brief Returns a list of timezones on success.
572 * In case of an error, it returns NULL.
573 */
574 function getTimezones()
575 {
576 $rpc = $this->config->getRpcHandle();
577 $res = $rpc->getTimezones();
579 // Failed to load backend values, keep reported error and return with FALSE;
580 $this->rpcError = !$rpc->success();
581 if(!$rpc->success()){
582 $this->rpcErrorMessage = $rpc->get_error();
583 return(NULL);
584 }
585 return($res);
586 }
589 /*! \brief Returns a list of installation mirrors on success.
590 * In case of an error, it returns NULL.
591 */
592 function reloadInstallationMirrors($initially = FALSE)
593 {
594 $res = array(
595 'dc=intranet,dc=gonicus,dc=de' => 'Intranet',
596 'ou=systems,dc=intranet,dc=gonicus,dc=de' => 'System');
597 $this->installMirrorList =$res;
598 }
601 /*! \brief Returns a list of installation templates on success.
602 * In case of an error, it returns NULL.
603 */
604 function loadInstallationTemplates()
605 {
606 $rpc = $this->config->getRpcHandle();
607 $res = $rpc->installListTemplates();
609 // Failed to load backend values, keep reported error and return with FALSE;
610 $this->rpcError = !$rpc->success();
611 if(!$rpc->success()){
612 $this->rpcErrorMessage = $rpc->get_error();
613 return(NULL);
614 }
615 return($res);
616 }
619 /*! \brief Returns a list of keyboard layouts on success.
620 * In case of an error, it returns NULL.
621 */
622 function loadInstallationKeyboardLayouts()
623 {
624 $rpc = $this->config->getRpcHandle();
625 $res = $rpc->getKeyboardModels();
627 // Failed to load backend values, keep reported error and return with FALSE;
628 $this->rpcError = !$rpc->success();
629 if(!$rpc->success()){
630 $this->rpcErrorMessage = $rpc->get_error();
631 return(NULL);
632 }
633 $lay = array();
634 foreach($res as $key => $data){
635 $lay[$key] = "{$data[0]} - {$data[2]}";
636 }
637 asort($lay);
638 return($lay);
639 }
642 /*! \brief Returns a list of system locales on success.
643 * In case of an error, it returns NULL.
644 */
645 function getSystemLocales()
646 {
647 $rpc = $this->config->getRpcHandle();
648 $res = $rpc->getSystemLocales();
650 // Failed to load backend values, keep reported error and return with FALSE;
651 $this->rpcError = !$rpc->success();
652 if(!$rpc->success()){
653 $this->rpcErrorMessage = $rpc->get_error();
654 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
655 return(NULL);
656 }
658 return($res);
659 }
662 /*! \brief Try to load install and bootstrap methods from the GOsa-backend
663 * This is done via jsonRPC, if calling the backend method fails,
664 * this method returns FALSE, in case of success it return TRUE;
665 */
666 function loadInstallationMethods()
667 {
668 $rpc = $this->config->getRpcHandle();
669 $res = $rpc->getSupportedBaseInstallMethods();
671 // Failed to load backend values, keep reported error and return with FALSE;
672 $this->rpcError = !$rpc->success();
673 if(!$rpc->success()){
674 $this->rpcErrorMessage = $rpc->get_error();
675 return(NULL);
676 }
678 // Walk through result and set bootstrap methods.
679 foreach($res as $name => $method){
680 $res['installBootstrapMethodList'][$name] = $method['name'];
681 foreach($method['methods'] as $m){
682 $res['installConfigManagementList'][$name][$m] = $m;
683 }
684 }
685 return($res);
686 }
689 static function plInfo()
690 {
691 return (array(
692 "plShortName" => _("Device"),
693 "plDescription" => _("Registered device"),
694 "plSelfModify" => FALSE,
695 "plDepends" => array(),
696 "plPriority" => 1,
697 "plSection" => array("administration"),
698 "plCategory" => array("Device"),
699 "plProvidedAcls" => array(
701 "installRelease" => _("Release"),
702 "installTemplate" => _("Template"),
703 "installKeyboardlayout" => _("Keyboard layout"),
704 "installSystemLocale" => _("Locale"),
705 "installTimezone" => _("Timezone"),
706 "installTimeUTC" => _("Utc"),
707 "installNTPServer" => _("Ntp server"),
708 "installMirror" => _("Mirror"),
709 "installRootEnabled" => _("Root login enabled"),
710 "installRootPasswordHash" => _("Root password hash"),
711 "installKernelPackage" => _("Kernel package"),
712 "installConfigManagement" => _("Config mangement"),
713 "installBootstrapMethod" => _("Bootstrap method"),
714 "installPartitionTable" => _("Partition table")
715 )
716 )
717 );
718 }
719 }
720 ?>