diff --git a/.gitignore b/.gitignore
index 9b116dab9125e8effb4be41b6e133bdb6b38a082..239beea576fd63cb0e706678ce5fe0c5e08c8384 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
 .DS_Store
 *.swp
 *~
-*Gemfile.lock
\ No newline at end of file
diff --git a/dev/lib/hash/hash.rb b/dev/lib/hash/hash.rb
index de0cdf54c44e965911ae6393d7744f319bf9043e..13984da3cdc72e81c4751a498dcaea2dc8585a5f 100644
--- a/dev/lib/hash/hash.rb
+++ b/dev/lib/hash/hash.rb
@@ -11,18 +11,19 @@ def deep_merge_entries(a, b)
   end
 end
 
+def rec_sort(h)
+  case h
+  when Array
+    h.map{|v| rec_sort(v)}#.sort_by!{|v| (v.to_s rescue nil) }
+  when Hash
+    Hash[Hash[h.map{|k,v| [rec_sort(k),rec_sort(v)]}].sort_by{|k,v| [(k.to_s rescue nil), (v.to_s rescue nil)]}]
+  else
+    h
+  end
+end
+
 # Write pretty and sorted JSON files
 def write_json(filepath, data)
-  def rec_sort(h)
-    case h
-    when Array
-      h.map{|v| rec_sort(v)}#.sort_by!{|v| (v.to_s rescue nil) }
-    when Hash
-      Hash[Hash[h.map{|k,v| [rec_sort(k),rec_sort(v)]}].sort_by{|k,v| [(k.to_s rescue nil), (v.to_s rescue nil)]}]
-    else
-      h
-    end
-  end
   File.open(filepath, 'w') do |f|
     f.write(JSON.pretty_generate(rec_sort(data)))
   end
@@ -30,16 +31,6 @@ end
 
 # Write sorted YAML files
 def write_yaml(filepath, data)
-  def rec_sort(h)
-    case h
-    when Array
-      h.map{|v| rec_sort(v)}#.sort_by!{|v| (v.to_s rescue nil) }
-    when Hash
-      Hash[Hash[h.map{|k,v| [rec_sort(k),rec_sort(v)]}].sort_by{|k,v| [(k.to_s rescue nil), (v.to_s rescue nil)]}]
-    else
-      h
-    end
-  end
   File.open(filepath, 'w') do |f|
     f.write(rec_sort(data).to_yaml)
   end
@@ -118,7 +109,7 @@ class ::Hash
     }
   end
 
-  # sort a hash according to the position of the key in the array.
+  # Sort a hash according to the position of the key in the array.
   def sort_by_array(array)
     Hash[sort_by{|key, _| array.index(key) || length}] 
   end
@@ -148,8 +139,19 @@ class ::Hash
     }
   end
 
-  def deep_copy(o)
-    Marshal.load(Marshal.dump(o))
+  # Ex: { a: 1, b: nil, c: { d: nil, e: '' } }.deep_reject! { |k, v| v.blank? }
+  # ==> { a: 1 }
+  # Note: the blk delete condition is also applied to hash
+  #       use  { |k, v| !Hash === v } if you do not want this default behavior
+  def deep_reject!(&blk)
+    self.each do |k, v|
+      v.deep_reject!(&blk) if v.is_a?(Hash)
+      self.delete(k) if blk.call(k, v)
+    end
   end
 
 end
+
+def deep_copy(o)
+  Marshal.load(Marshal.dump(o))
+end
diff --git a/dev/puppet/conmang5k.rb b/dev/puppet/conmang5k.rb
index 72b622bd7728e5419d9ac29ddef74a1c0bfe401f..04d021f5e68c85b529d2bc6c9bc60ff8bbc3cb37 100644
--- a/dev/puppet/conmang5k.rb
+++ b/dev/puppet/conmang5k.rb
@@ -1,5 +1,7 @@
 #!/usr/bin/ruby
 
+# This script generates conmang5k/files/<site_uid>/conman.conf from input/ and conf/conman.yaml
+
 require 'pp'
 require 'erb'
 require 'fileutils'
@@ -7,12 +9,14 @@ require '../lib/input_loader'
 require '../lib/hash/hash.rb'
 
 global_hash = load_yaml_file_hierarchy("../input/grid5000/")
-passwd_hash = YAML::load_file('./conman-password.yaml')
-passwd_hash = passwd_hash.expand_square_brackets()
+output_dir = 'output'
+
+conf_hash = YAML::load_file('./conf/conman-password.yaml')
+conf_hash = conf_hash.expand_square_brackets()
 
 def write_conman_file(site_uid, site, passwd)
   erb = ERB.new(File.read("templates/conman.erb"))
-  output_file = File.join('output', 'conmang5k', 'files', site_uid, 'conman.conf')
+  output_file = File.join(output_dir, 'conmang5k', 'files', site_uid, 'conman.conf')
   
   # Create directory hierarchy
   dirname = File.dirname(output_file)
@@ -26,5 +30,5 @@ end
 
 # Loop over Grid'5000 sites
 global_hash["sites"].each { |site_uid, site|
-  write_conman_file(site_uid, site, passwd_hash[site_uid])
+  write_conman_file(site_uid, site, conf_hash[site_uid])
 }
diff --git a/dev/puppet/kadeployg5k.rb b/dev/puppet/kadeployg5k.rb
index 03c1d1243c5e62fd0c9cb446b8431fbffc1857ba..2f0b331e49931301a1106c222a3f62af55e5ec60 100644
--- a/dev/puppet/kadeployg5k.rb
+++ b/dev/puppet/kadeployg5k.rb
@@ -1,5 +1,9 @@
 #!/usr/bin/ruby
 
+# This script generates:
+# - kadeployg5k/files/<site_uid>/server_conf[_dev]/clusters.conf  from input/
+# - kadeployg5k/files/<site_uid>/server_conf[_dev]/<cluster_uid>-cluster.conf from conf/kadeployg5k.yaml and template/kadeployg5k.yaml.Erb
+
 require 'pp'
 require 'erb'
 require 'fileutils'
@@ -7,10 +11,7 @@ require '../lib/input_loader'
 require '../lib/hash/hash.rb'
 
 global_hash = load_yaml_file_hierarchy("../input/grid5000/")
-
-template_hash = YAML::load_file('templates/kadeployg5k.yaml')
-
-write_yaml('/tmp/test.yaml', template_hash)
+output_dir = 'output'
 
 # Compute cluster prefix
 # input: cluster_list = ['graoully', 'graphene', 'griffon', ...]
@@ -36,6 +37,7 @@ def cluster_prefix(cluster_list)
 
 end
 
+# Extract the node ip from the node hash
 def get_ip(node)
   node['network_adapters'].each { |device, network_adapter|
     if network_adapter['mounted'] && /^eth[0-9]$/.match(device)
@@ -44,10 +46,15 @@ def get_ip(node)
   }
 end
 
+# There is two kadeploy servers : kadeploy and kadeploy-dev
 ['', '-dev'].each {|suffix|
+
   global_hash['sites'].each { |site_uid, site|
-    next if site_uid != 'nancy'
 
+    #
+    # Generate site/<site_uid>/servers_conf[_dev]/clusters.conf
+    #
+    
     clusters_conf = { 'clusters'=> [] } # output clusters.conf
     prefix = cluster_prefix(site['clusters'].keys)
 
@@ -107,8 +114,7 @@ end
 
     } # site['clusters'].each
 
-
-    output_file = File.join('output', 'kadeployg5k', 'files', site_uid, "server_conf#{suffix.tr('-', '_')}", 'clusters.conf')
+    output_file = File.join(output_dir, 'kadeployg5k', 'files', site_uid, "server_conf#{suffix.tr('-', '_')}", 'clusters.conf')
     dirname = File.dirname(output_file)
     FileUtils.mkdir_p(dirname) unless File.directory?(dirname)