diff --git a/generators/wiki/cpu_parameters.rb b/generators/wiki/cpu_parameters.rb index 418875937e16f8a4b4e9aab5cb44ee311b3a2cfa..f141066420c7a0d644093aee59947ed349e83d9b 100644 --- a/generators/wiki/cpu_parameters.rb +++ b/generators/wiki/cpu_parameters.rb @@ -1,90 +1,67 @@ -require "optparse" -require "mediawiki_api" - require_relative '../lib/input_loader' +require_relative './wiki_generator' require_relative './mw_utils' -options = {} - -opt_parse = OptionParser.new do |opts| - opts.banner = "Usage: cpuParameters.rb --api-user user --api-password password" +class CPUParametersGenerator < WikiGenerator - opts.on('-u=user', '--api-user=user', String, 'User for HTTP authentication ') do |user| - options[:user] = user + def initialize(page_name) + super(page_name) end - opts.on('-p=pwd', '--api-password=pwd', String, 'Password for HTTP authentication') do |pwd| - options[:pwd] = pwd + def generate_content + + table_columns = ["Installation date", "Site", "Cluster", "CPU Family", "CPU Version", "Core Codename", "Frequency", "Server type", "HT enabled", "Turboboost enabled", "P-State driver", "C-State driver"] + table_data = [] + global_hash = load_yaml_file_hierarchy(File.expand_path("../../input/grid5000/", File.dirname(__FILE__))) + + # Loop over Grid'5000 sites + global_hash["sites"].each { |site_uid, site_hash| + site_hash.fetch("clusters").each { |cluster_uid, cluster_hash| + + node_hash = cluster_hash.fetch('nodes').first[1] + + cpu_family = node_hash["processor"]["model"] rescue "" + cpu_version = node_hash["processor"]["version"] rescue "" + cpu_freq = node_hash["processor"]["clock_speed"] / 1000000000.0 rescue 0.0 #GHz + cpu_codename = node_hash["processor"]["microarchitecture"] rescue "" + ht_enabled = node_hash["bios"]["configuration"]["ht_enabled"] rescue false + turboboost_enabled = node_hash["bios"]["configuration"]["turboboost_enabled"] rescue false + pstate_driver = node_hash["operating_system"]["pstate_driver"] rescue "" + cstate_driver = node_hash["operating_system"]["cstate_driver"] rescue "" + + #One line per cluster + table_data << [ + DateTime.new(*cluster_hash["created_at"].to_s.scan(/\d+/).map {|i| i.to_i}).strftime("%Y-%m-%d"), + site_uid, + cluster_uid, + cpu_family, + cpu_version, + cpu_codename, + cpu_freq.to_s + " GHz", + cluster_hash["model"], + ht_enabled ? "{{Yes}}" : "{{No}}", + turboboost_enabled ? "{{Yes}}" : "{{No}}", + pstate_driver, + cstate_driver + ] + } + } + #Sort by cluster date + table_data.sort_by! { |row| + DateTime.parse(row[0]) + } + + #Table construction + table_options = 'class="G5KDataTable" border="1" style="text-align: center;"' + @generated_content = MW.generate_table(table_options, table_columns, table_data) + @generated_content += MW.italic(MW.small("Generated from the Grid5000 APIs on " + Time.now.strftime("%Y-%m-%d"))) + @generated_content += MW::LINE_FEED end end -opt_parse.parse! +generator = CPUParametersGenerator.new("Generated/CPUParameters") -if (options[:user].nil? || options[:pwd].nil?) - puts opt_parse.to_s - exit +options = WikiGenerator::parse_options +if (options) + WikiGenerator::exec(generator, options) end - -target_page = "Generated/CPUParameters" - -table_columns = ["Installation date", "Site", "Cluster", "CPU Family", "CPU Version", "Core Codename", "Frequency", "Server type", "HT enabled", "Turboboost enabled", "P-State driver", "C-State driver"] - -table_data = [] - -global_hash = load_yaml_file_hierarchy(File.expand_path("../../input/grid5000/", File.dirname(__FILE__))) - -# Loop over Grid'5000 sites -global_hash["sites"].each { |site_uid, site_hash| - - site_hash.fetch("clusters").each { |cluster_uid, cluster_hash| - - node_hash = cluster_hash.fetch('nodes').first[1] - - cpu_family = node_hash["processor"]["model"] rescue "" - cpu_version = node_hash["processor"]["version"] rescue "" - cpu_freq = node_hash["processor"]["clock_speed"] / 1000000000.0 rescue 0.0 #GHz - cpu_codename = node_hash["processor"]["microarchitecture"] rescue "" - - ht_enabled = node_hash["bios"]["configuration"]["ht_enabled"] rescue false - turboboost_enabled = node_hash["bios"]["configuration"]["turboboost_enabled"] rescue false - pstate_driver = node_hash["operating_system"]["pstate_driver"] rescue "" - cstate_driver = node_hash["operating_system"]["cstate_driver"] rescue "" - - #One line per cluster - table_data << [ - DateTime.new(*cluster_hash["created_at"].to_s.scan(/\d+/).map {|i| i.to_i}).strftime("%Y-%m-%d"), - site_uid, - cluster_uid, - cpu_family, - cpu_version, - cpu_codename, - cpu_freq.to_s + " GHz", - cluster_hash["model"], - ht_enabled ? "{{Yes}}" : "{{No}}", - turboboost_enabled ? "{{Yes}}" : "{{No}}", - pstate_driver, - cstate_driver - ] - - } -} - -#Sort by cluster date -table_data.sort_by! { |row| - DateTime.parse(row[0]) -} - -#Table construction - -table_options = 'class="G5KDataTable" border="1" style="text-align: center;"' - -page_text = MW.generate_table(table_options, table_columns, table_data) - -page_text += MW.italic(MW.small("Generated from the Grid5000 APIs on " + Time.now.strftime("%Y-%m-%d"))) - -#Finally Create/modify the page on mediawiki -client = MediawikiApi::Client.new(MW::BASE_URL) -client.log_in(options[:user], options[:pwd]) -client.edit({"title" => target_page, "text" => page_text }) - -puts "Page '#{target_page}' created/updated" diff --git a/generators/wiki/mw_utils.rb b/generators/wiki/mw_utils.rb index cba7652365d3953ea89fdb8160e4ce00ebc915de..f3c3ec5ab8565d281d9ad74ff5bd7946351dc154 100644 --- a/generators/wiki/mw_utils.rb +++ b/generators/wiki/mw_utils.rb @@ -1,9 +1,38 @@ +require 'open-uri' +require 'uri' +require 'net/http' +require 'net/https' + +#Adding method to mediawiki_api client +module MediawikiApi + + class Client + + def get_page_content(page_name) + get_conn = Faraday.new(url: MW::BASE_URL + "index.php/#{page_name}") do |faraday| + faraday.request :multipart + faraday.request :url_encoded + faraday.use :cookie_jar, jar: @cookies + faraday.use FaradayMiddleware::FollowRedirects + faraday.adapter Faraday.default_adapter + end + params = { + :token_type => false, + :action => 'raw' + } + params[:token] = get_token(:csrf) + res = get_conn.send(:get, '', params) + res.body + end + end +end #Defines MediaWiki helpers - module MW - BASE_URL = "https://www.grid5000.fr/mediawiki/api.php" + BASE_URL = "https://www.grid5000.fr/mediawiki/" + + API_URL = BASE_URL + "api.php" TABLE_START = "{|" @@ -61,5 +90,4 @@ module MW def self.bold(text) "'''" + text + "'''" end - end diff --git a/generators/wiki/wiki_generator.rb b/generators/wiki/wiki_generator.rb new file mode 100644 index 0000000000000000000000000000000000000000..41a7c48249f69afcba119bf6b9f5e5ae3f2c4d3b --- /dev/null +++ b/generators/wiki/wiki_generator.rb @@ -0,0 +1,107 @@ + +require "optparse" +require "mediawiki_api" +require "diffy" + +require_relative "./mw_utils" + +class WikiGenerator + + def initialize(page_name) + @mw_client = MediawikiApi::Client.new(MW::API_URL) + @page_name = page_name + end + + def login(options) + if (options[:user] && options[:pwd]) + @mw_client.log_in(options[:user], options[:pwd]) + end + end + + def generate_content + raise "To be implemented in actual generators" + end + + #Actually edit the mediawiki page with the new generated content + def update_page + @mw_client.edit({"title" => @page_name, "text" => @generated_content }) + end + + #Get the given page content and print a diff if any + #Return true if there are differences, false otherwise + def diff_page() + wiki_content = @mw_client.get_page_content(@page_name) + diff = Diffy::Diff.new(wiki_content, @generated_content, :context => 0) + if (diff.to_s.empty?) + return false + end + puts "Differences between generated and current wiki content for page #{@page_name}:\n#{diff.to_s(:color)}" + end + + #print generator content to stdout + def print() + puts @generated_content + end + + #Generic static method for cli arguments parsing + def self.parse_options + options = { + :diff => false, + :print => false, + :update => false + } + + opt_parse = OptionParser.new do |opts| + opts.banner = "Usage: <wiki_generator>.rb --api-user user --api-password password" + + opts.on('-u=user', '--api-user=user', String, 'User for HTTP authentication ') do |user| + options[:user] = user + end + + opts.on('-p=pwd', '--api-password=pwd', String, 'Password for HTTP authentication') do |pwd| + options[:pwd] = pwd + end + + opts.on('-d', '--diff', 'Print a diff of the current wiki page against the content to generated') do + options[:diff] = true + end + + opts.on('-u', '--update', 'Update the wiki page with the new generated content') do + options[:update] = true + end + + opts.on('-p', '--print', 'Print the new generated content on stdout') do + options[:print] = true + end + + # Print an options summary. + opts.on_tail("-h", "--help", "Show this message") do + puts opts + exit + end + end + opt_parse.parse! + if (!options[:diff] && !options[:print] && !options[:update]) + puts "At least one action must be given!\n#{opt_parse.to_s}" + return false + end + return options + end + + #Execute actions on generator based on given options + def self.exec(generator, options) + generator.login(options) + generator.generate_content() + + if (options[:diff]) + generator.diff_page + end + if (options[:print]) + generator.print + end + if (options[:update]) + generator.update_page + end + end + +end