diff --git a/lib/refrepo/gen/wiki/generators/hardware.rb b/lib/refrepo/gen/wiki/generators/hardware.rb
index 28f25ea6f88315aee793f410d9349b4af0825b67..2a6989d844e1c3ed8f0db97ada9aef31f19e1178 100644
--- a/lib/refrepo/gen/wiki/generators/hardware.rb
+++ b/lib/refrepo/gen/wiki/generators/hardware.rb
@@ -14,7 +14,7 @@ class G5KHardwareGenerator < WikiGenerator
     @generated_content = "__NOEDITSECTION__\n"
     @generated_content += "{{Portal|User}}\n"
     @generated_content += "<div class=\"sitelink\">Hardware: [[Hardware|Global]] | " + G5K::SITES.map { |e| "[[#{e.capitalize}:Hardware|#{e.capitalize}]]" }.join(" | ") + "</div>\n"
-    @generated_content += generate_summary
+    @generated_content += SiteHardwareGenerator.generate_header_summary(@global_hash['sites'])
     @generated_content += "\n= Clusters =\n"
     @generated_content += SiteHardwareGenerator.generate_all_clusters
     @generated_content += generate_totals
@@ -22,54 +22,6 @@ class G5KHardwareGenerator < WikiGenerator
     @generated_content += MW::LINE_FEED
   end
 
-  def generate_summary
-    sites = @global_hash['sites'].length
-    clusters = 0
-    nodes = 0
-    cores = 0
-    gpus = 0
-    hdds = 0
-    ssds = 0
-    storage_space = 0
-    ram = 0
-    pmem = 0
-    flops = 0
-
-    @global_hash['sites'].sort.to_h.each do |site_uid, site_hash|
-      clusters += site_hash['clusters'].length
-      site_hash['clusters'].sort.to_h.each do |cluster_uid, cluster_hash|
-        cluster_hash['nodes'].sort.to_h.each do |node_uid, node_hash|
-          next if node_hash['status'] == 'retired'
-          nodes += 1
-          cores += node_hash['architecture']['nb_cores']
-          ram += node_hash['main_memory']['ram_size']
-          pmem += node_hash['main_memory']['pmem_size'] if node_hash['main_memory']['pmem_size']
-          if node_hash['gpu_devices']
-            gpus += node_hash['gpu_devices'].length
-          end
-          ssds += node_hash['storage_devices'].select { |d| d['storage'] == 'SSD' }.length
-          hdds += node_hash['storage_devices'].select { |d| d['storage'] == 'HDD' }.length
-          node_hash['storage_devices'].each do |i|
-            storage_space += i['size']
-          end
-          flops += node_hash['performance']['node_flops']
-        end
-      end
-    end
-    tflops = sprintf("%.1f", flops.to_f / (10**12))
-    return <<-EOF
-= Summary =
-* #{sites} sites
-* #{clusters} clusters
-* #{nodes} nodes
-* #{cores} CPU cores
-* #{gpus} GPUs
-* #{G5K.get_size(ram)} RAM + #{G5K.get_size(pmem)} PMEM
-* #{ssds} SSDs and #{hdds} HDDs on nodes (total: #{G5K.get_size(storage_space, 'metric')})
-* #{tflops} TFLOPS (excluding GPUs)
-    EOF
-  end
-
   def generate_totals
     data = {
       'proc_families' => {},
diff --git a/lib/refrepo/gen/wiki/generators/site_hardware.rb b/lib/refrepo/gen/wiki/generators/site_hardware.rb
index 5ca121c672acc80590517ba4a920bb5d907a5a94..0e62c2c2fc149e5d7bdcbcb084d05c25ce96e0af 100644
--- a/lib/refrepo/gen/wiki/generators/site_hardware.rb
+++ b/lib/refrepo/gen/wiki/generators/site_hardware.rb
@@ -23,8 +23,8 @@ class SiteHardwareGenerator < WikiGenerator
       "{{Portal|User}}\n" +
       "<div class=\"sitelink\">Hardware: [[Hardware|Global]] | " + G5K::SITES.map { |e| "[[#{e.capitalize}:Hardware|#{e.capitalize}]]" }.join(" | ") + "</div>\n" +
       "'''See also:''' [[#{@site.capitalize}:Network|Network topology for #{@site.capitalize}]]\n" +
-      "\n= Summary =\n" +
-      "'''#{generate_oneline_summary}'''\n" +
+      "#{SiteHardwareGenerator.generate_header_summary({@site => G5K::get_global_hash['sites'][@site]})}\n" +
+      "= Clusters =\n" +
       self.class.generate_summary(@site, false) +
       (has_reservable_disks ? "''*: disk is [[Disk_reservation|reservable]]''" : '') +
       self.class.generate_description(@site) +
@@ -42,21 +42,53 @@ class SiteHardwareGenerator < WikiGenerator
     MW.generate_table('class="wikitable sortable"', table_columns, table_data) + "\n"
   end
 
-  def generate_oneline_summary
-    h = G5K::get_global_hash['sites'][@site]
-    # remove retired nodes
-    # FIXME this should probably move to a helper
-    h['clusters'].each_pair do |cl, v|
-      v['nodes'].delete_if { |n, v2| v2['status'] == 'retired' }
+  def self.generate_header_summary(sites_hash)
+    sites = sites_hash.length
+    clusters = 0
+    nodes = 0
+    cores = 0
+    gpus = 0
+    hdds = 0
+    ssds = 0
+    storage_space = 0
+    ram = 0
+    pmem = 0
+    flops = 0
+
+    sites_hash.sort.to_h.each do |site_uid, site_hash|
+      clusters += site_hash['clusters'].length
+      site_hash['clusters'].sort.to_h.each do |cluster_uid, cluster_hash|
+        cluster_hash['nodes'].sort.to_h.each do |node_uid, node_hash|
+          next if node_hash['status'] == 'retired'
+          nodes += 1
+          cores += node_hash['architecture']['nb_cores']
+          ram += node_hash['main_memory']['ram_size']
+          pmem += node_hash['main_memory']['pmem_size'] if node_hash['main_memory']['pmem_size']
+          if node_hash['gpu_devices']
+            gpus += node_hash['gpu_devices'].length
+          end
+          ssds += node_hash['storage_devices'].select { |d| d['storage'] == 'SSD' }.length
+          hdds += node_hash['storage_devices'].select { |d| d['storage'] == 'HDD' }.length
+          node_hash['storage_devices'].each do |i|
+            storage_space += i['size']
+          end
+          flops += node_hash['performance']['node_flops']
+        end
+      end
     end
-    h['clusters'].delete_if { |k, v| v['nodes'].empty? }
-
-    clusters = h['clusters'].length
-    nodes = h['clusters'].inject(0) { |a, b| a + b[1]['nodes'].values.length }
-    cores = h['clusters'].inject(0) { |a, b| cnodes = b[1]['nodes'].values ; a + cnodes.length * cnodes.first['architecture']['nb_cores'] }
-    flops = h['clusters'].inject(0) { |a, b| cnodes = b[1]['nodes'].values ; a + cnodes.length * (cnodes.first['performance']['node_flops'] rescue 0) }
     tflops = sprintf("%.1f", flops.to_f / (10**12))
-    return "#{clusters} cluster#{clusters > 1 ? 's' : ''}, #{nodes} node#{nodes > 1 ? 's' : ''}, #{cores} core#{cores > 1 ? 's' : ''}, #{tflops} TFLOPS"
+
+    summary  = "= Summary =\n"
+    summary += sites > 1 ? "* #{sites} sites\n":''
+    summary += "* #{clusters} clusters\n"
+    summary += "* #{nodes} nodes\n"
+    summary += "* #{cores} CPU cores\n"
+    summary += "* #{gpus} GPUs\n"
+    summary += "* #{G5K.get_size(ram)} RAM"
+    summary += pmem > 0 ? " + #{G5K.get_size(pmem)} PMEM\n":"\n"
+    summary += "* #{ssds} SSDs and #{hdds} HDDs on nodes (total: #{G5K.get_size(storage_space, 'metric')})\n"
+    summary += "* #{tflops} TFLOPS (excluding GPUs)\n"
+    summary
   end
 
   def self.generate_summary(site, with_sites)