From 71a71f7e8b991a2e6802b517b7e2015d84d53133 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Wed, 26 Jun 2019 17:15:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E8=AE=AD=E9=85=8D=E7=BD=AE=E6=94=B9?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/myshixuns_controller.rb | 4 +- app/controllers/shixuns_controller.rb | 43 +- app/helpers/application_helper.rb | 15 + app/models/shixun.rb | 14 +- app/models/shixun_service_config.rb | 7 + app/services/games_service.rb | 6 +- .../_new_or_edit_task_page.html.erb | 46 ++ app/views/challenges/_pass_task_show.html.erb | 14 + app/views/shixuns/_form.html.erb | 20 +- app/views/shixuns/_settings_edit.html.erb | 703 ++++++++++-------- ...626064125_create_shixun_service_configs.rb | 14 + .../20190626070641_add_limit_for_shixuns.rb | 19 + spec/factories/shixun_service_configs.rb | 5 + spec/models/shixun_service_config_spec.rb | 5 + 14 files changed, 563 insertions(+), 352 deletions(-) create mode 100644 app/models/shixun_service_config.rb create mode 100644 db/migrate/20190626064125_create_shixun_service_configs.rb create mode 100644 db/migrate/20190626070641_add_limit_for_shixuns.rb create mode 100644 spec/factories/shixun_service_configs.rb create mode 100644 spec/models/shixun_service_config_spec.rb diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index 68e4b4b0..85735080 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -333,7 +333,7 @@ class MyshixunsController < ApplicationController shixun_tomcat = Redmine::Configuration['shixun_tomcat'] uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo" user_id = User.current.id - params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), containers:(Base64.urlsafe_encode64(container_limit @myshixun.shixun.mirror_repositories))} + params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))} res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:92)") @@ -362,7 +362,7 @@ class MyshixunsController < ApplicationController begin uri = "#{shixun_tomcat}/bridge/vnc/getvnc" shixun = @myshixun.shixun - params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(container_limit(shixun.mirror_repositories))}"} + params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"} res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:99)") diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index e47938ac..1e3f105b 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -791,7 +791,7 @@ class ShixunsController < ApplicationController shixun_script = modify_shixun_script @shixun, shixun_script end end - @shixun.evaluate_script = shixun_script + #@shixun.evaluate_script = shixun_script ActiveRecord::Base.transaction do begin @@ -808,24 +808,27 @@ class ShixunsController < ApplicationController @shixun.shixun_members << m # 镜像-实训关联表 ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present? + # 创建Pod配置信息 + ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if sub_type.present? sub_mirrors = sub_type.split(",").map(&:to_i) sub_mirrors.each do |mirror| ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) + ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) end end - # 自动构建版本库 - repository = Repository.new - repository.shixun = @shixun - repository.type = 'Repository::Gitlab' - repository.identifier = @shixun.identifier.downcase - repository.project_id = -1 - repository.save! - s = Trustie::Gitlab::Sync.new - gproject = s.create_shixun(@shixun, repository) - raise "版本库创建失败" if @shixun.gpid.blank? # 若和gitlab没同步成功,则抛出异常 - g = Gitlab.client - @shixun.update_column(:git_url, g.project(@shixun.gpid).path_with_namespace) + # # 自动构建版本库 + # repository = Repository.new + # repository.shixun = @shixun + # repository.type = 'Repository::Gitlab' + # repository.identifier = @shixun.identifier.downcase + # repository.project_id = -1 + # repository.save! + # s = Trustie::Gitlab::Sync.new + # gproject = s.create_shixun(@shixun, repository) + # raise "版本库创建失败" if @shixun.gpid.blank? # 若和gitlab没同步成功,则抛出异常 + # g = Gitlab.client + # @shixun.update_column(:git_url, g.project(@shixun.gpid).path_with_namespace) # g = Gitlab.client # hook_url = Setting.protocol + "://" + Setting.host_name + "/shixuns/#{@shixun.identifier}" + "/ghook" # g.add_project_hook(@shixun.gpid, hook_url) @@ -1025,6 +1028,7 @@ class ShixunsController < ApplicationController end def update + logger.info("#######-----#{params[:config]}") @shixun.attributes = params[:shixun] #@shixun.language = params[:language] @shixun.trainee = params[:trainee] @@ -1058,6 +1062,19 @@ class ShixunsController < ApplicationController end end + # 超级管理员才能保存 中间层服务器pod信息的配置 + if User.current.admin? + @shixun.shixun_service_configs.each_with_index do |config, index| + config.update_attributes(:cpu_limit => params[:cpu_limit][index], + :lower_cpu_limit => params[:lower_cpu_limit][index], + :memory_limit => params[:memory_limit][index], + # :resource_limit => params[:resource_limit][index], + :request_limit => params[:request_limit][index], + :mirror_repository_id => params[:mirror_id][index]) + end + end + + ActiveRecord::Base.transaction do begin diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 34fa1a8d..8ab4e31f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -268,6 +268,21 @@ module ApplicationHelper return container.to_json end + def shixun_container_limit shixun + shixun.shixun_service_configs.each do |config| + mirror = config.mirror_repository + if mirror.name.present? + container << {:image => mirror.name, + :cpuLimit => config.cpu_limit, + :cpuRequest => config.lower_cpu_limit, + :memoryLimit => "#{config.memory_limit}M", + :memoryRequest => "#{config.request_limit}", + :resourceLimit => "#{config.resource_limit}K", + :type => mirror.try(:main_type) == "1" ? "main" : "sub"} + end + end + end + # 实训作品列表的提交状态 def list_work_status work, homework, course_group_id if work.work_status == 0 diff --git a/app/models/shixun.rb b/app/models/shixun.rb index bf06b583..bbc64946 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -52,7 +52,7 @@ class Shixun < ActiveRecord::Base has_many :exercise_bank_shixun_challenges, :dependent => :destroy has_many :tag_repertoires, :through => :shixun_tag_repertoires has_many :shixun_tag_repertoires, :dependent => :destroy - + has_many :shixun_service_configs, :dependent => :destroy scope :visible, lambda{where(status: [2,3])} scope :min, lambda { select([:id, :name, :gpid, :modify_time, :reset_time, :language, :propaedeutics, :status, :identifier, @@ -66,6 +66,18 @@ class Shixun < ActiveRecord::Base #scope :visible, -> { where(status: -1) } after_create :send_tiding + def description + self.has_attribute?(:description) ? self[:description] : "" + end + + def propaedeutics + self.has_attribute?(:propaedeutics) ? self[:propaedeutics] : "" + end + + def evaluate_script + self.has_attribute?(:evaluate_script) ? self[:evaluate_script] : "" + end + def should_compile? self.mirror_repositories.published_main_mirror.first.try(:should_compile) end diff --git a/app/models/shixun_service_config.rb b/app/models/shixun_service_config.rb new file mode 100644 index 00000000..94d67190 --- /dev/null +++ b/app/models/shixun_service_config.rb @@ -0,0 +1,7 @@ +class ShixunServiceConfig < ActiveRecord::Base + # attr_accessible :title, :body + # image_type: 镜像类型: 1 主镜像、2子镜像 + belongs_to :shixun + belongs_to :mirror_repository + +end diff --git a/app/services/games_service.rb b/app/services/games_service.rb index c77e7437..8589023a 100644 --- a/app/services/games_service.rb +++ b/app/services/games_service.rb @@ -42,7 +42,7 @@ class GamesService is_teacher = (user.user_extensions.identity == 0) tpm_identifier = shixun.try(:identifier) # 实训超时设置 - time_limit = shixun.exec_time + time_limit = game_challenge.exec_time # 高性能取上一关、下一关 prev_game = Game.prev_identifier(shixun.id, game.myshixun_id, game_challenge.position) @@ -82,7 +82,7 @@ class GamesService shixun_tomcat = Redmine::Configuration['shixun_tomcat'] service_host = Redmine::Configuration['vnc_url'] uri = "#{shixun_tomcat}/bridge/vnc/getvnc" - params = {tpiID: myshixun.id, :containers => "#{Base64.urlsafe_encode64(container_limit(shixun.mirror_repositories))}"} + params = {tpiID: myshixun.id, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}"} res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:99)") @@ -573,7 +573,7 @@ class GamesService content_modified = params[:content_modified] # 决定文件内容是否有修改,有修改如果中间成pull没有更新,则轮询等待更新 params = {:tpiID => "#{myshixun.id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{taskId}",:instanceChallenge => "#{step}", :testCases => "#{testCases}", :resubmit => "#{resubmit}", :times => params[:first].to_i, :podType => shixun.webssh, - :containers => "#{Base64.urlsafe_encode64(container_limit(shixun.mirror_repositories))}", :tpmScript => "#{tpmScript}", + :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(shixun))}", :tpmScript => "#{tpmScript}", :timeLimit => "#{shixun.exec_time}", :content_modified => content_modified, :persistenceName => shixun.identifier, :isPublished => (shixun.status < 2 ? 0 : 1), :sec_key => params[:sec_key]} diff --git a/app/views/challenges/_new_or_edit_task_page.html.erb b/app/views/challenges/_new_or_edit_task_page.html.erb index b31e3373..4ddde7e5 100644 --- a/app/views/challenges/_new_or_edit_task_page.html.erb +++ b/app/views/challenges/_new_or_edit_task_page.html.erb @@ -82,6 +82,52 @@ 必填项 +
+

服务配置

+
+ +
+ +
+
+
+ <%# if User.current.admin? %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <%# end %> +
+ <% end %>
提交 diff --git a/app/views/challenges/_pass_task_show.html.erb b/app/views/challenges/_pass_task_show.html.erb index 2e116e9f..32527f1b 100644 --- a/app/views/challenges/_pass_task_show.html.erb +++ b/app/views/challenges/_pass_task_show.html.erb @@ -55,6 +55,20 @@ <% end %>
+
+

评测时限(S):

+ + <%# if User.current.admin? %> + + + + + + + + + <%# end %> +
<% end %> \ No newline at end of file + $("#unit-all").show(); + } + + $("input[name='public_degree']").live("click", function () { + var item = $(this).attr("id"); + if ($(this).is(":checked") && item == "public-part") { + $("#person-unit").show(); + $("#person-unit").find("input").val(""); + //$(".unit-part").remove(); + $("#unit-all").show(); + } else { + $("#unit-all").hide(); + } + }); + + $("body").on("click", function (e) { + //alert($(e.target).attr("id")); + if ($(e.target).attr("id") != "person-unit") { + $("#scope-down-list").hide(); + } + }); + //设置编辑时显示的单位 + $(".unit-part input").each(function () { + $(this).attr("size", parseInt($(this).val().length) * 2); + }) + }); + + //申请新建 + function post_apply() { + var html = "<%= escape_javascript(render :partial => 'shixuns/apply_setnew') %>"; + pop_box_new(html, 460, 416); + } + + var setting_editormd = editormd("setting_introduction", { + width: "100%", + height: 210, + syncScrolling: "single", + //你的lib目录的路径,我这边用JSP做测试的 + path: "/editormd/lib/", + tex: true, + toolbarIcons: function () { + // Or return editormd.toolbarModes[name]; // full, simple, mini + // Using "||" set icons align right. + return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"] + }, + toolbarCustomIcons: { + testIcon: "
", + testIcon1: "
" + }, + onload: function () { + $("#setting_introduction [type=\"latex\"]").bind("click", function () { + setting_editormd.cm.replaceSelection("```latex"); + setting_editormd.cm.replaceSelection("\n"); + setting_editormd.cm.replaceSelection("\n"); + setting_editormd.cm.replaceSelection("```"); + var __Cursor = setting_editormd.cm.getDoc().getCursor(); + setting_editormd.cm.setCursor(__Cursor.line - 1, 0); + }); + + $("#setting_introduction [type=\"inline\"]").bind("click", function () { + setting_editormd.cm.replaceSelection("$$$$"); + var __Cursor = setting_editormd.cm.getDoc().getCursor(); + setting_editormd.cm.setCursor(__Cursor.line, __Cursor.ch - 2); + setting_editormd.cm.focus(); + }); + $("[type=\"inline\"]").attr("title", "行内公式"); + $("[type=\"latex\"]").attr("title", "多行公式"); + + }, + //这个配置在simple.html中并没有,但是为了能够提交表单,使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中,方便post提交表单。 + saveHTMLToTextarea: true, + autoFocus: false, + // 用于增加自定义工具栏的功能,可以直接插入HTML标签,不使用默认的元素创建图标 + dialogMaskOpacity: 0.6, + placeholder: "请输入完成当前任务依赖的知识点或者其它相关信息", + imageUpload: true, + imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"], + imageUploadURL: "<%= upload_with_markdown_path(:container_id => @shixun.id, :container_type => @shixun.class) %>" //url + }); + md_elocalStorage(setting_editormd, "shixun_edit_<%= User.current.id %>", "in"); + + var script_Codemirror = CodeMirror.fromTextArea(document.getElementById("shixun_script"), { + lineNumbers: true, + theme: "default", + // extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键 + indentUnit: 4, //代码缩进为一个tab的距离 + matchBrackets: true, + autoRefresh: true, + smartIndent: true,//智能换行 + styleActiveLine: true, + lint: true + }); + script_Codemirror.setSize("auto", "600px"); + // 非管理员只能查看 + \ No newline at end of file diff --git a/db/migrate/20190626064125_create_shixun_service_configs.rb b/db/migrate/20190626064125_create_shixun_service_configs.rb new file mode 100644 index 00000000..a15a30f6 --- /dev/null +++ b/db/migrate/20190626064125_create_shixun_service_configs.rb @@ -0,0 +1,14 @@ +class CreateShixunServiceConfigs < ActiveRecord::Migration + def change + create_table :shixun_service_configs do |t| + t.references :shixun + t.integer :cpu_limit, :default => 1 + t.integer :memory_limit, :default => 1024 + t.integer :request_limit, :default => 10 + t.float :lower_cpu_limit, :default => 0.1 + t.integer :resource_limit, :default => 10000 + t.references :mirror_repository + t.timestamps + end + end +end diff --git a/db/migrate/20190626070641_add_limit_for_shixuns.rb b/db/migrate/20190626070641_add_limit_for_shixuns.rb new file mode 100644 index 00000000..1de29c80 --- /dev/null +++ b/db/migrate/20190626070641_add_limit_for_shixuns.rb @@ -0,0 +1,19 @@ +class AddLimitForShixuns < ActiveRecord::Migration + def up + Shixun.find_each do |shixun| + shixun.challenges.update_all(:exec_time => shixun.exec_time) + shixun.mirror_repositories.each do |mirror| + ShixunServiceConfig.create!(:shixun_id => shixun.id, + :cpu_limit => mirror.cpu_limit, + :memory_limit => mirror.memory_limit, + :request_limit => mirror.memory_limit / 3, + :mirror_repository_id => mirror.id) + end + end + + + end + + def down + end +end diff --git a/spec/factories/shixun_service_configs.rb b/spec/factories/shixun_service_configs.rb new file mode 100644 index 00000000..e1467908 --- /dev/null +++ b/spec/factories/shixun_service_configs.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :shixun_service_config do + + end +end diff --git a/spec/models/shixun_service_config_spec.rb b/spec/models/shixun_service_config_spec.rb new file mode 100644 index 00000000..ca83dde1 --- /dev/null +++ b/spec/models/shixun_service_config_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ShixunServiceConfig, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end