diff --git a/apps/dashboard/app/controllers/projects_controller.rb b/apps/dashboard/app/controllers/projects_controller.rb index 1db4279ef2..a40104653a 100644 --- a/apps/dashboard/app/controllers/projects_controller.rb +++ b/apps/dashboard/app/controllers/projects_controller.rb @@ -11,7 +11,12 @@ def show else @scripts = Script.all(@project.directory) @valid_project = Script.clusters? - flash.now[:alert] = I18n.t("dashboard.jobs_project_invalid_configuration_clusters") unless @valid_project + @valid_scripts = Script.scripts?(@project.directory) + + alert_messages = [] + alert_messages << I18n.t('dashboard.jobs_project_invalid_configuration_clusters') unless @valid_project + alert_messages << I18n.t('dashboard.jobs_project_invalid_configuration_scripts') if @scripts.any? && !@valid_scripts + flash.now[:alert] = alert_messages.join(' ') if alert_messages.any? end end diff --git a/apps/dashboard/app/controllers/scripts_controller.rb b/apps/dashboard/app/controllers/scripts_controller.rb index fe93fdaae0..2359e2d195 100644 --- a/apps/dashboard/app/controllers/scripts_controller.rb +++ b/apps/dashboard/app/controllers/scripts_controller.rb @@ -23,9 +23,12 @@ def new def create opts = { project_dir: @project.directory }.merge(create_script_params[:script]) @script = Script.new(opts) + default_script_created = @script.create_default_script if @script.save - redirect_to project_path(params[:project_id]), notice: I18n.t('dashboard.jobs_scripts_created') + notice_messages = [I18n.t('dashboard.jobs_scripts_created')] + notice_messages << I18n.t('dashboard.jobs_scripts_default_created') if default_script_created + redirect_to project_path(params[:project_id]), notice: notice_messages.join(' ') else redirect_to project_path(params[:project_id]), alert: @script.errors[:save].last end diff --git a/apps/dashboard/app/models/script.rb b/apps/dashboard/app/models/script.rb index ce7157d740..82f73f46b1 100644 --- a/apps/dashboard/app/models/script.rb +++ b/apps/dashboard/app/models/script.rb @@ -50,6 +50,11 @@ def clusters? cluster_attribute = SmartAttributes::AttributeFactory.build('auto_batch_clusters', {}) cluster_attribute.select_choices(hide_excludable: false).any? end + + def scripts?(project_dir) + script_attribute = SmartAttributes::AttributeFactory.build('auto_scripts', { directory: project_dir }) + script_attribute.select_choices(hide_excludable: false).any? + end end def initialize(opts = {}) @@ -193,12 +198,28 @@ def most_recent_job_cluster most_recent_job['cluster'] end + def create_default_script + return false if Script.scripts?(project_dir) || default_script_path.exist? + + script_content = <<~DEFAULT_SCRIPT + #!/bin/bash + # Sample script to configure project defaults. Delete when other scripts are available. + echo "Hello World" + DEFAULT_SCRIPT + File.open(default_script_path, 'w+') { |file| file.write(script_content) } + true + end + private def self.script_path(root_dir, script_id) Pathname.new(File.join(Script.scripts_dir(root_dir), script_id.to_s)) end + def default_script_path + Pathname(File.join(project_dir, 'hello_world.sh')) + end + def self.script_form_file(script_path) File.join(script_path, "form.yml") end diff --git a/apps/dashboard/config/locales/en.yml b/apps/dashboard/config/locales/en.yml index d56a09a509..ef30f41313 100644 --- a/apps/dashboard/config/locales/en.yml +++ b/apps/dashboard/config/locales/en.yml @@ -237,12 +237,14 @@ en: jobs_project_save_error: "Cannot save manifest to %{path}" jobs_project_generic_error: "There was an error processing your request: %{error}" jobs_project_invalid_configuration_clusters: "An HPC cluster is required. Contact your administrator to add one to the system." + jobs_project_invalid_configuration_scripts: "An executable script is required for your project. Upload a script using the file application." jobs_scripts_created: "Script successfully created!" + jobs_scripts_default_created: "A 'hello_world.sh' was also added to this project." jobs_scripts_updated: "Script manifest updated!" jobs_scripts_not_found: "Cannot find script %{script_id}" jobs_scripts_deleted: "Script successfully deleted!" - jobs_scripts_submitted: "Successfully submited job %{job_id}." + jobs_scripts_submitted: "Successfully submitted job %{job_id}." jobs_scripts_delete_script_confirmation: "Delete all contents of script?" jobs_scripts_fixed_field: "Fixed Value" diff --git a/apps/dashboard/test/models/script_test.rb b/apps/dashboard/test/models/script_test.rb index efcdf548c2..b478b28415 100644 --- a/apps/dashboard/test/models/script_test.rb +++ b/apps/dashboard/test/models/script_test.rb @@ -14,18 +14,6 @@ class ScriptTest < ActiveSupport::TestCase assert target.send('attribute_parameter?', 'account_fixed') end - test 'clusters? return false when auto_batch_clusters returns no clusters' do - Configuration.stubs(:job_clusters).returns([]) - - assert_equal false, Script.clusters? - end - - test 'clusters? return true when auto_batch_clusters returns clusters' do - Configuration.stubs(:job_clusters).returns(OodCore::Clusters.load_file('test/fixtures/config/clusters.d')) - - assert_equal true, Script.clusters? - end - test 'creates script' do Dir.mktmpdir do |tmp| projects_path = Pathname.new(tmp) @@ -51,6 +39,18 @@ class ScriptTest < ActiveSupport::TestCase end end + test 'clusters? return false when auto_batch_clusters returns no clusters' do + Configuration.stubs(:job_clusters).returns([]) + + assert_equal false, Script.clusters? + end + + test 'clusters? return true when auto_batch_clusters returns clusters' do + Configuration.stubs(:job_clusters).returns(OodCore::Clusters.load_file('test/fixtures/config/clusters.d')) + + assert_equal true, Script.clusters? + end + test 'deletes script should succeed when directory does not exists' do Dir.mktmpdir do |tmp| projects_path = Pathname.new(tmp) @@ -67,4 +67,58 @@ class ScriptTest < ActiveSupport::TestCase assert_not Dir.entries("#{projects_path}/.ondemand/scripts").include?('33') end end + + test 'scripts? returns true when there are scripts in the project directory' do + Dir.mktmpdir do |tmp| + projects_path = Pathname.new(tmp) + OodAppkit.stubs(:dataroot).returns(projects_path) + + script_content = <<~TEST_SCRIPT + echo "Testing Scripts" + TEST_SCRIPT + File.open(File.join(projects_path, 'test_script.sh'), 'w+') { |file| file.write(script_content) } + + assert_equal true, Script.scripts?(projects_path) + end + end + + test 'scripts? returns false when there are no scripts in the project directory' do + Dir.mktmpdir do |tmp| + projects_path = Pathname.new(tmp) + OodAppkit.stubs(:dataroot).returns(projects_path) + + assert_equal false, Script.scripts?(projects_path) + end + end + + test 'create_default_script should create hello_world.sh script' do + Dir.mktmpdir do |tmp| + projects_path = Pathname.new(tmp) + OodAppkit.stubs(:dataroot).returns(projects_path) + + target = Script.new({ project_dir: projects_path.to_s, id: 1234, title: 'Default Script' }) + created_script = target.create_default_script + + assert_equal true, created_script + assert_equal true, Pathname(File.join(projects_path, 'hello_world.sh')).exist? + end + end + + test 'create_default_script should not create hello_world.sh script if there is an script already in the project' do + Dir.mktmpdir do |tmp| + projects_path = Pathname.new(tmp) + OodAppkit.stubs(:dataroot).returns(projects_path) + + script_content = <<~TEST_SCRIPT + echo "Testing Scripts" + TEST_SCRIPT + File.open(File.join(projects_path, 'test_script.sh'), 'w+') { |file| file.write(script_content) } + + target = Script.new({ project_dir: projects_path.to_s, id: 1234, title: 'With Script' }) + created_script = target.create_default_script + + assert_equal false, created_script + assert_equal false, Pathname(File.join(projects_path, 'hello_world.sh')).exist? + end + end end