Code

Updated partition dialog, it supports volume groups now
[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);
155     }
157    
158     /*! \brief   Loads client-information values from the GOsa-backend using jsonRPC 
159      */ 
160     function init_client_info()
161     {
162         if(empty($this->deviceUUID)){
163             return;
164         }
166         $rpc = $this->config->getRpcHandle();
167         $res = $rpc->systemGetBaseInstallParameters($this->deviceUUID);
168        
169         // Failed to load backend values, keep reported error and return with FALSE; 
170         $this->rpcError = !$rpc->success();
171         if(!$rpc->success()){
172             $this->rpcErrorMessage = $rpc->get_error();
173             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
174             return(NULL);
175         }
176    
177         // Apply received options
178         $this->is_account = $res == True;
179         if($this->is_account){
181             $map = array(
182                     'ntp-servers' => "installNTPServer", 
183                     'template' => "installTemplate", 
184                     'keyboard-layout' => "installKeyboardlayout");
186             // We receive an array for these attributes, but require a string instead
187             //  we just use the first element of the array.
188             $mapArray = array(
189                     'release' => "installRelease", 
190                     'timezone' => "installTimezone", 
191                     'utc' => "installTimeUTC", 
192                     'kernel' => "installKernelPackage", 
193                     'system-locale' => "installSystemLocale", 
194                     'root-user' => "installRootEnabled", 
195                     'root-hash' => "installRootPasswordHash", 
196                     'disk-setup' => "installPartitionTable");
197  
198             foreach($res as $name => $data){
199                 if(isset($map[$name])){
200                     $target = $map[$name];
201                     $value = $res[$name];
202                 }elseif(isset($mapArray[$name])){
203                     $target = $mapArray[$name];
204                     $value = $res[$name][0];
205                 }
206                 $this->$target = $value;
207             }
209             // Convert Bool values to Bool.
210             $boolean = array("installRootEnabled", "installTimeUTC");
211             foreach($boolean as $attr){
212                 $this->$attr = ($this->$attr != FALSE && !preg_match("/false/i", $this->$attr));
213             }
214         }
216         return;
217     }
220     function init_static_info()
221     { 
222         // Load static values.
223         foreach(array(
224                 "timeozones" => "getTimezones",
225                 "distributions" => "loadDistributions",
226                 "keyboardLayouts" => "loadInstallationKeyboardLayouts",
227                 "installationTemplates" => "loadInstallationTemplates",
228                 "installationMethods" => "loadInstallationMethods",
229                 "locales" => "getSystemLocales"    ) as $target => $func){
230             $$target = $this->$func();
231             if($$target == NULL){
232                 $this->initFailed = TRUE;
233                 msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
234                 return;
235             }
236         }
238         // Assign fetchted values
239         $this->timezones = $timeozones;
240         $this->installBootstrapMethodList = $installationMethods['installBootstrapMethodList'];
241         $this->installConfigManagementList = $installationMethods['installConfigManagementList'];
242         $this->installSystemLocaleList = $locales;
243         $this->installKeyboardlayoutList = $keyboardLayouts;
244         $this->distributions = $distributions;
246         # Create template to relase map
247         $this->templateToRelease = array();
249         // Walk through installation templates and use the 'repositories' attribute
250         // to supported releases.
251         foreach($installationTemplates as $name => $tdata){
252             
253             $mName = isset($this->installBootstrapMethodList[$tdata['method']]) ? 
254                 $this->installBootstrapMethodList[$tdata['method']]: $tdata['method'];
256             $this->installationTemplateNames[$name] = $tdata['description']." (".$mName.")";
257             $this->installationTemplates[$name] = $tdata;
258             $this->templateToRelease[$name] = array();
260             // Check if the 'repository'-category of the template can be found in any 
261             // received release list.
262             if(isset($installationMethods[$tdata['method']]['repositories'])){
263                 $repos = $installationMethods[$tdata['method']]['repositories'];
264                 foreach($distributions as $dist){
265                     if(in_array($dist['type']['name'],$repos) && isset($dist['releases'])){
266                         foreach($dist['releases'] as $release){
267                             $rname = $dist['name'].'/'.$release['name'];
268                             $this->templateToRelease[$name][$rname] = $rname;
269                         }
270                     }
271                 }
272             }
273         }
274     }
277     function check()
278     {
279             // Check if the parents deviceUUID has changed
280             if($this->deviceUUID != $this->_device->deviceUUID){
281                 $this->deviceUUID = $this->_device->deviceUUID;
282                 print "The device uuid has changed.";
283             }
284     }
285     
286     
287     function execute()
288     {
289         // Log account access
290         if($this->is_account && !$this->view_logged){
291             $this->view_logged = TRUE;
292             new log("view","Device/".get_class($this),$this->dn);
293         }
295         /***************
296           Handle account state
297          ***************/
299         // Allow to add or remove the distribution list extension
300         if(isset($_POST['modify_state'])){
301             if($this->is_account && $this->acl_is_removeable()){
302                 $this->is_account= FALSE;
303             }elseif(!$this->is_account && $this->acl_is_createable()){
304                 $this->is_account= TRUE;
305             }
306         }
308         // Show account status-changer
309         $display = "";
310         if ($this->parent !== NULL){
311             if ($this->is_account){
312                 $display= $this->show_disable_header(_("Remove install profile"),
313                         msgPool::featuresEnabled(_("Install profile")));
314             } else {
315                 $display= $this->show_enable_header(_("Add install profile"),
316                         msgPool::featuresDisabled(_("Install profile")));
317                 return ($display);
318             }
319         }
321         /***************
322           Root password hash dialog
323          ***************/
325         $this->dialog = FALSE;
326         if($this->setPasswordHash){
327             $this->dialog = TRUE;
328             $smarty = get_smarty();
329             $smarty->assign('hashes', set_post($this->hashes));
330             $smarty->assign('hash', set_post($this->hash));
331             return($smarty->fetch(get_template_path('goto/Device/SetPassword.tpl', TRUE)));
332         }
334         /***************
335           Partition dialog
336          ***************/
338         if(isset($_POST['partition_finish']) && $this->partitionEdit){
339             $this->installPartitionTable = $this->partitionEdit->save();
340             $this->partitionEdit = NULL;
341         }
342         if(isset($_POST['partition_cancel']) && $this->partitionEdit){
343             $this->partitionEdit = NULL;
344         }
345         if(isset($_POST['edit_installPartitionTable'])){
346             $this->partitionEdit = new DevicePartition($this->config, $this->installPartitionTable);
347         }
348         if($this->partitionEdit){
349             $this->partitionEdit->save_object();
350             $this->dialog = TRUE;
351             return($this->partitionEdit->execute());
352         }
356         /***************
357           Generate HTML content
358          ***************/
360         $this->installNTPServerList->setAcl($this->getacl('installNTPServer'));
361         $this->installNTPServerList->update();
363         plugin::execute();    
364         $smarty = get_smarty();
365         $smarty->assign('installTemplateList', $this->installationTemplateNames);
366         $smarty->assign('installReleaseList', $this->templateToRelease[$this->installTemplate]);
369         $smarty->assign('timezones', $this->timezones);
370         $smarty->assign('installKeyboardlayoutList', $this->installKeyboardlayoutList);
371         $smarty->assign('installKernelPackageList', $this->installKernelPackageList);
372         $smarty->assign('installMirrorList', $this->installMirrorList);
373         $smarty->assign('installSystemLocaleList', $this->installSystemLocaleList);
374         $smarty->assign('installNTPServerList', $this->installNTPServerList->render());
376         $smarty->assign('installBootstrapMethod', $this->installBootstrapMethod);
377         $smarty->assign('installBootstrapMethodList', $this->installBootstrapMethodList);
378         $smarty->assign('installConfigManagement', $this->installConfigManagement);
380         // Assign list of available config-management types.
381         if(isset($this->installConfigManagementList[$this->installBootstrapMethod])){ 
382             $smarty->assign('installConfigManagementList', $this->installConfigManagementList[$this->installBootstrapMethod]);
383         }else{
384             $smarty->assign('installConfigManagementList', array());
385         }
387         foreach($this->attributes as $attr){
388             $smarty->assign($attr, $this->$attr);
389         }
390         $this->dialog = false;
391         return($display.$smarty->fetch(get_template_path('goto/Device/InstallRecipe.tpl', TRUE)));
392     }
395     function save_object()
396     {
397         if(isset($_POST['InstallRecipePosted'])){
399             $currentInstallMethod = $this->installConfigManagement;
401             $oldRelease = $this->installRelease;
402             plugin::save_object();
403             $this->installRootEnabled = isset($_POST['installRootEnabled']);
404             $this->installTimeUTC = isset($_POST['installTimeUTC']);
407             if(isset($_POST['setPasswordHash'])){
408                 $this->setPasswordHash = true;
409             }
411             $this->installNTPServerList->save_object();
412             $this->installNTPServer = $this->installNTPServerList->getMaintainedData();
413             if(isset($_POST['installNTPServer_Input']) && isset($_POST['installNTPServer_Add'])){
414                 $add = get_post('installNTPServer_Input');
415                 if(!in_array($add, $this->installNTPServer) && !empty($add)){
416                     $this->installNTPServer[] = $add;
417                 }
418             }
419             $this->installNTPServerList->setListData($this->installNTPServer);
420             $this->installBootstrapMethod = $this->installationTemplates[$this->installTemplate]['method'];
422             // The selected release is no longer available for the current template
423             if(!in_array($this->installRelease, $this->templateToRelease[$this->installTemplate])){
424                 $this->installRelease = key($this->templateToRelease[$this->installTemplate]);
425             }
427             // Reload list of kernel packages and mirrors
428             if($oldRelease != $this->installRelease){
429                 $this->reloadInstallationKernelPackages();
430                 $this->reloadInstallationMirrors();
431             }
432         }
434         if(isset($_POST['cancelPassword'])) $this->setPasswordHash =false;
435         if(isset($_POST['setPassword'])) {
436             $this->setPasswordHash =false;
437             $hash = get_post('passwordHash');
439             // Not sure, why this is here, but maybe some encryption methods require it.
440             mt_srand((double) microtime()*1000000);
442             // Generate the requested hash
443             $methods = new passwordMethod($this->config, $this->dn);
444             $available = $methods->get_available_methods();
445             $test = new $available[$hash]($this->config,$this->dn);
446             $this->installRootPasswordHash = @$test->generate_hash(get_post('rootPassword'));
447         }
448     }
451     function save()
452     {
453         if(!$this->installRootEnabled) $this->installRootPasswordHash = "";
455         $map = array(
456             "installNTPServer"=>'ntp-servers',
457             "installTemplate"=>'template',
458             "installRelease"=>'release',
459             "installTimezone"=>'timezone',
460             "installTimeUTC"=>'utc',
461             "installKernelPackage"=>'kernel',
462             "installSystemLocale"=>'system-locale',
463             "installRootEnabled"=>'root-user',
464             "installRootPasswordHash"=>'root-hash',
465             "installPartitionTable"=>'disk-setup',
466             "installKeyboardlayout"=>'keyboard-layout',
467             );
469         // Collect values to be saved.
470         $data = array();
471         foreach($map as $source => $dest){
472             if(!empty($this->$source)){
473                 $data[$dest] = $this->$source;
474              }
475         } 
477         // Enforce an array for ntp-servers
478         $data['ntp-servers'] = array_values($data['ntp-servers']);
480         // Save Boolean like a String 
481         $boolean = array("root-user" => "installRootEnabled", "utc" => "installTimeUTC");
482         foreach($boolean as $attr => $source){
483             $data[$attr] = ($this->$source) ? $data[$attr] = "TRUE" : $data[$attr] = "FALSE";
484         }
486         print_a($data);
488         $rpc = $this->config->getRpcHandle();
489         $res = $rpc->systemSetBaseInstallParameters($this->deviceUUID, $data);
490        
491         // Failed to load backend values, keep reported error and return with FALSE; 
492         $this->rpcError = !$rpc->success();
493         if(!$rpc->success()){
494             $this->rpcErrorMessage = $rpc->get_error();
495             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
496             return(NULL);
497         }
499     }
501     
502     function remove_from_parent()
503     {
504        print "Missing"; 
505     }
506  
507     
508     /*! \brief  Refreshes the list of selectable kernel packages.
509      */
510     function reloadInstallationKernelPackages($initially = FALSE)
511     {
512         // Do nothing if no release is given.
513         if(empty($this->installRelease)){
514             $this->installKernelPackageList = array();
515             return;
516         }
518         $rpc = $this->config->getRpcHandle();
519         $res = $rpc->getKernelPackages($this->installRelease);
520       
521         // Failed to load backend values, keep reported error and return with FALSE; 
522         $this->rpcError = !$rpc->success();
523         if(!$rpc->success()){
524             $this->rpcErrorMessage = $rpc->get_error();
525             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
526         }else{
527             $this->installKernelPackageList = array();
528             foreach($res as $name){
529                 $this->installKernelPackageList[$name] = $name;
530             }
532             if(!isset($this->installKernelPackageList[$this->installKernelPackage])){
533                 $new = key($this->installKernelPackageList);
534                 if($initially){
535                     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);
536                 }
537                 $this->installKernelPackage = $new;
538             }
539         }
540     }
543     /*! \brief  Returns a list of distributions on success.
544      *          In case of an error, it returns NULL.
545      */
546     function loadDistributions()
547     {
548         $rpc = $this->config->getRpcHandle();
549         $res = $rpc->getDistributions();
550        
551         // Failed to load backend values, keep reported error and return with FALSE; 
552         $this->rpcError = !$rpc->success();
553         if(!$rpc->success()){
554             $this->rpcErrorMessage = $rpc->get_error();
555             return(NULL);
556         }
557         return($res);
558     }
561     /*! \brief  Returns a list of timezones on success.
562      *          In case of an error, it returns NULL.
563      */
564     function getTimezones()
565     {
566         $rpc = $this->config->getRpcHandle();
567         $res = $rpc->getTimezones();
568        
569         // Failed to load backend values, keep reported error and return with FALSE; 
570         $this->rpcError = !$rpc->success();
571         if(!$rpc->success()){
572             $this->rpcErrorMessage = $rpc->get_error();
573             return(NULL);
574         }
575         return($res);
576     }
577     
579     /*! \brief  Returns a list of installation mirrors on success.
580      *          In case of an error, it returns NULL.
581      */
582     function reloadInstallationMirrors($initially = FALSE)
583     {
584         $res = array(
585                 'dc=intranet,dc=gonicus,dc=de' => 'Intranet',
586                 'ou=systems,dc=intranet,dc=gonicus,dc=de' => 'System');
587         $this->installMirrorList =$res;
588     }
591     /*! \brief  Returns a list of installation templates on success.
592      *          In case of an error, it returns NULL.
593      */
594     function loadInstallationTemplates()
595     {
596         $rpc = $this->config->getRpcHandle();
597         $res = $rpc->installListTemplates();
598        
599         // Failed to load backend values, keep reported error and return with FALSE; 
600         $this->rpcError = !$rpc->success();
601         if(!$rpc->success()){
602             $this->rpcErrorMessage = $rpc->get_error();
603             return(NULL);
604         }
605         return($res);
606     } 
609     /*! \brief  Returns a list of keyboard layouts on success.
610      *          In case of an error, it returns NULL.
611      */
612     function loadInstallationKeyboardLayouts()
613     {
614         $rpc = $this->config->getRpcHandle();
615         $res = $rpc->getKeyboardModels();
616        
617         // Failed to load backend values, keep reported error and return with FALSE; 
618         $this->rpcError = !$rpc->success();
619         if(!$rpc->success()){
620             $this->rpcErrorMessage = $rpc->get_error();
621             return(NULL);
622         }
623         $lay = array();
624         foreach($res as $key => $data){
625             $lay[$key] = "{$data[0]} - {$data[2]}";
626         }
627         asort($lay);
628         return($lay);
629     } 
631     
632     /*! \brief  Returns a list of system locales on success.
633      *          In case of an error, it returns NULL.
634      */
635     function getSystemLocales()
636     {
637         $rpc = $this->config->getRpcHandle();
638         $res = $rpc->getSystemLocales();
639       
640         // Failed to load backend values, keep reported error and return with FALSE; 
641         $this->rpcError = !$rpc->success();
642         if(!$rpc->success()){
643             $this->rpcErrorMessage = $rpc->get_error();
644             msg_dialog::display(_("Error"), msgPool::rpcError($this->rpcErrorMessage), ERROR_DIALOG);
645             return(NULL);
646         }
648         return($res);
649     }
650  
652     /*! \brief  Try to load install and bootstrap methods from the GOsa-backend
653      *          This is done via jsonRPC, if calling the backend method fails,
654      *           this method returns FALSE, in case of success it return TRUE; 
655      */ 
656     function loadInstallationMethods()
657     { 
658         $rpc = $this->config->getRpcHandle();
659         $res = $rpc->getSupportedBaseInstallMethods();
660       
661         // Failed to load backend values, keep reported error and return with FALSE; 
662         $this->rpcError = !$rpc->success();
663         if(!$rpc->success()){
664             $this->rpcErrorMessage = $rpc->get_error();
665             return(NULL);
666         }
668         // Walk through result and set bootstrap methods.
669         foreach($res as $name => $method){
670             $res['installBootstrapMethodList'][$name] = $method['name'];
671             foreach($method['methods'] as $m){
672                 $res['installConfigManagementList'][$name][$m] = $m; 
673             }
674         }
675         return($res);
676     }
677     
679     static function plInfo()
680     {
681         return (array(
682                     "plShortName"   => _("Device"),
683                     "plDescription" => _("Registered device"),
684                     "plSelfModify"  => FALSE,
685                     "plDepends"     => array(),
686                     "plPriority"    => 1,
687                     "plSection"     => array("administration"),
688                     "plCategory"    => array("Device"),
689                     "plProvidedAcls" => array(
690                         "member" => _("Member"),
691                         "installTemplate" => _("Installation template"),
692                         "installRelease" => _("Installation release"),
694                         "installBootstrapMethod" => _("Bootstrap method"),
695                         "installConfigManagement" => _("Config management"),
696                         "installKeyboardlayout" => _("Keyboard layout"),
697                         "installSystemLocale" => _("System locale"),
698                         "installTimezone" => _("Timezone"),
699                         "installTimeUTC" => _("Time"),
700                         "installNTPServer" => _("NTP-Server"),
701                         "installMirror" => _("Mirror"),
702                         "installRootEnabled" => _("Root login enabled"),
703                         "installRootPasswordHash" => _("Root password hash"),
704                         "installKernelPackage" => _("Kernel package"),
705                         "installPartitionTable" => _("Partition table")
706                         )
707                         )
708                         );
709     }
711 ?>