# Conflicts: # routers/api/v1/repo/cloudbrain.gopull/1789/head
@@ -44,12 +44,6 @@ | |||||
-webkit-line-clamp: 2; | -webkit-line-clamp: 2; | ||||
-webkit-box-orient: vertical; | -webkit-box-orient: vertical; | ||||
} | } | ||||
.ui.label{ | |||||
font-weight: normal; | |||||
} | |||||
.active { | |||||
color: #0366D6 !important; | |||||
} | |||||
.opacity5{ opacity:0.5;} | .opacity5{ opacity:0.5;} | ||||
.radius15{ border-radius:1.5rem !important; } | .radius15{ border-radius:1.5rem !important; } | ||||
@@ -287,70 +281,6 @@ | |||||
position: relative; | position: relative; | ||||
} | } | ||||
/**seach**/ | |||||
/**搜索导航条适配窄屏**/ | |||||
.seachnav{ | |||||
overflow-x: auto; | |||||
overflow-y: hidden; | |||||
scrollbar-width: none; /* firefox */ | |||||
-ms-overflow-style: none; /* IE 10+ */ | |||||
} | |||||
.seachnav::-webkit-scrollbar { | |||||
display: none; /* Chrome Safari */ | |||||
} | |||||
.ui.green.button, .ui.green.buttons .button{ | |||||
background-color: #5BB973; | |||||
} | |||||
.seach .repos--seach{ | |||||
padding-bottom: 0; | |||||
border-bottom: none; | |||||
} | |||||
.seach .ui.secondary.pointing.menu{ | |||||
border-bottom: none; | |||||
} | |||||
.seach .ui.secondary.pointing.menu .item > i{ | |||||
margin-right: 5px; | |||||
} | |||||
.seach .ui.secondary.pointing.menu .active.item{ | |||||
border-bottom-width: 2px; | |||||
margin: 0 0 -1px; | |||||
} | |||||
.seach .ui.menu .active.item>.label { | |||||
background: #1684FC; | |||||
color: #FFF; | |||||
} | |||||
.seach .ui.menu .item>.label:not(.active.item>.label) { | |||||
background: #e8e8e8; | |||||
color: rgba(0,0,0,.6); | |||||
} | |||||
.highlight{ | |||||
color: red; | |||||
} | |||||
.ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||||
width: calc(100% - 3.0em); | |||||
margin-left: 0; | |||||
} | |||||
.seach .ui.list .list>.item .header, .seach .ui.list>.item .header{ | |||||
margin-bottom: 0.5em; | |||||
font-size: 1.4rem !important; | |||||
font-weight: normal; | |||||
} | |||||
.seach .time, .seach .time a{ | |||||
font-size: 12px; | |||||
color: grey; | |||||
} | |||||
.seach .list .item.members .ui.avatar.image { | |||||
width: 3.2em; | |||||
height: 3.2em; | |||||
} | |||||
.ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content { | |||||
width: calc(100% - 4.0em); | |||||
margin-left: 0; | |||||
} | |||||
@media only screen and (max-width: 767px) { | @media only screen and (max-width: 767px) { | ||||
.am-mt-30{ margin-top: 1.5rem !important;} | .am-mt-30{ margin-top: 1.5rem !important;} | ||||
.ui.secondary.hometop.segment{ | .ui.secondary.hometop.segment{ | ||||
@@ -57,6 +57,7 @@ const ( | |||||
ActionCreateInferenceTask // 28 | ActionCreateInferenceTask // 28 | ||||
ActionCreateBenchMarkTask //29 | ActionCreateBenchMarkTask //29 | ||||
ActionCreateNewModelTask //30 | ActionCreateNewModelTask //30 | ||||
ActionCreateGPUTrainTask //31 | |||||
) | ) | ||||
// Action represents user operation type and other information to | // Action represents user operation type and other information to | ||||
@@ -21,8 +21,16 @@ type JobType string | |||||
type ModelArtsJobStatus string | type ModelArtsJobStatus string | ||||
const ( | const ( | ||||
TypeCloudBrainOne int = iota | |||||
TypeCloudBrainTwo | |||||
TypeCloudBrainAll = -1 | |||||
) | |||||
const ( | |||||
NPUResource = "NPU" | NPUResource = "NPU" | ||||
GPUResource = "CPU/GPU" | GPUResource = "CPU/GPU" | ||||
AllResource = "all" | |||||
//notebook storage category | //notebook storage category | ||||
EVSCategory = "EVS" | EVSCategory = "EVS" | ||||
@@ -0,0 +1,186 @@ | |||||
DROP FOREIGN TABLE public.dataset_es; | |||||
CREATE FOREIGN TABLE public.dataset_es | |||||
( | |||||
id bigint NOT NULL, | |||||
title character varying(255), | |||||
status integer, | |||||
category character varying(255), | |||||
description text, | |||||
download_times bigint, | |||||
license character varying(255), | |||||
task character varying(255), | |||||
release_id bigint, | |||||
user_id bigint, | |||||
repo_id bigint, | |||||
created_unix bigint, | |||||
updated_unix bigint, | |||||
file_name text, | |||||
file_desc text | |||||
)SERVER multicorn_es | |||||
OPTIONS | |||||
( | |||||
host '192.168.207.94', | |||||
port '9200', | |||||
index 'dataset-es-index', | |||||
rowid_column 'id', | |||||
default_sort '_id' | |||||
) | |||||
; | |||||
DELETE FROM public.dataset_es; | |||||
INSERT INTO public.dataset_es( | |||||
id, | |||||
title, | |||||
status, | |||||
category, | |||||
description, | |||||
download_times, | |||||
license, task, | |||||
release_id, | |||||
user_id, | |||||
repo_id, | |||||
created_unix, | |||||
updated_unix, | |||||
file_name, | |||||
file_desc | |||||
) | |||||
SELECT | |||||
b.id, | |||||
b.title, | |||||
b.status, | |||||
b.category, | |||||
b.description, | |||||
b.download_times, | |||||
b.license, | |||||
b.task, | |||||
b.release_id, | |||||
b.user_id, | |||||
b.repo_id, | |||||
b.created_unix, | |||||
b.updated_unix, | |||||
(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false), | |||||
(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false) | |||||
FROM public.dataset b,public.repository c where b.repo_id=c.id and c.is_private=false; | |||||
DROP TRIGGER IF EXISTS es_insert_dataset on public.dataset; | |||||
CREATE OR REPLACE FUNCTION public.insert_dataset_data() RETURNS trigger AS | |||||
$def$ | |||||
DECLARE | |||||
privateValue boolean=false; | |||||
BEGIN | |||||
select into privateValue is_private from public.repository where id=NEW.repo_id; | |||||
if not privateValue then | |||||
INSERT INTO public.dataset_es( | |||||
id, | |||||
title, | |||||
status, | |||||
category, | |||||
description, | |||||
download_times, | |||||
license, | |||||
task, | |||||
release_id, | |||||
user_id, | |||||
repo_id, | |||||
created_unix, | |||||
updated_unix) | |||||
VALUES ( | |||||
NEW.id, | |||||
NEW.title, | |||||
NEW.status, | |||||
NEW.category, | |||||
NEW.description, | |||||
NEW.download_times, | |||||
NEW.license, | |||||
NEW.task, | |||||
NEW.release_id, | |||||
NEW.user_id, | |||||
NEW.repo_id, | |||||
NEW.created_unix, | |||||
NEW.updated_unix | |||||
); | |||||
end if; | |||||
RETURN NEW; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_insert_dataset | |||||
AFTER INSERT ON public.dataset | |||||
FOR EACH ROW EXECUTE PROCEDURE insert_dataset_data(); | |||||
ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_insert_dataset; | |||||
DROP TRIGGER IF EXISTS es_udpate_dataset_file_name on public.attachment; | |||||
CREATE OR REPLACE FUNCTION public.udpate_dataset_file_name() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
if (TG_OP = 'UPDATE') then | |||||
update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id; | |||||
elsif (TG_OP = 'INSERT') then | |||||
update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id; | |||||
elsif (TG_OP = 'DELETE') then | |||||
update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id; | |||||
update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id; | |||||
end if; | |||||
return NEW; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_udpate_dataset_file_name | |||||
AFTER INSERT OR UPDATE OR DELETE ON public.attachment | |||||
FOR EACH ROW EXECUTE PROCEDURE udpate_dataset_file_name(); | |||||
ALTER TABLE public.attachment ENABLE ALWAYS TRIGGER es_udpate_dataset_file_name; | |||||
DROP TRIGGER IF EXISTS es_update_dataset on public.dataset; | |||||
CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
UPDATE public.dataset_es | |||||
SET description=NEW.description, | |||||
title=NEW.title, | |||||
category=NEW.category, | |||||
task=NEW.task, | |||||
download_times=NEW.download_times, | |||||
updated_unix=NEW.updated_unix, | |||||
file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false), | |||||
file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false) | |||||
where id=NEW.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_update_dataset | |||||
AFTER UPDATE ON public.dataset | |||||
FOR EACH ROW EXECUTE PROCEDURE update_dataset(); | |||||
ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_update_dataset; | |||||
DROP TRIGGER IF EXISTS es_delete_dataset on public.dataset; | |||||
CREATE OR REPLACE FUNCTION public.delete_dataset() RETURNS trigger AS | |||||
$def$ | |||||
declare | |||||
BEGIN | |||||
DELETE FROM public.dataset_es where id=OLD.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_delete_dataset | |||||
AFTER DELETE ON public.dataset | |||||
FOR EACH ROW EXECUTE PROCEDURE delete_dataset(); | |||||
ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_delete_dataset; |
@@ -0,0 +1,215 @@ | |||||
DROP FOREIGN TABLE public.issue_es; | |||||
CREATE FOREIGN TABLE public.issue_es | |||||
( | |||||
id bigint NOT NULL, | |||||
repo_id bigint, | |||||
index bigint, | |||||
poster_id bigint, | |||||
original_author character varying(255), | |||||
original_author_id bigint, | |||||
name character varying(255) , | |||||
content text, | |||||
comment text, | |||||
milestone_id bigint, | |||||
priority integer, | |||||
is_closed boolean, | |||||
is_pull boolean, | |||||
pr_id bigint, | |||||
num_comments integer, | |||||
ref character varying(255), | |||||
deadline_unix bigint, | |||||
created_unix bigint, | |||||
updated_unix bigint, | |||||
closed_unix bigint, | |||||
is_locked boolean NOT NULL, | |||||
amount bigint, | |||||
is_transformed boolean NOT NULL | |||||
)SERVER multicorn_es | |||||
OPTIONS | |||||
( | |||||
host '192.168.207.94', | |||||
port '9200', | |||||
index 'issue-es-index', | |||||
rowid_column 'id', | |||||
default_sort '_id' | |||||
) | |||||
; | |||||
delete from public.issue_es; | |||||
INSERT INTO public.issue_es( | |||||
id, | |||||
repo_id, | |||||
index, | |||||
poster_id, | |||||
original_author, | |||||
original_author_id, | |||||
name, | |||||
content, | |||||
milestone_id, | |||||
priority, | |||||
is_closed, | |||||
is_pull, | |||||
num_comments, | |||||
ref, | |||||
deadline_unix, | |||||
created_unix, | |||||
updated_unix, | |||||
closed_unix, | |||||
is_locked, | |||||
amount, | |||||
is_transformed,comment,pr_id) | |||||
SELECT | |||||
b.id, | |||||
b.repo_id, | |||||
b.index, | |||||
b.poster_id, | |||||
b.original_author, | |||||
b.original_author_id, | |||||
b.name, | |||||
b.content, | |||||
b.milestone_id, | |||||
b.priority, | |||||
b.is_closed, | |||||
b.is_pull, | |||||
b.num_comments, | |||||
b.ref, | |||||
b.deadline_unix, | |||||
b.created_unix, | |||||
b.updated_unix, | |||||
b.closed_unix, | |||||
b.is_locked, | |||||
b.amount, | |||||
b.is_transformed, | |||||
(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id), | |||||
(select id from public.pull_request d where b.id=d.issue_id and b.is_pull=true) | |||||
FROM public.issue b,public.repository c where b.repo_id=c.id and c.is_private=false; | |||||
CREATE OR REPLACE FUNCTION public.insert_issue_data() RETURNS trigger AS | |||||
$def$ | |||||
DECLARE | |||||
privateValue boolean=false; | |||||
BEGIN | |||||
select into privateValue is_private from public.repository where id=NEW.repo_id; | |||||
if not privateValue then | |||||
INSERT INTO public.issue_es( | |||||
id, | |||||
repo_id, | |||||
index, | |||||
poster_id, | |||||
original_author, | |||||
original_author_id, | |||||
name, | |||||
content, | |||||
milestone_id, | |||||
priority, | |||||
is_closed, | |||||
is_pull, | |||||
num_comments, | |||||
ref, | |||||
deadline_unix, | |||||
created_unix, | |||||
updated_unix, | |||||
closed_unix, | |||||
is_locked, | |||||
amount, | |||||
is_transformed) | |||||
VALUES ( | |||||
NEW.id, | |||||
NEW.repo_id, | |||||
NEW.index, | |||||
NEW.poster_id, | |||||
NEW.original_author, | |||||
NEW.original_author_id, | |||||
NEW.name, | |||||
NEW.content, | |||||
NEW.milestone_id, | |||||
NEW.priority, | |||||
NEW.is_closed, | |||||
NEW.is_pull, | |||||
NEW.num_comments, | |||||
NEW.ref, | |||||
NEW.deadline_unix, | |||||
NEW.created_unix, | |||||
NEW.updated_unix, | |||||
NEW.closed_unix, | |||||
NEW.is_locked, | |||||
NEW.amount, | |||||
NEW.is_transformed | |||||
); | |||||
end if; | |||||
RETURN NEW; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
DROP TRIGGER IF EXISTS es_insert_issue on public.issue; | |||||
CREATE TRIGGER es_insert_issue | |||||
AFTER INSERT ON public.issue | |||||
FOR EACH ROW EXECUTE PROCEDURE insert_issue_data(); | |||||
ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_insert_issue; | |||||
CREATE OR REPLACE FUNCTION public.udpate_issue_comment() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
if (TG_OP = 'DELETE') then | |||||
update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=OLD.issue_id) where id=OLD.issue_id; | |||||
elsif (TG_OP = 'UPDATE') then | |||||
update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.issue_id) where id=NEW.issue_id; | |||||
end if; | |||||
return null; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
DROP TRIGGER IF EXISTS es_udpate_issue_comment on public.comment; | |||||
CREATE TRIGGER es_udpate_issue_comment | |||||
AFTER DELETE OR UPDATE ON public.comment | |||||
FOR EACH ROW EXECUTE PROCEDURE udpate_issue_comment(); | |||||
ALTER TABLE public.comment ENABLE ALWAYS TRIGGER es_udpate_issue_comment; | |||||
CREATE OR REPLACE FUNCTION public.update_issue() RETURNS trigger AS | |||||
$def$ | |||||
declare | |||||
BEGIN | |||||
UPDATE public.issue_es | |||||
SET content=NEW.content, | |||||
name=NEW.name, | |||||
is_closed=NEW.is_closed, | |||||
num_comments=NEW.num_comments, | |||||
comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.id) | |||||
where id=NEW.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
DROP TRIGGER IF EXISTS es_update_issue on public.issue; | |||||
CREATE TRIGGER es_update_issue | |||||
AFTER UPDATE ON public.issue | |||||
FOR EACH ROW EXECUTE PROCEDURE update_issue(); | |||||
ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_update_issue; | |||||
CREATE OR REPLACE FUNCTION public.delete_issue() RETURNS trigger AS | |||||
$def$ | |||||
declare | |||||
BEGIN | |||||
DELETE FROM public.issue_es where id=OLD.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
DROP TRIGGER IF EXISTS es_delete_issue on public.issue; | |||||
CREATE TRIGGER es_delete_issue | |||||
AFTER DELETE ON public.issue | |||||
FOR EACH ROW EXECUTE PROCEDURE delete_issue(); | |||||
ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_delete_issue; |
@@ -0,0 +1,532 @@ | |||||
-- 要处理项目从私有变为公有,并且从公有变成私有的情况 | |||||
DROP FOREIGN table if exists public.repository_es; | |||||
CREATE FOREIGN TABLE public.repository_es ( | |||||
id bigint NOT NULL, | |||||
owner_id bigint, | |||||
owner_name character varying(255), | |||||
lower_name character varying(255) NOT NULL, | |||||
name character varying(255) NOT NULL, | |||||
description text, | |||||
website character varying(2048), | |||||
original_service_type integer, | |||||
original_url character varying(2048), | |||||
default_branch character varying(255), | |||||
num_watches integer, | |||||
num_stars integer, | |||||
num_forks integer, | |||||
num_issues integer, | |||||
num_closed_issues integer, | |||||
num_pulls integer, | |||||
num_closed_pulls integer, | |||||
num_milestones integer DEFAULT 0 NOT NULL, | |||||
num_closed_milestones integer DEFAULT 0 NOT NULL, | |||||
is_private boolean, | |||||
is_empty boolean, | |||||
is_archived boolean, | |||||
is_mirror boolean, | |||||
status integer DEFAULT 0 NOT NULL, | |||||
is_fork boolean DEFAULT false NOT NULL, | |||||
fork_id bigint, | |||||
is_template boolean DEFAULT false NOT NULL, | |||||
template_id bigint, | |||||
size bigint DEFAULT 0 NOT NULL, | |||||
is_fsck_enabled boolean DEFAULT true NOT NULL, | |||||
close_issues_via_commit_in_any_branch boolean DEFAULT false NOT NULL, | |||||
topics text, | |||||
avatar character varying(64), | |||||
created_unix bigint, | |||||
updated_unix bigint, | |||||
contract_address character varying(255), | |||||
block_chain_status integer DEFAULT 0 NOT NULL, | |||||
balance character varying(255) DEFAULT '0'::character varying NOT NULL, | |||||
clone_cnt bigint DEFAULT 0 NOT NULL, | |||||
license character varying(100), | |||||
download_cnt bigint DEFAULT 0 NOT NULL, | |||||
num_commit bigint DEFAULT 0 NOT NULL, | |||||
git_clone_cnt bigint DEFAULT 0 NOT NULL, | |||||
creator_id bigint NOT NULL DEFAULT 0, | |||||
repo_type integer NOT NULL DEFAULT 0, | |||||
lang character varying(2048), | |||||
alias character varying(255), | |||||
lower_alias character varying(255) | |||||
) SERVER multicorn_es | |||||
OPTIONS | |||||
( | |||||
host '192.168.207.94', | |||||
port '9200', | |||||
index 'repository-es-index', | |||||
rowid_column 'id', | |||||
default_sort '_id' | |||||
) | |||||
; | |||||
delete from public.repository_es; | |||||
INSERT INTO public.repository_es (id, | |||||
owner_id, | |||||
owner_name, | |||||
lower_name, | |||||
name, | |||||
description, | |||||
website, | |||||
original_service_type, | |||||
original_url, | |||||
default_branch, | |||||
num_watches, | |||||
num_stars, | |||||
num_forks, | |||||
num_issues, | |||||
num_closed_issues, | |||||
num_pulls, | |||||
num_closed_pulls, | |||||
num_milestones, | |||||
num_closed_milestones, | |||||
is_private, | |||||
is_empty, | |||||
is_archived, | |||||
is_mirror, | |||||
status, | |||||
is_fork, | |||||
fork_id, | |||||
is_template, | |||||
template_id, | |||||
size, | |||||
is_fsck_enabled, | |||||
close_issues_via_commit_in_any_branch, | |||||
topics, | |||||
avatar, | |||||
created_unix, | |||||
updated_unix, | |||||
contract_address, | |||||
block_chain_status, | |||||
balance, | |||||
clone_cnt, | |||||
num_commit, | |||||
git_clone_cnt, | |||||
creator_id, | |||||
repo_type, | |||||
lang, | |||||
alias, | |||||
lower_alias | |||||
) | |||||
SELECT | |||||
id, | |||||
owner_id, | |||||
owner_name, | |||||
lower_name, | |||||
name, | |||||
description, | |||||
website, | |||||
original_service_type, | |||||
original_url, | |||||
default_branch, | |||||
num_watches, | |||||
num_stars, | |||||
num_forks, | |||||
num_issues, | |||||
num_closed_issues, | |||||
num_pulls, | |||||
num_closed_pulls, | |||||
num_milestones, | |||||
num_closed_milestones, | |||||
is_private, | |||||
is_empty, | |||||
is_archived, | |||||
is_mirror, | |||||
status, | |||||
is_fork, | |||||
fork_id, | |||||
is_template, | |||||
template_id, | |||||
size, | |||||
is_fsck_enabled, | |||||
close_issues_via_commit_in_any_branch, | |||||
topics, | |||||
avatar, | |||||
created_unix, | |||||
updated_unix, | |||||
contract_address, | |||||
block_chain_status, | |||||
balance, | |||||
clone_cnt, | |||||
num_commit, | |||||
git_clone_cnt, | |||||
creator_id, | |||||
repo_type, | |||||
(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id), | |||||
alias, | |||||
lower_alias | |||||
FROM public.repository b where b.is_private=false; | |||||
DROP TRIGGER IF EXISTS es_insert_repository on public.repository; | |||||
CREATE OR REPLACE FUNCTION public.insert_repository_data() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
if not NEW.is_private then | |||||
INSERT INTO public.repository_es (id, | |||||
owner_id, | |||||
owner_name, | |||||
lower_name, | |||||
name, | |||||
description, | |||||
website, | |||||
original_service_type, | |||||
original_url, | |||||
default_branch, | |||||
num_watches, | |||||
num_stars, | |||||
num_forks, | |||||
num_issues, | |||||
num_closed_issues, | |||||
num_pulls, | |||||
num_closed_pulls, | |||||
num_milestones, | |||||
num_closed_milestones, | |||||
is_private, | |||||
is_empty, | |||||
is_archived, | |||||
is_mirror, | |||||
status, | |||||
is_fork, | |||||
fork_id, | |||||
is_template, | |||||
template_id, | |||||
size, | |||||
is_fsck_enabled, | |||||
close_issues_via_commit_in_any_branch, | |||||
topics, | |||||
avatar, | |||||
created_unix, | |||||
updated_unix, | |||||
contract_address, | |||||
block_chain_status, | |||||
balance, | |||||
clone_cnt, | |||||
num_commit, | |||||
git_clone_cnt, | |||||
creator_id, | |||||
repo_type, | |||||
alias, | |||||
lower_alias) VALUES | |||||
(NEW.id, | |||||
NEW.owner_id, | |||||
NEW.owner_name, | |||||
NEW.lower_name, | |||||
NEW.name, | |||||
NEW.description, | |||||
NEW.website, | |||||
NEW.original_service_type, | |||||
NEW.original_url, | |||||
NEW.default_branch, | |||||
NEW.num_watches, | |||||
NEW.num_stars, | |||||
NEW.num_forks, | |||||
NEW.num_issues, | |||||
NEW.num_closed_issues, | |||||
NEW.num_pulls, | |||||
NEW.num_closed_pulls, | |||||
NEW.num_milestones, | |||||
NEW.num_closed_milestones, | |||||
NEW.is_private, | |||||
NEW.is_empty, | |||||
NEW.is_archived, | |||||
NEW.is_mirror, | |||||
NEW.status, | |||||
NEW.is_fork, | |||||
NEW.fork_id, | |||||
NEW.is_template, | |||||
NEW.template_id, | |||||
NEW.size, | |||||
NEW.is_fsck_enabled, | |||||
NEW.close_issues_via_commit_in_any_branch, | |||||
NEW.topics, | |||||
NEW.avatar, | |||||
NEW.created_unix, | |||||
NEW.updated_unix, | |||||
NEW.contract_address, | |||||
NEW.block_chain_status, | |||||
NEW.balance, | |||||
NEW.clone_cnt, | |||||
NEW.num_commit, | |||||
NEW.git_clone_cnt, | |||||
NEW.creator_id, | |||||
NEW.repo_type, | |||||
NEW.alias, | |||||
NEW.lower_alias); | |||||
end if; | |||||
RETURN NEW; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_insert_repository | |||||
AFTER INSERT ON public.repository | |||||
FOR EACH ROW EXECUTE PROCEDURE insert_repository_data(); | |||||
ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_insert_repository; | |||||
DROP TRIGGER IF EXISTS es_update_repository on public.repository; | |||||
CREATE OR REPLACE FUNCTION public.update_repository() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
if OLD.is_private != NEW.is_private then | |||||
if OLD.is_private and not NEW.is_private then | |||||
--insert | |||||
INSERT INTO public.repository_es (id, | |||||
owner_id, | |||||
owner_name, | |||||
lower_name, | |||||
name, | |||||
description, | |||||
website, | |||||
original_service_type, | |||||
original_url, | |||||
default_branch, | |||||
num_watches, | |||||
num_stars, | |||||
num_forks, | |||||
num_issues, | |||||
num_closed_issues, | |||||
num_pulls, | |||||
num_closed_pulls, | |||||
num_milestones, | |||||
num_closed_milestones, | |||||
is_private, | |||||
is_empty, | |||||
is_archived, | |||||
is_mirror, | |||||
status, | |||||
is_fork, | |||||
fork_id, | |||||
is_template, | |||||
template_id, | |||||
size, | |||||
is_fsck_enabled, | |||||
close_issues_via_commit_in_any_branch, | |||||
topics, | |||||
avatar, | |||||
created_unix, | |||||
updated_unix, | |||||
contract_address, | |||||
block_chain_status, | |||||
balance, | |||||
clone_cnt, | |||||
num_commit, | |||||
git_clone_cnt, | |||||
creator_id, | |||||
repo_type, | |||||
lang, | |||||
alias, | |||||
lower_alias) | |||||
SELECT | |||||
id, | |||||
owner_id, | |||||
owner_name, | |||||
lower_name, | |||||
name, | |||||
description, | |||||
website, | |||||
original_service_type, | |||||
original_url, | |||||
default_branch, | |||||
num_watches, | |||||
num_stars, | |||||
num_forks, | |||||
num_issues, | |||||
num_closed_issues, | |||||
num_pulls, | |||||
num_closed_pulls, | |||||
num_milestones, | |||||
num_closed_milestones, | |||||
is_private, | |||||
is_empty, | |||||
is_archived, | |||||
is_mirror, | |||||
status, | |||||
is_fork, | |||||
fork_id, | |||||
is_template, | |||||
template_id, | |||||
size, | |||||
is_fsck_enabled, | |||||
close_issues_via_commit_in_any_branch, | |||||
topics, | |||||
avatar, | |||||
created_unix, | |||||
updated_unix, | |||||
contract_address, | |||||
block_chain_status, | |||||
balance, | |||||
clone_cnt, | |||||
num_commit, | |||||
git_clone_cnt, | |||||
creator_id, | |||||
repo_type, | |||||
(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id), | |||||
alias, | |||||
lower_alias | |||||
FROM public.repository b where b.id=NEW.id; | |||||
INSERT INTO public.dataset_es( | |||||
id, | |||||
title, | |||||
status, | |||||
category, | |||||
description, | |||||
download_times, | |||||
license, task, | |||||
release_id, | |||||
user_id, | |||||
repo_id, | |||||
created_unix, | |||||
updated_unix,file_name) | |||||
SELECT | |||||
b.id, | |||||
b.title, | |||||
b.status, | |||||
b.category, | |||||
b.description, | |||||
b.download_times, | |||||
b.license, | |||||
b.task, | |||||
b.release_id, | |||||
b.user_id, | |||||
b.repo_id, | |||||
b.created_unix, | |||||
b.updated_unix,(select array_to_string(array_agg(name order by created_unix desc),',') from public.attachment a where a.dataset_id=b.id and a.is_private=false) | |||||
FROM public.dataset b where b.repo_id=NEW.id; | |||||
INSERT INTO public.issue_es( | |||||
id, | |||||
repo_id, | |||||
index, | |||||
poster_id, | |||||
original_author, | |||||
original_author_id, | |||||
name, | |||||
content, | |||||
milestone_id, | |||||
priority, | |||||
is_closed, | |||||
is_pull, | |||||
num_comments, | |||||
ref, | |||||
deadline_unix, | |||||
created_unix, | |||||
updated_unix, | |||||
closed_unix, | |||||
is_locked, | |||||
amount, | |||||
is_transformed,comment,pr_id) | |||||
SELECT | |||||
b.id, | |||||
b.repo_id, | |||||
b.index, | |||||
b.poster_id, | |||||
b.original_author, | |||||
b.original_author_id, | |||||
b.name, | |||||
b.content, | |||||
b.milestone_id, | |||||
b.priority, | |||||
b.is_closed, | |||||
b.is_pull, | |||||
b.num_comments, | |||||
b.ref, | |||||
b.deadline_unix, | |||||
b.created_unix, | |||||
b.updated_unix, | |||||
b.closed_unix, | |||||
b.is_locked, | |||||
b.amount, | |||||
b.is_transformed, | |||||
(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id), | |||||
(select id from public.pull_request d where d.issue_id=b.id) | |||||
FROM public.issue b where b.repo_id=NEW.id; | |||||
end if; | |||||
if not OLD.is_private and NEW.is_private then | |||||
delete from public.issue_es where repo_id=NEW.id; | |||||
delete from public.dataset_es where repo_id=NEW.id; | |||||
delete from public.repository_es where id=NEW.id; | |||||
end if; | |||||
end if; | |||||
if not NEW.is_private then | |||||
raise notice 'update repo,the updated_unix is %',NEW.updated_unix; | |||||
update public.repository_es SET description=NEW.description, | |||||
name=NEW.name, | |||||
lower_name=NEW.lower_name, | |||||
owner_name=NEW.owner_name, | |||||
website=NEW.website, | |||||
updated_unix=NEW.updated_unix, | |||||
num_watches=NEW.num_watches, | |||||
num_stars=NEW.num_stars, | |||||
num_forks=NEW.num_forks, | |||||
topics=NEW.topics, | |||||
alias = NEW.alias, | |||||
lower_alias = NEW.lower_alias, | |||||
avatar=NEW.avatar | |||||
where id=NEW.id; | |||||
end if; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_update_repository | |||||
AFTER UPDATE ON public.repository | |||||
FOR EACH ROW EXECUTE PROCEDURE update_repository(); | |||||
ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_update_repository; | |||||
DROP TRIGGER IF EXISTS es_delete_repository on public.repository; | |||||
CREATE OR REPLACE FUNCTION public.delete_repository() RETURNS trigger AS | |||||
$def$ | |||||
declare | |||||
BEGIN | |||||
delete from public.issue_es where repo_id=OLD.id; | |||||
delete from public.dataset_es where repo_id=OLD.id; | |||||
DELETE FROM public.repository_es where id=OLD.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_delete_repository | |||||
AFTER DELETE ON public.repository | |||||
FOR EACH ROW EXECUTE PROCEDURE delete_repository(); | |||||
ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_delete_repository; | |||||
DROP TRIGGER IF EXISTS es_udpate_repository_lang on public.language_stat; | |||||
CREATE OR REPLACE FUNCTION public.udpate_repository_lang() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
if (TG_OP = 'UPDATE') then | |||||
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||||
elsif (TG_OP = 'INSERT') then | |||||
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||||
elsif (TG_OP = 'DELETE') then | |||||
if exists(select 1 from public.repository where id=OLD.repo_id) then | |||||
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id; | |||||
end if; | |||||
end if; | |||||
return null; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_udpate_repository_lang | |||||
AFTER INSERT OR UPDATE OR DELETE ON public.language_stat | |||||
FOR EACH ROW EXECUTE PROCEDURE udpate_repository_lang(); | |||||
ALTER TABLE public.language_stat ENABLE ALWAYS TRIGGER es_udpate_repository_lang; |
@@ -0,0 +1,308 @@ | |||||
DROP FOREIGN table if exists public.user_es; | |||||
CREATE FOREIGN TABLE public.user_es | |||||
( | |||||
id bigint NOT NULL , | |||||
lower_name character varying(255) NULL, | |||||
name character varying(255) NULL, | |||||
full_name character varying(255), | |||||
email character varying(255), | |||||
keep_email_private boolean, | |||||
email_notifications_preference character varying(20) , | |||||
passwd character varying(255) , | |||||
passwd_hash_algo character varying(255) , | |||||
must_change_password boolean NOT NULL DEFAULT false, | |||||
login_type integer, | |||||
login_source bigint NOT NULL DEFAULT 0, | |||||
login_name character varying(255) , | |||||
type integer, | |||||
location character varying(255), | |||||
website character varying(255), | |||||
rands character varying(10), | |||||
salt character varying(10), | |||||
language character varying(5), | |||||
description character varying(255), | |||||
created_unix bigint, | |||||
updated_unix bigint, | |||||
last_login_unix bigint, | |||||
last_repo_visibility boolean, | |||||
max_repo_creation integer, | |||||
is_active boolean, | |||||
is_admin boolean, | |||||
is_restricted boolean NOT NULL DEFAULT false, | |||||
allow_git_hook boolean, | |||||
allow_import_local boolean, | |||||
allow_create_organization boolean DEFAULT true, | |||||
prohibit_login boolean NOT NULL DEFAULT false, | |||||
avatar character varying(2048) , | |||||
avatar_email character varying(255), | |||||
use_custom_avatar boolean, | |||||
num_followers integer, | |||||
num_following integer NOT NULL DEFAULT 0, | |||||
num_stars integer, | |||||
num_repos integer, | |||||
num_teams integer, | |||||
num_members integer, | |||||
visibility integer NOT NULL DEFAULT 0, | |||||
repo_admin_change_team_access boolean NOT NULL DEFAULT false, | |||||
diff_view_style character varying(255), | |||||
theme character varying(255), | |||||
token character varying(1024) , | |||||
public_key character varying(255), | |||||
private_key character varying(255), | |||||
is_operator boolean NOT NULL DEFAULT false, | |||||
num_dataset_stars integer NOT NULL DEFAULT 0 | |||||
) SERVER multicorn_es | |||||
OPTIONS | |||||
( | |||||
host '192.168.207.94', | |||||
port '9200', | |||||
index 'user-es-index', | |||||
rowid_column 'id', | |||||
default_sort '_id' | |||||
) | |||||
; | |||||
delete from public.user_es; | |||||
INSERT INTO public.user_es( | |||||
id, | |||||
lower_name, | |||||
name, | |||||
full_name, | |||||
email, | |||||
keep_email_private, | |||||
email_notifications_preference, | |||||
must_change_password, | |||||
login_type, | |||||
login_source, | |||||
login_name, | |||||
type, | |||||
location, | |||||
website, | |||||
rands, | |||||
language, | |||||
description, | |||||
created_unix, | |||||
updated_unix, | |||||
last_login_unix, | |||||
last_repo_visibility, | |||||
max_repo_creation, | |||||
is_active, | |||||
is_restricted, | |||||
allow_git_hook, | |||||
allow_import_local, | |||||
allow_create_organization, | |||||
prohibit_login, | |||||
avatar, | |||||
avatar_email, | |||||
use_custom_avatar, | |||||
num_followers, | |||||
num_following, | |||||
num_stars, | |||||
num_repos, | |||||
num_teams, | |||||
num_members, | |||||
visibility, | |||||
repo_admin_change_team_access, | |||||
diff_view_style, | |||||
theme, | |||||
is_operator, | |||||
num_dataset_stars) | |||||
SELECT | |||||
id, | |||||
lower_name, | |||||
name, | |||||
full_name, | |||||
email, | |||||
keep_email_private, | |||||
email_notifications_preference, | |||||
must_change_password, | |||||
login_type, | |||||
login_source, | |||||
login_name, | |||||
type, | |||||
location, | |||||
website, | |||||
rands, | |||||
language, | |||||
description, | |||||
created_unix, | |||||
updated_unix, | |||||
last_login_unix, | |||||
last_repo_visibility, | |||||
max_repo_creation, | |||||
is_active, | |||||
is_restricted, | |||||
allow_git_hook, | |||||
allow_import_local, | |||||
allow_create_organization, | |||||
prohibit_login, | |||||
avatar, | |||||
avatar_email, | |||||
use_custom_avatar, | |||||
num_followers, | |||||
num_following, | |||||
num_stars, | |||||
num_repos, | |||||
num_teams, | |||||
num_members, | |||||
visibility, | |||||
repo_admin_change_team_access, | |||||
diff_view_style, | |||||
theme, | |||||
is_operator, | |||||
num_dataset_stars | |||||
FROM public.user; | |||||
DROP TRIGGER IF EXISTS es_insert_user on public.user; | |||||
CREATE OR REPLACE FUNCTION public.insert_user_data() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
INSERT INTO public."user_es"( | |||||
id, | |||||
lower_name, | |||||
name, | |||||
full_name, | |||||
email, | |||||
keep_email_private, | |||||
email_notifications_preference, | |||||
must_change_password, | |||||
login_type, | |||||
login_source, | |||||
login_name, | |||||
type, | |||||
location, | |||||
website, | |||||
rands, | |||||
language, | |||||
description, | |||||
created_unix, | |||||
updated_unix, | |||||
last_login_unix, | |||||
last_repo_visibility, | |||||
max_repo_creation, | |||||
is_active, | |||||
is_restricted, | |||||
allow_git_hook, | |||||
allow_import_local, | |||||
allow_create_organization, | |||||
prohibit_login, | |||||
avatar, | |||||
avatar_email, | |||||
use_custom_avatar, | |||||
num_followers, | |||||
num_following, | |||||
num_stars, | |||||
num_repos, | |||||
num_teams, | |||||
num_members, | |||||
visibility, | |||||
repo_admin_change_team_access, | |||||
diff_view_style, | |||||
theme, | |||||
is_operator, | |||||
num_dataset_stars) | |||||
VALUES ( | |||||
NEW.id, | |||||
NEW.lower_name, | |||||
NEW.name, | |||||
NEW.full_name, | |||||
NEW.email, | |||||
NEW.keep_email_private, | |||||
NEW.email_notifications_preference, | |||||
NEW.must_change_password, | |||||
NEW.login_type, | |||||
NEW.login_source, | |||||
NEW.login_name, | |||||
NEW.type, | |||||
NEW.location, | |||||
NEW.website, | |||||
NEW.rands, | |||||
NEW.language, | |||||
NEW.description, | |||||
NEW.created_unix, | |||||
NEW.updated_unix, | |||||
NEW.last_login_unix, | |||||
NEW.last_repo_visibility, | |||||
NEW.max_repo_creation, | |||||
NEW.is_active, | |||||
NEW.is_restricted, | |||||
NEW.allow_git_hook, | |||||
NEW.allow_import_local, | |||||
NEW.allow_create_organization, | |||||
NEW.prohibit_login, | |||||
NEW.avatar, | |||||
NEW.avatar_email, | |||||
NEW.use_custom_avatar, | |||||
NEW.num_followers, | |||||
NEW.num_following, | |||||
NEW.num_stars, | |||||
NEW.num_repos, | |||||
NEW.num_teams, | |||||
NEW.num_members, | |||||
NEW.visibility, | |||||
NEW.repo_admin_change_team_access, | |||||
NEW.diff_view_style, | |||||
NEW.theme, | |||||
NEW.is_operator, | |||||
NEW.num_dataset_stars | |||||
); | |||||
RETURN NEW; | |||||
END; | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_insert_user | |||||
AFTER INSERT ON public.user | |||||
FOR EACH ROW EXECUTE PROCEDURE insert_user_data(); | |||||
ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_insert_user; | |||||
DROP TRIGGER IF EXISTS es_update_user on public.user; | |||||
CREATE OR REPLACE FUNCTION public.update_user() RETURNS trigger AS | |||||
$def$ | |||||
BEGIN | |||||
UPDATE public.user_es | |||||
SET description=NEW.description, | |||||
name=NEW.name, | |||||
full_name=NEW.full_name, | |||||
location=NEW.location, | |||||
website=NEW.website, | |||||
email=NEW.email, | |||||
num_dataset_stars=NEW.num_dataset_stars, | |||||
updated_unix=NEW.updated_unix | |||||
where id=NEW.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_update_user | |||||
AFTER UPDATE ON public.user | |||||
FOR EACH ROW EXECUTE PROCEDURE update_user(); | |||||
ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_update_user; | |||||
DROP TRIGGER IF EXISTS es_delete_user on public.user; | |||||
CREATE OR REPLACE FUNCTION public.delete_user() RETURNS trigger AS | |||||
$def$ | |||||
declare | |||||
BEGIN | |||||
DELETE FROM public.user_es where id=OLD.id; | |||||
return new; | |||||
END | |||||
$def$ | |||||
LANGUAGE plpgsql; | |||||
CREATE TRIGGER es_delete_user | |||||
AFTER DELETE ON public.user | |||||
FOR EACH ROW EXECUTE PROCEDURE delete_user(); | |||||
ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_delete_user; |
@@ -13,11 +13,6 @@ const ( | |||||
FileUploaded | FileUploaded | ||||
) | ) | ||||
const ( | |||||
TypeCloudBrainOne int = iota | |||||
TypeCloudBrainTwo | |||||
) | |||||
type FileChunk struct { | type FileChunk struct { | ||||
ID int64 `xorm:"pk autoincr"` | ID int64 `xorm:"pk autoincr"` | ||||
UUID string `xorm:"uuid UNIQUE"` | UUID string `xorm:"uuid UNIQUE"` | ||||
@@ -138,6 +138,7 @@ func init() { | |||||
new(OfficialTag), | new(OfficialTag), | ||||
new(OfficialTagRepos), | new(OfficialTagRepos), | ||||
new(WechatBindLog), | new(WechatBindLog), | ||||
new(SearchRecord), | |||||
) | ) | ||||
tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
@@ -6,13 +6,14 @@ | |||||
package models | package models | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/git" | |||||
"context" | "context" | ||||
"crypto/md5" | "crypto/md5" | ||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
"html/template" | "html/template" | ||||
"math/rand" | "math/rand" | ||||
"code.gitea.io/gitea/modules/git" | |||||
"xorm.io/xorm" | "xorm.io/xorm" | ||||
"code.gitea.io/gitea/modules/blockchain" | "code.gitea.io/gitea/modules/blockchain" | ||||
@@ -190,7 +190,8 @@ type SearchRepoOptions struct { | |||||
// None -> include all repos | // None -> include all repos | ||||
// True -> include just courses | // True -> include just courses | ||||
// False -> include just no courses | // False -> include just no courses | ||||
Course util.OptionalBool | |||||
Course util.OptionalBool | |||||
OnlySearchPrivate bool | |||||
} | } | ||||
//SearchOrderBy is used to sort the result | //SearchOrderBy is used to sort the result | ||||
@@ -219,12 +220,15 @@ const ( | |||||
SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | ||||
SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | ||||
SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | ||||
SearchOrderByWatches SearchOrderBy = "num_watches DESC" | |||||
) | ) | ||||
// SearchRepositoryCondition creates a query condition according search repository options | // SearchRepositoryCondition creates a query condition according search repository options | ||||
func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | ||||
var cond = builder.NewCond() | var cond = builder.NewCond() | ||||
if opts.OnlySearchPrivate { | |||||
cond = cond.And(builder.Eq{"is_private": true}) | |||||
} | |||||
if opts.Private { | if opts.Private { | ||||
if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID { | if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID { | ||||
// OK we're in the context of a User | // OK we're in the context of a User | ||||
@@ -337,7 +341,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | |||||
if !opts.TopicOnly { | if !opts.TopicOnly { | ||||
var likes = builder.NewCond() | var likes = builder.NewCond() | ||||
for _, v := range strings.Split(opts.Keyword, ",") { | for _, v := range strings.Split(opts.Keyword, ",") { | ||||
likes = likes.Or(builder.Like{"lower_name", strings.ToLower(v)}) | |||||
likes = likes.Or(builder.Like{"lower_alias", strings.ToLower(v)}) | |||||
likes = likes.Or(builder.Like{"alias", v}) | likes = likes.Or(builder.Like{"alias", v}) | ||||
if opts.IncludeDescription { | if opts.IncludeDescription { | ||||
likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)}) | likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)}) | ||||
@@ -0,0 +1,83 @@ | |||||
package models | |||||
import ( | |||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/timeutil" | |||||
"xorm.io/xorm" | |||||
) | |||||
type SearchRecord struct { | |||||
ID int64 `xorm:"pk autoincr"` | |||||
//user | |||||
Keyword string `xorm:"NOT NULL"` | |||||
// | |||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||||
} | |||||
func SaveSearchKeywordToDb(keyword string) error { | |||||
record := &SearchRecord{ | |||||
Keyword: keyword, | |||||
} | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
_, err := sess.Insert(record) | |||||
if err != nil { | |||||
log.Info("insert error." + err.Error()) | |||||
return err | |||||
} | |||||
return nil | |||||
} | |||||
func setIssueQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId int64) { | |||||
sess.And("issue.poster_id=?", userId) | |||||
sess.And("issue.is_pull=?", isPull) | |||||
sess.And("(issue.name like '%" + Keyword + "%' or issue.content like '%" + Keyword + "%')") | |||||
sess.Join("INNER", "repository", "issue.repo_id = repository.id").And("repository.is_private = ?", true) | |||||
} | |||||
func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool, userId int64) ([]*Issue, int64, error) { | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
setIssueQueryCondition(sess, Keyword, isPull, userId) | |||||
count, err := sess.Count(new(Issue)) | |||||
if err != nil { | |||||
return nil, 0, err | |||||
} | |||||
setIssueQueryCondition(sess, Keyword, isPull, userId) | |||||
sess.Desc("issue.created_unix") | |||||
sess.Limit(PageSize, (Page-1)*PageSize) | |||||
issues := make([]*Issue, 0) | |||||
if err := sess.Find(&issues); err != nil { | |||||
return nil, 0, err | |||||
} else { | |||||
return issues, count, nil | |||||
} | |||||
} | |||||
func setDataSetQueryCondition(sess *xorm.Session, Keyword string, userId int64) { | |||||
sess.And("dataset.user_id=?", userId) | |||||
sess.And("(dataset.title like '%" + Keyword + "%' or dataset.description like '%" + Keyword + "%')") | |||||
sess.Join("INNER", "repository", "dataset.repo_id = repository.id").And("repository.is_private = ?", true) | |||||
} | |||||
func SearchDatasetBySQL(Page int, PageSize int, Keyword string, userId int64) ([]*Dataset, int64, error) { | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
setDataSetQueryCondition(sess, Keyword, userId) | |||||
count, err := sess.Count(new(Dataset)) | |||||
if err != nil { | |||||
return nil, 0, err | |||||
} | |||||
setDataSetQueryCondition(sess, Keyword, userId) | |||||
sess.Desc("dataset.created_unix") | |||||
sess.Limit(PageSize, (Page-1)*PageSize) | |||||
datasets := make([]*Dataset, 0) | |||||
if err := sess.Find(&datasets); err != nil { | |||||
return nil, 0, err | |||||
} else { | |||||
return datasets, count, nil | |||||
} | |||||
} |
@@ -20,6 +20,9 @@ type CreateCloudBrainForm struct { | |||||
ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | ||||
BenchmarkTypeID int `form:"benchmark_types_id"` | BenchmarkTypeID int `form:"benchmark_types_id"` | ||||
BenchmarkChildTypeID int `form:"benchmark_child_types_id"` | BenchmarkChildTypeID int `form:"benchmark_child_types_id"` | ||||
BootFile string `form:"boot_file"` | |||||
Params string `form:"run_para_list"` | |||||
BranchName string `form:"branch_name"` | |||||
} | } | ||||
type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
@@ -15,14 +15,13 @@ import ( | |||||
) | ) | ||||
const ( | const ( | ||||
Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple; | |||||
service ssh stop; | |||||
jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | |||||
Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | |||||
//CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | //CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | ||||
CommandBenchmark = `echo "start benchmark";cd /benchmark && bash run_bk.sh;echo "end benchmark"` | CommandBenchmark = `echo "start benchmark";cd /benchmark && bash run_bk.sh;echo "end benchmark"` | ||||
CodeMountPath = "/code" | CodeMountPath = "/code" | ||||
DataSetMountPath = "/dataset" | DataSetMountPath = "/dataset" | ||||
ModelMountPath = "/model" | ModelMountPath = "/model" | ||||
LogFile = "log.txt" | |||||
BenchMarkMountPath = "/benchmark" | BenchMarkMountPath = "/benchmark" | ||||
BenchMarkResourceID = 1 | BenchMarkResourceID = 1 | ||||
Snn4imagenetMountPath = "/snn4imagenet" | Snn4imagenetMountPath = "/snn4imagenet" | ||||
@@ -32,10 +31,13 @@ const ( | |||||
SubTaskName = "task1" | SubTaskName = "task1" | ||||
Success = "S000" | Success = "S000" | ||||
DefaultBranchName = "master" | |||||
) | ) | ||||
var ( | var ( | ||||
ResourceSpecs *models.ResourceSpecs | |||||
ResourceSpecs *models.ResourceSpecs | |||||
TrainResourceSpecs *models.ResourceSpecs | |||||
) | ) | ||||
func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool { | func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool { | ||||
@@ -147,7 +149,7 @@ func AdminOrJobCreaterRightForTrain(ctx *context.Context) { | |||||
} | } | ||||
func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description, branchName, bootFile, params string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
@@ -155,13 +157,25 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
uuid | uuid | ||||
var resourceSpec *models.ResourceSpec | var resourceSpec *models.ResourceSpec | ||||
if ResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||||
} | |||||
for _, spec := range ResourceSpecs.ResourceSpec { | |||||
if resourceSpecId == spec.Id { | |||||
resourceSpec = spec | |||||
var versionCount int | |||||
if jobType == string(models.JobTypeTrain) { | |||||
versionCount = 1 | |||||
if TrainResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs) | |||||
} | |||||
for _, spec := range TrainResourceSpecs.ResourceSpec { | |||||
if resourceSpecId == spec.Id { | |||||
resourceSpec = spec | |||||
} | |||||
} | |||||
} else { | |||||
if ResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||||
} | |||||
for _, spec := range ResourceSpecs.ResourceSpec { | |||||
if resourceSpecId == spec.Id { | |||||
resourceSpec = spec | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -171,6 +185,15 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
return errors.New("no such resourceSpec") | return errors.New("no such resourceSpec") | ||||
} | } | ||||
var datasetName string | |||||
attach, err := models.GetAttachmentByUUID(uuid) | |||||
if err != nil { | |||||
//for benchmark, do not return error | |||||
log.Error("GetAttachmentByUUID failed:%v", err) | |||||
} else { | |||||
datasetName = attach.Name | |||||
} | |||||
jobResult, err := CreateJob(jobName, models.CreateJobParams{ | jobResult, err := CreateJob(jobName, models.CreateJobParams{ | ||||
JobName: jobName, | JobName: jobName, | ||||
RetryCount: 1, | RetryCount: 1, | ||||
@@ -265,6 +288,12 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
BenchmarkTypeID: benchmarkTypeID, | BenchmarkTypeID: benchmarkTypeID, | ||||
BenchmarkChildTypeID: benchmarkChildTypeID, | BenchmarkChildTypeID: benchmarkChildTypeID, | ||||
Description: description, | Description: description, | ||||
IsLatestVersion: "1", | |||||
VersionCount: versionCount, | |||||
BranchName: branchName, | |||||
BootFile: bootFile, | |||||
DatasetName: datasetName, | |||||
Parameters: params, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -280,6 +309,8 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
if string(models.JobTypeBenchmark) == jobType { | if string(models.JobTypeBenchmark) == jobType { | ||||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | ||||
} else if string(models.JobTypeTrain) == jobType { | |||||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, displayJobName, models.ActionCreateGPUTrainTask) | |||||
} else { | } else { | ||||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | ||||
} | } | ||||
@@ -56,7 +56,6 @@ const ( | |||||
PerPage = 10 | PerPage = 10 | ||||
IsLatestVersion = "1" | IsLatestVersion = "1" | ||||
NotLatestVersion = "0" | NotLatestVersion = "0" | ||||
DebugType = -1 | |||||
VersionCount = 1 | VersionCount = 1 | ||||
SortByCreateTime = "create_time" | SortByCreateTime = "create_time" | ||||
@@ -437,7 +437,7 @@ var ( | |||||
//home page | //home page | ||||
RecommentRepoAddr string | RecommentRepoAddr string | ||||
ESSearchURL string | |||||
//notice config | //notice config | ||||
UserNameOfNoticeRepo string | UserNameOfNoticeRepo string | ||||
RepoNameOfNoticeRepo string | RepoNameOfNoticeRepo string | ||||
@@ -452,16 +452,18 @@ var ( | |||||
DecompressOBSTaskName string | DecompressOBSTaskName string | ||||
//cloudbrain config | //cloudbrain config | ||||
CBAuthUser string | |||||
CBAuthPassword string | |||||
RestServerHost string | |||||
JobPath string | |||||
CBCodePathPrefix string | |||||
JobType string | |||||
GpuTypes string | |||||
DebugServerHost string | |||||
ResourceSpecs string | |||||
MaxDuration int64 | |||||
CBAuthUser string | |||||
CBAuthPassword string | |||||
RestServerHost string | |||||
JobPath string | |||||
CBCodePathPrefix string | |||||
JobType string | |||||
GpuTypes string | |||||
DebugServerHost string | |||||
ResourceSpecs string | |||||
MaxDuration int64 | |||||
TrainGpuTypes string | |||||
TrainResourceSpecs string | |||||
//benchmark config | //benchmark config | ||||
IsBenchmarkEnabled bool | IsBenchmarkEnabled bool | ||||
@@ -1265,6 +1267,7 @@ func NewContext() { | |||||
sec = Cfg.Section("homepage") | sec = Cfg.Section("homepage") | ||||
RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/") | RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/") | ||||
ESSearchURL = sec.Key("ESSearchURL").MustString("http://192.168.207.94:9200") | |||||
sec = Cfg.Section("notice") | sec = Cfg.Section("notice") | ||||
UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG") | UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG") | ||||
@@ -1285,6 +1288,8 @@ func NewContext() { | |||||
GpuTypes = sec.Key("GPU_TYPES").MustString("") | GpuTypes = sec.Key("GPU_TYPES").MustString("") | ||||
ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("") | ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("") | ||||
MaxDuration = sec.Key("MAX_DURATION").MustInt64(14400) | MaxDuration = sec.Key("MAX_DURATION").MustInt64(14400) | ||||
TrainGpuTypes = sec.Key("TRAIN_GPU_TYPES").MustString("") | |||||
TrainResourceSpecs = sec.Key("TRAIN_RESOURCE_SPECS").MustString("") | |||||
sec = Cfg.Section("benchmark") | sec = Cfg.Section("benchmark") | ||||
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | ||||
@@ -254,6 +254,18 @@ page_dev_yunlao_desc3=Developers can freely choose the corresponding computing r | |||||
page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately. | page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately. | ||||
page_dev_yunlao_apply=Apply Separately | page_dev_yunlao_apply=Apply Separately | ||||
search=Search | |||||
search_repo=Repository | |||||
search_dataset=DataSet | |||||
search_issue=Issue | |||||
search_pr=Pull Request | |||||
search_user=User | |||||
search_org=Organization | |||||
search_finded=Find | |||||
search_related=related | |||||
search_maybe=maybe | |||||
search_ge= | |||||
[explore] | [explore] | ||||
repos = Repositories | repos = Repositories | ||||
select_repos = Select the project | select_repos = Select the project | ||||
@@ -1010,7 +1022,8 @@ modelarts.train_job.parameter_value=Parameter Value | |||||
modelarts.train_job.resource_setting=resource_setting | modelarts.train_job.resource_setting=resource_setting | ||||
modelarts.train_job.resource_setting_info=resource_setting_info | modelarts.train_job.resource_setting_info=resource_setting_info | ||||
modelarts.train_job.resource_pool=resource_pool | modelarts.train_job.resource_pool=resource_pool | ||||
modelarts.train_job.resource_type=resource_type | |||||
modelarts.train_job.resource_type=Resource Type | |||||
modelarts.train_job.train_dataset=Train Dataset | |||||
modelarts.train_job.standard=Standard | modelarts.train_job.standard=Standard | ||||
modelarts.train_job.NAS_address=NAS Address | modelarts.train_job.NAS_address=NAS Address | ||||
modelarts.train_job.NAS_mount_path=NAS Mount Path | modelarts.train_job.NAS_mount_path=NAS Mount Path | ||||
@@ -2790,10 +2803,11 @@ reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>` | |||||
upload_dataset=`upload dataset <a href="%s/datasets?type=%s">%s</a>` | upload_dataset=`upload dataset <a href="%s/datasets?type=%s">%s</a>` | ||||
task_gpudebugjob=`created CPU/GPU type debugging task<a href="%s/cloudbrain/%s">%s</a>` | task_gpudebugjob=`created CPU/GPU type debugging task<a href="%s/cloudbrain/%s">%s</a>` | ||||
task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>` | task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>` | ||||
task_trainjob=`created training task<a href="%s/modelarts/train-job/%s">%s</a>` | |||||
task_nputrainjob=`created NPU training task<a href="%s/modelarts/train-job/%s">%s</a>` | |||||
task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s">%s</a>` | task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s">%s</a>` | ||||
task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>` | task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>` | ||||
task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
task_gputrainjob=`created CPU/GPU training task<a href="%s/cloudbrain/train-job/%s">%s</a>` | |||||
[tool] | [tool] | ||||
ago = %s ago | ago = %s ago | ||||
@@ -256,6 +256,18 @@ page_dev_yunlao_desc3=开发者可以根据使用需求,自由选择相应计 | |||||
page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请 | page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请 | ||||
page_dev_yunlao_apply=单独申请 | page_dev_yunlao_apply=单独申请 | ||||
search=搜索 | |||||
search_repo=项目 | |||||
search_dataset=数据集 | |||||
search_issue=任务 | |||||
search_pr=合并请求 | |||||
search_user=用户 | |||||
search_org=组织 | |||||
search_finded=找到 | |||||
search_related=相关 | |||||
search_maybe=约为 | |||||
search_ge=个 | |||||
[explore] | [explore] | ||||
repos=项目 | repos=项目 | ||||
select_repos=精选项目 | select_repos=精选项目 | ||||
@@ -2797,10 +2809,11 @@ reject_pull_request=`建议变更 <a href="%s/pulls/%s">%s#%[2]s</a>` | |||||
upload_dataset=`上传了数据集文件 <a href="%s/datasets?type=%s">%s</a>` | upload_dataset=`上传了数据集文件 <a href="%s/datasets?type=%s">%s</a>` | ||||
task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%s">%s</a>` | task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%s">%s</a>` | ||||
task_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>` | task_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>` | ||||
task_trainjob=`创建了训练任务 <a href="%s/modelarts/train-job/%s">%s</a>` | |||||
task_nputrainjob=`创建了NPU类型训练任务 <a href="%s/modelarts/train-job/%s">%s</a>` | |||||
task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s">%s</a>` | task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s">%s</a>` | ||||
task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | ||||
task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>` | |||||
[tool] | [tool] | ||||
ago=%s前 | ago=%s前 | ||||
@@ -135,7 +135,7 @@ socket.onmessage = function (e) { | |||||
html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | ||||
} | } | ||||
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"){ | |||||
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30" || record.OpType == "31"){ | |||||
html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | ||||
} | } | ||||
@@ -175,6 +175,8 @@ function getTaskLink(record){ | |||||
re = re + "/cloudbrain/benchmark/" + record.Content; | re = re + "/cloudbrain/benchmark/" + record.Content; | ||||
}else if(record.OpType == 30){ | }else if(record.OpType == 30){ | ||||
re = re + "/modelmanage/show_model_info?name=" + record.RefName; | re = re + "/modelmanage/show_model_info?name=" + record.RefName; | ||||
}else if(record.OpType == 31){ | |||||
re = re + "/cloudbrain/train-job/" + record.Content; | |||||
} | } | ||||
re = encodeURI(re); | re = encodeURI(re); | ||||
return re; | return re; | ||||
@@ -321,10 +323,11 @@ var actionNameZH={ | |||||
"24":"上传了数据集文件", | "24":"上传了数据集文件", | ||||
"25":"创建了CPU/GPU类型调试任务", | "25":"创建了CPU/GPU类型调试任务", | ||||
"26":"创建了NPU类型调试任务", | "26":"创建了NPU类型调试任务", | ||||
"27":"创建了训练任务", | |||||
"27":"创建了NPU类型训练任务", | |||||
"28":"创建了推理任务", | "28":"创建了推理任务", | ||||
"29":"创建了评测任务", | "29":"创建了评测任务", | ||||
"30":"导入了新模型" | |||||
"30":"导入了新模型", | |||||
"31":"创建了CPU/GPU类型训练任务" | |||||
}; | }; | ||||
var actionNameEN={ | var actionNameEN={ | ||||
@@ -346,10 +349,11 @@ var actionNameEN={ | |||||
"24":" upload dataset ", | "24":" upload dataset ", | ||||
"25":" created CPU/GPU type debugging task ", | "25":" created CPU/GPU type debugging task ", | ||||
"26":" created NPU type debugging task ", | "26":" created NPU type debugging task ", | ||||
"27":" created training task", | |||||
"27":" created NPU type training task", | |||||
"28":" created reasoning task", | "28":" created reasoning task", | ||||
"29":" created profiling task", | "29":" created profiling task", | ||||
"30":" created new model" | |||||
"30":" created new model", | |||||
"31":" created CPU/GPU type training task", | |||||
}; | }; | ||||
var repoAndOrgZH={ | var repoAndOrgZH={ | ||||
@@ -620,10 +620,10 @@ function showfilelist(){ | |||||
for (var i=0;i<labeltastresult.length;i++){ | for (var i=0;i<labeltastresult.length;i++){ | ||||
var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | ||||
console.log(labeltastresult[i]) | |||||
//console.log(labeltastresult[i]) | |||||
if(labeltastresult[i].pic_image_field.length > 70){ | if(labeltastresult[i].pic_image_field.length > 70){ | ||||
var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | ||||
console.log(tmpIndex) | |||||
//console.log(tmpIndex) | |||||
if(tmpIndex != -1){ | if(tmpIndex != -1){ | ||||
fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | ||||
fname = fname.substring(fname.indexOf('/')+1); | fname = fname.substring(fname.indexOf('/')+1); | ||||
@@ -679,7 +679,7 @@ function breadFiles(){ | |||||
fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | ||||
} | } | ||||
var fname_path = fname_full_path.split('/') | var fname_path = fname_full_path.split('/') | ||||
console.log(fname_path) | |||||
//console.log(fname_path) | |||||
// var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | ||||
var html_breadFile = '' | var html_breadFile = '' | ||||
// var source_name = filename_title+'.zip' | // var source_name = filename_title+'.zip' | ||||
@@ -41,7 +41,7 @@ func CloudBrains(ctx *context.Context) { | |||||
if page <= 0 { | if page <= 0 { | ||||
page = 1 | page = 1 | ||||
} | } | ||||
debugType := modelarts.DebugType | |||||
debugType := models.TypeCloudBrainAll | |||||
if listType == models.GPUResource { | if listType == models.GPUResource { | ||||
debugType = models.TypeCloudBrainOne | debugType = models.TypeCloudBrainOne | ||||
} else if listType == models.NPUResource { | } else if listType == models.NPUResource { | ||||
@@ -121,7 +121,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||||
Page: page, | Page: page, | ||||
PageSize: 1, | PageSize: 1, | ||||
}, | }, | ||||
Type: modelarts.DebugType, | |||||
Type: models.TypeCloudBrainAll, | |||||
NeedRepoInfo: false, | NeedRepoInfo: false, | ||||
IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
}) | }) | ||||
@@ -151,7 +151,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||||
Page: page, | Page: page, | ||||
PageSize: pageSize, | PageSize: pageSize, | ||||
}, | }, | ||||
Type: modelarts.DebugType, | |||||
Type: models.TypeCloudBrainAll, | |||||
NeedRepoInfo: true, | NeedRepoInfo: true, | ||||
IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
}) | }) | ||||
@@ -62,10 +62,10 @@ import ( | |||||
"net/http" | "net/http" | ||||
"strings" | "strings" | ||||
"code.gitea.io/gitea/routers/authentication" | |||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
"code.gitea.io/gitea/modules/cloudbrain" | |||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
@@ -77,6 +77,7 @@ import ( | |||||
"code.gitea.io/gitea/routers/api/v1/repo" | "code.gitea.io/gitea/routers/api/v1/repo" | ||||
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation | _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation | ||||
"code.gitea.io/gitea/routers/api/v1/user" | "code.gitea.io/gitea/routers/api/v1/user" | ||||
"code.gitea.io/gitea/routers/authentication" | |||||
repo_ext "code.gitea.io/gitea/routers/repo" | repo_ext "code.gitea.io/gitea/routers/repo" | ||||
"gitea.com/macaron/binding" | "gitea.com/macaron/binding" | ||||
@@ -882,6 +883,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
m.Get("/:id", repo.GetCloudbrainTask) | m.Get("/:id", repo.GetCloudbrainTask) | ||||
m.Get("/:id/log", repo.CloudbrainGetLog) | m.Get("/:id/log", repo.CloudbrainGetLog) | ||||
m.Group("/train-job", func() { | |||||
m.Group("/:jobid", func() { | |||||
m.Get("", repo.GetModelArtsTrainJobVersion) | |||||
m.Get("/model_list", repo.CloudBrainModelList) | |||||
m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | |||||
}) | |||||
}) | |||||
}, reqRepoReader(models.UnitTypeCloudBrain)) | }, reqRepoReader(models.UnitTypeCloudBrain)) | ||||
m.Group("/modelarts", func() { | m.Group("/modelarts", func() { | ||||
m.Group("/notebook", func() { | m.Group("/notebook", func() { | ||||
@@ -6,15 +6,19 @@ | |||||
package repo | package repo | ||||
import ( | import ( | ||||
"encoding/json" | |||||
"net/http" | "net/http" | ||||
"sort" | "sort" | ||||
"strings" | |||||
"time" | "time" | ||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/cloudbrain" | "code.gitea.io/gitea/modules/cloudbrain" | ||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/storage" | |||||
"code.gitea.io/gitea/modules/timeutil" | |||||
routerRepo "code.gitea.io/gitea/routers/repo" | |||||
) | ) | ||||
// cloudbrain get job task by jobid | // cloudbrain get job task by jobid | ||||
@@ -152,3 +156,55 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
func CloudBrainModelList(ctx *context.APIContext) { | |||||
var ( | |||||
err error | |||||
) | |||||
var jobID = ctx.Params(":jobid") | |||||
var versionName = ctx.Query("version_name") | |||||
parentDir := ctx.Query("parentDir") | |||||
dirArray := strings.Split(parentDir, "/") | |||||
task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName) | |||||
if err != nil { | |||||
log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error()) | |||||
return | |||||
} | |||||
//get dirs | |||||
dirs, err := routerRepo.GetModelDirs(task.JobName, parentDir) | |||||
if err != nil { | |||||
log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"]) | |||||
ctx.ServerError("GetModelDirs failed:", err) | |||||
return | |||||
} | |||||
var fileInfos []storage.FileInfo | |||||
err = json.Unmarshal([]byte(dirs), &fileInfos) | |||||
if err != nil { | |||||
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return | |||||
} | |||||
for i, fileInfo := range fileInfos { | |||||
temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime) | |||||
fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05") | |||||
} | |||||
sort.Slice(fileInfos, func(i, j int) bool { | |||||
return fileInfos[i].ModTime > fileInfos[j].ModTime | |||||
}) | |||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||||
"JobID": jobID, | |||||
"VersionName": versionName, | |||||
"StatusOK": 0, | |||||
"Path": dirArray, | |||||
"Dirs": fileInfos, | |||||
"task": task, | |||||
"PageIsCloudBrain": true, | |||||
}) | |||||
} |
@@ -6,16 +6,17 @@ | |||||
package repo | package repo | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/timeutil" | |||||
"net/http" | "net/http" | ||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/cloudbrain" | |||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
"code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
"code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
"code.gitea.io/gitea/modules/timeutil" | |||||
routerRepo "code.gitea.io/gitea/routers/repo" | routerRepo "code.gitea.io/gitea/routers/repo" | ||||
) | ) | ||||
@@ -66,8 +67,8 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
ctx.NotFound(err) | ctx.NotFound(err) | ||||
return | return | ||||
} | } | ||||
if job.StartTime == 0 && result.Lease.CreateTime > 0 { | |||||
job.StartTime = timeutil.TimeStamp(result.Lease.CreateTime / 1000) | |||||
if job.StartTime == 0 && result.Lease.UpdateTime > 0 { | |||||
job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | |||||
} | } | ||||
job.Status = result.Status | job.Status = result.Status | ||||
if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { | if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { | ||||
@@ -133,27 +134,61 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
ctx.NotFound(err) | ctx.NotFound(err) | ||||
return | return | ||||
} | } | ||||
result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10)) | |||||
if err != nil { | |||||
ctx.NotFound(err) | |||||
return | |||||
} | |||||
if job.StartTime == 0 && result.StartTime > 0 { | |||||
job.StartTime = timeutil.TimeStamp(result.StartTime / 1000) | |||||
} | |||||
job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | |||||
job.Duration = result.Duration / 1000 | |||||
job.TrainJobDuration = result.TrainJobDuration | |||||
job.TrainJobDuration = models.ConvertDurationToStr(job.Duration) | |||||
if job.Type == models.TypeCloudBrainOne { | |||||
jobResult, err := cloudbrain.GetJob(job.JobID) | |||||
if err != nil { | |||||
ctx.NotFound(err) | |||||
log.Error("GetJob failed:", err) | |||||
return | |||||
} | |||||
result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||||
if err != nil { | |||||
ctx.NotFound(err) | |||||
log.Error("ConvertToJobResultPayload failed:", err) | |||||
return | |||||
} | |||||
if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 { | |||||
job.EndTime = job.StartTime.Add(job.Duration) | |||||
} | |||||
job.Status = result.JobStatus.State | |||||
if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||||
taskRoles := result.TaskRoles | |||||
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||||
err = models.UpdateTrainJobVersion(job) | |||||
if err != nil { | |||||
log.Error("UpdateJob failed:", err) | |||||
job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||||
job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||||
job.Status = taskRes.TaskStatuses[0].State | |||||
} | |||||
if result.JobStatus.State != string(models.JobWaiting) { | |||||
err = models.UpdateJob(job) | |||||
if err != nil { | |||||
log.Error("UpdateJob failed:", err) | |||||
} | |||||
} | |||||
} else { | |||||
result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10)) | |||||
if err != nil { | |||||
ctx.NotFound(err) | |||||
return | |||||
} | |||||
if job.StartTime == 0 && result.StartTime > 0 { | |||||
job.StartTime = timeutil.TimeStamp(result.StartTime / 1000) | |||||
} | |||||
job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | |||||
job.Duration = result.Duration / 1000 | |||||
job.TrainJobDuration = result.TrainJobDuration | |||||
job.TrainJobDuration = models.ConvertDurationToStr(job.Duration) | |||||
if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 { | |||||
job.EndTime = job.StartTime.Add(job.Duration) | |||||
} | |||||
err = models.UpdateTrainJobVersion(job) | |||||
if err != nil { | |||||
log.Error("UpdateJob failed:", err) | |||||
} | |||||
} | } | ||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
@@ -71,6 +71,8 @@ func NewServices() { | |||||
log.Info("decompression.NewContext() succeed.") | log.Info("decompression.NewContext() succeed.") | ||||
labelmsg.Init() | labelmsg.Init() | ||||
log.Info("labelmsg.Init() succeed.") | log.Info("labelmsg.Init() succeed.") | ||||
InitESClient() | |||||
log.Info("ES Client succeed.") | |||||
} | } | ||||
// In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | ||||
@@ -37,6 +37,9 @@ const ( | |||||
tplCloudBrainBenchmarkIndex base.TplName = "repo/cloudbrain/benchmark/index" | tplCloudBrainBenchmarkIndex base.TplName = "repo/cloudbrain/benchmark/index" | ||||
tplCloudBrainBenchmarkNew base.TplName = "repo/cloudbrain/benchmark/new" | tplCloudBrainBenchmarkNew base.TplName = "repo/cloudbrain/benchmark/new" | ||||
tplCloudBrainBenchmarkShow base.TplName = "repo/cloudbrain/benchmark/show" | tplCloudBrainBenchmarkShow base.TplName = "repo/cloudbrain/benchmark/show" | ||||
tplCloudBrainTrainJobNew base.TplName = "repo/cloudbrain/trainjob/new" | |||||
tplCloudBrainTrainJobShow base.TplName = "repo/cloudbrain/trainjob/show" | |||||
) | ) | ||||
var ( | var ( | ||||
@@ -45,6 +48,7 @@ var ( | |||||
benchmarkTypes *models.BenchmarkTypes | benchmarkTypes *models.BenchmarkTypes | ||||
benchmarkGpuInfos *models.GpuInfos | benchmarkGpuInfos *models.GpuInfos | ||||
benchmarkResourceSpecs *models.ResourceSpecs | benchmarkResourceSpecs *models.ResourceSpecs | ||||
trainGpuInfos *models.GpuInfos | |||||
) | ) | ||||
const BENCHMARK_TYPE_CODE = "repo.cloudbrain.benchmark.types" | const BENCHMARK_TYPE_CODE = "repo.cloudbrain.benchmark.types" | ||||
@@ -143,6 +147,11 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
} | } | ||||
ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ||||
if trainGpuInfos == nil { | |||||
json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
} | |||||
ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||||
if benchmarkGpuInfos == nil { | if benchmarkGpuInfos == nil { | ||||
json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | ||||
} | } | ||||
@@ -157,6 +166,14 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | ||||
} | } | ||||
ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | ||||
if cloudbrain.TrainResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||||
} | |||||
ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||||
ctx.Data["params"] = "" | |||||
ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ||||
ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ||||
@@ -184,38 +201,52 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
image := form.Image | image := form.Image | ||||
uuid := form.Attachment | uuid := form.Attachment | ||||
jobType := form.JobType | jobType := form.JobType | ||||
command := cloudbrain.Command | |||||
gpuQueue := form.GpuType | gpuQueue := form.GpuType | ||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
resourceSpecId := form.ResourceSpecId | resourceSpecId := form.ResourceSpecId | ||||
branchName := form.BranchName | |||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||||
tpl := tplCloudBrainNew | |||||
command := cloudbrain.Command | |||||
if jobType == string(models.JobTypeTrain) { | |||||
tpl = tplCloudBrainTrainJobNew | |||||
commandTrain, err := getTrainJobCommand(form) | |||||
if err != nil { | |||||
log.Error("getTrainJobCommand failed: %v", err) | |||||
ctx.RenderWithErr(err.Error(), tpl, &form) | |||||
return | |||||
} | |||||
command = commandTrain | |||||
} | |||||
tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) | |||||
if err == nil { | if err == nil { | ||||
if len(tasks) != 0 { | if len(tasks) != 0 { | ||||
log.Error("the job name did already exist", ctx.Data["MsgID"]) | log.Error("the job name did already exist", ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr("the job name did already exist", tpl, &form) | |||||
return | return | ||||
} | } | ||||
} else { | } else { | ||||
if !models.IsErrJobNotExist(err) { | if !models.IsErrJobNotExist(err) { | ||||
log.Error("system error, %v", err, ctx.Data["MsgID"]) | log.Error("system error, %v", err, ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr("system error", tpl, &form) | |||||
return | return | ||||
} | } | ||||
} | } | ||||
if !jobNamePattern.MatchString(displayJobName) { | if !jobNamePattern.MatchString(displayJobName) { | ||||
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | |||||
return | return | ||||
} | } | ||||
if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) { | |||||
if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) && jobType != string(models.JobTypeTrain) { | |||||
log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr("jobtype error", tpl, &form) | |||||
return | return | ||||
} | } | ||||
@@ -223,18 +254,21 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr("system error", tpl, &form) | |||||
return | return | ||||
} else { | } else { | ||||
if count >= 1 { | if count >= 1 { | ||||
log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tpl, &form) | |||||
return | return | ||||
} | } | ||||
} | } | ||||
downloadCode(repo, codePath) | |||||
if branchName == "" { | |||||
branchName = cloudbrain.DefaultBranchName | |||||
} | |||||
downloadCode(repo, codePath, branchName) | |||||
uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | ||||
modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" | modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" | ||||
@@ -268,15 +302,19 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, | |||||
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, branchName, form.BootFile, form.Params, | |||||
0, 0, resourceSpecId) | 0, 0, resourceSpecId) | ||||
if err != nil { | if err != nil { | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | |||||
ctx.RenderWithErr(err.Error(), tpl, &form) | |||||
return | return | ||||
} | } | ||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
if jobType == string(models.JobTypeTrain) { | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=all") | |||||
} else { | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
} | |||||
} | } | ||||
func CloudBrainRestart(ctx *context.Context) { | func CloudBrainRestart(ctx *context.Context) { | ||||
@@ -342,18 +380,29 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
} | } | ||||
func CloudBrainBenchMarkShow(ctx *context.Context) { | func CloudBrainBenchMarkShow(ctx *context.Context) { | ||||
cloudBrainShow(ctx, tplCloudBrainBenchmarkShow) | |||||
cloudBrainShow(ctx, tplCloudBrainBenchmarkShow, models.JobTypeBenchmark) | |||||
} | } | ||||
func CloudBrainShow(ctx *context.Context) { | func CloudBrainShow(ctx *context.Context) { | ||||
cloudBrainShow(ctx, tplCloudBrainShow) | |||||
cloudBrainShow(ctx, tplCloudBrainShow, models.JobTypeDebug) | |||||
} | |||||
func CloudBrainTrainJobShow(ctx *context.Context) { | |||||
cloudBrainShow(ctx, tplCloudBrainTrainJobShow, models.JobTypeTrain) | |||||
} | } | ||||
func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.JobType) { | |||||
ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
var ID = ctx.Params(":id") | |||||
debugListType := ctx.Query("debugListType") | debugListType := ctx.Query("debugListType") | ||||
task, err := models.GetCloudbrainByID(ID) | |||||
var task *models.Cloudbrain | |||||
var err error | |||||
if jobType == models.JobTypeTrain { | |||||
task, err = models.GetCloudbrainByJobID(ctx.Params(":jobid")) | |||||
} else { | |||||
task, err = models.GetCloudbrainByID(ctx.Params(":id")) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
log.Info("error:" + err.Error()) | log.Info("error:" + err.Error()) | ||||
ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
@@ -368,6 +417,16 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | ||||
spec := "GPU数:" + strconv.Itoa(jobRes.Resource.NvidiaComGpu) + ",CPU数:" + strconv.Itoa(jobRes.Resource.CPU) + ",内存(MB):" + jobRes.Resource.Memory | spec := "GPU数:" + strconv.Itoa(jobRes.Resource.NvidiaComGpu) + ",CPU数:" + strconv.Itoa(jobRes.Resource.CPU) + ",内存(MB):" + jobRes.Resource.Memory | ||||
ctx.Data["resource_spec"] = spec | ctx.Data["resource_spec"] = spec | ||||
if task.JobType == string(models.JobTypeTrain) { | |||||
if trainGpuInfos == nil { | |||||
json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
} | |||||
for _, resourceType := range trainGpuInfos.GpuInfo { | |||||
if resourceType.Queue == jobRes.Config.GpuType { | |||||
ctx.Data["resource_type"] = resourceType.Value | |||||
} | |||||
} | |||||
} | |||||
taskRoles := jobRes.TaskRoles | taskRoles := jobRes.TaskRoles | ||||
if jobRes.JobStatus.State != string(models.JobFailed) { | if jobRes.JobStatus.State != string(models.JobFailed) { | ||||
@@ -429,6 +488,29 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | ||||
} | } | ||||
ctx.Data["duration"] = task.TrainJobDuration | ctx.Data["duration"] = task.TrainJobDuration | ||||
if len(task.Parameters) > 0 { | |||||
var parameters models.Parameters | |||||
err := json.Unmarshal([]byte(task.Parameters), ¶meters) | |||||
if err != nil { | |||||
log.Error("Failed to Unmarshal Parameters: %s (%v)", task.Parameters, err) | |||||
task.Parameters = "" | |||||
} else { | |||||
if len(parameters.Parameter) > 0 { | |||||
paramTemp := "" | |||||
for _, Parameter := range parameters.Parameter { | |||||
param := Parameter.Label + " = " + Parameter.Value + "; " | |||||
paramTemp = paramTemp + param | |||||
} | |||||
task.Parameters = paramTemp[:len(paramTemp)-2] | |||||
} else { | |||||
task.Parameters = "" | |||||
} | |||||
} | |||||
} | |||||
ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
ctx.Data["displayJobName"] = task.DisplayJobName | ctx.Data["displayJobName"] = task.DisplayJobName | ||||
@@ -436,6 +518,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
version_list_task = append(version_list_task, task) | version_list_task = append(version_list_task, task) | ||||
ctx.Data["version_list_task"] = version_list_task | ctx.Data["version_list_task"] = version_list_task | ||||
ctx.Data["debugListType"] = debugListType | ctx.Data["debugListType"] = debugListType | ||||
ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||||
ctx.HTML(200, tpName) | ctx.HTML(200, tpName) | ||||
} | } | ||||
@@ -507,11 +590,12 @@ func CloudBrainStop(ctx *context.Context) { | |||||
break | break | ||||
} | } | ||||
ctx.JSON(200, map[string]string{ | |||||
ctx.JSON(200, map[string]interface{}{ | |||||
"result_code": resultCode, | "result_code": resultCode, | ||||
"error_msg": errorMsg, | "error_msg": errorMsg, | ||||
"status": status, | "status": status, | ||||
"id": ID, | "id": ID, | ||||
"StatusOK": 0, | |||||
}) | }) | ||||
} | } | ||||
@@ -763,8 +847,8 @@ func GetRate(ctx *context.Context) { | |||||
} | } | ||||
} | } | ||||
func downloadCode(repo *models.Repository, codePath string) error { | |||||
if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{}); err != nil { | |||||
func downloadCode(repo *models.Repository, codePath, branchName string) error { | |||||
if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{Branch: branchName}); err != nil { | |||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | ||||
return err | return err | ||||
} | } | ||||
@@ -1005,8 +1089,8 @@ func SyncCloudbrainStatus() { | |||||
if result != nil { | if result != nil { | ||||
task.Status = result.Status | task.Status = result.Status | ||||
if task.StartTime == 0 && result.Lease.CreateTime > 0 { | |||||
task.StartTime = timeutil.TimeStamp(result.Lease.CreateTime / 1000) | |||||
if task.StartTime == 0 && result.Lease.UpdateTime > 0 { | |||||
task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | |||||
} | } | ||||
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | ||||
task.EndTime = timeutil.TimeStampNow() | task.EndTime = timeutil.TimeStampNow() | ||||
@@ -1464,7 +1548,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
} | } | ||||
os.RemoveAll(codePath) | os.RemoveAll(codePath) | ||||
if err := downloadCode(repo, codePath); err != nil { | |||||
if err := downloadCode(repo, codePath, cloudbrain.DefaultBranchName); err != nil { | |||||
log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | ||||
@@ -1529,7 +1613,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, | |||||
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, cloudbrain.DefaultBranchName, "", "", | |||||
benchmarkTypeID, benchmarkChildTypeID, resourceSpecId) | benchmarkTypeID, benchmarkChildTypeID, resourceSpecId) | ||||
if err != nil { | if err != nil { | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
@@ -1555,10 +1639,66 @@ func BenchmarkDel(ctx *context.Context) { | |||||
} | } | ||||
} | } | ||||
func CloudBrainTrainJobNew(ctx *context.Context) { | |||||
err := cloudBrainNewDataPrepare(ctx) | |||||
if err != nil { | |||||
ctx.ServerError("get new train-job info failed", err) | |||||
return | |||||
} | |||||
ctx.HTML(http.StatusOK, tplCloudBrainTrainJobNew) | |||||
} | |||||
func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) { | |||||
var command string | |||||
bootFile := form.BootFile | |||||
params := form.Params | |||||
if !strings.HasSuffix(bootFile, ".py") { | |||||
log.Error("bootFile(%s) format error", bootFile) | |||||
return command, errors.New("bootFile format error") | |||||
} | |||||
var parameters models.Parameters | |||||
var param string | |||||
if len(params) != 0 { | |||||
err := json.Unmarshal([]byte(params), ¶meters) | |||||
if err != nil { | |||||
log.Error("Failed to Unmarshal params: %s (%v)", params, err) | |||||
return command, err | |||||
} | |||||
for _, parameter := range parameters.Parameter { | |||||
param += " --" + parameter.Label + "=" + parameter.Value | |||||
} | |||||
} | |||||
command += "python /code/" + bootFile + param + " > " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||||
return command, nil | |||||
} | |||||
func CloudBrainTrainJobDel(ctx *context.Context) { | |||||
var listType = ctx.Query("listType") | |||||
if err := deleteCloudbrainJob(ctx); err != nil { | |||||
log.Error("deleteCloudbrainJob failed: %v", err, ctx.Data["msgID"]) | |||||
ctx.ServerError(err.Error(), err) | |||||
return | |||||
} | |||||
var isAdminPage = ctx.Query("isadminpage") | |||||
if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | |||||
ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | |||||
} else { | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) | |||||
} | |||||
} | |||||
func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes { | func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes { | ||||
var lang = ctx.Locale.Language() | var lang = ctx.Locale.Language() | ||||
if benchmarkTypesMap[lang] == nil { | if benchmarkTypesMap[lang] == nil { | ||||
var val = i18n.Tr(lang, BENCHMARK_TYPE_CODE) | var val = i18n.Tr(lang, BENCHMARK_TYPE_CODE) | ||||
//use config | |||||
val = setting.BenchmarkTypes | |||||
var tempType *models.BenchmarkTypes | var tempType *models.BenchmarkTypes | ||||
if err := json.Unmarshal([]byte(val), &tempType); err != nil { | if err := json.Unmarshal([]byte(val), &tempType); err != nil { | ||||
log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", val, err, ctx.Data["MsgID"]) | log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", val, err, ctx.Data["MsgID"]) | ||||
@@ -47,20 +47,26 @@ const ( | |||||
) | ) | ||||
func DebugJobIndex(ctx *context.Context) { | func DebugJobIndex(ctx *context.Context) { | ||||
debugListType := ctx.Query("debugListType") | |||||
ctx.Data["ListType"] = debugListType | |||||
listType := ctx.Query("debugListType") | |||||
ctx.Data["ListType"] = listType | |||||
MustEnableCloudbrain(ctx) | MustEnableCloudbrain(ctx) | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
if page <= 0 { | if page <= 0 { | ||||
page = 1 | page = 1 | ||||
} | } | ||||
debugType := modelarts.DebugType | |||||
typeCloudBrain := models.TypeCloudBrainAll | |||||
jobTypeNot := false | jobTypeNot := false | ||||
if debugListType == models.GPUResource { | |||||
debugType = models.TypeCloudBrainOne | |||||
} else if debugListType == models.NPUResource { | |||||
debugType = models.TypeCloudBrainTwo | |||||
if listType == models.GPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainOne | |||||
} else if listType == models.NPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainTwo | |||||
} else if listType == models.AllResource { | |||||
typeCloudBrain = models.TypeCloudBrainAll | |||||
} else { | |||||
log.Error("listType(%s) error", listType) | |||||
ctx.ServerError("listType error", errors.New("listType error")) | |||||
return | |||||
} | } | ||||
var jobTypes []string | var jobTypes []string | ||||
@@ -71,7 +77,7 @@ func DebugJobIndex(ctx *context.Context) { | |||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
}, | }, | ||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
Type: debugType, | |||||
Type: typeCloudBrain, | |||||
JobTypeNot: jobTypeNot, | JobTypeNot: jobTypeNot, | ||||
JobTypes: jobTypes, | JobTypes: jobTypes, | ||||
}) | }) | ||||
@@ -93,7 +99,7 @@ func DebugJobIndex(ctx *context.Context) { | |||||
ctx.Data["Tasks"] = ciTasks | ctx.Data["Tasks"] = ciTasks | ||||
ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx) | ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx) | ||||
ctx.Data["RepoIsEmpty"] = repo.IsEmpty | ctx.Data["RepoIsEmpty"] = repo.IsEmpty | ||||
ctx.Data["debugListType"] = debugListType | |||||
ctx.Data["debugListType"] = listType | |||||
ctx.HTML(200, tplDebugJobIndex) | ctx.HTML(200, tplDebugJobIndex) | ||||
} | } | ||||
@@ -410,20 +416,45 @@ func NotebookManage(ctx *context.Context) { | |||||
break | break | ||||
} | } | ||||
task.Status = res.Status | |||||
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | |||||
task.EndTime = timeutil.TimeStampNow() | |||||
} | |||||
task.ComputeAndSetDuration() | |||||
err = models.UpdateJob(task) | |||||
if err != nil { | |||||
log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
resultCode = "-1" | |||||
errorMsg = "system error" | |||||
break | |||||
} | |||||
status = res.Status | |||||
if action == models.ActionStart { | |||||
newTask := &models.Cloudbrain{ | |||||
Status: status, | |||||
UserID: task.UserID, | |||||
RepoID: task.RepoID, | |||||
JobID: task.JobID, | |||||
JobName: task.JobName, | |||||
DisplayJobName: task.DisplayJobName, | |||||
JobType: task.JobType, | |||||
Type: task.Type, | |||||
Uuid: task.Uuid, | |||||
Image: task.Image, | |||||
ComputeResource: task.ComputeResource, | |||||
Description: task.Description, | |||||
} | |||||
status = task.Status | |||||
err = models.RestartCloudbrain(task, newTask) | |||||
if err != nil { | |||||
log.Error("RestartCloudbrain(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
resultCode = "-1" | |||||
errorMsg = "system error" | |||||
break | |||||
} | |||||
ID = strconv.FormatInt(newTask.ID, 10) | |||||
} else { | |||||
task.Status = res.Status | |||||
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | |||||
task.EndTime = timeutil.TimeStampNow() | |||||
} | |||||
task.ComputeAndSetDuration() | |||||
err = models.UpdateJob(task) | |||||
if err != nil { | |||||
log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
resultCode = "-1" | |||||
errorMsg = "system error" | |||||
break | |||||
} | |||||
} | |||||
break | break | ||||
} | } | ||||
@@ -480,6 +511,26 @@ func TrainJobIndex(ctx *context.Context) { | |||||
page = 1 | page = 1 | ||||
} | } | ||||
listType := ctx.Query("listType") | |||||
if len(listType) == 0 { | |||||
listType = models.AllResource | |||||
} | |||||
ctx.Data["ListType"] = listType | |||||
typeCloudBrain := models.TypeCloudBrainAll | |||||
if listType == models.GPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainOne | |||||
} else if listType == models.NPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainTwo | |||||
} else if listType == models.AllResource { | |||||
typeCloudBrain = models.TypeCloudBrainAll | |||||
} | |||||
//else { | |||||
// log.Error("listType(%s) error", listType) | |||||
// ctx.ServerError("listType error", errors.New("listType error")) | |||||
// return | |||||
//} | |||||
var jobTypes []string | var jobTypes []string | ||||
jobTypes = append(jobTypes, string(models.JobTypeTrain)) | jobTypes = append(jobTypes, string(models.JobTypeTrain)) | ||||
tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | ||||
@@ -488,7 +539,7 @@ func TrainJobIndex(ctx *context.Context) { | |||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
}, | }, | ||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
Type: models.TypeCloudBrainTwo, | |||||
Type: typeCloudBrain, | |||||
JobTypeNot: false, | JobTypeNot: false, | ||||
JobTypes: jobTypes, | JobTypes: jobTypes, | ||||
IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
@@ -501,11 +552,16 @@ func TrainJobIndex(ctx *context.Context) { | |||||
for i, task := range tasks { | for i, task := range tasks { | ||||
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | ||||
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | ||||
tasks[i].ComputeResource = models.NPUResource | |||||
if task.Cloudbrain.Type == models.TypeCloudBrainOne { | |||||
tasks[i].ComputeResource = models.GPUResource | |||||
} else if task.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||||
tasks[i].ComputeResource = models.NPUResource | |||||
} | |||||
} | } | ||||
pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | ||||
pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
pager.AddParam(ctx, "listType", "ListType") | |||||
ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
@@ -1555,6 +1611,7 @@ func trainJobGetLog(jobID string) (*models.GetTrainJobLogFileNamesResult, *model | |||||
func TrainJobDel(ctx *context.Context) { | func TrainJobDel(ctx *context.Context) { | ||||
var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
var listType = ctx.Query("listType") | |||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
var jobTypes []string | var jobTypes []string | ||||
@@ -1596,12 +1653,13 @@ func TrainJobDel(ctx *context.Context) { | |||||
if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | ||||
ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | ||||
} else { | } else { | ||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) | |||||
} | } | ||||
} | } | ||||
func TrainJobStop(ctx *context.Context) { | func TrainJobStop(ctx *context.Context) { | ||||
var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
var listType = ctx.Query("listType") | |||||
task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
_, err := modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10)) | _, err := modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10)) | ||||
@@ -1611,7 +1669,7 @@ func TrainJobStop(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) | |||||
} | } | ||||
func canUserCreateTrainJob(uid int64) (bool, error) { | func canUserCreateTrainJob(uid int64) (bool, error) { | ||||
@@ -2276,7 +2334,7 @@ func SetJobCount(ctx *context.Context) { | |||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
_, jobCount, err := models.Cloudbrains(&models.CloudbrainsOptions{ | _, jobCount, err := models.Cloudbrains(&models.CloudbrainsOptions{ | ||||
RepoID: repoId, | RepoID: repoId, | ||||
Type: modelarts.DebugType, | |||||
Type: models.TypeCloudBrainAll, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("Get job faild:", err) | ctx.ServerError("Get job faild:", err) | ||||
@@ -323,6 +323,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Get("/action/notification", routers.ActionNotification) | m.Get("/action/notification", routers.ActionNotification) | ||||
m.Get("/recommend/org", routers.RecommendOrgFromPromote) | m.Get("/recommend/org", routers.RecommendOrgFromPromote) | ||||
m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | ||||
m.Post("/all/search/", routers.Search) | |||||
m.Get("/all/search/", routers.EmptySearch) | |||||
m.Get("/all/dosearch/", routers.SearchApi) | |||||
m.Get("/home/term", routers.HomeTerm) | m.Get("/home/term", routers.HomeTerm) | ||||
m.Group("/explore", func() { | m.Group("/explore", func() { | ||||
m.Get("", func(ctx *context.Context) { | m.Get("", func(ctx *context.Context) { | ||||
@@ -1035,6 +1038,19 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) | m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) | ||||
m.Get("/get_child_types", repo.GetChildTypes) | m.Get("/get_child_types", repo.GetChildTypes) | ||||
}) | }) | ||||
m.Group("/train-job", func() { | |||||
m.Group("/:jobid", func() { | |||||
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
//m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) | |||||
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
//m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobNewVersion) | |||||
//m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||||
}) | |||||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainTrainJobNew) | |||||
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | |||||
}) | |||||
}, context.RepoRef()) | }, context.RepoRef()) | ||||
m.Group("/modelmanage", func() { | m.Group("/modelmanage", func() { | ||||
m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) | m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) | ||||
@@ -10,7 +10,7 @@ import ( | |||||
"github.com/elliotchance/orderedmap" | "github.com/elliotchance/orderedmap" | ||||
) | ) | ||||
var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 25, 26, 27, 28, 29, 30} | |||||
var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 25, 26, 27, 28, 29, 30, 31} | |||||
type ClientsManager struct { | type ClientsManager struct { | ||||
Clients *orderedmap.OrderedMap | Clients *orderedmap.OrderedMap | ||||
@@ -95,9 +95,9 @@ | |||||
{{if .IsSigned}} | {{if .IsSigned}} | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="hot"> | <input type="hidden" name="sort" value="hot"> | ||||
@@ -199,9 +199,9 @@ | |||||
<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="hot"> | <input type="hidden" name="sort" value="hot"> | ||||
@@ -93,9 +93,9 @@ | |||||
{{if .IsSigned}} | {{if .IsSigned}} | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
@@ -196,9 +196,9 @@ | |||||
<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
@@ -96,9 +96,9 @@ | |||||
{{if .IsSigned}} | {{if .IsSigned}} | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
@@ -199,9 +199,9 @@ | |||||
<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
<div class="right stackable menu"> | <div class="right stackable menu"> | ||||
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
<input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
<input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
@@ -0,0 +1,95 @@ | |||||
{{template "base/head" .}} | |||||
<div class="explore seach"> | |||||
<div class="repos--seach"> | |||||
<div class="ui container"> | |||||
<div id="search_div" class="ui two column centered grid"> | |||||
<div class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin-top:1.2rem;margin-bottom: 1.2rem;"> | |||||
<div class="ui fluid action input"> | |||||
<input name="q" id="keyword_input" value="{{.Keyword}}" placeholder="{{.i18n.Tr "home.search"}}..." autofocus=""> | |||||
<input type="hidden" name="topic" value=""> | |||||
<input type="hidden" name="tab" value=""> | |||||
<input type="hidden" name="sort" value="hot"> | |||||
<button class="ui green button" onclick="search()">{{.i18n.Tr "home.search"}}</button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div id="search_label_div" style="display:none"> | |||||
</div> | |||||
</div> | |||||
<div class="ui container seachnav"> | |||||
<div class="ui secondary pointing menu"> | |||||
<a id="repo_item" class="item" href="javascript:searchItem(1,10);"> | |||||
{{.i18n.Tr "home.search_repo"}} | |||||
<span class="ui circular mini label" id="repo_total"></span> | |||||
</a> | |||||
<a id="dataset_item" class="item" href="javascript:searchItem(5,50);"> | |||||
{{.i18n.Tr "home.search_dataset"}} | |||||
<span class="ui circular mini label" id="dataset_total"></span> | |||||
</a> | |||||
<a id="issue_item" class="item" href="javascript:searchItem(2,20);"> | |||||
{{.i18n.Tr "home.search_issue"}} | |||||
<span class="ui circular mini label" id="issue_total"></span> | |||||
</a> | |||||
<a id="pr_item" class="item" href="javascript:searchItem(6,60);"> | |||||
{{.i18n.Tr "home.search_pr"}} | |||||
<span class="ui circular mini label" id="pr_total"></span> | |||||
</a> | |||||
<a id="user_item" class="item" href="javascript:searchItem(3,30);"> | |||||
{{.i18n.Tr "home.search_user"}} | |||||
<span class="ui circular mini label" id="user_total"></span> | |||||
</a> | |||||
<a id="org_item" class="item" href="javascript:searchItem(4,40);"> | |||||
{{.i18n.Tr "home.search_org"}} <span class="ui circular mini label" id="org_total"></span> | |||||
</a> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui container"> | |||||
<span id="find_id">{{.i18n.Tr "home.search_finded"}}</span><span id="find_title"></span> | |||||
<div class="ui right floated secondary filter menu"> | |||||
<!-- Sort --> | |||||
<div class="ui right dropdown type jump item"> | |||||
<span class="text"> | |||||
{{.i18n.Tr "repo.issues.filter_sort"}} | |||||
<i class="dropdown icon"></i> | |||||
</span> | |||||
<div class="menu" id="sort_type"> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui divider" style="margin-top: 1.25rem;"></div> | |||||
<div class="ui very relaxed divided list" id="child_search_item"> | |||||
</div><!--seach list end--> | |||||
<div class="center page buttons" style="margin: 0px auto 15px"> | |||||
<div class="ui borderless mini pagination menu" id="page_menu"> | |||||
</div> | |||||
</div> | |||||
<div id="tipmsg"></div> | |||||
</div> | |||||
</div> | |||||
<script src="/self/js/jquery.min.js" type="text/javascript"></script> | |||||
<script src="/home/search.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<div class="am-mt-30"></div> | |||||
{{template "base/footer" .}} |
@@ -0,0 +1,451 @@ | |||||
{{template "base/head" .}} | |||||
<style> | |||||
.unite{ | |||||
font-family: SourceHanSansSC-medium !important; | |||||
color: rgba(16, 16, 16, 100) !important; | |||||
} | |||||
.title{ | |||||
font-size: 16px !important; | |||||
padding-left: 3rem !important; | |||||
} | |||||
.min_title{ | |||||
font-size: 14px !important; | |||||
padding-left: 6rem !important; | |||||
margin-bottom: 2rem !important; | |||||
} | |||||
.width{ | |||||
width:100% !important; | |||||
} | |||||
.width80{ | |||||
width: 80.7% !important; | |||||
margin-left: 10px; | |||||
} | |||||
.width806{ | |||||
width: 80.6% !important; | |||||
margin-left: -2px; | |||||
} | |||||
.width85{ | |||||
width: 85% !important; | |||||
margin-left: 4.5rem !important; | |||||
} | |||||
.width81{ | |||||
margin-left: 1.5rem !important; | |||||
width: 81% !important; | |||||
} | |||||
.add{font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 0px 5px 5px 0px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
.min{ | |||||
font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 5px 0px 0px 5px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
</style> | |||||
<!-- <div class="ui page dimmer"> | |||||
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> | |||||
</div> --> | |||||
<div id="mask"> | |||||
<div id="loadingPage"> | |||||
<div class="rect1"></div> | |||||
<div class="rect2"></div> | |||||
<div class="rect3"></div> | |||||
<div class="rect4"></div> | |||||
<div class="rect5"></div> | |||||
</div> | |||||
</div> | |||||
<div class="repository"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui container"> | |||||
{{template "base/alert" .}} | |||||
<h4 class="ui top attached header"> | |||||
{{.i18n.Tr "repo.modelarts.train_job.new"}} | |||||
</h4> | |||||
<div class="ui attached segment"> | |||||
<!-- equal width --> | |||||
<form class="ui form" action="{{.Link}}" method="post"> | |||||
{{.CsrfTokenHtml}} | |||||
<input type="hidden" name="action" value="update"> | |||||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
<div class="ui blue mini menu compact selectcloudbrain"> | |||||
<a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | |||||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
<path fill="none" d="M0 0h24v24H0z"/> | |||||
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
</svg> | |||||
CPU/GPU | |||||
</a> | |||||
<a class="item" href="{{.RepoLink}}/modelarts/train-job/create"> | |||||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
<path fill="none" d="M0 0h24v24H0z"/> | |||||
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
</svg> | |||||
Ascend NPU</a> | |||||
</div> | |||||
</div> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
</div> | |||||
<div class="unite min_title inline field"> | |||||
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
</div> | |||||
<div class="ui divider"></div> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
{{if .branch_name}} | |||||
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branch_name }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{else}} | |||||
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branchName }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="inline required field" style="display: none;"> | |||||
<label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||||
<select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
<option name="job_type" value="TRAIN">TRAIN</option> | |||||
</select> | |||||
</div> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
<select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||||
{{range .train_gpu_types}} | |||||
<option value="{{.Queue}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="required unite min_title inline field" style="position: relative;"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}} </label> | |||||
<input class="width81" type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||||
<i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||||
<datalist class="ui search" id="cloudbrain_image" name="image"> | |||||
{{range .images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
{{range .public_images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
</datalist> | |||||
</div> | |||||
<div class="inline unite min_title field required"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
{{if .bootFile}} | |||||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
{{else}} | |||||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
{{end}} | |||||
<span> | |||||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
</span> | |||||
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">查看样例</a> | |||||
</div> | |||||
<div class="required unite min_title inline field" style="position: relative;"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.dataset"}}</label> | |||||
<select id="cloudbrain_dataset" class="ui search dropdown width80" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||||
{{range .attachments}} | |||||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
{{end}} | |||||
</select> | |||||
<span class="tooltips">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||||
</div> | |||||
<div class="inline unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
<input id="store_run_para" type="hidden" name="run_para_list"> | |||||
<div class="dynamic field" style="margin-top: 1rem;"> | |||||
{{if .params}} | |||||
{{if ne 0 (len .params)}} | |||||
{{range $k ,$v := .params}} | |||||
<div class="two fields width85" id="para{{$k}}"> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
</div> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
</div> | |||||
<span> | |||||
<i class="trash icon"></i> | |||||
</span> | |||||
</div> | |||||
{{end}} | |||||
{{end}} | |||||
{{end}} | |||||
</div> | |||||
</div> | |||||
<div class="required inline unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
{{range .train_resource_specs}} | |||||
<option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="inline unite min_title field"> | |||||
<button class="ui create_train_job green button"> | |||||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||||
</button> | |||||
<a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
</div> | |||||
<!-- 模态框 --> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} | |||||
<script> | |||||
//let url_href = window.location.pathname.split('create')[0] | |||||
//$(".ui.button").attr('href',url_href) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
$('.menu .item') | |||||
.tab(); | |||||
let sever_num = $('#trainjob_work_server_num') | |||||
$('.add').click(function(){ | |||||
sever_num.val(parseInt(sever_num.val())+1) | |||||
if(sever_num.val()>=26){ | |||||
sever_num.val(parseInt(sever_num.val())-1) | |||||
} | |||||
}) | |||||
$('.min').click(function(){ | |||||
sever_num.val(parseInt(sever_num.val())-1) | |||||
if(sever_num.val()<=0){ | |||||
sever_num.val(parseInt(sever_num.val())+1) | |||||
} | |||||
}) | |||||
// 参数增加、删除、修改、保存 | |||||
function Add_parameter(i){ | |||||
value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
'<div class="field">' + | |||||
'<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
'</div> ' + | |||||
'<div class="field"> ' + | |||||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
'</div>'+ | |||||
'<span>' + | |||||
'<i class="trash icon">' + | |||||
'</i>' + | |||||
'</span>' + | |||||
'</div>' | |||||
$(".dynamic.field").append(value) | |||||
} | |||||
$('#add_run_para').click(function(){ | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
}); | |||||
$(".dynamic.field").on("click",".trash.icon", function() { | |||||
var index = $(this).parent().parent().index() | |||||
$(this).parent().parent().remove() | |||||
var len = $(".dynamic.field .two.fields").length | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var cur_index = $(this).index() | |||||
$(this).attr('id', 'para' + cur_index) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.green.button').click(function(){ | |||||
var parameters = []; | |||||
$('table tr').each(function() { | |||||
$(this).find('td:eq(1)').each(function(){ | |||||
parameters.push($(this).text()); | |||||
}) | |||||
$(this).find('input').each(function(){ | |||||
parameters.push($(this).text()) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
for(var i = 2; i < parameters.length; i++){ | |||||
switch(i) { | |||||
// 数据集uuid待完成 | |||||
// case (2): | |||||
// console.log(1) | |||||
// break; | |||||
// $("#trainjob_datasets").val(parameters[i]); | |||||
// console.log($("#trainjob_datasets").val()) | |||||
case (3): | |||||
$("input[name='boot_file']").val(parameters[i]); | |||||
break; | |||||
case (4): | |||||
var para = parameters[i].split(" ") | |||||
for(var j = 0; j < para.length; j++){ | |||||
var para_name = para[j].split('=')[0] | |||||
var para_value = para[j].split('=')[1] | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
var pid = 'para' + len | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
} | |||||
break; | |||||
// 数据集pool_id待完成 | |||||
// case (5): | |||||
// $("select[name='pool_id']").val(parameters[i]); | |||||
// break; | |||||
case (6): | |||||
$("input[name='work_server_number']").val(parameters[i]); | |||||
break; | |||||
} | |||||
} | |||||
}) | |||||
$('.ui.save.checkbox').click(function(){ | |||||
$(this).checkbox({ | |||||
onChange: function(){ | |||||
if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
$('#save_para').removeClass("disabled") | |||||
}else{ | |||||
$('#save_para').addClass("disabled") | |||||
} | |||||
} | |||||
}); | |||||
}) | |||||
$('.question.circle.icon').hover(function(){ | |||||
$(this).popup('show') | |||||
}); | |||||
$(".item.active.parameter_config").click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('setting', 'closable', false) | |||||
.modal('show'); | |||||
}) | |||||
$('.ui.deny.button').click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
}) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
function validate(){ | |||||
$('.ui.form') | |||||
.form({ | |||||
on: 'blur', | |||||
fields: { | |||||
boot_file: { | |||||
identifier : 'boot_file', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/.+\.py$/g]', | |||||
} | |||||
] | |||||
}, | |||||
display_job_name:{ | |||||
identifier : 'display_job_name', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
} | |||||
] | |||||
}, | |||||
attachment:{ | |||||
identifier : 'attachment', | |||||
rules: [ | |||||
{ | |||||
type: 'empty', | |||||
} | |||||
] | |||||
}, | |||||
work_server_number: { | |||||
identifier : 'work_server_number', | |||||
rules: [ | |||||
{ | |||||
type : 'integer[1..25]', | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
onSuccess: function(){ | |||||
// $('.ui.page.dimmer').dimmer('show') | |||||
document.getElementById("mask").style.display = "block" | |||||
}, | |||||
onFailure: function(e){ | |||||
return false; | |||||
} | |||||
}) | |||||
} | |||||
document.onreadystatechange = function() { | |||||
if (document.readyState === "complete") { | |||||
document.getElementById("mask").style.display = "none" | |||||
} | |||||
} | |||||
function send_run_para(){ | |||||
var run_parameters = [] | |||||
var msg = {} | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
run_parameters.push({"label": para_name, "value": para_value}) | |||||
}) | |||||
msg["parameter"] = run_parameters | |||||
msg = JSON.stringify(msg) | |||||
$('#store_run_para').val(msg) | |||||
} | |||||
function get_name(){ | |||||
let name1=$("#engine_name .text").text() | |||||
let name2=$("#flaver_name .text").text() | |||||
$("input#ai_engine_name").val(name1) | |||||
$("input#ai_flaver_name").val(name2) | |||||
} | |||||
$('.ui.create_train_job.green.button').click(function(e) { | |||||
get_name() | |||||
send_run_para() | |||||
validate() | |||||
}) | |||||
</script> |
@@ -0,0 +1,653 @@ | |||||
{{template "base/head" .}} | |||||
<style> | |||||
.according-panel-heading{ | |||||
box-sizing: border-box; | |||||
padding: 8px 16px; | |||||
color: #252b3a; | |||||
background-color: #f2f5fc; | |||||
line-height: 1.5; | |||||
cursor: pointer; | |||||
-moz-user-select: none; | |||||
-webkit-user-select: none; | |||||
-ms-user-select: none; | |||||
-khtml-user-select: none; | |||||
user-select: none; | |||||
} | |||||
.accordion-panel-title { | |||||
margin-top: 0; | |||||
margin-bottom: 0; | |||||
color: #252b3a; | |||||
} | |||||
.accordion-panel-title-content{ | |||||
vertical-align: middle; | |||||
display: inline-block; | |||||
width: calc(100% - 32px); | |||||
cursor: default; | |||||
} | |||||
.acc-margin-bottom { | |||||
margin-bottom: 5px; | |||||
} | |||||
.title_text { | |||||
font-size: 12px; | |||||
} | |||||
.ac-display-inblock { | |||||
display: inline-block; | |||||
} | |||||
.cti-mgRight-sm { | |||||
margin-right: 8px; | |||||
} | |||||
.ac-text-normal { | |||||
font-size: 14px; | |||||
color: #575d6c; | |||||
} | |||||
.uc-accordionTitle-black { | |||||
color: #333; | |||||
} | |||||
.accordion-border{ | |||||
border:1px solid #cce2ff; | |||||
} | |||||
.padding0{ | |||||
padding: 0 !important; | |||||
} | |||||
.content-pad{ | |||||
padding: 15px 35px; | |||||
} | |||||
.content-margin{ | |||||
margin:10px 5px ; | |||||
} | |||||
.tab_2_content { | |||||
min-height: 360px; | |||||
margin-left: 10px; | |||||
} | |||||
.ac-grid { | |||||
display: block; | |||||
*zoom: 1; | |||||
} | |||||
.ac-grid-col { | |||||
float: left; | |||||
width: 100%; | |||||
} | |||||
.ac-grid-col2 .ac-grid-col { | |||||
width: 50%; | |||||
} | |||||
.ti-form { | |||||
text-align: left; | |||||
max-width: 100%; | |||||
vertical-align: middle; | |||||
} | |||||
.ti-form>tbody { | |||||
font-size: 12px; | |||||
} | |||||
.ti-form>tbody, .ti-form>tbody>tr { | |||||
vertical-align: inherit; | |||||
} | |||||
.ti-text-form-label { | |||||
padding-bottom: 20px; | |||||
padding-right: 20px; | |||||
color: #8a8e99; | |||||
font-size: 12px; | |||||
white-space: nowrap !important; | |||||
width: 80px; | |||||
line-height: 30px; | |||||
} | |||||
.ti-text-form-content{ | |||||
line-height: 30px; | |||||
padding-bottom: 20px; | |||||
} | |||||
.ti-form>tbody>tr>td { | |||||
vertical-align: top; | |||||
white-space: normal; | |||||
} | |||||
td, th { | |||||
padding: 0; | |||||
} | |||||
.ac-grid-col .text-span { | |||||
width: 450px; | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
white-space: nowrap; | |||||
} | |||||
.redo-color{ | |||||
color: #3291F8; | |||||
} | |||||
.ti-action-menu-item:not(:last-child){ | |||||
margin-right: 10px; | |||||
padding-right: 11px; | |||||
text-decoration: none!important; | |||||
color: #526ecc; | |||||
cursor: pointer; | |||||
display: inline-block; | |||||
-moz-user-select: none; | |||||
-webkit-user-select: none; | |||||
-ms-user-select: none; | |||||
-khtml-user-select: none; | |||||
user-select: none; | |||||
position: relative; | |||||
} | |||||
.ti-action-menu-item:not(:last-child):after { | |||||
content: ""; | |||||
display: inline-block; | |||||
position: absolute; | |||||
height: 12px; | |||||
right: 0; | |||||
top: 50%; | |||||
-webkit-transform: translateY(-6px); | |||||
-ms-transform: translateY(-6px); | |||||
-o-transform: translateY(-6px); | |||||
transform: translateY(-6px); | |||||
border-right: 1px solid #dfe1e6; | |||||
} | |||||
.text-width80{ | |||||
width: 100px; | |||||
line-height: 30px; | |||||
} | |||||
.border-according{ | |||||
border: 1px solid #dfe1e6; | |||||
} | |||||
.disabled { | |||||
cursor: default; | |||||
pointer-events: none; | |||||
color: rgba(0,0,0,.6) !important; | |||||
opacity: .45 !important; | |||||
} | |||||
.pad20{ | |||||
border:0px !important; | |||||
} | |||||
.model_file_bread{ | |||||
margin-bottom: -0.5rem !important; | |||||
padding-left: 1rem; | |||||
padding-top: 0.5rem ; | |||||
} | |||||
</style> | |||||
<div id="mask"> | |||||
<div id="loadingPage"> | |||||
<div class="rect1"></div> | |||||
<div class="rect2"></div> | |||||
<div class="rect3"></div> | |||||
<div class="rect4"></div> | |||||
<div class="rect5"></div> | |||||
</div> | |||||
</div> | |||||
<div class="repository"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui container"> | |||||
<h4 class="ui header" id="vertical-segment"> | |||||
<div class="ui breadcrumb"> | |||||
<a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||||
{{.i18n.Tr "repo.cloudbrain"}} | |||||
</a> | |||||
<div class="divider"> / </div> | |||||
<a class="section" href="{{$.RepoLink}}/modelarts/train-job"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job"}} | |||||
</a> | |||||
<div class="divider"> / </div> | |||||
<div class="active section">{{.displayJobName}}</div> | |||||
</div> | |||||
</h4> | |||||
{{range $k ,$v := .version_list_task}} | |||||
<div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||||
<div class="{{if eq $k 0}}active{{end}} title padding0"> | |||||
<div class="according-panel-heading"> | |||||
<div class="accordion-panel-title"> | |||||
<i class="dropdown icon"></i> | |||||
<span class="accordion-panel-title-content"> | |||||
<span> | |||||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||||
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||||
<span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
</span> | |||||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||||
<span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||||
</div> | |||||
</span> | |||||
</span> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="{{if eq $k 0}}active{{end}} content"> | |||||
<div class="content-pad"> | |||||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||||
<a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||||
<!--<a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a>--> | |||||
<a class="item" data-tab="third{{$k}}" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||||
</div> | |||||
<div class="ui tab active" data-tab="first{{$k}}"> | |||||
<div style="padding-top: 10px;"> | |||||
<div class="tab_2_content"> | |||||
<div class="ac-grid ac-grid-col2"> | |||||
<div class="ac-grid-col"> | |||||
<table class="ti-form"> | |||||
<tbody class="ti-text-form"> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.DisplayJobName}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.status"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||||
{{.Status}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
<span style="font-size: 12px;" class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||||
{{$.duration}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{$.resource_type}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{$.resource_spec}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<div class="ac-grid-col"> | |||||
<table class="ti-form"> | |||||
<tbody class="ti-text-form"> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
镜像 | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||||
{{.Image}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.code_version"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.BranchName}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.BootFile}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.DatasetName}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80" > | |||||
{{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" title="{{.Parameters}}"> | |||||
{{.Parameters}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" title="{{.Description}}"> | |||||
{{.Description}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="second{{$k}}"> | |||||
<div> | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log" id="log{{.VersionName}}" style="height: 300px !important; overflow: auto;"> | |||||
<input type="hidden" name="end_line" value> | |||||
<input type="hidden" name="start_line" value> | |||||
<pre id="log_file{{.VersionName}}"></pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="third{{$k}}"> | |||||
<input type="hidden" name="model{{.VersionName}}" value="-1"> | |||||
<input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||||
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||||
<div class="active section">{{.VersionName}}</div> | |||||
<div class="divider"> / </div> | |||||
</div> | |||||
<div id="dir_list{{.VersionName}}"> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{end}} {{template "base/paginate" .}} | |||||
</div> | |||||
<!-- 确认模态框 --> | |||||
<div id="deletemodel"> | |||||
<div class="ui basic modal"> | |||||
<div class="ui icon header"> | |||||
<i class="trash icon"></i> 删除任务 | |||||
</div> | |||||
<div class="content"> | |||||
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
</div> | |||||
<div class="actions"> | |||||
<div class="ui red basic inverted cancel button"> | |||||
<i class="remove icon"></i> 取消操作 | |||||
</div> | |||||
<div class="ui green basic inverted ok button"> | |||||
<i class="checkmark icon"></i> 确定操作 | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} | |||||
<script> | |||||
$('.menu .item').tab() | |||||
$(document).ready(function(){ | |||||
$('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||||
}); | |||||
$(document).ready(function(){ | |||||
$('.secondary.menu .item').tab(); | |||||
}); | |||||
let userName | |||||
let repoPath | |||||
let jobID | |||||
let downlaodFlag = {{$.canDownload}} | |||||
let taskID = {{$.task.ID}} | |||||
let realJobName = {{$.task.JobName}} | |||||
$(document).ready(function(){ | |||||
let url = window.location.href; | |||||
let urlArr = url.split('/') | |||||
userName = urlArr.slice(-5)[0] | |||||
repoPath = urlArr.slice(-4)[0] | |||||
jobID = urlArr.slice(-1)[0] | |||||
}) | |||||
function stopBubbling(e) { | |||||
e = window.event || e; | |||||
if (e.stopPropagation) { | |||||
e.stopPropagation(); //阻止事件 冒泡传播 | |||||
} else { | |||||
e.cancelBubble = true; //ie兼容 | |||||
} | |||||
} | |||||
let timeid = window.setInterval(loadJobStatus, 30000); | |||||
$(document).ready(loadJobStatus); | |||||
function loadLog(version_name){ | |||||
document.getElementById("mask").style.display = "block" | |||||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||||
$('input[name=end_line]').val(data.EndLine) | |||||
$('input[name=start_line]').val(data.StartLine) | |||||
$(`#log_file${version_name}`).text(data.Content) | |||||
document.getElementById("mask").style.display = "none" | |||||
}).fail(function(err) { | |||||
console.log(err); | |||||
document.getElementById("mask").style.display = "none" | |||||
}); | |||||
} | |||||
function loadModelFile(version_name,parents,filename,init){ | |||||
parents = parents || '' | |||||
filename = filename || '' | |||||
init = init || '' | |||||
console.log("start") | |||||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | |||||
$(`#dir_list${version_name}`).empty() | |||||
renderDir(data,version_name) | |||||
if(init==="init"){ | |||||
$(`input[name=model${version_name}]`).val("") | |||||
$(`input[name=modelback${version_name}]`).val(version_name) | |||||
$(`#file_breadcrumb${version_name}`).empty() | |||||
let htmlBread = "" | |||||
htmlBread += `<div class='active section'>${version_name}</div>` | |||||
htmlBread += "<div class='divider'> / </div>" | |||||
$(`#file_breadcrumb${version_name}`).append(htmlBread) | |||||
}else{ | |||||
renderBrend(version_name,parents,filename,init) | |||||
} | |||||
}).fail(function(err) { | |||||
console.log(err,version_name); | |||||
}); | |||||
} | |||||
function renderBrend(version_name,parents,filename,init){ | |||||
if(init=="folder"){ | |||||
let htmlBrend = "" | |||||
let sectionName=$(`#file_breadcrumb${version_name} .active.section`).text() | |||||
let parents1 = $(`input[name=model${version_name}]`).val() | |||||
let filename1 = $(`input[name=modelback${version_name}]`).val() | |||||
if(parents1===""){ | |||||
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','','init')">${sectionName}</a>`) | |||||
}else{ | |||||
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | |||||
} | |||||
htmlBrend += `<div class='active section'>${filename}</div>` | |||||
htmlBrend += "<div class='divider'> / </div>" | |||||
$(`#file_breadcrumb${version_name}`).append(htmlBrend) | |||||
$(`input[name=model${version_name}]`).val(parents) | |||||
$(`input[name=modelback${version_name}]`).val(filename) | |||||
}else{ | |||||
$(`input[name=model${version_name}]`).val(parents) | |||||
$(`input[name=modelback${version_name}]`).val(filename) | |||||
$(`#file_breadcrumb${version_name} a.section:contains(${filename})`).nextAll().remove() | |||||
$(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | |||||
$(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | |||||
} | |||||
} | |||||
function renderDir(data,version_name){ | |||||
let html="" | |||||
html += "<div class='ui grid' style='margin:0;'>" | |||||
html += "<div class='row' style='padding: 0;'>" | |||||
html += "<div class='ui sixteen wide column' style='padding:1rem;'>" | |||||
html += "<div class='dir list'>" | |||||
html += "<table id='repo-files-table' class='ui single line table pad20'>" | |||||
html += '<tbody>' | |||||
// html += "</tbody>" | |||||
for(let i=0;i<data.Dirs.length;i++){ | |||||
let dirs_size = renderSize(data.Dirs[i].Size) | |||||
html += "<tr>" | |||||
html += "<td class='name six wid'>" | |||||
html += "<span class='truncate'>" | |||||
html += "<span class='octicon octicon-file-directory'>" | |||||
html += "</span>" | |||||
if(data.Dirs[i].IsDir){ | |||||
html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | |||||
html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
}else{ | |||||
if(downlaodFlag){ | |||||
html += `<a href="${location.href}/download_model?version_name=${version_name}&fileName=${data.Dirs[i].FileName}&parentDir=${data.Dirs[i].ParenDir}&jobName=${realJobName}">` | |||||
} | |||||
else{ | |||||
html += `<a class="disabled">` | |||||
} | |||||
html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
} | |||||
html += '</a>' | |||||
html += "</span>" | |||||
html += "</td>" | |||||
html += "<td class='message seven wide'>" | |||||
if(data.Dirs[i].IsDir){ | |||||
html += "<span class='truncate has-emoji'></span>" | |||||
}else{ | |||||
html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | |||||
} | |||||
html += "</td>" | |||||
html += "<td class='text right age three wide'>" | |||||
html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | |||||
html += "</td>" | |||||
html += "</tr>" | |||||
} | |||||
html += "</tbody>" | |||||
html += "</table>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
$(`#dir_list${version_name}`).append(html) | |||||
} | |||||
function renderSize(value){ | |||||
if(null==value||value==''){ | |||||
return "0 Bytes"; | |||||
} | |||||
var unitArr = new Array("Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"); | |||||
var index=0; | |||||
var srcsize = parseFloat(value); | |||||
index=Math.floor(Math.log(srcsize)/Math.log(1024)); | |||||
var size =srcsize/Math.pow(1024,index); | |||||
size=size.toFixed(0);//保留的小数位数 | |||||
return size+unitArr[index]; | |||||
} | |||||
function loadJobStatus() { | |||||
$(".ui.accordion.border-according").each((index, job) => { | |||||
const jobID = job.dataset.jobid; | |||||
const repoPath = job.dataset.repopath; | |||||
const versionname = job.dataset.version | |||||
// ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||||
// if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED' | |||||
// || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED' | |||||
// || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||||
// return | |||||
// } | |||||
let status = $(`#${versionname}-status-span`).text() | |||||
if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUCCEEDED'].includes(status)){ | |||||
return | |||||
} | |||||
let stopArray=["KILLED","FAILED","START_FAILED","KILLING","COMPLETED","SUCCEEDED"] | |||||
$.get(`/api/v1/repos/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`, (data) => { | |||||
//$(`#${versionname}-duration-span`).text(data.JobDuration) | |||||
$(`#${versionname}-status-span span`).text(data.JobStatus) | |||||
$(`#${versionname}-status-span i`).attr("class",data.JobStatus) | |||||
// detail status and duration | |||||
//$('#'+versionname+'-duration').text(data.JobDuration) | |||||
$('#'+versionname+'-status').text(data.JobStatus) | |||||
if(stopArray.includes(data.JobStatus)){ | |||||
$('#'+versionname+'-stop').addClass('disabled') | |||||
} | |||||
if(data.JobStatus==="COMPLETED"){ | |||||
$('#'+versionname+'-create-model').removeClass('disabled').addClass('blue') | |||||
} | |||||
}).fail(function(err) { | |||||
console.log(err); | |||||
}); | |||||
}); | |||||
}; | |||||
function refreshStatus(version_name){ | |||||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`,(data)=>{ | |||||
// header status and duration | |||||
//$(`#${version_name}-duration-span`).text(data.JobDuration) | |||||
$(`#${version_name}-status-span span`).text(data.JobStatus) | |||||
$(`#${version_name}-status-span i`).attr("class",data.JobStatus) | |||||
// detail status and duration | |||||
//$('#'+version_name+'-duration').text(data.JobDuration) | |||||
$('#'+version_name+'-status').text(data.JobStatus) | |||||
loadLog(version_name) | |||||
}).fail(function(err) { | |||||
console.log(err); | |||||
}); | |||||
stopBubbling(arguments.callee.caller.arguments[0]) | |||||
} | |||||
</script> |
@@ -27,7 +27,7 @@ | |||||
</div> | </div> | ||||
<div class="field"> | <div class="field"> | ||||
<div class="files"></div> | <div class="files"></div> | ||||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}asdsadsad" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div> | |||||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div> | |||||
</div> | </div> | ||||
{{template "repo/editor/commit_form" .}} | {{template "repo/editor/commit_form" .}} | ||||
</form> | </form> | ||||
@@ -39,8 +39,18 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="column right aligned"> | <div class="column right aligned"> | ||||
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||||
{{svg "octicon-server" 16}} | |||||
<div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||||
<i class="dropdown icon"></i> | |||||
<div class="menu"> | |||||
<div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||||
<div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||||
<div class="item" data-value="NPU">NPU</div> | |||||
</div> | |||||
</div> | |||||
{{if .Permission.CanWrite $.UnitTypeCloudBrain}} | {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | ||||
<a class="ui green button" href="{{.RepoLink}}/modelarts/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | |||||
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | |||||
{{else}} | {{else}} | ||||
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | ||||
{{end}} | {{end}} | ||||
@@ -102,7 +112,7 @@ | |||||
<!-- 任务名 --> | <!-- 任务名 --> | ||||
<div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
<a class="title" href='{{if eq .ComputeResource "NPU" }}{{$.Link}}/{{.JobID}}{{else}}{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}{{end}}' title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
<span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
</a> | </a> | ||||
@@ -143,7 +153,7 @@ | |||||
<div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
{{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
{{if .CanDel}} | {{if .CanDel}} | ||||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{$.RepoRelPath}}/modelarts/train-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" data-repopath='{{$.RepoRelPath}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}' data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
{{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
</a> | </a> | ||||
{{else}} | {{else}} | ||||
@@ -154,7 +164,8 @@ | |||||
</div> | </div> | ||||
<!-- 删除任务 --> | <!-- 删除任务 --> | ||||
<form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | |||||
<form class="ui compact buttons" id="delForm-{{.JobID}}" action='{{if eq .ComputeResource "NPU" }}{{$.Link}}/{{.JobID}}{{else}}{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}{{end}}/del' method="post"> | |||||
<input type="hidden" name="listType" value="{{$.ListType}}"> | |||||
{{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
{{if .CanDel}} | {{if .CanDel}} | ||||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | ||||
@@ -206,3 +217,27 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script> | |||||
let url = {{$.RepoLink}}; | |||||
let all = {{$.i18n.Tr "repo.gpu_type_all"}} | |||||
$(document).ready(function(){ | |||||
const params = new URLSearchParams(location.search) | |||||
if(!location.search){ | |||||
$('.default.text').text(all) | |||||
}else{ | |||||
if(params.has('listType') && params.get('listType')=='all'){ | |||||
$('.default.text').text(all) | |||||
} | |||||
else{ | |||||
$('.default.text').text(params.get('listType')) | |||||
} | |||||
} | |||||
$('.ui.selection.dropdown').dropdown({ | |||||
onChange:function(value){ | |||||
location.href = `${url}/modelarts/train-job?listType=${value}` | |||||
} | |||||
}) | |||||
}) | |||||
</script> |
@@ -79,6 +79,24 @@ | |||||
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | ||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
<div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
<div class="ui blue mini menu compact selectcloudbrain"> | |||||
<a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | |||||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
<path fill="none" d="M0 0h24v24H0z"/> | |||||
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
</svg> | |||||
CPU/GPU | |||||
</a> | |||||
<a class="active item" href="{{.RepoLink}}/modelarts/train-job/create"> | |||||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
<path fill="none" d="M0 0h24v24H0z"/> | |||||
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
</svg> | |||||
Ascend NPU</a> | |||||
</div> | |||||
</div> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | ||||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | ||||
@@ -77,13 +77,15 @@ | |||||
{{else if eq .GetOpType 26}} | {{else if eq .GetOpType 26}} | ||||
{{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | ||||
{{else if eq .GetOpType 27}} | {{else if eq .GetOpType 27}} | ||||
{{$.i18n.Tr "action.task_trainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
{{$.i18n.Tr "action.task_nputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
{{else if eq .GetOpType 28}} | {{else if eq .GetOpType 28}} | ||||
{{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | ||||
{{else if eq .GetOpType 29}} | {{else if eq .GetOpType 29}} | ||||
{{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | ||||
{{else if eq .GetOpType 30}} | {{else if eq .GetOpType 30}} | ||||
{{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | ||||
{{else if eq .GetOpType 31}} | |||||
{{$.i18n.Tr "action.task_gputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
{{end}} | {{end}} | ||||
</p> | </p> | ||||
{{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | ||||
@@ -129,6 +131,8 @@ | |||||
<span class="text grey"><i class="ri-vip-crown-line icon big"></i></span> | <span class="text grey"><i class="ri-vip-crown-line icon big"></i></span> | ||||
{{else if eq .GetOpType 30}} | {{else if eq .GetOpType 30}} | ||||
<span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | <span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | ||||
{{else if eq .GetOpType 31}} | |||||
<span class="text grey"><i class="ri-character-recognition-line icon big"></i></span> | |||||
{{else}} | {{else}} | ||||
<span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | ||||
{{end}} | {{end}} | ||||
@@ -628,6 +628,32 @@ display: block; | |||||
.a_margin{ | .a_margin{ | ||||
margin: 0px !important; | margin: 0px !important; | ||||
} | } | ||||
/*pages*/ | |||||
.ui.borderless.pagination {border:none} | |||||
.ui.pagination.menu .item { | |||||
min-width: 32px; | |||||
text-align: center; | |||||
height: 32px; | |||||
border-radius: .28571429rem; | |||||
margin: 0 5px; | |||||
background-color: #F2F2F2; | |||||
} | |||||
.ui.pagination.menu>.item:first-child, .ui.pagination.menu .item:last-child { | |||||
background-color: #FFF !important; | |||||
} | |||||
.ui.ui.menu .item.disabled{ | |||||
background-color: #F2F2F2; | |||||
} | |||||
.ui.pagination.menu .active.item { | |||||
background-color: #3291F8; | |||||
color: #FFF; | |||||
} | |||||
.ui.pagination.menu .item>.input { | |||||
margin: 0em .5em; | |||||
width: 3em; | |||||
height: 32px; | |||||
} | |||||
@media only screen and (max-width: 767px) { | @media only screen and (max-width: 767px) { | ||||
.following.bar #navbar .brand{ | .following.bar #navbar .brand{ | ||||
padding-top: 6px; | padding-top: 6px; | ||||
@@ -783,4 +809,87 @@ display: block; | |||||
border: none !important; | border: none !important; | ||||
color: #0366d6 !important; | color: #0366d6 !important; | ||||
box-shadow: -15px 0px 10px #fff; | box-shadow: -15px 0px 10px #fff; | ||||
} | |||||
/**seach**/ | |||||
/**搜索导航条适配窄屏**/ | |||||
.seachnav{ | |||||
overflow-x: auto; | |||||
overflow-y: hidden; | |||||
scrollbar-width: none; /* firefox */ | |||||
-ms-overflow-style: none; /* IE 10+ */ | |||||
} | |||||
.seachnav::-webkit-scrollbar { | |||||
display: none; /* Chrome Safari */ | |||||
} | |||||
.ui.green.button, .ui.green.buttons .button{ | |||||
background-color: #5BB973; | |||||
} | |||||
.seach .repos--seach{ | |||||
padding-bottom: 0; | |||||
border-bottom: none; | |||||
} | |||||
.seach .ui.secondary.pointing.menu{ | |||||
border-bottom: none; | |||||
} | |||||
.seach .ui.secondary.pointing.menu .item > i{ | |||||
margin-right: 5px; | |||||
} | |||||
.seach .ui.secondary.pointing.menu .active.item{ | |||||
border-bottom-width: 2px; | |||||
margin: 0 0 -1px; | |||||
} | |||||
.seach .ui.menu .active.item>.label { | |||||
background: #1684FC; | |||||
color: #FFF; | |||||
} | |||||
.seach .ui.menu .item>.label:not(.active.item>.label) { | |||||
background: #e8e8e8; | |||||
color: rgba(0,0,0,.6); | |||||
} | |||||
.highlight{ | |||||
color: red; | |||||
} | |||||
.ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||||
width: calc(100% - 4.0em); | |||||
margin-left: 0; | |||||
} | |||||
.seach .ui.list .list>.item .header, .seach .ui.list>.item .header{ | |||||
margin-bottom: 0.5em; | |||||
font-size: 1.4rem !important; | |||||
font-weight: normal; | |||||
} | |||||
.seach .time, .seach .time a{ | |||||
font-size: 12px; | |||||
color: grey; | |||||
} | |||||
.seach .list .item.members .ui.avatar.image { | |||||
width: 3.2em; | |||||
height: 3.2em; | |||||
} | |||||
.ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content { | |||||
width: calc(100% - 4.0em); | |||||
margin-left: 0; | |||||
} | |||||
.searchlabel{ | |||||
color: rgba(16, 16, 16, 100); | |||||
font-size: 24px; | |||||
text-align: left; | |||||
font-family: SourceHanSansSC-medium; | |||||
} | |||||
.hiddenSearch{ | |||||
margin: auto; | |||||
display: none; | |||||
} | |||||
#tipmsg { | |||||
display: none; | |||||
z-index: 9999; | |||||
width:150; | |||||
height: 80; | |||||
} | } |