require 'nera_simulator_layer_controller' require 'nera_job_layer_controller' require 'nera_parameter_layer_controller' require 'nera_run_layer_controller' require 'nera_dialog' # --- start CUI based NER analyzer --- # - db_name : name of the database folder module NERA class CUI_exec # folder structure @path_db_folder # simulator layer controller @sim_cont # param layer controller @param_cont # run layer controller @run_cont # job layer controller @job_cont # state [ :simulator_layer, :parameter_layer, :run_layer, :job_layer, :exit] @state # model which is currently selected @simulator_class # parameter which is currently selected @parameter_id # --- main method def initialize( path_db_folder) @state = :simulator_layer @path_db_folder = path_db_folder unless FileTest.directory?(@path_db_folder) NERA::DbFolders.create_db(@path_db_folder) end while true case @state when :simulator_layer @state = sim_layer_action when :parameter_layer @state = param_layer_action when :run_layer @state = run_layer_action when :job_layer @state = job_layer_action when :exit return 0 else raise "Must not happen" end end end # --- action at simulator layer def sim_layer_action $stdout.puts <<"HEADER" =============================================== --- in simulator layer ------------------------ #{@path_db_folder} =============================================== HEADER slc = NERA::SimulatorLayerController.new(@path_db_folder) list = slc.list names = list.map do |r| r[:name] end names.unshift("go to Jobs layer") names += ["show logs", "remove a simulator", "dump a simulator", "import a simulator", "exit"] selected = 0 Dir.chdir( slc.path_to_sim_layer) { selected = Dialog::select_one_or_return_string( names, "Select a simulator.") if selected.is_a?(String) system( selected) return :simulator_layer end } case names[selected] when "go to Jobs layer" return :job_layer when "show logs" system "less #{slc.path_to_log_file}" return :simulator_layer when "remove a simulator" sim_names = ["Cancel"] + slc.list.map do |r| r[:name] end selected = Dialog::select_one( sim_names, "Select a simulator to be removed.") return :simulator_layer if selected == 0 flag = slc.remove_simulator( sim_names[selected]) if flag Dialog::message("Simulator \"#{sim_names[selected]}\" have been successfully removed from the database.") else Dialog::message("Failed to remove the simulator \"#{sim_names[selected]}\". There are uncompleted jobs.") end return :simulator_layer when "dump a simulator" sim_names = ["Cancel"] + slc.list.map do |r| r[:name] end selected = Dialog::select_one( sim_names, "Select a simulator to be dumped.") return :simulator_layer if selected == 0 flag = slc.dump_simulator( sim_names[selected]) if flag Dialog::message("Data for the simulator \"#{sim_names[selected]}\" have been successfully dumped.") else Dialog::message("Failed to dump the simulator \"#{sim_names[selected]}\". There are uncompleted jobs.") end return :simulator_layer when "import a simulator" list = ["Cancel"] + slc.importable_simulators selected = Dialog::select_one( list, "Select a simulator to be dumped.") return :simulator_layer if selected == 0 flag = slc.import_simulator( list[selected]) if flag Dialog::message("Simulator \"#{list[selected]}\" have been successfully imported.") else Dialog::message("Failed to import the simulator \"#{sim_names[selected]}\".") end return :simulator_layer when "exit" return :exit else @simulator_class = names[selected] return :parameter_layer end end # --- selection of a parameter set def param_layer_action plc = NERA::ParameterLayerController.new( @path_db_folder, @simulator_class) unless plc Dialog::message("Specified simulator does not exist #{@path_db_folder}/#{@simulator_class}") return :simulator_layer end $stdout.puts <<"HEADER" =============================================== --- in parameter layer ------------------------ #{@path_db_folder} / #{@simulator_class} =============================================== HEADER header,list = plc.parameters_list_in_csv list.unshift( "Menu") selected = 0 Dir.chdir( plc.path_to_param_layer) { selected = Dialog::select_one_or_return_string( list, header) if selected.is_a?(String) system(selected) return :parameter_layer end } if selected == 0 layer = parameter_layer_menu_select return layer else id = plc.get_id_from_csv_string( list[selected]) @parameter_id = id return :run_layer end end # --- menu at a parameter layer def parameter_layer_menu_select menu = ["return to simulator layer", "create a new parameter set", "move a parameter set into the trashbox", "revert a parameter set in the trashbox", "delete a parameter set completely", "exit"] s = Dialog::select_one( menu, "Select one from the following") plc = NERA::ParameterLayerController.new( @path_db_folder, @simulator_class) case menu[s] when "return to simulator layer" return :simulator_layer when "create a new parameter set" plist = plc.list_of_parameters( @parameter_id) new_param_hash = Dialog::set_multiple_values( plist, "Input the new parameter set") f = plc.create_a_new_parameter_set( new_param_hash) if f Dialog::message("A new parameter is successfully added to the table.") @parameter_id = f else Dialog::message("This parameter already exists in the database.") end return :parameter_layer when "move a parameter set into the trashbox" header,list = plc.parameters_list_in_csv list.unshift("Cancel") s = Dialog::select_one( list, header) if s == 0 return :parameter_layer else id = plc.get_id_from_csv_string( list[s]) f = plc.move_a_parameter_set_into_trashbox(id) if f Dialog::message("Parameter #{id} was successfully moved into the trashbox") else Dialog::message("Couldn't move the parameter #{id} to the trashbox.\nYou have to cancel all the jobs that are not finished.") end return :parameter_layer end when "revert a parameter set in the trashbox" header,list = plc.trashbox_parameter_list_in_csv list.unshift("Cancel") s = Dialog::select_one( list, header) if s == 0 return :parameter_layer else id = plc.get_id_from_csv_string( list[s]) f = plc.revert_a_parameter_set_in_trashbox(id) if f Dialog::message("Parameter #{id} was successfully reverted.") else Dialog::message("Couldn't revert the parameter #{id}") end return :parameter_layer end when "delete a parameter set completely" header,list = plc.trashbox_parameter_list_in_csv list.unshift("Cancel") s = Dialog::select_one( list, header) if s == 0 return :parameter_layer else id = plc.get_id_from_csv_string( list[s]) f = plc.delete_a_parameter_set( id) if f Dialog::message("Parameter #{id} was successfully deleted.") else Dialog::message("Couldn't delete the parameter #{id}") end return :parameter_layer end when "exit" return :exit else raise "must not happen" end end # --- action at run layer def run_layer_action rlc = NERA::RunLayerController.new( @path_db_folder, @simulator_class, @parameter_id) unless rlc Dialog::message("Table #{@path_db_folder}/#{@simulator_class}/#{@parameter_id} is not found.") return :parameter_layer end $stdout.puts <<"HEADER" =============================================== --- in run layer ------------------------------ #{@path_db_folder} / #{@simulator_class} / #{@parameter_id} =============================================== HEADER action_list = ["Back to parameter layer", "Show run infos", "Create jobs", #"Execute created jobs", #"Submit created jobs to remote host", "Cancel jobs", "Analyze data", "Exit"] selected = 0 Dir.chdir( rlc.path_to_run_layer) { selected = Dialog::select_one_or_return_string( action_list, "Select one") if selected.is_a?(String) system( selected) return :run_layer end } case action_list[selected] when "Back to parameter layer" return :parameter_layer when "Show run infos" Dir.chdir( rlc.path_to_run_layer) { system("less runs.yml") } return :run_layer when "Create jobs" num_job = Dialog::get_integer( "Input the number of jobs (must be equal or larger than zero)") { |i| i >= 0 } return :run_layer if num_job == 0 num_run_per_job = Dialog::get_integer( "Input the number of runs per job (must be larger than zero)") { |i| i > 0 } jobids = rlc.create_jobs( num_job, num_run_per_job) str = jobids.join(", ") Dialog::message( "The following jobs are newly created.\n#{str}") return :run_layer when "Execute created jobs" =begin header,list = rlc.not_finished_runs_list_in_csv list = RunLayerController::get_created_runs_list( @db_folder, @model_id, @parameter_id) selected = select_one( list, "Select a job to execute") job_id = list[selected][:job_id] stat = JobLayerController::execute_one( @db_folder, job_id) if stat $stderr.puts "Simulation finished successfully" else $stderr.puts "Simulation failed" end =end return :run_layer when "Submit created jobs to remote host" =begin header,list = rlc.not_finished_runs_list_in_csv list.unshift("Cancel") selected_jobs = Dialog::select_many( list, header) unless selected_jobs.include?(0) rc = RemoteConnector.new( @db_folder) hosts = rc.hostnames hosts.unshift("Cancel") s = Dialog::select_one( hosts, "Select a host") return :run_layer if s == 0 if rc.connect( hosts[s]) Dialog::message( rc.get_status) action = Dialog::select_one( ["Transfer", "Transfer and Submit", "Cancel"], "Select action") stat = nil case action when 0 stat = rc.transfer( selected_jobs) Dialog::message("File transfer to #{hosts[s]} failed") unless stat when 1 stat = rc.submit( selected_jobs) Dialog::message("Submission to #{hosts[s]} failed") unless stat when 2 end Dialog::message("Completed successfully.") if stat else Dialog::message("Connection to #{hosts[s]} failed.") end end =end return :run_layer when "Cancel jobs" header,list = rlc.not_finished_jobs_list_in_csv list.unshift("Cancel") selected_jobs = Dialog::select_many( list, header).map do |num| list[num].split(',')[0].to_i end unless selected_jobs.include?(0) stat = rlc.cancel_jobs( selected_jobs) if stat str = selected_jobs.join(", ") Dialog::message("The following jobs are successfully cancelled.\n#{str}") else Dialog::message("Cancellation failed.") end end return :run_layer when "Analyze data" list = rlc.analysis_methods list = [ "Cancel", "All"] + list sel = Dialog.select_many( list, "Select numbers.") if sel.include?(0) return :run_layer elsif sel.include?(1) rlc.analyze_all return :run_layer else sel.each do |i| rlc.analyze( list[i]) end return :run_layer end when "Exit" return :exit else raise "Must not happen" end end # --- action at job layer def job_layer_action $stdout.puts <<"HEADER" =============================================== --- in job layer ------------------------------ #{@path_db_folder} / Jobs =============================================== HEADER action_list = ["Back to simulator layer", "Show job infos", "Cancel jobs", "Execute jobs now", "Show host infos", "Upload jobs", "Download data", "Include data", "Exit"] jlc = NERA::JobLayerController.new( @path_db_folder) rc = NERA::RemoteConnector.new( @path_db_folder) selected = 0 Dir.chdir( jlc.path_to_job_layer) { selected = Dialog.select_one_or_return_string( action_list, "Select one") if selected.is_a?(String) system( selected) return :job_layer end } case action_list[selected] when "Back to simulator layer" return :simulator_layer when "Show job infos" Dir.chdir( jlc.path_to_job_layer) { system("less jobs.yml") } return :job_layer when "Cancel jobs" header,list = jlc.not_finished_list_in_csv list.unshift("Cancel") selected_jobs = Dialog::select_many( list, header).map do |num| list[num].split(',')[0].to_i end unless selected_jobs.include?(0) stat = jlc.cancel_jobs( selected_jobs) if stat str = selected_jobs.join(", ") Dialog::message("The following jobs are successfully cancelled.\n#{str}") else Dialog::message("Cancellation failed.") end end return :job_layer when "Execute jobs now" header,list = jlc.not_finished_list_in_csv list.unshift("Cancel") selected_jobs = Dialog::select_many( list, header).map do |num| list[num].split(',')[0].to_i end return :job_layer if selected_jobs.include?(0) system "top" if Dialog::ask("Will you execute now?", true) flag = jlc.execute_jobs_now( selected_jobs) Dialog::message("The following jobs are successfully submitted.\n#{flag.join(', ')}") if flag non_submitted = selected_jobs - flag.to_a Dialog::message("Warning! The following jobs are not submitted.\n#{non_submitted.join(', ')}") if non_submitted.size > 0 end return :job_layer when "Show host infos" h_list = ["Cancel", "All"] + rc.hostnames sel = Dialog::select_many( h_list) if sel.include?(0) return :job_layer elsif sel.include?(1) rc.hostnames.each do |hname| Dialog::message("Information of the host #{hname} =========================") Dialog::message( rc.show_status( hname) ) end else sel.each do |num| Dialog::message("Information of the host #{h_list[num]} =========================") Dialog::message( rc.show_status( h_list[num]) ) end end return :job_layer when "Upload jobs" header,list = jlc.not_finished_list_in_csv list.unshift("Cancel") selected_jobs = Dialog::select_many( list, header).map do |num| list[num].split(',')[0].to_i end return :job_layer if selected_jobs.include?(0) h_list = ["Cancel"] + rc.hostnames sel = Dialog::select_one( h_list, "Select the host") return :job_layer if sel == 0 selected_host = h_list[sel] Dialog::message("Information of the host #{selected_host} =========================") Dialog::message( rc.show_status( selected_host) + "\n" ) if Dialog::ask("Will you upload the script?", true) if rc.submittable_hostnames.include?(selected_host) and Dialog::ask("Will you submit the jobs?", true) v = rc.submit( selected_jobs, selected_host) Dialog::message(v.to_s) else v = rc.transfer( selected_jobs, selected_host) Dialog::message(v.to_s) end end return :job_layer when "Download data" d_hash = rc.check_completion_all list = ["Cancel", "All"] d_hash.each_pair do |host, d_files| if d_files.is_a?(Array) d_files.each do |f| list << "#{f} @ #{host}" end end end sel = Dialog::select_many( list) if sel.include?(0) return :job_layer elsif sel.include?(1) d_hash.each_pair do |host, d_files| res = rc.download( d_files, host) if res.is_a?(Array) Dialog::message("#{res.join(', ')} have been downloaded.") else Dialog::message(res.to_s) end end else downloaded = [] sel.each do |num| a = list[num].split('@') res = rc.download( [ a[0].strip ], a[1].strip) downloaded += res if res.is_a?(Array) end Dialog::message("#{downloaded.join(', ')} have been downloaded.") end return :job_layer when "Include data" list = jlc.include_list list = ["Cancel","All"] + list sel = Dialog::select_many( list) status = nil if sel.include?(0) return :job_layer elsif sel.include?(1) status = jlc.include_all else sel.each do |num| status = jlc.include( list[num]) end end if status Dialog::message("Inclusion successfully completed.") else Dialog::message("Inclusion failed.") end return :job_layer when "Exit" return :exit end end end end