|
|
|
|
class CreateShixunService < ApplicationService
|
|
|
|
|
attr_reader :user, :params, :permit_params
|
|
|
|
|
|
|
|
|
|
def initialize(user, permit_params, params)
|
|
|
|
|
@user = user
|
|
|
|
|
@params = params
|
|
|
|
|
@permit_params = permit_params
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def call
|
|
|
|
|
shixun = Shixun.new(permit_params)
|
|
|
|
|
identifier = Util::UUID.generate_identifier(Shixun, 8)
|
|
|
|
|
shixun.identifier= identifier
|
|
|
|
|
shixun.user_id = user.id
|
|
|
|
|
shixun.can_copy = 1
|
|
|
|
|
main_mirror = MirrorRepository.find params[:main_type]
|
|
|
|
|
sub_mirrors = MirrorRepository.where(id: params[:sub_type])
|
|
|
|
|
begin
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
shixun.save!
|
|
|
|
|
# 获取脚本内容
|
|
|
|
|
shixun_script = get_shixun_script(shixun, main_mirror, sub_mirrors)
|
|
|
|
|
# 创建额外信息
|
|
|
|
|
ShixunInfo.create!(shixun_id: shixun.id, evaluate_script: shixun_script, description: params[:description])
|
|
|
|
|
# 创建合作者
|
|
|
|
|
shixun.shixun_members.create!(user_id: user.id, role: 1)
|
|
|
|
|
# 创建镜像
|
|
|
|
|
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id)
|
|
|
|
|
# 创建主服务配置
|
|
|
|
|
config_params =
|
|
|
|
|
if shixun.is_jupyter?
|
|
|
|
|
{shixun_id: shixun.id, mirror_repository_id: main_mirror.id, cpu_limit: 2,
|
|
|
|
|
memory_limit: 1024, lower_cpu_limit: 0.2, request_limit: 100}
|
|
|
|
|
else
|
|
|
|
|
{shixun_id: shixun.id, mirror_repository_id: main_mirror.id}
|
|
|
|
|
end
|
|
|
|
|
ShixunServiceConfig.create!(config_params)
|
|
|
|
|
# 创建子镜像相关数据(实训镜像关联表,子镜像服务配置)
|
|
|
|
|
sub_mirrors.each do |sub|
|
|
|
|
|
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id)
|
|
|
|
|
# 实训子镜像服务配置
|
|
|
|
|
name = sub.name #查看镜像是否有名称,如果没有名称就不用服务配置
|
|
|
|
|
ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) if name.present?
|
|
|
|
|
end
|
|
|
|
|
# 创建版本库
|
|
|
|
|
repo_path = repo_namespace(user.login, shixun.identifier)
|
|
|
|
|
GitService.add_repository(repo_path: repo_path)
|
|
|
|
|
shixun.update_column(:repo_name, repo_path.split(".")[0])
|
|
|
|
|
# 如果是云上实验室,创建相关记录
|
|
|
|
|
if !Laboratory.current.main_site?
|
|
|
|
|
Laboratory.current.laboratory_shixuns.create!(shixun: shixun, ownership: true)
|
|
|
|
|
end
|
|
|
|
|
# 如果是jupyter,先创建一个目录,为了挂载(因为后续数据集,开启Pod后环境在没销毁前,你上传数据集是挂载不上目录的,因此要先创建目录,方便中间层挂载)
|
|
|
|
|
if shixun.is_jupyter?
|
|
|
|
|
folder = EduSetting.get('shixun_folder')
|
|
|
|
|
path = "#{folder}/#{identifier}"
|
|
|
|
|
FileUtils.mkdir_p(path, :mode => 0777) unless File.directory?(path)
|
|
|
|
|
end
|
|
|
|
|
return shixun
|
|
|
|
|
end
|
|
|
|
|
rescue => e
|
|
|
|
|
Rails.logger.error("shixun_create_error: #{e.message}")
|
|
|
|
|
raise("创建实训失败!")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
def get_shixun_script shixun, main_mirror, sub_mirrors
|
|
|
|
|
if !shixun.is_jupyter?
|
|
|
|
|
mirror = main_mirror.mirror_scripts
|
|
|
|
|
if main_mirror.blank?
|
|
|
|
|
modify_shixun_script shixun, mirror.first&.(:script)
|
|
|
|
|
else
|
|
|
|
|
sub_name = sub_mirrors.pluck(:type_name)
|
|
|
|
|
if main_mirror.type_name == "Java" && sub_name.include?("Mysql")
|
|
|
|
|
mirror.last.try(:script)
|
|
|
|
|
else
|
|
|
|
|
shixun_script = mirror.first&.script
|
|
|
|
|
modify_shixun_script shixun, shixun_script
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def modify_shixun_script shixun, script
|
|
|
|
|
if script.present?
|
|
|
|
|
source_class_name = []
|
|
|
|
|
challenge_program_name = []
|
|
|
|
|
shixun.challenges.map(&:exec_path).each do |exec_path|
|
|
|
|
|
challenge_program_name << "\"#{exec_path}\""
|
|
|
|
|
if shixun.main_mirror_name == "Java"
|
|
|
|
|
if exec_path.nil? || exec_path.split("src/")[1].nil?
|
|
|
|
|
source = "\"\""
|
|
|
|
|
else
|
|
|
|
|
source = "\"#{exec_path.split("src/")[1].split(".java")[0]}\""
|
|
|
|
|
end
|
|
|
|
|
logger.info("----source: #{source}")
|
|
|
|
|
source_class_name << source.gsub("/", ".") if source.present?
|
|
|
|
|
elsif shixun.main_mirror_name.try(:first) == "C#"
|
|
|
|
|
if exec_path.nil? || exec_path.split(".")[1].nil?
|
|
|
|
|
source = "\"\""
|
|
|
|
|
else
|
|
|
|
|
source = "\"#{exec_path.split(".")[0]}.exe\""
|
|
|
|
|
end
|
|
|
|
|
source_class_name << source if source.present?
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
script = if script.include?("sourceClassName") && script.include?("challengeProgramName")
|
|
|
|
|
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)")
|
|
|
|
|
else
|
|
|
|
|
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return script
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 版本库目录空间
|
|
|
|
|
def repo_namespace(user, shixun_identifier)
|
|
|
|
|
"#{user}/#{shixun_identifier}.git"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|