Code

msgPool
[gosa.git] / gosa-core / include / class_hostActionQueue.inc
1 <?php
2 /*
3  * This code is part of GOsa (http://www.gosa-project.org)
4  * Copyright (C) 2003-2008 GONICUS GmbH
5  *
6  * ID: $$Id$$
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
23 /*! 
24   \brief   This class represents the host action queue.
25   \author  Fabian Hickert <hickert@gonicus.de>
26   \version 2.6
27   \date    24.10.2007
29   This class is a queue handler, which allows adding,removing,
30    priority settings,stop and resume actions... for each queue entry
31  */
32 class hostActionQueue {
34   private $o_config       = NULL;
35   private $s_queue_file   = ""; 
36   private $s_error        = "";
37   private $b_error        = FALSE;
39   private $a_queue        = array();
40   private $i_pointer      = 0;
41   private $b_queue_loaded = false;
42   private $i_fileversion  = 0;
44   private $id_entry_map   = array();
46   public function __construct($config)
47   {
48     $this->o_config= $config;
50     /* Define source file */
51     $this->s_queue_file = CONFIG_DIR."/gotomasses_machines";
53     $file = $this->o_config->search("gotomasses", "STORAGE_FILE",array('menu'));
54     if(!empty($file)){
55       $this->s_queue_file = $file;
56     }
57   }
59   private function _reload_queue()
60   {
61     $this->_reset_error();
62     $this->b_queue_loaded = FALSE;
63     $this->b_error        = FALSE;
64     $this->s_error        = "";
65     $this->i_pointer      = 0;
67     /* Check file accessibility */
68     if(!file_exists($this->s_queue_file)){
69       $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
70       return(FALSE);
71     }
72     if(!is_readable($this->s_queue_file)){
73       $this->set_error(sprintf(_("Can't read gotomasses queue file '%s'."),$this->s_queue_file));
74       return(FALSE);
75     }
77     /* Check if file contents could be read */
78     $fp = @fopen($this->s_queue_file,"r");
79     if(!$fp){
80       $this->set_error(sprintf(_("Can't read gotomasses storage file '%s'."),$this->s_queue_file));
81       return(FALSE);
82     }
83     $this->i_fileversion = filemtime($this->s_queue_file);
84     clearstatcache();
85  
86     /* Get file contents */
87     $data ="";
88     while(!feof($fp)){
89       $data.= fread($fp,512);
90     }
91     
92     /* Get lines from file */
93     $this->a_queue  = array();
94     $comment        = "";
95     $rows           = split("\n",$data);
96  
97     $used_ids = array();
98  
99     /* Walk trough rows and parse data */
100     foreach($rows as $row){
102       /* Skip empty lines */
103       $row = trim($row);
104       if(empty($row)){
105         continue;
106       }
108       /* Get comment, if available */
109       if(preg_match("/^#/",$row)){
110         $comment = preg_replace("/^#/","",$row);
111         continue;
112       }
114       $entry_id = $task_id= "";    
115   
116       /* Comment must be set correctly */
117       if(empty($comment)){
118         $desc     = "";
119       }else{
120         $task_id =preg_replace("/^.*taskid:([0-9a-z]*).*$/i","\\1",$comment);
121         $entry_id=preg_replace("/^.*entryid:([0-9a-z]*).*$/i","\\1",$comment);
122         $desc    =preg_replace("/^.*desc:(.*)$/","\\1",$comment);
123       }
124       if($task_id == "" || empty($task_id)){ 
125         $task_id  = $this->get_new_id();
126       }
127       if($entry_id == "" || empty($entry_id)){
128         $entry_id = $this->get_new_id();
129       }
130    
131       /* Get unige id */ 
132       while(in_array($entry_id,$used_ids)){
133         $entry_id = $this->get_new_id();
134       }
135       $used_ids[] = $entry_id;
136  
137       /* Split row into minutes/ hours ...*/
138       $row    = preg_replace('/[\t ]/umi'," ",$row);
139       $row    = preg_replace('/  */umi'," ",$row);
140       $parts  = split(" ",$row);
142       if(count($parts) != 10){
143         msg_dialog::display(_("GOsa infrastructure"), _("Cannot read broken entry - skipped!"), WARNING_DIALOG);
144       }else{
146         $entry = array();
147         $entry['TASK_ID'] = $task_id;
148         $entry['ID']      = $entry_id;
149         $entry['Minute']  = $parts[0];
150         $entry['Hour']    = $parts[1];
151         $entry['Day']     = $parts[2];
152         $entry['Month']   = $parts[3];
153         $entry['Weekday'] = $parts[4];
154         $entry['Action']  = $parts[5];
155         $entry['OGroup']  = $parts[6];
156         $entry['Zone']    = $parts[7];
157         $entry['Section'] = $parts[8];
158         if($entry['Action'] == "initial_install"){
159           $tmp2 = split(";",$parts[9]);
160           foreach($tmp2 as $target){
161             $tmp = split(",",$target);
162             $entry['Initial_Target'][]  = array(
163                           "MAC"     => $tmp[0],
164                           "IP"      => $tmp[1],
165                           "NAME"    => $tmp[2]);
166           }
167           $entry['Target']  = array();
168         }else{
169           $entry['Initial_Target']  = array();
170           $entry['Target']  = split(";",$parts[9]);
171         }
172         $entry['Comment'] = $desc;
173         $this->a_queue[]   = $entry;
174       }
175       $comment = "";
176     }
177    
178     /* Udpate ENTRY_ID -> id mapping */ 
179     reset($this->a_queue);
180     foreach($this->a_queue as $id => $entry){
181       $this->id_entry_map[$entry['ID']] = $id;
182     }   
183  
184     return(TRUE);
185   }
188   private function _save_data()
189   {
190     $this->_reset_error();
192     /* Check file accessibility */
193     if(!file_exists($this->s_queue_file)){
194       $this->set_error(sprintf(_("Can't locate gotomasses queue file '%s'."),$this->s_queue_file));
195       return(FALSE);
196     }
197     if(!is_writeable($this->s_queue_file)){
198       $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
199       return(FALSE);
200     }
201     if($this->i_fileversion != filemtime($this->s_queue_file)){
202       $this->set_error(_("The queue file was modified since last reload. Can't save changes."));
203       return(FALSE);
204     }
205     $fp = @fopen($this->s_queue_file,"w");
206     if(!$fp){
207       $this->set_error(sprintf(_("Can't write gotomasses queue file '%s'."),$this->s_queue_file));
208       return(FALSE);
209     }
211     $str = "#GOsa generated file, please just modify if you really know what you do.";
212     reset($this->a_queue);
213     foreach($this->a_queue as $task){
214       $str .= "\n#taskid:".trim($task['TASK_ID']).";entryid:".$task['ID'].";desc:".trim($task['Comment']);
215       $str .= "\n";
216       if($task['Action'] == "initial_install"){
217         $str .= "*     *     *     *     *     ";
218       }else{
219         $str .= str_pad($task['Minute'] ,5," ")." ";
220         $str .= str_pad($task['Hour']   ,5," ")." ";
221         $str .= str_pad($task['Day']    ,5," ")." ";
222         $str .= str_pad($task['Month']  ,5," ")." ";
223         $str .= str_pad($task['Weekday'],5," ")." ";
224       }
225       $str .= str_pad($task['Action'] ,5," ")." ";
226       $str .= str_pad($task['OGroup'] ,5," ")." ";
227       $str .= str_pad($task['Zone']   ,5," ")." ";
228       $str .= str_pad($task['Section'],5," ")." ";
229       if($task['Action'] == "initial_install"){
230         foreach($task['Initial_Target'] as $target){
231           $str .= trim($target['MAC']).",".trim($target['IP']).",".trim($target['NAME']).";";
232         }
233       }else{
234         foreach($task['Target'] as $target){
235           $str .= $target.";";
236         }
237       }
238       $str = preg_replace("/;$/","",$str);
239     }
241     /* Write contents */
242     $str .= "\n";
243     fwrite($fp,$str);
244     fclose($fp);
245     clearstatcache();
246     $this->i_fileversion = filemtime($this->s_queue_file);
247     clearstatcache();
249     /* Update ENTRY_ID -> id mapping */ 
250     reset($this->a_queue);
251     foreach($this->a_queue as $id => $entry){
252       $this->id_entry_map[$entry['ID']] = $id;
253     }   
254  
255     return(TRUE);
256   }
258   private function _add_entry($entry,$task_id = "")
259   {
260     if($task_id == "" || empty($task_id)){
261       $task_id = $this->get_new_id();
262     }
263     $entry['TASK_ID'] = $task_id;
264     if(!isset($entry['ID']) || empty($entry['ID']) || !isset($entry['ID']) || empty($entry['ID'])){
265       $entry['ID'] = $this->get_new_id();
266     }
267     $this->a_queue[] = $entry;
268     
269     return(true);
270   }
272   public function get_entry($id)
273   {
274     if(isset($this->a_queue[$this->id_entry_map[$id]])){
275       return($this->a_queue[$this->id_entry_map[$id]]);
276     }else{
277       $this->set_error(sprintf(_("Entry with id '%s' not found."),$id));
278     }
279   }
281   public function update_entry($id,$entry)
282   {
283     if(isset($this->id_entry_map[$id])){
284       $this->a_queue[$this->id_entry_map[$id]] = $entry;
285       return($this->_save_data());
286     }else{
287       $this->set_error(sprintf(_("Could not update entry, entry with id '%s' not found."),$id));
288     }
289   }
291   public function remove_entry($id)
292   {
293     if(isset($this->id_entry_map[$id])){
294       unset($this->a_queue[$this->id_entry_map[$id]]);
295       unset($this->id_entry_map[$id]);
296       return($this->_save_data());
297     }else{
298       $this->set_error(sprintf(_("Could not remove entry, entry with id '%s' not found."),$id));
299     }
300   }
302   public function id_exists($id)
303   {
304     return(isset($this->id_entry_map[$id]));
305   }
308   public function add($entry)
309   {
310     if(!$this->_add_entry($entry)){
311       return(FALSE);
312     }
313     return($this->_save_data());
314   }
316   public function add_multiple($array)
317   {
318     $task_id = $this->get_new_id();
319     foreach($array as $entry){
320       if(!$this->_add_entry($entry,$task_id)){
321         return(FALSE);
322       }
323     }
324     return($this->_save_data());
325   }
327   public function fetch()
328   {
329     if(isset($this->a_queue[$this->i_pointer])){
330       $p = $this->a_queue[$this->i_pointer];
331       $this->i_pointer ++;
332       return($p);
333     }   
334     return(FALSE);    
335   }
337   public function load()
338   {
339     return($this->_reload_queue());    
340   }
342   public function save()
343   {
344     return($this->_save_data());    
345   }
347   private function _reset_error()
348   {
349     $this->b_error = FALSE;
350     $this->s_error = "";
351   }
352  
353   private function set_error($str)
354   {
355     $this->b_error = TRUE;
356     $this->s_error = $str;
357   }
359   public function is_error()
360   {
361     return($this->b_error);
362   }
364   public function get_error()
365   {
366     return($this->s_error);
367   }
369   public function max_entry_priority($id)
370   {
371     if(!$this->id_exists($id)){
372       $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
373       return(FALSE);
374     }
375     $tmp = array();
376     $tmp[]= $this->get_entry($id);
377     reset($this->a_queue);
378     foreach($this->a_queue as $key => $entry){
379       if($id != $entry['ID']){
380         $tmp[] = $entry;
381       }
382     }
383     $this->a_queue=$tmp;
384     return($this->_save_data());
385   }
387   public function increase_entry_priority($id)
388   {
389     if(!$this->id_exists($id)){
390       $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
391       return(FALSE);
392     }
393     $tmp = array();
394     $skip = NULL;
395     $next = NULL;
396     reset($this->a_queue);
397     foreach($this->a_queue as $key => $entry){
398       if($next != NULL){
399         if($id == $entry['ID']){
400           $tmp[] = $entry; 
401           $tmp[] = $next;
402           $next = NULL;
403         }else{
404           $tmp[] = $next;
405           $next = $entry;
406         }
407       }else{
408         $next = $entry;
409       }
410     }
411     if($next != NULL){
412       $tmp[] = $next;
413     }
414     $this->a_queue=$tmp;
415     return($this->_save_data());
416   }
418   public function decrease_entry_priority($id)
419   {
420     if(!$this->id_exists($id)){
421       $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
422       return(FALSE);
423     }
424     $tmp = array();
425     $skip = NULL;
426     reset($this->a_queue);
427     foreach($this->a_queue as $key => $entry){
428       if($id != $entry['ID']){
429         $tmp[] = $entry;
430         if($skip != NULL){
431           $tmp[] = $skip;
432           $skip = NULL;
433         }
434       }else{
435         $skip = $entry;
436       }
437     }
438     if($skip != NULL){
439       $tmp[] = $skip;
440     }
441     $this->a_queue=$tmp;
442     return($this->_save_data());
443   }
445   private function get_new_id()
446   {
447     $mt = microtime();
448     $sec  = preg_replace("/^0.([0-9]*) ([0-9]*)$/","\\2",$mt);
449     $msec = preg_replace("/^0.([0-9]*) ([0-9]*)$/","\\1",$mt);
450     return(strtoupper(base_convert($sec,10,36).base_convert($msec,10,36)));
451   }
453   public function min_entry_priority($id)
454   {
455     if(!$this->id_exists($id)){
456       $this->set_error(sprintf(_("Can't set priority for ID '%s'. ID does not exist."),$id));
457       return(FALSE);
458     }
459     reset($this->a_queue);
460     $tmp = array();
461     foreach($this->a_queue as $key => $entry){
462       if($id != $entry['ID']){
463         $tmp[] = $entry;
464       }
465     }
466     $tmp[]= $this->get_entry($id);
467     $this->a_queue=$tmp;
468     return($this->_save_data());
469   }
471 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
472 ?>