diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/controllers/concerns/acceleratorable.rb b/app/controllers/concerns/acceleratorable.rb new file mode 100644 index 000000000..9a11e46c2 --- /dev/null +++ b/app/controllers/concerns/acceleratorable.rb @@ -0,0 +1,28 @@ +module Acceleratorable + extend ActiveSupport::Concern + + def enable_accelerator?(clone_addr) + clone_addr.include?(github_domain) || clone_addr.include?(gitlab_domain) + end + + def accelerator_url(repo_name) + [accelerator_domain, accelerator_username, "#{repo_name}.git"].join('/') + end + + def github_domain + 'github.com' + end + + def gitlab_domain + 'gitlab.com' + end + + def accelerator_domain + Gitea.gitea_config[:accelerator]["domain"] + end + + def accelerator_username + Gitea.gitea_config[:accelerator]["access_key_id"] + end + +end \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index ca66b4361..e6abf98a4 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -2,6 +2,8 @@ class ProjectsController < ApplicationController include ApplicationHelper include OperateProjectAbilityAble include ProjectsHelper + include Acceleratorable + before_action :require_login, except: %i[index branches group_type_list simple show fork_users praise_users watch_users recommend about menu_list] before_action :load_project, except: %i[index group_type_list migrate create recommend] before_action :authorizate_user_can_edit_project!, only: %i[update] @@ -53,7 +55,23 @@ class ProjectsController < ApplicationController def migrate Projects::MigrateForm.new(mirror_params).validate! - @project = Projects::MigrateService.new(current_user, mirror_params).call + + @project = + if enable_accelerator?(mirror_params[:clone_addr]) + source_clone_url = mirror_params[:clone_addr] + uid_logger("########## 已动加速器 ##########") + result = Gitea::Accelerator::MigrateService.call(mirror_params) + if result[:status] == :success + Rails.logger.info "########## 加速镜像成功 ########## " + Projects::MigrateService.call(current_user, + mirror_params.merge(source_clone_url: source_clone_url, + clone_addr: accelerator_url(mirror_params[:repository_name]))) + else + Projects::MigrateService.call(current_user, mirror_params) + end + else + Projects::MigrateService.call(current_user, mirror_params) + end rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index aec4b38d7..c220701a1 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -34,15 +34,14 @@ module ProjectsHelper end def json_response(project, user) - # repo = project.repository - repo = Repository.includes(:mirror).select(:id, :mirror_url).find_by(project: project) + repo = Repository.includes(:mirror).select(:id, :mirror_url, :source_clone_url).find_by(project: project) tmp_json = {} unless project.common? tmp_json = tmp_json.merge({ mirror_status: repo.mirror_status, mirror_num: repo.mirror_num, - mirror_url: repo.mirror_url, + mirror_url: repo.source_clone_url || repo.mirror_url, first_sync: repo.first_sync? }) end diff --git a/app/models/project.rb b/app/models/project.rb index 170bae06a..b48680830 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,75 +1,76 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) default(""), not null -# description :text(4294967295) -# homepage :string(255) default("") -# is_public :boolean default("1"), not null -# parent_id :integer -# created_on :datetime -# updated_on :datetime -# identifier :string(255) -# status :integer default("1"), not null -# lft :integer -# rgt :integer -# inherit_members :boolean default("0"), not null -# project_type :integer default("0") -# hidden_repo :boolean default("0"), not null -# attachmenttype :integer default("1") -# user_id :integer -# dts_test :integer default("0") -# enterprise_name :string(255) -# organization_id :integer -# project_new_type :integer -# gpid :integer -# forked_from_project_id :integer -# forked_count :integer default("0") -# publish_resource :integer default("0") -# visits :integer default("0") -# hot :integer default("0") -# invite_code :string(255) -# qrcode :string(255) -# qrcode_expiretime :integer default("0") -# script :text(65535) -# training_status :integer default("0") -# rep_identifier :string(255) -# project_category_id :integer -# project_language_id :integer -# praises_count :integer default("0") -# watchers_count :integer default("0") -# issues_count :integer default("0") -# pull_requests_count :integer default("0") -# language :string(255) -# versions_count :integer default("0") -# issue_tags_count :integer default("0") -# closed_issues_count :integer default("0") -# open_devops :boolean default("0") -# gitea_webhook_id :integer -# open_devops_count :integer default("0") -# recommend :boolean default("0") -# platform :integer default("0") -# license_id :integer -# ignore_id :integer -# default_branch :string(255) default("master") -# website :string(255) -# lesson_url :string(255) -# -# Indexes -# -# index_projects_on_forked_from_project_id (forked_from_project_id) -# index_projects_on_identifier (identifier) -# index_projects_on_is_public (is_public) -# index_projects_on_lft (lft) -# index_projects_on_name (name) -# index_projects_on_platform (platform) -# index_projects_on_project_type (project_type) -# index_projects_on_recommend (recommend) -# index_projects_on_rgt (rgt) -# index_projects_on_status (status) -# index_projects_on_updated_on (updated_on) -# +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) default(""), not null +# description :text(4294967295) +# homepage :string(255) default("") +# is_public :boolean default("1"), not null +# parent_id :integer +# created_on :datetime +# updated_on :datetime +# identifier :string(255) +# status :integer default("1"), not null +# lft :integer +# rgt :integer +# inherit_members :boolean default("0"), not null +# project_type :integer default("0") +# hidden_repo :boolean default("0"), not null +# attachmenttype :integer default("1") +# user_id :integer +# dts_test :integer default("0") +# enterprise_name :string(255) +# organization_id :integer +# project_new_type :integer +# gpid :integer +# forked_from_project_id :integer +# forked_count :integer default("0") +# publish_resource :integer default("0") +# visits :integer default("0") +# hot :integer default("0") +# invite_code :string(255) +# qrcode :string(255) +# qrcode_expiretime :integer default("0") +# script :text(65535) +# training_status :integer default("0") +# rep_identifier :string(255) +# project_category_id :integer +# project_language_id :integer +# praises_count :integer default("0") +# watchers_count :integer default("0") +# issues_count :integer default("0") +# pull_requests_count :integer default("0") +# language :string(255) +# versions_count :integer default("0") +# issue_tags_count :integer default("0") +# closed_issues_count :integer default("0") +# open_devops :boolean default("0") +# gitea_webhook_id :integer +# open_devops_count :integer default("0") +# recommend :boolean default("0") +# platform :integer default("0") +# license_id :integer +# ignore_id :integer +# default_branch :string(255) default("master") +# website :string(255) +# lesson_url :string(255) +# +# Indexes +# +# index_projects_on_forked_from_project_id (forked_from_project_id) +# index_projects_on_identifier (identifier) +# index_projects_on_is_public (is_public) +# index_projects_on_lft (lft) +# index_projects_on_name (name) +# index_projects_on_platform (platform) +# index_projects_on_project_type (project_type) +# index_projects_on_recommend (recommend) +# index_projects_on_rgt (rgt) +# index_projects_on_status (status) +# index_projects_on_updated_on (updated_on) +# + class Project < ApplicationRecord include Matchable diff --git a/app/models/repository.rb b/app/models/repository.rb index 978bc3c57..f4556cea1 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -22,6 +22,8 @@ # version_releases_count :integer default("0") # fork_url :string(255) # is_mirror :boolean default("0") +# accelerator_url :string(255) default("") +# source_clone_url :string(255) default("") # # Indexes # diff --git a/app/services/gitea/accelerator/migrate_service.rb b/app/services/gitea/accelerator/migrate_service.rb new file mode 100644 index 000000000..afe35f139 --- /dev/null +++ b/app/services/gitea/accelerator/migrate_service.rb @@ -0,0 +1,146 @@ +class Gitea::Accelerator::MigrateService < ApplicationService + attr_reader :params + + # params description: + # { + # auth_username string + # clone_addr* string #clone地址 + # description string + # issues boolean + # labels boolean + # milestones boolean + # mirror boolean + # private boolean + # pull_requests boolean + # releases boolean + # repo_name* string #仓库名称 + # uid* integer($int64) #gitea用户id或组织id + # wiki boolean + # } + # EX: + # params = { + # clone_addr: 'xxx.com', + # repo_name: 'repo_name', + # uid: 2, + # private: false + # } + + def initialize(params) + @params = params + end + + def call + return error('[gitea:] accelerator config missing') if check_accelerator! + response = post(url, request_params) + + render_status(response) + end + + private + + def request_params + { + uid: access_uid, + clone_addr: params[:clone_addr], + repo_name: params[:repository_name], + auth_username: params[:auth_username], + auth_password: params[:auth_password], + mirror: ActiveModel::Type::Boolean.new.cast(params[:is_mirror]) + } + end + + def url + "/repos/migrate".freeze + end + + def post(url, params) + puts "[gitea] request params: #{params}" + puts "[gitea] access_username: #{access_username}" + puts "[gitea] access_password: #{access_password}" + conn.post do |req| + req.url full_url(url) + req.body = params.to_json + end + end + + def conn + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.response :logger # 显示日志 + req.adapter Faraday.default_adapter + req.basic_auth(access_username, access_password) + end + end + @client + end + + def base_url + accelerator["base_url"] + end + + def domain + accelerator["domain"] + end + + def api_url + [domain, base_url].join('') + end + + def full_url(api_rest, action='post') + url = [api_url, api_rest].join('').freeze + url = action === 'get' ? url : URI.escape(url) + puts "[gitea] request url: #{url}" + url + end + + def access_username + accelerator["access_key_id"] + end + + def access_password + accelerator["access_key_secret"] + end + + def access_uid + accelerator["access_admin_uid"] + end + + def accelerator + Gitea.gitea_config[:accelerator] + end + + def render_status(response) + puts "[gitea] response status: #{response.status}" + puts "[gitea] response body: #{response.body}" + case response.status + when 201 + success + when 403 + error('APIForbiddenError') + when 422 + error('APIValidationError') + end + end + + def error(message) + { + status: :error, + message: message, + data: nil + } + end + + def success(data=nil) + { + status: :success, + message: nil, + data: data + } + end + + def check_accelerator! + accelerator.blank? || access_username.blank? || access_password.blank? || domain.blank? + end +end \ No newline at end of file diff --git a/app/services/projects/migrate_service.rb b/app/services/projects/migrate_service.rb index d1e14088f..c5c2cf753 100644 --- a/app/services/projects/migrate_service.rb +++ b/app/services/projects/migrate_service.rb @@ -48,7 +48,8 @@ class Projects::MigrateService < ApplicationService user_id: params[:user_id], login: params[:auth_username], password: params[:auth_password], - is_mirror: params[:is_mirror] + is_mirror: params[:is_mirror], + source_clone_url: params[:source_clone_url] } end diff --git a/app/services/repositories/migrate_service.rb b/app/services/repositories/migrate_service.rb index 156777cc3..b737b2ef5 100644 --- a/app/services/repositories/migrate_service.rb +++ b/app/services/repositories/migrate_service.rb @@ -21,7 +21,9 @@ class Repositories::MigrateService < ApplicationService private def repository_params - params.merge(project_id: project.id, identifier: params[:identifier]) + params.merge(project_id: project.id, + identifier: params[:identifier], + source_clone_url: params[:source_clone_url]) end def gitea_repository_params diff --git a/app/views/repositories/detail.json.jbuilder b/app/views/repositories/detail.json.jbuilder index fc1dc830b..644a472ab 100644 --- a/app/views/repositories/detail.json.jbuilder +++ b/app/views/repositories/detail.json.jbuilder @@ -21,7 +21,7 @@ json.versions_count @project.versions_count #里程碑数量 json.version_releases_count @project.releases_size(@user.try(:id), "all") json.version_releasesed_count @project.releases_size(@user.try(:id), "released") #已发行的版本 json.permission render_permission(@user, @project) -json.mirror_url @project&.repository.mirror_url +json.mirror_url @project&.repository.source_clone_url json.mirror @project&.repository.mirror_url.present? json.type @project.numerical_for_project_type json.open_devops @project.open_devops? diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 823d8547e..b45c9532c 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -45,10 +45,16 @@ default: &default signature_key: 'test12345678' gitea: - access_key_id: 'root' - access_key_secret: '_Trustie_10010' - domain: 'https://testgitea.trustie.net' + access_key_id: '' + access_key_secret: '' + domain: 'https://testgit.trustie.net' base_url: '/api/v1' + accelerator: + access_key_id: '' + access_key_secret: '' + access_admin_uid: 1 + domain: 'https://testgit.trustie.net' + base_url: '/api/v1' production: diff --git a/db/migrate/20210429095016_add_accelerator_url_to_repositories.rb b/db/migrate/20210429095016_add_accelerator_url_to_repositories.rb new file mode 100644 index 000000000..0c33ef7b5 --- /dev/null +++ b/db/migrate/20210429095016_add_accelerator_url_to_repositories.rb @@ -0,0 +1,5 @@ +class AddAcceleratorUrlToRepositories < ActiveRecord::Migration[5.2] + def change + add_column :repositories, :accelerator_url, :string, default: "" + end +end diff --git a/db/migrate/20210429100619_add_source_clone_url_to_repositories.rb b/db/migrate/20210429100619_add_source_clone_url_to_repositories.rb new file mode 100644 index 000000000..a7f213037 --- /dev/null +++ b/db/migrate/20210429100619_add_source_clone_url_to_repositories.rb @@ -0,0 +1,5 @@ +class AddSourceCloneUrlToRepositories < ActiveRecord::Migration[5.2] + def change + add_column :repositories, :source_clone_url, :string, default: "" + end +end