Code

Added a new special casing for debconf variables
[gosa.git] / trunk / gosa-plugins / fai / admin / fai / class_FAI.inc
index 7cfb966cc671c30d73154f39b713594989842182..2922694972d0b5606474214f985d3be3fdfeef3d 100644 (file)
@@ -185,10 +185,12 @@ class FAI
     if(!$removed){
       $ldap = $config->get_ldap_link();
       $ldap->cd($config->current['BASE']);
+      $parent_dn = FAI::get_parent_object($Current_DN);
 
       /* Get some basic informations */
       $parent_obj   = FAI::get_parent_release_object($Current_DN);
-      if(!empty($parent_obj)){
+      /* Check whether parent object is removed, do not create object in this case */
+      if(!empty($parent_obj) && !FAI::parent_is_removed($Current_DN)){
         $ldap->cat($parent_obj,array("*"));
         $attrs = FAI::                           prepare_ldap_fetch_to_be_saved($ldap->fetch());
 
@@ -499,11 +501,15 @@ class FAI
             }
 
             foreach($r as $key ){
-              if(DEBUG_FAI_FUNC) { 
-                echo "<b>Create an empty placeholder in follwing release</b> ".$key; 
-                print_a($objectAttrs);
+              /* Only save removed parent objects, not their children, unless
+                 they are a child of a copy-on-write parent in a subrelease */
+              if (FAI::is_parent_object($Current_DN) || FAI::is_child_of_cow_parent($key)){
+                if(DEBUG_FAI_FUNC) { 
+                  echo "<b>Create an empty placeholder in follwing release</b> ".$key; 
+                  print_a($objectAttrs);
+                }
+                FAI::save_FAI_object($key,$objectAttrs);
               }
-              FAI::save_FAI_object($key,$objectAttrs);
             }
           }
         }else{
@@ -512,16 +518,18 @@ class FAI
           if(!empty($r)){
 
             foreach($r as $key ){
-              if(DEBUG_FAI_FUNC) { 
-                echo "<b>Copy current objects original attributes to next release</b> ".$key;
-                print_a($parent_attrs);
-              }
-             
               /* Append FAIstate tag to ensure that freezed objects stay freezed
                */ 
               $rTag = FAI::get_release_tag(FAI::get_release_dn($key));
               $parent_attrs['FAIstate'] = $rTag;
-              FAI::save_FAI_object($key,$parent_attrs);
+              /* Don't copy over subobjects in subreleases if their parent is in "removed" state */
+              if(!FAI::parent_is_removed($key)){
+                if(DEBUG_FAI_FUNC) { 
+                  echo "<b>Copy current objects original attributes to next release</b> ".$key;
+                  print_a($parent_attrs);
+                }
+                FAI::save_FAI_object($key,$parent_attrs);
+              }
             }
           }
 
@@ -1270,6 +1278,139 @@ class FAI
     }                                                         
   }                                                           
 
+  /* Returns true if this is a parent object, e.g. FAIpartitionTable, not FAIpartitionDisk */
+  static function is_parent_object($dn)
+  {
+    global $config;
+    $Current_DN = $dn;
+
+    /* special case partitions and debconf variables, as they don't start with cn= in their DN */
+    if (preg_match('/^(FAIpartitionNr|FAIvariable)=/', $Current_DN)){
+      return false;
+    }
+
+    $parent_dn = preg_replace('/^cn=[^,.]*,/', '', $Current_DN);
+    if (preg_match('/^cn=/', $parent_dn)) {
+      $ldap = $config->get_ldap_link();
+      $ldap->cd($config->current['BASE']);
+      $ldap->cat($parent_dn);
+      if($ldap->count()){
+        return false;
+      }
+    }else{
+      return true;
+    }
+  }
+
+  /* Return child objects, if there are any */
+  static function get_child_objects($dn)
+  {
+    global $config;
+    $Current_DN = $dn;
+    $children= array();
+
+    if (FAI::is_parent_object($Current_DN)){
+      $ldap = $config->get_ldap_link();
+      $ldap->cd($dn);
+      $ldap->search("(objectClass=FAIclass)",array("dn"));
+      while($attrs = $ldap->fetch()){
+        if(preg_match("/".preg_quote($Current_DN, '/')."/",$attrs['dn']) && $attrs['dn'] != $Current_DN){
+          $children[] = $attrs['dn'];
+        }
+      }
+    }
+    return $children;
+  }
+
+  /* Get the DN of the parent object; e.g. the FAIpartitionTable of a FAIpartitionDisk.
+     If $check is false, do not check whether the parent actually exists in LDAP */
+  static function get_parent_object($dn, $check=true)
+  {
+    global $config;
+    $Current_DN = $dn;
+    $i = 0;
+
+    $tmp_dn = $Current_DN;
+    $parent_dn = array();
+
+    /* special case partitions and debconf variables, as they don't start with cn= in their DN */
+    $tmp_dn = preg_replace('/^(FAIpartitionNr|FAIvariable)=/', 'cn=', $tmp_dn);
+
+    $tmp_dn = gosa_ldap_explode_dn($tmp_dn);
+    while(preg_match('/^cn=/', $tmp_dn[$i])) {
+      $i++;
+    }
+    /* DN part does not start with cn= anymore, remove one from the counter to get the
+       last CN element */
+    $i--;
+
+    for ($i;$i<$tmp_dn['count'];$i++) {
+      $parent_dn[] = trim($tmp_dn[$i]);
+    }
+    $parent_dn = join($parent_dn, ',');
+
+    if ($parent_dn != $Current_DN){
+      if($check){
+        $ldap = $config->get_ldap_link();
+        $ldap->cd($config->current['BASE']);
+        $ldap->cat($parent_dn);
+        if(!$ldap->count()){
+          return "";
+        }
+      }
+      return $parent_dn;
+    }
+    return "";
+  }
+
+  /* Check whether parent object is removed */
+  static function parent_is_removed($dn)
+  {
+    global $config;
+    $Current_DN = $dn;
+
+    $ldap = $config->get_ldap_link();
+    $parent_dn = FAI::get_parent_object($Current_DN);
+    if ($parent_dn) { 
+      $ldap->cd($config->current['BASE']);
+      $ldap->cat($parent_dn);
+      $parentObjectAttrs = FAI::prepare_ldap_fetch_to_be_saved($ldap->fetch());
+      if(isset($parentObjectAttrs['FAIstate'][0])){
+        if(preg_match("/removed$/",$parentObjectAttrs['FAIstate'][0])){
+          return true;
+        }
+      }
+    } 
+    return false;
+  }
+
+  /* Check whether this is a child object of a Copy-on-Write parent */
+  static function is_child_of_cow_parent($dn)
+  { 
+    global $config;
+    $Current_DN = $dn;
+    $parent_dn = "";
+
+    if (!FAI::is_parent_object($Current_DN)){
+
+      /* This is a child object; check that the parent object is not 
+         marked as removed */
+      $cow_parent_dn = FAI::get_parent_object($Current_DN, false);
+      if ($cow_parent_dn && !FAI::parent_is_removed($Current_DN)){
+
+        /* This is a child object, check whether the parent object in 
+           the main release exists */
+        $main_parent_dn = FAI::get_parent_release_object($cow_parent_dn);
+        $ldap = $config->get_ldap_link();
+        $ldap->cd($config->current['BASE']);
+        $ldap->cat($main_parent_dn);
+        if($ldap->count()){
+          return true;
+        }
+      }
+    }
+    return false;
+  }
 
 }