Code

Updated InstallRecipe class.
[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 = "";
50     // Keyboard-layout attribute
51     public $installKeyboardlayout = "";
52     public $installKeyboardlayoutList = array();
54     // Mirror related attribute
55     public $installMirror = "";
56     public $installMirrorList = array();
58     public $objectclasses = array();
59     public $attributes = array("installRelease", "installTemplate","installKeyboardlayout","installSystemLocale",
60             "installTimezone","installTimeUTC","installNTPServer","installMirror",
61             "installRootEnabled","installRootPasswordHash","installKernelPackage",
62             "installPartitionTable","installConfigManagement","installBootstrapMethod");
65     /* Some plugin management related attributes 
66      * See class plugin for details.
67      */
68     public $view_logged = FALSE;
69     public $ignore_account = FALSE;
70     public $parent = NULL;
72     /*! \brief  Initialize the plugin and its widgets. 
73      *          Finally call init() to load values from the backend.
74      */ 
75     function __construct(&$config, $dn, $parent)
76     {
77         plugin::plugin($config, $dn);
79         $this->is_account = $this->initially_was_account = FALSE;
81         $this->_device = &$parent;
82         $this->deviceUUID = $parent->deviceUUID;
84         // Set default password hash
85         $this->hash = $this->config->get_cfg_value("core","passwordDefaultHash"); 
87         // Get list of password hashes
88         $tmp = passwordMethod::get_available_methods();
89         $this->hashes = array();
90         foreach($tmp['name'] as $name){
91             $this->hashes[$name] = $name;
92         }
94         // Initialize plugin
95         $this->init_static_info();
96         $this->init($initially = TRUE); 
97     }
99     function init($initially = FALSE)
100     {
101         // Init the object values.
102         $this->init_client_info();
104         // Prepare NTP servers list 
105         $this->installNTPServerList= new sortableListing($this->installNTPServer);
106         $this->installNTPServerList->setDeleteable(true);
107         $this->installNTPServerList->setEditable(false);
108         $this->installNTPServerList->setColspecs(array('*'));
109         $this->installNTPServerList->setWidth("100%");
110         $this->installNTPServerList->setHeight("70px");
112         // Preset values for new devices
113         if(!$this->is_account){
114             $this->installTemplate = key($this->installationTemplates);
115             $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
116         }else{
118             if(!isset($this->installationTemplates[$this->installTemplate])){
120                 // The selected template is no longer available, select the next selectable template.
121                 $new = key($this->installationTemplates);
123                 if($initially){
124                     $message = sprintf(_("The selected template '%s' is no longer available. Selecting '%s' as replacement!"), 
125                             $this->installTemplate, $new);
126                     msg_dialog::display(_("Warning"), $message, WARNING_DIALOG);
127                 }
128                 $this->installTemplate = $new;
129                 $installRelease = key($this->templateToRelease[$this->installTemplate]); 
131             }elseif(!isset($this->installationTemplates[$this->installTemplate]['method'])){
133                 // Not necessary to warn the user here, the input fields will be empty and thus
134                 //  avoid saving.
136             }elseif(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
138                 // The selected release is no longer available for the current template
139                 // Warn the user and select the next selectable release.
140                 $new = key($this->templateToRelease[$this->installTemplate]); 
141                 if($initially){
142                     $message = sprintf(_("The selected release '%s' is no longer available. Selecting '%s' as replacement!"),
143                             $this->installRelease, $new);
144                 }
145                 $this->installRelease = $new;
146                 msg_dialog::display(_("Warning"), $message, WARNING_DIALOG);
147             }
148         } 
150         // Update selectable items like kernels and mirrors depending on the current setup (relase)
151         $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
152         $this->reloadInstallationKernelPackages($initially);
153         $this->reloadInstallationMirrors($initially);
154     }
156    
157     /*! \brief   Loads client-information values from the GOsa-backend using jsonRPC 
158      */ 
159     function init_client_info()
160     {
161         if(empty($this->deviceUUID)){
162             return;
163         }
165         $rpc = $this->config->getRpcHandle();
166         $res = $rpc->systemGetBaseInstallParameters($this->deviceUUID);
167        
168         // Failed to load backend values, keep reported error and return with FALSE; 
169         $this->rpcError = !$rpc->success();
170         if(!$rpc->success()){
171             $this->rpcErrorMessage = $rpc->get_error();
172             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
173             return(NULL);
174         }
175     
176         // Apply received options
177         $this->is_account = $res == True;
178         if($this->is_account){
180             $map = array(
181                     'ntp-servers' => "installNTPServer", 
182                     'template' => "installTemplate", 
183                     'keyboard-layout' => "installKeyboardlayout");
185             // We receive an array for these attributes, but require a string instead
186             //  we just use the first element of the array.
187             $mapArray = array(
188                     'release' => "installRelease", 
189                     'timezone' => "installTimezone", 
190                     'utc' => "installTimeUTC", 
191                     'kernel' => "installKernelPackage", 
192                     'system-locale' => "installSystemLocale", 
193                     'root-user' => "installRootEnabled", 
194                     'root-hash' => "installRootPasswordHash", 
195                     'disk-setup' => "installPartitionTable");
196  
197             foreach($res as $name => $data){
198                 if(isset($map[$name])){
199                     $target = $map[$name];
200                     $value = $res[$name];
201                 }elseif(isset($mapArray[$name])){
202                     $target = $mapArray[$name];
203                     $value = $res[$name][0];
204                 }
205                 $this->$target = $value;
206             }
208             // Convert Bool values to Bool.
209             $boolean = array("installRootEnabled", "installTimeUTC");
210             foreach($boolean as $attr){
211                 $this->$attr = ($this->$attr != FALSE);
212             }
213         }
215         return;
216     }
219     function init_static_info()
220     { 
221         // Load static values.
222         foreach(array(
223                 "timeozones" => "getTimezones",
224                 "distributions" => "loadDistributions",
225                 "keyboardLayouts" => "loadInstallationKeyboardLayouts",
226                 "installationTemplates" => "loadInstallationTemplates",
227                 "installationMethods" => "loadInstallationMethods",
228                 "locales" => "getSystemLocales"    ) as $target => $func){
229             $$target = $this->$func();
230             if($$target == NULL){
231                 $this->initFailed = TRUE;
232                 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
233                 return;
234             }
235         }
237         // Assign fetchted values
238         $this->timezones = $timeozones;
239         $this->installBootstrapMethodList = $installationMethods['installBootstrapMethodList'];
240         $this->installConfigManagementList = $installationMethods['installConfigManagementList'];
241         $this->installSystemLocaleList = $locales;
242         $this->installKeyboardlayoutList = $keyboardLayouts;
243         $this->distributions = $distributions;
245         # Create template to relase map
246         $this->templateToRelease = array();
248         // Walk through installation templates and use the 'repositories' attribute
249         // to supported releases.
250         foreach($installationTemplates as $name => $tdata){
251             
252             $mName = isset($this->installBootstrapMethodList[$tdata['method']]) ? 
253                 $this->installBootstrapMethodList[$tdata['method']]: $tdata['method'];
255             $this->installationTemplateNames[$name] = $tdata['description']." (".$mName.")";
256             $this->installationTemplates[$name] = $tdata;
257             $this->templateToRelease[$name] = array();
259             // Check if the 'repository'-category of the template can be found in any 
260             // received release list.
261             if(isset($installationMethods[$tdata['method']]['repositories'])){
262                 $repos = $installationMethods[$tdata['method']]['repositories'];
263                 foreach($distributions as $dist){
264                     if(in_array($dist['type']['name'],$repos) && isset($dist['releases'])){
265                         foreach($dist['releases'] as $release){
266                             $rname = $dist['name'].'/'.$release['name'];
267                             $this->templateToRelease[$name][$rname] = $rname;
268                         }
269                     }
270                 }
271             }
272         }
273     }
276     function check()
277     {
278             // Check if the parents deviceUUID has changed
279             if($this->deviceUUID != $this->_device->deviceUUID){
280                 $this->deviceUUID = $this->_device->deviceUUID;
281                 print "The device uuid has changed.";
282             }
283     }
284     
285     
286     function execute()
287     {
288         // Log account access
289         if($this->is_account && !$this->view_logged){
290             $this->view_logged = TRUE;
291             new log("view","Device/".get_class($this),$this->dn);
292         }
294         /***************
295           Handle account state
296          ***************/
298         // Allow to add or remove the distribution list extension
299         if(isset($_POST['modify_state'])){
300             if($this->is_account && $this->acl_is_removeable()){
301                 $this->is_account= FALSE;
302             }elseif(!$this->is_account && $this->acl_is_createable()){
303                 $this->is_account= TRUE;
304             }
305         }
307         // Show account status-changer
308         $display = "";
309         if ($this->parent !== NULL){
310             if ($this->is_account){
311                 $display= $this->show_disable_header(_("Remove install profile"),
312                         msgPool::featuresEnabled(_("Install profile")));
313             } else {
314                 $display= $this->show_enable_header(_("Add install profile"),
315                         msgPool::featuresDisabled(_("Install profile")));
316                 return ($display);
317             }
318         }
320         /***************
321           Root password hash dialog
322          ***************/
324         if($this->setPasswordHash){
325             $this->dialog = TRUE;
326             $smarty = get_smarty();
327             $smarty->assign('hashes', set_post($this->hashes));
328             $smarty->assign('hash', set_post($this->hash));
329             return($smarty->fetch(get_template_path('goto/Device/SetPassword.tpl', TRUE)));
330         }
332         /***************
333           Generate HTML content
334          ***************/
336         $this->installNTPServerList->setAcl($this->getacl('installNTPServer'));
337         $this->installNTPServerList->update();
339         plugin::execute();    
340         $smarty = get_smarty();
341         $smarty->assign('installTemplateList', $this->installationTemplateNames);
342         $smarty->assign('installReleaseList', $this->templateToRelease[$this->installTemplate]);
345         $smarty->assign('timezones', $this->timezones);
346         $smarty->assign('installKeyboardlayoutList', $this->installKeyboardlayoutList);
347         $smarty->assign('installKernelPackageList', $this->installKernelPackageList);
348         $smarty->assign('installMirrorList', $this->installMirrorList);
349         $smarty->assign('installSystemLocaleList', $this->installSystemLocaleList);
350         $smarty->assign('installNTPServerList', $this->installNTPServerList->render());
352         $smarty->assign('installBootstrapMethod', $this->installBootstrapMethod);
353         $smarty->assign('installBootstrapMethodList', $this->installBootstrapMethodList);
354         $smarty->assign('installConfigManagement', $this->installConfigManagement);
356         // Assign list of available config-management types.
357         if(isset($this->installConfigManagementList[$this->installBootstrapMethod])){ 
358             $smarty->assign('installConfigManagementList', $this->installConfigManagementList[$this->installBootstrapMethod]);
359         }else{
360             $smarty->assign('installConfigManagementList', array());
361         }
363         foreach($this->attributes as $attr){
364             $smarty->assign($attr, $this->$attr);
365         }
366         $this->dialog = false;
367         return($display.$smarty->fetch(get_template_path('goto/Device/InstallRecipe.tpl', TRUE)));
368     }
371     function save_object()
372     {
373         if(isset($_POST['InstallRecipePosted'])){
375             $currentInstallMethod = $this->installConfigManagement;
377             $oldRelease = $this->installRelease;
378             plugin::save_object();
379             $this->installRootEnabled = isset($_POST['installRootEnabled']);
380             $this->installTimeUTC = isset($_POST['installTimeUTC']);
383             if(isset($_POST['setPasswordHash'])){
384                 $this->setPasswordHash = true;
385             }
387             $this->installNTPServerList->save_object();
388             $this->installNTPServer = $this->installNTPServerList->getMaintainedData();
389             if(isset($_POST['installNTPServer_Input']) && isset($_POST['installNTPServer_Add'])){
390                 $add = get_post('installNTPServer_Input');
391                 if(!in_array($add, $this->installNTPServer) && !empty($add)){
392                     $this->installNTPServer[] = $add;
393                 }
394             }
395             $this->installNTPServerList->setListData($this->installNTPServer);
396             $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
398             // The selected release is no longer available for the current template
399             if(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
400                 $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
401             }
403             // Reload list of kernel packages and mirrors
404             if($oldRelease != $this->installRelease){
405                 $this->reloadInstallationKernelPackages();
406                 $this->reloadInstallationMirrors();
407             }
408         }
410         if(isset($_POST['cancelPassword'])) $this->setPasswordHash =false;
411         if(isset($_POST['setPassword'])) {
412             $this->setPasswordHash =false;
413             $hash = get_post('passwordHash');
415             // Not sure, why this is here, but maybe some encryption methods require it.
416             mt_srand((double) microtime()*1000000);
418             // Generate the requested hash
419             $methods = new passwordMethod($this->config, $this->dn);
420             $available = $methods->get_available_methods();
421             $test = new $available[$hash]($this->config,$this->dn);
422             $this->installRootPasswordHash = @$test->generate_hash(get_post('rootPassword'));
423         }
424     }
427     function save()
428     {
429         if(!$this->installRootEnabled) $this->installRootPasswordHash = "";
431         $map = array(
432             "installNTPServer"=>'ntp-servers',
433             "installTemplate"=>'template',
434             "installRelease"=>'release',
435             "installTimezone"=>'timezone',
436             "installTimeUTC"=>'utc',
437             "installKernelPackage"=>'kernel',
438             "installSystemLocale"=>'system-locale',
439             "installRootEnabled"=>'root-user',
440             "installRootPasswordHash"=>'root-hash',
441             "installPartitionTable"=>'disk-setup',
442             "installKeyboardlayout"=>'keyboard-layout',
443             );
445         // Collect values to be saved.
446         $data = array();
447         foreach($map as $source => $dest){
448             if(!empty($this->$source)){
449                 $data[$dest] = $this->$source;
450              }
451         } 
453         // Enforce an array for ntp-servers
454         $data['ntp-servers'] = array_values($data['ntp-servers']);
456         // Save Boolean like a String 
457         $boolean = array("root-user", "utc");
458         foreach($boolean as $attr){
459             $data[$attr] = ($data[$attr]) ? $data[$attr] = TRUE : $data[$attr] = FALSE;
460         }
462         $rpc = $this->config->getRpcHandle();
463         $res = $rpc->systemSetBaseInstallParameters($this->deviceUUID, $data);
464        
465         // Failed to load backend values, keep reported error and return with FALSE; 
466         $this->rpcError = !$rpc->success();
467         if(!$rpc->success()){
468             $this->rpcErrorMessage = $rpc->get_error();
469             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
470             return(NULL);
471         }
473     }
475     
476     function remove_from_parent()
477     {
478        print "Missing"; 
479     }
480  
481     
482     /*! \brief  Refreshes the list of selectable kernel packages.
483      */
484     function reloadInstallationKernelPackages($initially = FALSE)
485     {
486         // Do nothing if no release is given.
487         if(empty($this->installRelease)){
488             $this->installKernelPackageList = array();
489             return;
490         }
492         $rpc = $this->config->getRpcHandle();
493         $res = $rpc->getKernelPackages($this->installRelease);
494       
495         // Failed to load backend values, keep reported error and return with FALSE; 
496         $this->rpcError = !$rpc->success();
497         if(!$rpc->success()){
498             $this->rpcErrorMessage = $rpc->get_error();
499             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
500         }else{
501             $this->installKernelPackageList = array();
502             foreach($res as $name){
503                 $this->installKernelPackageList[$name] = $name;
504             }
506             if(!isset($this->installKernelPackageList[$this->installKernelPackage])){
507                 $new = key($this->installKernelPackageList);
508                 if($initially){
509                     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);
510                 }
511                 $this->installKernelPackage = $new;
512             }
513         }
514     }
517     /*! \brief  Returns a list of distributions on success.
518      *          In case of an error, it returns NULL.
519      */
520     function loadDistributions()
521     {
522         $rpc = $this->config->getRpcHandle();
523         $res = $rpc->getDistributions();
524        
525         // Failed to load backend values, keep reported error and return with FALSE; 
526         $this->rpcError = !$rpc->success();
527         if(!$rpc->success()){
528             $this->rpcErrorMessage = $rpc->get_error();
529             return(NULL);
530         }
531         return($res);
532     }
535     /*! \brief  Returns a list of timezones on success.
536      *          In case of an error, it returns NULL.
537      */
538     function getTimezones()
539     {
540         $rpc = $this->config->getRpcHandle();
541         $res = $rpc->getTimezones();
542        
543         // Failed to load backend values, keep reported error and return with FALSE; 
544         $this->rpcError = !$rpc->success();
545         if(!$rpc->success()){
546             $this->rpcErrorMessage = $rpc->get_error();
547             return(NULL);
548         }
549         return($res);
550     }
551     
553     /*! \brief  Returns a list of installation mirrors on success.
554      *          In case of an error, it returns NULL.
555      */
556     function reloadInstallationMirrors($initially = FALSE)
557     {
558         $res = array(
559                 'dc=intranet,dc=gonicus,dc=de' => 'Intranet',
560                 'ou=systems,dc=intranet,dc=gonicus,dc=de' => 'System');
561         $this->installMirrorList =$res;
562     }
565     /*! \brief  Returns a list of installation templates on success.
566      *          In case of an error, it returns NULL.
567      */
568     function loadInstallationTemplates()
569     {
570         $rpc = $this->config->getRpcHandle();
571         $res = $rpc->installListTemplates();
572        
573         // Failed to load backend values, keep reported error and return with FALSE; 
574         $this->rpcError = !$rpc->success();
575         if(!$rpc->success()){
576             $this->rpcErrorMessage = $rpc->get_error();
577             return(NULL);
578         }
579         return($res);
580     } 
583     /*! \brief  Returns a list of keyboard layouts on success.
584      *          In case of an error, it returns NULL.
585      */
586     function loadInstallationKeyboardLayouts()
587     {
588         $rpc = $this->config->getRpcHandle();
589         $res = $rpc->getKeyboardModels();
590        
591         // Failed to load backend values, keep reported error and return with FALSE; 
592         $this->rpcError = !$rpc->success();
593         if(!$rpc->success()){
594             $this->rpcErrorMessage = $rpc->get_error();
595             return(NULL);
596         }
597         $lay = array();
598         foreach($res as $key => $data){
599             $lay[$key] = "{$data[0]} - {$data[2]}";
600         }
601         asort($lay);
602         return($lay);
603     } 
605     
606     /*! \brief  Returns a list of system locales on success.
607      *          In case of an error, it returns NULL.
608      */
609     function getSystemLocales()
610     {
611         $rpc = $this->config->getRpcHandle();
612         $res = $rpc->getSystemLocales();
613       
614         // Failed to load backend values, keep reported error and return with FALSE; 
615         $this->rpcError = !$rpc->success();
616         if(!$rpc->success()){
617             $this->rpcErrorMessage = $rpc->get_error();
618             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
619             return(NULL);
620         }
622         return($res);
623     }
624  
626     /*! \brief  Try to load install and bootstrap methods from the GOsa-backend
627      *          This is done via jsonRPC, if calling the backend method fails,
628      *           this method returns FALSE, in case of success it return TRUE; 
629      */ 
630     function loadInstallationMethods()
631     { 
632         $rpc = $this->config->getRpcHandle();
633         $res = $rpc->getSupportedBaseInstallMethods();
634       
635         // Failed to load backend values, keep reported error and return with FALSE; 
636         $this->rpcError = !$rpc->success();
637         if(!$rpc->success()){
638             $this->rpcErrorMessage = $rpc->get_error();
639             return(NULL);
640         }
642         // Walk through result and set bootstrap methods.
643         foreach($res as $name => $method){
644             $res['installBootstrapMethodList'][$name] = $method['name'];
645             foreach($method['methods'] as $m){
646                 $res['installConfigManagementList'][$name][$m] = $m; 
647             }
648         }
649         return($res);
650     }
651     
653     static function plInfo()
654     {
655         return (array(
656                     "plShortName"   => _("Device"),
657                     "plDescription" => _("Registered device"),
658                     "plSelfModify"  => FALSE,
659                     "plDepends"     => array(),
660                     "plPriority"    => 1,
661                     "plSection"     => array("administration"),
662                     "plCategory"    => array("Device"),
663                     "plProvidedAcls" => array(
664                         "member" => _("Member"),
665                         "installTemplate" => _("Installation template"),
666                         "installRelease" => _("Installation release"),
668                         "installBootstrapMethod" => _("Bootstrap method"),
669                         "installConfigManagement" => _("Config management"),
670                         "installKeyboardlayout" => _("Keyboard layout"),
671                         "installSystemLocale" => _("System locale"),
672                         "installTimezone" => _("Timezone"),
673                         "installTimeUTC" => _("Time"),
674                         "installNTPServer" => _("NTP-Server"),
675                         "installMirror" => _("Mirror"),
676                         "installRootEnabled" => _("Root login enabled"),
677                         "installRootPasswordHash" => _("Root password hash"),
678                         "installKernelPackage" => _("Kernel package"),
679                         "installPartitionTable" => _("Partition table")
680                         )
681                         )
682                         );
683     }
685 ?>