Code

211e33ccda4149ce7bf56b9b4a5e03fd864cd352
[gosa.git] / gosa-plugins / goto / admin / systems / goto / Device / class_InstallRecipe.inc
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();
14     
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     }
165    
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);
176        
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         }
184    
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");
205  
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){
260             
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     }
293     
294     
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);
500        
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     }
511     
512     function remove_from_parent()
513     {
514        print "Missing"; 
515     }
516  
517     
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);
530       
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();
560        
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();
578        
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     }
587     
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();
608        
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();
626        
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     } 
641     
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();
649       
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     }
660  
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();
670       
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     }
687     
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     }
720 ?>