"
html += "
"
html += "
" + name + " "
return html;
@@ -236,6 +321,7 @@ function getRepotext(record){
return record.Repo.OwnerName + "/" + record.Repo.Name;
}
}
+
function getRepoLink(record){
return encodeURI(record.Repo.OwnerName + "/" + record.Repo.Name);
@@ -437,10 +523,6 @@ function getAction(opType,isZh){
}
}
-
-
-
-
function queryRecommendData(){
$.ajax({
type:"GET",
@@ -453,7 +535,10 @@ function queryRecommendData(){
success:function(json){
displayOrg(json.org);
displayRepo(json.repo);
- displayActivity(json.image);
+ displayActivity(json.activity);
+ displayDataset(json.dataset);
+ displayUserExp(json.user_experience);
+ LetterAvatar && LetterAvatar.transform();
},
error:function(response) {
}
@@ -463,49 +548,99 @@ function queryRecommendData(){
function displayActivity(json){
var activityDiv = document.getElementById("recommendactivity");
+ if (!activityDiv) return;
var html = "";
if (json != null && json.length > 0){
for(var i = 0; i < json.length;i++){
- var record = json[i]
- html += "
";
- html += "
";
- html += " "
+ var record = json[i];
+ var name = isZh ? (record["name"] || '') : (record["name_en"] || record["name"]);
+ html += "";
}
+ var swiperEvent = new Swiper(".event-list", {
+ slidesPerView: 1,
+ spaceBetween: 30,
+ // pagination: {
+ // el: ".swiper-pagination",
+ // clickable: true,
+ // },
+ autoplay: {
+ delay: 2500,
+ disableOnInteraction: false,
+ },
+ breakpoints: {
+ 768: {
+ slidesPerView: Math.min(2, json.length),
+ },
+ 1024: {
+ slidesPerView: Math.min(3, json.length),
+ },
+ 1200: {
+ slidesPerView: Math.min(3, json.length),
+ },
+ 1440: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ 1840: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ 1920: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ },
+ });
+ activityDiv.innerHTML = html;
+ swiperEvent.updateSlides();
+ swiperEvent.updateProgress();
}
- activityDiv.innerHTML = html;
- swiperEvent.updateSlides();
- swiperEvent.updateProgress();
}
function displayRepo(json){
var orgRepo = document.getElementById("recommendrepo");
var html = "";
if (json != null && json.length > 0){
- for(var i = 0; i < json.length;i++){
- var record = json[i]
- html += "";
- html += "
";
- html += "
";
- html += "
";
- html += " " + record["NumStars"] + " " + record["NumForks"];
- html += " ";
- html += "
";
- html += " ";
- html += "
" + record["Description"] + "
";
- html += "
"
- if(record["Topics"] != null){
- for(var j = 0; j < record["Topics"].length; j++){
- topic = record["Topics"][j];
- url = "/explore/repos?q=" + (topic) + "&topic="
- html += "
" + topic + " ";
- }
+ var repoMap = {};
+ for (var i = 0, iLen = json.length; i < iLen; i++) {
+ var repo = json[i];
+ var label = isZh ? repo.Label : repo.Label_en;
+ if (repoMap[label]) {
+ repoMap[label].push(repo);
+ } else {
+ repoMap[label] = [repo];
}
- html += "
";
- html += "
";
- html += "
";
- html += "
";
+ }
+
+ for (var label in repoMap) {
+ var repos = repoMap[label];
+ var labelSearch = repos[0].Label;
+ html += ``;
+ for (var i = 0, iLen = repos.length; i < iLen; i++) {
+ if (i >= 4) break;
+ var repo = repos[i];
+ //
${repo["NumStars"]}
${repo["NumForks"]}
+ html += `
+
+ ${repo["Avatar"] ? `
` : `
`}
+
+
${repo["Description"]}
+ `;
+ // if (repo["Topics"] != null) {
+ // for(var j = 0; j < repo["Topics"].length; j++){
+ // var topic = repo["Topics"][j];
+ // var url = "/explore/repos?q=" + (topic) + "&topic="
+ // html += `
${topic} `;
+ // }
+ // }
+ html += `
+
+
`;
+ }
+ html += '
'
}
}
orgRepo.innerHTML = html;
@@ -513,7 +648,6 @@ function displayRepo(json){
swiperRepo.updateProgress();
}
-
function getRepoOrOrg(key,isZhLang,numbers=1){
if(numbers > 1){
key+="1";
@@ -537,7 +671,7 @@ function displayOrg(json){
html += " ";
html += " ";
html += "
" + record["Name"] + " " + record["FullName"];
- html += "
" + record["NumRepos"] +" " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ " + record["NumMembers"] +" " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ " + record["NumTeams"] + " " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "
";
+ html += "
" + record["NumRepos"] +" " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ " + record["NumMembers"] +" " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ " + record["NumTeams"] + " " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "
";
html += "
";
html += " ";
html += "
";
@@ -548,3 +682,187 @@ function displayOrg(json){
orgDiv.innerHTML = html;
swiperOrg.updateSlides();
}
+
+function displayDataset(data) {
+ var homeDatasetEl = document.getElementById("home_dataset");
+ if (!homeDatasetEl) return;
+ var html = '';
+ var svgStrMap = {
+ '0': '
',
+ '1': '
',
+ '2': '
',
+ '3': '
',
+ '4': '
',
+ '5': '
',
+ '6': '
',
+ }
+ for (var i = 0, iLen = data.length; i < iLen; i++) {
+ var dataI = data[i];
+ html += `
`
+ }
+ homeDatasetEl.innerHTML = html;
+ swiperDataset.updateSlides();
+ swiperDataset.updateProgress();
+}
+
+function displayUserExp(data) {
+ var homeUserExpEl = document.getElementById("home_user-exp");
+ if (!homeUserExpEl) return;
+ var html = '';
+ for (var i = 0, iLen = data.length; i < iLen; i++) {
+ var dataI = data[i];
+ html += `
+
+
+
${dataI.fullname || dataI.name}
+
+
+
`
+ }
+ homeUserExpEl.innerHTML = html;
+ swiperUserExp.updateSlides();
+ swiperUserExp.updateProgress();
+}
+
+function getNotice() {
+ $.ajax({
+ type:"GET",
+ url:"/dashboard/invitation",
+ headers: { authorization:token, },
+ dataType:"json",
+ data: {
+ filename: 'notice/notice.json',
+ },
+ success:function(json){
+ if (json) {
+ try {
+ var noticeList = JSON.parse(json).Notices || [];
+ var noticeEls = $('._hm-recommend-info-area-1 a._hm-notice');
+ for (var i = 0, iLen = noticeEls.length; i < iLen; i++) {
+ var noticeEl = noticeEls.eq(i);
+ var noticeObj = noticeList[i];
+ if (noticeObj) {
+ var title = isZh ? noticeObj.Title : (noticeObj.Title_en || noticeObj.Title);
+ noticeEl.attr('href', noticeObj.Link);
+ noticeEl.find('span').text(title).attr('title', title);
+ noticeEl.show();
+ } else {
+ noticeEl.hide();
+ }
+ }
+ } catch (e) {
+ console.info(e);
+ }
+ }
+ },
+ error:function(response) {
+ }
+ });
+}
+
+function getRecommendModule() {
+ $.ajax({
+ type:"GET",
+ url:"/dashboard/invitation",
+ headers: { authorization:token, },
+ dataType:"json",
+ data: {
+ filename: 'home/newfunction',
+ },
+ success:function(json){
+ if (json) {
+ try {
+ var recommendModuleList = JSON.parse(json) || [];
+ var recommendModuleEls = $('._hm-recommend-info-area a._hm-link');
+ for (var i = 0, iLen = recommendModuleEls.length; i < iLen; i++) {
+ var recommendModuleEl = recommendModuleEls.eq(i);
+ var recommendModuleObj = recommendModuleList[i];
+ if (recommendModuleObj) {
+ recommendModuleEl.attr('href', recommendModuleObj.image_link);
+ recommendModuleEl.text(isZh ? recommendModuleObj.name : (recommendModuleObj.name_en || recommendModuleObj.name));
+ } else {
+ }
+ }
+ } catch (e) {
+ console.info(e);
+ }
+ }
+ },
+ error:function(response) {
+ }
+ });
+}
+
+function initHomeTopBanner() {
+ var homeSlideTimer = null;
+ var homeSlideDuration = 8000;
+ function homeSlide(direction, index) {
+ var slidePages = $('._hm-pg-c ._hm-pg');
+ var currentPage = slidePages.filter('._hm-pg-show');
+ var slidePagination = $('._hm-slide-pagination-c ._hm-slide-pagination-item');
+ var currentIndex = currentPage.index();
+ var next = 0;
+ if (direction) {
+ next = direction == 'left' ? currentIndex - 1 : currentIndex + 1;
+ } else {
+ next = index || 0;
+ }
+ if (next < 0) next = slidePages.length - 1;
+ if (next == slidePages.length) next = 0;
+ slidePages.removeClass('_hm-pg-show');
+ slidePages.eq(next).addClass('_hm-pg-show');
+ slidePagination.removeClass('_hm-slide-pagination-item-active');
+ slidePagination.eq(next).addClass('_hm-slide-pagination-item-active');
+ }
+
+ function startSlide() {
+ homeSlideTimer && clearTimeout(homeSlideTimer);
+ homeSlideTimer = setTimeout(function() {
+ homeSlide('right');
+ startSlide();
+ }, homeSlideDuration);
+ }
+
+ function stopSlide() {
+ homeSlideTimer && clearTimeout(homeSlideTimer);
+ }
+
+ $('._hm-slide-btn').on('click', function () {
+ if ($(this).hasClass('_hm-slide-btn-left')) {
+ homeSlide('left');
+ } else {
+ homeSlide('right');
+ }
+ startSlide();
+ });
+ $('._hm-pg #homenews').on('mouseenter', function() {
+ stopSlide();
+ }).on('mouseleave', function() {
+ startSlide();
+ });
+ $('._hm-slide-pagination-c ._hm-slide-pagination-item').on('click', function() {
+ var self = $(this);
+ if (self.hasClass('_hm-slide-pagination-item-active')) return;
+ homeSlide('', self.index());
+ startSlide();
+ });
+ setTimeout(function() { startSlide(); }, 500);
+}
+
+initHomeTopBanner();
+getNotice();
+getRecommendModule();
diff --git a/public/img/search.svg b/public/img/search.svg
index ec91b07dd..a4d965f9a 100644
--- a/public/img/search.svg
+++ b/public/img/search.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/routers/admin/cloudbrains.go b/routers/admin/cloudbrains.go
index cbf6782ed..91685251b 100755
--- a/routers/admin/cloudbrains.go
+++ b/routers/admin/cloudbrains.go
@@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
)
const (
@@ -95,6 +96,8 @@ func CloudBrains(ctx *context.Context) {
models.LoadSpecs4CloudbrainInfo(ciTasks)
for i, task := range ciTasks {
+ ciTasks[i] = cloudbrainService.UpdateCloudbrainAiCenter(ciTasks[i])
+ ciTasks[i].Cloudbrain.AiCenter = repo.GetAiCenterNameByCode(ciTasks[i].Cloudbrain.AiCenter, ctx.Language())
ciTasks[i].CanDebug = true
ciTasks[i].CanDel = true
ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource
@@ -186,7 +189,8 @@ func DownloadCloudBrains(ctx *context.Context) {
}
models.LoadSpecs4CloudbrainInfo(pageRecords)
for _, record := range pageRecords {
-
+ record = cloudbrainService.UpdateCloudbrainAiCenter(record)
+ record.Cloudbrain.AiCenter = repo.GetAiCenterNameByCode(record.Cloudbrain.AiCenter, ctx.Language())
for k, v := range allValues(row, record, ctx) {
f.SetCellValue(cloudBrain, k, v)
}
@@ -208,7 +212,7 @@ func allValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[str
return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): repo.GetCloudbrainCluster(rs.Cloudbrain, ctx),
getCellName("C", row): rs.JobType, getCellName("D", row): rs.Status, getCellName("E", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT),
getCellName("F", row): getDurationTime(rs), getCellName("G", row): rs.ComputeResource,
- getCellName("H", row): repo.GetCloudbrainAiCenter(rs.Cloudbrain, ctx), getCellName("I", row): getCloudbrainCardType(rs),
+ getCellName("H", row): rs.Cloudbrain.AiCenter, getCellName("I", row): getCloudbrainCardType(rs),
getCellName("J", row): rs.Name, getCellName("K", row): getRepoPathName(rs), getCellName("L", row): rs.JobName,
}
}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 5ee065514..3e50b00fc 100755
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -544,6 +544,10 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/complete_multipart", repo.CompleteMultipart)
}, reqToken())
+ m.Group("/pipeline", func() {
+ m.Post("/notification", bind(api.PipelineNotification{}), notify.PipelineNotify)
+
+ }, reqToken())
// Notifications
m.Group("/notifications", func() {
@@ -610,10 +614,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/query_invitation_yesterday", operationReq, repo_ext.QueryInvitationYesterday)
m.Get("/query_invitation_all", operationReq, repo_ext.QueryInvitationAll)
m.Get("/query_invitation_userdefine", operationReq, repo_ext.QueryUserDefineInvitationPage)
+ m.Get("/query_user_annual_report", repo_ext.QueryUserAnnualReport)
m.Get("/download_invitation_detail", operationReq, repo_ext.DownloadInvitationDetail)
//cloudbrain board
+ m.Get("/cloudbrainboard/cloudbrain/resource_queues", repo.GetResourceQueues)
m.Group("/cloudbrainboard", func() {
m.Get("/downloadAll", repo.DownloadCloudBrainBoard)
m.Group("/cloudbrain", func() {
@@ -736,6 +742,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/my_favorite", repo.MyFavoriteDatasetMultiple)
}, reqToken(), repoAssignment())
+ m.Group("/file_notebook", func() {
+ m.Get("", repo.GetFileNoteBookInfo)
+ m.Post("/create", reqToken(), reqWeChat(), bind(api.CreateFileNotebookJobOption{}), repo.CreateFileNoteBook)
+
+ })
+
m.Group("/repos", func() {
m.Get("/search", repo.Search)
@@ -751,6 +763,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:username/:reponame", func() {
m.Get("/right", reqToken(), repo.GetRight)
m.Get("/tagger", reqToken(), repo.ListTagger)
+ m.Get("/cloudBrainJobId", repo.GetCloudBrainJobId)
m.Combo("").Get(reqAnyRepoReader(), repo.Get).
Delete(reqToken(), reqOwner(), repo.Delete).
Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRef(), repo.Edit)
@@ -987,6 +1000,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/detail", reqToken(), reqRepoReader(models.UnitTypeCloudBrain), repo.CloudBrainShow)
m.Get("/model_list", repo.CloudBrainModelList)
m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop)
+ m.Put("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GeneralCloudBrainJobStop)
})
})
m.Group("/inference-job", func() {
@@ -1007,12 +1021,15 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Delete("/delete_model", repo.DeleteModel)
m.Get("/downloadall", repo.DownloadModel)
m.Get("/query_model_byId", repo.QueryModelById)
+ m.Get("/query_model_byName", repo.QueryModelByName)
m.Get("/query_model_for_predict", repo.QueryModelListForPredict)
m.Get("/query_modelfile_for_predict", repo.QueryModelFileForPredict)
m.Get("/query_train_model", repo.QueryTrainModelList)
m.Post("/create_model_convert", repo.CreateModelConvert)
+ m.Post("/convert_stop", repo.StopModelConvert)
m.Get("/show_model_convert_page", repo.ShowModelConvertPage)
m.Get("/query_model_convert_byId", repo.QueryModelConvertById)
+ m.Get("/query_model_convert_byName", repo.QueryModelConvertByName)
m.Get("/:id", repo.GetCloudbrainModelConvertTask)
m.Get("/:id/log", repo.CloudbrainForModelConvertGetLog)
diff --git a/routers/api/v1/notify/pipeline.go b/routers/api/v1/notify/pipeline.go
new file mode 100644
index 000000000..021af20dc
--- /dev/null
+++ b/routers/api/v1/notify/pipeline.go
@@ -0,0 +1,15 @@
+package notify
+
+import (
+ "net/http"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ api "code.gitea.io/gitea/modules/structs"
+)
+
+func PipelineNotify(ctx *context.APIContext, form api.PipelineNotification) {
+
+ ctx.JSON(http.StatusOK, models.BaseOKMessageApi)
+
+}
diff --git a/routers/api/v1/repo/cloudbrain.go b/routers/api/v1/repo/cloudbrain.go
index 7022dc011..1c5a58b47 100755
--- a/routers/api/v1/repo/cloudbrain.go
+++ b/routers/api/v1/repo/cloudbrain.go
@@ -11,11 +11,14 @@ import (
"io"
"net/http"
"os"
+ "path"
"sort"
"strconv"
"strings"
"time"
+ "code.gitea.io/gitea/modules/grampus"
+
cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
"code.gitea.io/gitea/modules/convert"
@@ -79,6 +82,98 @@ func CloudBrainShow(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)})
}
+func GeneralCloudBrainJobStop(ctx *context.APIContext) {
+ task := ctx.Cloudbrain
+ if task.IsTerminal() {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("cloudbrain.Already_stopped"))
+ return
+ }
+ var err error
+
+ if ctx.Cloudbrain.Type == models.TypeCloudBrainOne {
+ err = cloudbrain.StopJob(task.JobID)
+ } else if ctx.Cloudbrain.Type == models.TypeCloudBrainTwo {
+ _, err = modelarts.StopTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10))
+ } else {
+ _, err = grampus.StopJob(task.JobID)
+ }
+
+ if err != nil {
+ log.Warn("cloud brain stopped failed.", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("cloudbrain.Stopped_failed"))
+ return
+ }
+
+ ctx.JSON(http.StatusOK, models.BaseOKMessageApi)
+}
+func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) {
+ cloudbrainTask.FileNotebookCreate(ctx.Context, option)
+}
+
+func GetFileNoteBookInfo(ctx *context.APIContext) {
+ //image description spec description waiting count
+
+ specs, err := models.GetResourceSpecificationByIds([]int64{setting.FileNoteBook.SpecIdCPU, setting.FileNoteBook.SpecIdGPU, setting.FileNoteBook.SpecIdNPU, setting.FileNoteBook.SpecIdNPUCD})
+ if err != nil {
+ log.Error("Fail to query specifications", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
+ return
+ }
+
+ var specCPU, specGpu, specNPU, specNPUCD *api.SpecificationShow
+ var specGpuQueueCode string
+ for _, spec := range specs {
+ if spec.ID == setting.FileNoteBook.SpecIdCPU {
+ specCPU = convert.ToSpecification(spec)
+ } else if spec.ID == setting.FileNoteBook.SpecIdGPU {
+ specGpu = convert.ToSpecification(spec)
+ specGpuQueueCode = spec.QueueCode
+ } else if spec.ID == setting.FileNoteBook.SpecIdNPU {
+ specNPU = convert.ToSpecification(spec)
+ } else if spec.ID == setting.FileNoteBook.SpecIdNPUCD {
+ specNPUCD = convert.ToSpecification(spec)
+ }
+ }
+
+ waitCountNpu := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+
+ queuesMap, err := cloudbrain.GetQueuesDetail()
+ if err != nil {
+ log.Error("Fail to query gpu queues waiting count", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
+ return
+ }
+ waitCountGPU := (*queuesMap)[specGpuQueueCode]
+ if !setting.ModelartsCD.Enabled {
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "code": 0,
+ "projectName": setting.FileNoteBook.ProjectName,
+ "specCpu": specCPU,
+ "specGpu": specGpu,
+ "specNpu": specNPU,
+ "waitCountGpu": waitCountGPU,
+ "waitCountNpu": waitCountNpu,
+ "imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
+ "imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
+ "imageNpuDescription": setting.FileNoteBook.ImageNPUDescription,
+ })
+ } else {
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "code": 0,
+ "projectName": setting.FileNoteBook.ProjectName,
+ "specCpu": specCPU,
+ "specGpu": specGpu,
+ "specNpu": specNPUCD,
+ "waitCountGpu": waitCountGPU,
+ "waitCountNpu": waitCountNpu,
+ "imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
+ "imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
+ "imageNpuDescription": setting.FileNoteBook.ImageNPUCDDescription,
+ })
+
+ }
+
+}
func CreateCloudBrain(ctx *context.APIContext, option api.CreateTrainJobOption) {
if option.Type == cloudbrainTask.TaskTypeCloudbrainOne {
@@ -141,10 +236,11 @@ func GetCloudbrainTask(ctx *context.APIContext) {
)
ID := ctx.Params(":id")
- job, err := models.GetCloudbrainByID(ID)
+
+ job, err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
+
if err != nil {
ctx.NotFound(err)
- log.Error("GetCloudbrainByID failed:", err)
return
}
if job.JobType == string(models.JobTypeModelSafety) {
@@ -487,6 +583,12 @@ func ModelSafetyGetLog(ctx *context.APIContext) {
})
return
}
+ prefix := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, job.JobName, modelarts.LogPath, job.VersionName), "/") + "/job"
+ _, err = storage.GetObsLogFileName(prefix)
+ canLogDownload := isCanDownloadLog(ctx, job)
+ if err != nil {
+ canLogDownload = false
+ }
ctx.Data["log_file_name"] = resultLogFile.LogFileList[0]
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobID": job.JobID,
@@ -495,7 +597,7 @@ func ModelSafetyGetLog(ctx *context.APIContext) {
"EndLine": result.EndLine,
"Content": result.Content,
"Lines": result.Lines,
- "CanLogDownload": isCanDownloadLog(ctx, job),
+ "CanLogDownload": canLogDownload,
"StartTime": job.StartTime,
})
}
@@ -566,7 +668,6 @@ func CloudbrainDownloadLogFile(ctx *context.Context) {
url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName)
if err != nil {
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
- ctx.ServerError("Get minio get SignedUrl failed", err)
return
}
log.Info("fileName=" + fileName)
@@ -596,12 +697,24 @@ func CloudbrainGetLog(ctx *context.APIContext) {
existStr = taskRes.TaskStatuses[0].ExitDiagnostics
}
ctx.Data["existStr"] = existStr
- log.Info("existStr=" + existStr)
} else {
ModelSafetyGetLog(ctx)
return
}
+ }
+ if job.JobType == string(models.JobTypeTrain) || job.JobType == string(models.JobTypeInference) {
+ if job.Type == models.TypeCloudBrainOne {
+ result, err := cloudbrain.GetJob(job.JobID)
+ existStr := ""
+ if err == nil && result != nil {
+ jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
+ taskRoles := jobRes.TaskRoles
+ taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
+ existStr = taskRes.TaskStatuses[0].ExitDiagnostics
+ }
+ ctx.Data["existStr"] = existStr
+ }
}
lines := ctx.QueryInt("lines")
@@ -638,7 +751,7 @@ func CloudbrainGetLog(ctx *context.APIContext) {
result = getLogFromModelDir(job.JobName, startLine, endLine, resultPath)
if result == nil {
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"])
- ctx.ServerError(err.Error(), err)
+ //ctx.ServerError(err.Error(), err)
return
}
}
@@ -646,9 +759,11 @@ func CloudbrainGetLog(ctx *context.APIContext) {
if result["Content"] != nil {
content = result["Content"].(string)
}
+
if ctx.Data["existStr"] != nil && result["Lines"].(int) < 50 {
content = content + ctx.Data["existStr"].(string)
}
+
logFileName := result["FileName"]
//Logs can only be downloaded if the file exists
@@ -851,7 +966,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
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)
+ //ctx.ServerError("json.Unmarshal failed:", err)
return
}
@@ -882,7 +997,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
models, err := storage.GetObsListObject(job.ID, "output/", parentDir, versionName)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
- ctx.ServerError("GetObsListObject:", err)
+ //ctx.ServerError("GetObsListObject:", err)
return
}
@@ -927,7 +1042,7 @@ func CloudBrainModelList(ctx *context.APIContext) {
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)
+ //ctx.ServerError("json.Unmarshal failed:", err)
return
}
diff --git a/routers/api/v1/repo/cloudbrain_dashboard.go b/routers/api/v1/repo/cloudbrain_dashboard.go
index d1ccf1bf5..0d68fff30 100755
--- a/routers/api/v1/repo/cloudbrain_dashboard.go
+++ b/routers/api/v1/repo/cloudbrain_dashboard.go
@@ -11,7 +11,10 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/routers/repo"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+ "code.gitea.io/gitea/services/cloudbrain/resource"
"github.com/360EntSecGroup-Skylar/excelize/v2"
)
@@ -56,42 +59,30 @@ func GetAllCloudbrainsOverview(ctx *context.Context) {
return
}
cloudbrainTypeCount, err := models.GetCloudbrainTypeCount()
- log.Info("cloudbrainTypeCount:", cloudbrainTypeCount)
if err != nil {
log.Error("Can not query cloudbrainTypeCount.", err)
return
}
- cloudbrainTpyeDurationSum, err := models.GetCloudbrainTpyeDurationSum()
- log.Info("cloudbrainTpyeDurationSum:", cloudbrainTpyeDurationSum)
- if err != nil {
- log.Error("Can not query cloudbrainTpyeDurationSum.", err)
- return
- }
-
todayCloudbrainCount, err := models.GetTodayCloudbrainCount(beginTime, endTime)
- log.Info("todayCloudbrainCount:", todayCloudbrainCount)
if err != nil {
log.Error("Can not query todayCloudbrainCount.", err)
return
}
todayRunningCount, err := models.GetTodayRunningCount(beginTime, endTime)
- log.Info("todayRunningCount:", todayRunningCount)
if err != nil {
log.Error("Can not query todayRunningCount.", err)
return
}
todayWaitingCount, err := models.GetTodayWaitingCount(beginTime, endTime)
- log.Info("todayWaittingCount:", todayWaitingCount)
if err != nil {
log.Error("Can not query todayWaitingCount.", err)
return
}
todayCompletedCount := todayCloudbrainCount - todayRunningCount - todayWaitingCount
- log.Info("todayCompletedCount:", todayCompletedCount)
creatorCount, err := models.GetCreatorCount()
if err != nil {
@@ -121,8 +112,9 @@ func GetOverviewDuration(ctx *context.Context) {
recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
now := time.Now()
endTime := now
- worker_server_num := 1
- cardNum := 1
+ var workServerNumber int64
+ var cardNum int64
+
durationAllSum := int64(0)
cardDuSum := int64(0)
@@ -136,7 +128,7 @@ func GetOverviewDuration(ctx *context.Context) {
c2NetDuration := int64(0)
cDCenterDuration := int64(0)
- cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
+ cloudbrains, _, err := models.CloudbrainAllKanBan(&models.CloudbrainsOptions{
Type: models.TypeCloudBrainAll,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
@@ -148,34 +140,36 @@ func GetOverviewDuration(ctx *context.Context) {
models.LoadSpecs4CloudbrainInfo(cloudbrains)
for _, cloudbrain := range cloudbrains {
- if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
- worker_server_num = cloudbrain.Cloudbrain.WorkServerNumber
+ cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
+ if cloudbrain.Cloudbrain.Spec != nil {
+ cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum)
} else {
- worker_server_num = 1
- }
- if cloudbrain.Cloudbrain.Spec == nil {
cardNum = 1
+ }
+ if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
+ workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber)
} else {
- cardNum = cloudbrain.Cloudbrain.Spec.AccCardsNum
+ workServerNumber = 1
}
- duration := cloudbrain.Duration
- durationSum := cloudbrain.Duration * int64(worker_server_num) * int64(cardNum)
+ duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration)
+ CardDuration := workServerNumber * int64(cardNum) * duration
+
if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration += duration
- cloudBrainOneCardDuSum += durationSum
+ cloudBrainOneCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
cloudBrainTwoDuration += duration
- cloudBrainTwoCardDuSum += durationSum
+ cloudBrainTwoCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
c2NetDuration += duration
- c2NetCardDuSum += durationSum
+ c2NetCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
cDCenterDuration += duration
- cDNetCardDuSum += durationSum
+ cDNetCardDuSum += CardDuration
}
durationAllSum += duration
- cardDuSum += durationSum
+ cardDuSum += CardDuration
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"cloudBrainOneCardDuSum": cloudBrainOneCardDuSum,
@@ -192,6 +186,28 @@ func GetOverviewDuration(ctx *context.Context) {
})
}
+func GetCloudbrainCardDuration(task models.Cloudbrain) string {
+ cardNum := int(0)
+ spec, err := resource.GetCloudbrainSpec(task.ID)
+ if err != nil {
+ log.Info("error:" + err.Error())
+ return ""
+ }
+ if spec != nil {
+ cardNum = spec.AccCardsNum
+ } else {
+ cardNum = 1
+ }
+ var workServerNumber int64
+ if task.WorkServerNumber >= 1 {
+ workServerNumber = int64(task.WorkServerNumber)
+ } else {
+ workServerNumber = 1
+ }
+ cardDuration := models.ConvertDurationToStr(workServerNumber * int64(cardNum) * task.Duration)
+ return cardDuration
+}
+
func GetAllCloudbrainsTrend(ctx *context.Context) {
queryType := ctx.QueryTrim("type")
@@ -703,6 +719,30 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
aiCenter := ctx.Query("aiCenter")
needDeleteInfo := ctx.Query("needDeleteInfo")
+ if cloudBrainType == models.TypeCloudBrainOne && aiCenter == models.AICenterOfCloudBrainOne {
+ aiCenter = ""
+ }
+ if cloudBrainType == models.TypeCloudBrainTwo && aiCenter == models.AICenterOfCloudBrainTwo {
+ aiCenter = ""
+ }
+ if cloudBrainType == models.TypeCDCenter && aiCenter == models.AICenterOfChengdu {
+ aiCenter = ""
+ }
+ if cloudBrainType == models.TypeCloudBrainAll {
+ if aiCenter == models.AICenterOfCloudBrainOne {
+ cloudBrainType = models.TypeCloudBrainOne
+ aiCenter = ""
+ }
+ if aiCenter == models.AICenterOfCloudBrainTwo {
+ cloudBrainType = models.TypeCloudBrainTwo
+ aiCenter = ""
+ }
+ if aiCenter == models.AICenterOfChengdu {
+ cloudBrainType = models.TypeCDCenter
+ aiCenter = ""
+ }
+ }
+
page := ctx.QueryInt("page")
pageSize := ctx.QueryInt("pagesize")
if page <= 0 {
@@ -732,7 +772,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
keyword := strings.Trim(ctx.Query("q"), " ")
- ciTasks, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{
+ ciTasks, count, err := models.CloudbrainAll(&models.CloudbrainsOptions{
ListOptions: models.ListOptions{
Page: page,
PageSize: pageSize,
@@ -747,8 +787,8 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
NeedRepoInfo: true,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
- // AiCenter: aiCenter,
- NeedDeleteInfo: needDeleteInfo,
+ AiCenter: aiCenter,
+ NeedDeleteInfo: needDeleteInfo,
})
if err != nil {
ctx.ServerError("Get job failed:", err)
@@ -758,45 +798,43 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
nilTime := time.Time{}
tasks := []models.TaskDetail{}
for i, task := range ciTasks {
- if aiCenter == "" || aiCenter == task.Cloudbrain.Spec.AiCenterCode {
- ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource
- var taskDetail models.TaskDetail
- taskDetail.ID = ciTasks[i].Cloudbrain.ID
- taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
- taskDetail.JobName = ciTasks[i].JobName
- taskDetail.DisplayJobName = ciTasks[i].DisplayJobName
- taskDetail.Status = ciTasks[i].Status
- taskDetail.JobType = ciTasks[i].JobType
- taskDetail.CreatedUnix = ciTasks[i].Cloudbrain.CreatedUnix
- taskDetail.RunTime = ciTasks[i].Cloudbrain.TrainJobDuration
- taskDetail.StartTime = ciTasks[i].StartTime
- taskDetail.EndTime = ciTasks[i].EndTime
- taskDetail.ComputeResource = ciTasks[i].ComputeResource
- taskDetail.Type = ciTasks[i].Cloudbrain.Type
- taskDetail.UserName = ciTasks[i].User.Name
- taskDetail.RepoID = ciTasks[i].RepoID
- if ciTasks[i].Repo != nil {
- taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
- taskDetail.RepoAlias = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Alias
- }
- if ciTasks[i].Cloudbrain.WorkServerNumber >= 1 {
- taskDetail.WorkServerNum = int64(ciTasks[i].Cloudbrain.WorkServerNumber)
- } else {
- taskDetail.WorkServerNum = 1
- }
- taskDetail.CardDuration = repo.GetCloudbrainCardDuration(ciTasks[i].Cloudbrain)
- taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain)
+ task = cloudbrainService.UpdateCloudbrainAiCenter(task)
+ var taskDetail models.TaskDetail
+ taskDetail.ID = ciTasks[i].Cloudbrain.ID
+ taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
+ taskDetail.JobName = ciTasks[i].JobName
+ taskDetail.DisplayJobName = ciTasks[i].DisplayJobName
+ taskDetail.Status = ciTasks[i].Status
+ taskDetail.JobType = ciTasks[i].JobType
+ taskDetail.CreatedUnix = ciTasks[i].Cloudbrain.CreatedUnix
+ taskDetail.RunTime = ciTasks[i].Cloudbrain.TrainJobDuration
+ taskDetail.StartTime = ciTasks[i].StartTime
+ taskDetail.EndTime = ciTasks[i].EndTime
+ taskDetail.ComputeResource = ciTasks[i].ComputeResource
+ taskDetail.Type = ciTasks[i].Cloudbrain.Type
+ taskDetail.UserName = ciTasks[i].User.Name
+ taskDetail.RepoID = ciTasks[i].RepoID
+ taskDetail.AiCenter = repo.GetAiCenterNameByCode(task.Cloudbrain.AiCenter, ctx.Language())
+ if ciTasks[i].Repo != nil {
+ taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
+ taskDetail.RepoAlias = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Alias
+ }
+ if ciTasks[i].Cloudbrain.WorkServerNumber >= 1 {
+ taskDetail.WorkServerNum = int64(ciTasks[i].Cloudbrain.WorkServerNumber)
+ } else {
+ taskDetail.WorkServerNum = 1
+ }
+ taskDetail.CardDuration = repo.GetCloudbrainCardDuration(ciTasks[i].Cloudbrain)
+ taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain)
- if ciTasks[i].Cloudbrain.DeletedAt != nilTime || ciTasks[i].Repo == nil {
- taskDetail.IsDelete = true
- } else {
- taskDetail.IsDelete = false
- }
- taskDetail.Spec = ciTasks[i].Spec
- tasks = append(tasks, taskDetail)
+ if ciTasks[i].Cloudbrain.DeletedAt != nilTime || ciTasks[i].Repo == nil {
+ taskDetail.IsDelete = true
+ } else {
+ taskDetail.IsDelete = false
}
+ taskDetail.Spec = ciTasks[i].Spec
+ tasks = append(tasks, taskDetail)
}
- count := int64(len(tasks))
pager := context.NewPagination(int(count), pageSize, page, getTotalPage(count, pageSize))
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "listType", "ListType")
@@ -930,6 +968,8 @@ func GetWaittingTop(ctx *context.Context) {
taskDetail.RepoID = ciTasks[i].RepoID
if ciTasks[i].Repo != nil {
taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
+ } else {
+ taskDetail.RepoName = ""
}
WaitTimeInt := time.Now().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix()
taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt)
@@ -937,6 +977,13 @@ func GetWaittingTop(ctx *context.Context) {
if WaitTimeInt < 0 {
taskDetail.WaitTime = "00:00:00"
}
+
+ taskDetail.ID = ciTasks[i].Cloudbrain.ID
+ taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource
+ taskDetail.JobType = ciTasks[i].Cloudbrain.JobType
+ taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
+ taskDetail.Type = ciTasks[i].Cloudbrain.Type
+
tasks = append(tasks, taskDetail)
}
ctx.JSON(http.StatusOK, map[string]interface{}{
@@ -963,6 +1010,12 @@ func GetRunningTop(ctx *context.Context) {
taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
}
+ taskDetail.ID = ciTasks[i].Cloudbrain.ID
+ taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource
+ taskDetail.JobType = ciTasks[i].Cloudbrain.JobType
+ taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
+ taskDetail.Type = ciTasks[i].Cloudbrain.Type
+
tasks = append(tasks, taskDetail)
}
ctx.JSON(http.StatusOK, map[string]interface{}{
@@ -1176,6 +1229,12 @@ func getMonthCloudbrainInfo(beginTime time.Time, endTime time.Time) ([]DateCloud
}
func DownloadCloudBrainBoard(ctx *context.Context) {
+ recordCloudbrain, err := models.GetRecordBeginTime()
+ if err != nil {
+ log.Error("Can not get recordCloudbrain", err)
+ ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
+ return
+ }
page := 1
@@ -1184,14 +1243,20 @@ func DownloadCloudBrainBoard(ctx *context.Context) {
var cloudBrain = ctx.Tr("repo.cloudbrain")
fileName := getCloudbrainFileName(cloudBrain)
+ recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
+ now := time.Now()
+ endTime := now
+
_, total, err := models.CloudbrainAll(&models.CloudbrainsOptions{
ListOptions: models.ListOptions{
Page: page,
PageSize: pageSize,
},
- Type: models.TypeCloudBrainAll,
- NeedRepoInfo: false,
+ Type: models.TypeCloudBrainAll,
+ BeginTimeUnix: int64(recordBeginTime),
+ EndTimeUnix: endTime.Unix(),
})
+ log.Info("totalcountisis:", total)
if err != nil {
log.Warn("Can not get cloud brain info", err)
@@ -1216,8 +1281,10 @@ func DownloadCloudBrainBoard(ctx *context.Context) {
Page: page,
PageSize: pageSize,
},
- Type: models.TypeCloudBrainAll,
- NeedRepoInfo: true,
+ Type: models.TypeCloudBrainAll,
+ BeginTimeUnix: int64(recordBeginTime),
+ EndTimeUnix: endTime.Unix(),
+ NeedRepoInfo: true,
})
if err != nil {
log.Warn("Can not get cloud brain info", err)
@@ -1225,7 +1292,8 @@ func DownloadCloudBrainBoard(ctx *context.Context) {
}
models.LoadSpecs4CloudbrainInfo(pageRecords)
for _, record := range pageRecords {
-
+ record = cloudbrainService.UpdateCloudbrainAiCenter(record)
+ record.Cloudbrain.AiCenter = repo.GetAiCenterNameByCode(record.Cloudbrain.AiCenter, ctx.Language())
for k, v := range allCloudbrainValues(row, record, ctx) {
f.SetCellValue(cloudBrain, k, v)
}
@@ -1264,7 +1332,7 @@ func allCloudbrainValues(row int, rs *models.CloudbrainInfo, ctx *context.Contex
getCellName("G", row): rs.TrainJobDuration, getCellName("H", row): repo.GetCloudbrainCardDuration(rs.Cloudbrain),
getCellName("I", row): getBrainStartTime(rs),
getCellName("J", row): getBrainEndTime(rs), getCellName("K", row): rs.ComputeResource, getCellName("L", row): getCloudbrainCardType(rs),
- getCellName("M", row): getWorkServerNum(rs), getCellName("N", row): repo.GetCloudbrainAiCenter(rs.Cloudbrain, ctx),
+ getCellName("M", row): getWorkServerNum(rs), getCellName("N", row): rs.Cloudbrain.AiCenter,
getCellName("O", row): getCloudbrainFlavorName(rs), getCellName("P", row): rs.Name,
getCellName("Q", row): getBrainRepo(rs), getCellName("R", row): rs.JobName, getCellName("S", row): getBrainDeleteTime(rs),
}
@@ -1412,12 +1480,17 @@ func getCloudbrainTimePeroid(ctx *context.Context, recordBeginTime time.Time) (t
}
func GetCloudbrainResourceOverview(ctx *context.Context) {
+ var recordBeginTime timeutil.TimeStamp
recordCloudbrainDuration, err := models.GetDurationRecordBeginTime()
if err != nil {
log.Error("Can not get GetDurationRecordBeginTime", err)
return
}
- recordBeginTime := recordCloudbrainDuration[0].CreatedUnix
+ if len(recordCloudbrainDuration) > 0 && err == nil {
+ recordBeginTime = recordCloudbrainDuration[0].DateTimeUnix
+ } else {
+ recordBeginTime = timeutil.TimeStamp(time.Now().Unix())
+ }
recordUpdateTime := time.Now().Unix()
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
@@ -1428,11 +1501,12 @@ func GetCloudbrainResourceOverview(ctx *context.Context) {
C2NetResourceDetail := []models.ResourceDetail{}
for _, resourceQueue := range resourceQueues {
if resourceQueue.Cluster == models.OpenICluster {
+ aiCenterName := repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
var resourceDetail models.ResourceDetail
resourceDetail.QueueCode = resourceQueue.QueueCode
resourceDetail.Cluster = resourceQueue.Cluster
resourceDetail.AiCenterCode = resourceQueue.AiCenterCode
- resourceDetail.AiCenterName = resourceQueue.AiCenterName + "/" + resourceQueue.AiCenterCode
+ resourceDetail.AiCenterName = resourceQueue.AiCenterCode + "/" + aiCenterName
resourceDetail.ComputeResource = resourceQueue.ComputeResource
resourceDetail.AccCardType = resourceQueue.AccCardType + "(" + resourceQueue.ComputeResource + ")"
resourceDetail.CardsTotalNum = resourceQueue.CardsTotalNum
@@ -1440,11 +1514,12 @@ func GetCloudbrainResourceOverview(ctx *context.Context) {
OpenIResourceDetail = append(OpenIResourceDetail, resourceDetail)
}
if resourceQueue.Cluster == models.C2NetCluster {
+ aiCenterName := repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
var resourceDetail models.ResourceDetail
resourceDetail.QueueCode = resourceQueue.QueueCode
resourceDetail.Cluster = resourceQueue.Cluster
resourceDetail.AiCenterCode = resourceQueue.AiCenterCode
- resourceDetail.AiCenterName = resourceQueue.AiCenterName + "/" + resourceQueue.AiCenterCode
+ resourceDetail.AiCenterName = resourceQueue.AiCenterCode + "/" + aiCenterName
resourceDetail.ComputeResource = resourceQueue.ComputeResource
resourceDetail.AccCardType = resourceQueue.AccCardType + "(" + resourceQueue.ComputeResource + ")"
resourceDetail.CardsTotalNum = resourceQueue.CardsTotalNum
@@ -1542,6 +1617,7 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
now := time.Now()
beginTimeStr := ctx.QueryTrim("beginTime")
endTimeStr := ctx.QueryTrim("endTime")
+ var brainRecordBeginTime time.Time
var beginTime time.Time
var endTime time.Time
@@ -1554,7 +1630,12 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
return beginTime, endTime
}
- brainRecordBeginTime := recordCloudbrainDuration[0].CreatedUnix.AsTime()
+ if len(recordCloudbrainDuration) > 0 && err == nil {
+ brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
+ } else {
+ brainRecordBeginTime = now
+ }
+
beginTime = brainRecordBeginTime
endTime = now
} else if queryType == "today" {
@@ -1596,7 +1677,11 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
return beginTime, endTime
}
- brainRecordBeginTime := recordCloudbrainDuration[0].CreatedUnix.AsTime()
+ if len(recordCloudbrainDuration) > 0 && err == nil {
+ brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
+ } else {
+ brainRecordBeginTime = now
+ }
beginTime = brainRecordBeginTime
endTime = now
} else {
@@ -1627,7 +1712,7 @@ func getAiCenterUsageDuration(beginTime time.Time, endTime time.Time, cloudbrain
usageRate := float64(0)
for _, cloudbrainStatistic := range cloudbrainStatistics {
- if int64(cloudbrainStatistic.CreatedUnix) >= beginTime.Unix() && int64(cloudbrainStatistic.CreatedUnix) < endTime.Unix() {
+ if int64(cloudbrainStatistic.DateTimeUnix) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTimeUnix) < endTime.Unix() {
totalDuration += cloudbrainStatistic.CardsTotalDuration
usageDuration += cloudbrainStatistic.CardsUseDuration
}
@@ -1659,28 +1744,29 @@ func getDurationStatistic(beginTime time.Time, endTime time.Time) (models.Durati
return OpenIDurationRate, C2NetDurationRate, 0
}
for _, cloudbrainStatistic := range cardDurationStatistics {
+ aiCenterName := cloudbrainStatistic.AiCenterCode + "/" + repo.GetAiCenterNameByCode(cloudbrainStatistic.AiCenterCode, "zh-CN")
if cloudbrainStatistic.Cluster == models.OpenICluster {
- if _, ok := OpenITotalDuration[cloudbrainStatistic.AiCenterName]; !ok {
- OpenITotalDuration[cloudbrainStatistic.AiCenterName] = cloudbrainStatistic.CardsTotalDuration
+ if _, ok := OpenITotalDuration[aiCenterName]; !ok {
+ OpenITotalDuration[aiCenterName] = cloudbrainStatistic.CardsTotalDuration
} else {
- OpenITotalDuration[cloudbrainStatistic.AiCenterName] += cloudbrainStatistic.CardsTotalDuration
+ OpenITotalDuration[aiCenterName] += cloudbrainStatistic.CardsTotalDuration
}
- if _, ok := OpenIUsageDuration[cloudbrainStatistic.AiCenterName]; !ok {
- OpenIUsageDuration[cloudbrainStatistic.AiCenterName] = cloudbrainStatistic.CardsUseDuration
+ if _, ok := OpenIUsageDuration[aiCenterName]; !ok {
+ OpenIUsageDuration[aiCenterName] = cloudbrainStatistic.CardsUseDuration
} else {
- OpenIUsageDuration[cloudbrainStatistic.AiCenterName] += cloudbrainStatistic.CardsUseDuration
+ OpenIUsageDuration[aiCenterName] += cloudbrainStatistic.CardsUseDuration
}
}
if cloudbrainStatistic.Cluster == models.C2NetCluster {
- if _, ok := C2NetTotalDuration[cloudbrainStatistic.AiCenterName]; !ok {
- C2NetTotalDuration[cloudbrainStatistic.AiCenterName] = cloudbrainStatistic.CardsTotalDuration
+ if _, ok := C2NetTotalDuration[aiCenterName]; !ok {
+ C2NetTotalDuration[aiCenterName] = cloudbrainStatistic.CardsTotalDuration
} else {
- C2NetTotalDuration[cloudbrainStatistic.AiCenterName] += cloudbrainStatistic.CardsTotalDuration
+ C2NetTotalDuration[aiCenterName] += cloudbrainStatistic.CardsTotalDuration
}
- if _, ok := C2NetUsageDuration[cloudbrainStatistic.AiCenterName]; !ok {
- C2NetUsageDuration[cloudbrainStatistic.AiCenterName] = cloudbrainStatistic.CardsUseDuration
+ if _, ok := C2NetUsageDuration[aiCenterName]; !ok {
+ C2NetUsageDuration[aiCenterName] = cloudbrainStatistic.CardsUseDuration
} else {
- C2NetUsageDuration[cloudbrainStatistic.AiCenterName] += cloudbrainStatistic.CardsUseDuration
+ C2NetUsageDuration[aiCenterName] += cloudbrainStatistic.CardsUseDuration
}
}
}
@@ -1690,16 +1776,17 @@ func getDurationStatistic(beginTime time.Time, endTime time.Time) (models.Durati
return OpenIDurationRate, C2NetDurationRate, 0
}
for _, v := range ResourceAiCenterRes {
+ aiCenterName := v.AiCenterCode + "/" + repo.GetAiCenterNameByCode(v.AiCenterCode, "zh-CN")
if cutString(v.AiCenterCode, 4) == cutString(models.AICenterOfCloudBrainOne, 4) {
- if _, ok := OpenIUsageDuration[v.AiCenterName]; !ok {
- OpenIUsageDuration[v.AiCenterName] = 0
+ if _, ok := OpenIUsageDuration[aiCenterName]; !ok {
+ OpenIUsageDuration[aiCenterName] = 0
}
- if _, ok := OpenITotalDuration[v.AiCenterName]; !ok {
- OpenITotalDuration[v.AiCenterName] = 0
+ if _, ok := OpenITotalDuration[aiCenterName]; !ok {
+ OpenITotalDuration[aiCenterName] = 0
}
} else {
- if _, ok := C2NetUsageDuration[v.AiCenterName]; !ok {
- C2NetUsageDuration[v.AiCenterName] = 0
+ if _, ok := C2NetUsageDuration[aiCenterName]; !ok {
+ C2NetUsageDuration[aiCenterName] = 0
}
}
}
@@ -1716,7 +1803,7 @@ func getDurationStatistic(beginTime time.Time, endTime time.Time) (models.Durati
for _, v := range OpenITotalDuration {
totalCanUse += float64(v)
}
- for _, v := range OpenIUsageRate {
+ for _, v := range OpenIUsageDuration {
totalUse += float64(v)
}
if totalCanUse == 0 || totalUse == 0 {
@@ -1724,6 +1811,7 @@ func getDurationStatistic(beginTime time.Time, endTime time.Time) (models.Durati
} else {
totalUsageRate = totalUse / totalCanUse
}
+ delete(C2NetUsageDuration, "/")
OpenIDurationRate.AiCenterTotalDurationStat = OpenITotalDuration
OpenIDurationRate.AiCenterUsageDurationStat = OpenIUsageDuration
@@ -1831,3 +1919,30 @@ func getHourCloudbrainDuration(beginTime time.Time, endTime time.Time, aiCenterC
hourTimeStatistic.HourTimeUsageRate = hourTimeUsageRate
return hourTimeStatistic, nil
}
+
+func CloudbrainUpdateAiCenter(ctx *context.Context) {
+ repo.CloudbrainDurationStatisticHour()
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "message": 0,
+ })
+}
+
+func GetResourceQueues(ctx *context.Context) {
+ resourceQueues, err := models.GetCanUseCardInfo()
+ if err != nil {
+ log.Error("GetCanUseCardInfo err: %v", err)
+ return
+ }
+ Resource := make([]*models.ResourceQueue, 0)
+ aiCenterCodeMap := make(map[string]string)
+ for _, resourceQueue := range resourceQueues {
+ if _, ok := aiCenterCodeMap[resourceQueue.AiCenterCode]; !ok {
+ resourceQueue.AiCenterName = repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
+ aiCenterCodeMap[resourceQueue.AiCenterCode] = resourceQueue.AiCenterCode
+ Resource = append(Resource, resourceQueue)
+ }
+ }
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "resourceQueues": Resource,
+ })
+}
diff --git a/routers/api/v1/repo/mlops.go b/routers/api/v1/repo/mlops.go
index 43969330d..322edc3e5 100644
--- a/routers/api/v1/repo/mlops.go
+++ b/routers/api/v1/repo/mlops.go
@@ -69,3 +69,17 @@ func GetRight(ctx *context.APIContext) {
})
}
+
+func GetCloudBrainJobId(ctx *context.APIContext) {
+ cloudbrains, err := models.GetCloudbrainsByDisplayJobName(ctx.Repo.Repository.ID, ctx.Query("jobType"), ctx.Query("name"))
+ if err != nil {
+ log.Warn("get cloudbrain by display name failed", err)
+ ctx.JSON(http.StatusOK, map[string]string{"jobId": ""})
+ return
+ }
+ if len(cloudbrains) > 0 {
+ ctx.JSON(http.StatusOK, map[string]string{"jobId": cloudbrains[0].JobID})
+ return
+ }
+ ctx.JSON(http.StatusOK, map[string]string{"jobId": ""})
+}
diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go
index 16e4997a3..127ddd835 100755
--- a/routers/api/v1/repo/modelarts.go
+++ b/routers/api/v1/repo/modelarts.go
@@ -6,6 +6,7 @@
package repo
import (
+ "code.gitea.io/gitea/modules/cloudbrain"
"encoding/json"
"net/http"
"path"
@@ -37,11 +38,14 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {
)
ID := ctx.Params(":id")
- job, err := models.GetCloudbrainByID(ID)
+
+ job,err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
+
if err != nil {
ctx.NotFound(err)
return
}
+
err = modelarts.HandleNotebookInfo(job)
if err != nil {
ctx.NotFound(err)
@@ -146,7 +150,6 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {
if len(result.JobInfo.Tasks) > 0 {
if len(result.JobInfo.Tasks[0].CenterID) > 0 && len(result.JobInfo.Tasks[0].CenterName) > 0 {
job.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
- // aiCenterName = result.JobInfo.Tasks[0].CenterName[0]
aiCenterName = cloudbrainService.GetAiCenterShow(job.AiCenter, ctx.Context)
}
}
diff --git a/routers/api/v1/repo/modelmanage.go b/routers/api/v1/repo/modelmanage.go
index 15260790d..3b0aed0d5 100644
--- a/routers/api/v1/repo/modelmanage.go
+++ b/routers/api/v1/repo/modelmanage.go
@@ -43,8 +43,14 @@ func QueryModelById(ctx *context.APIContext) {
routerRepo.QueryModelById(ctx.Context)
}
+func QueryModelByName(ctx *context.APIContext) {
+ log.Info("QueryModelByName by api.")
+ routerRepo.ShowSingleModel(ctx.Context)
+}
+
func QueryModelListForPredict(ctx *context.APIContext) {
log.Info("QueryModelListForPredict by api.")
+ ctx.Context.SetParams("isOnlyThisRepo", "true")
routerRepo.QueryModelListForPredict(ctx.Context)
}
@@ -88,6 +94,11 @@ func CreateModelConvert(ctx *context.APIContext) {
routerRepo.SaveModelConvert(ctx.Context)
}
+func StopModelConvert(ctx *context.APIContext) {
+ log.Info("StopModelConvert by api.")
+ routerRepo.StopModelConvertApi(ctx.Context)
+}
+
func ShowModelConvertPage(ctx *context.APIContext) {
log.Info("ShowModelConvertPage by api.")
modelResult, count, err := routerRepo.GetModelConvertPageData(ctx.Context)
@@ -113,3 +124,12 @@ func QueryModelConvertById(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, nil)
}
}
+
+func QueryModelConvertByName(ctx *context.APIContext) {
+ modelResult, err := routerRepo.GetModelConvertByName(ctx.Context)
+ if err == nil {
+ ctx.JSON(http.StatusOK, modelResult)
+ } else {
+ ctx.JSON(http.StatusOK, nil)
+ }
+}
diff --git a/routers/home.go b/routers/home.go
index aab760611..092b30fe3 100755
--- a/routers/home.go
+++ b/routers/home.go
@@ -7,6 +7,7 @@ package routers
import (
"bytes"
+ "encoding/json"
"net/http"
"strconv"
"strings"
@@ -672,7 +673,7 @@ func NotFound(ctx *context.Context) {
}
func getRecommendOrg() ([]map[string]interface{}, error) {
- url := setting.RecommentRepoAddr + "organizations"
+ url := setting.RecommentRepoAddr + "home/organizations"
result, err := repository.RecommendFromPromote(url)
if err != nil {
@@ -745,7 +746,7 @@ func GetMapInfo(ctx *context.Context) {
}
func GetRankUser(index string) ([]map[string]interface{}, error) {
- url := setting.RecommentRepoAddr + "user_rank_" + index
+ url := setting.RecommentRepoAddr + "user_rank/user_rank_" + index
result, err := repository.RecommendFromPromote(url)
if err != nil {
@@ -756,13 +757,25 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
tmpIndex := strings.Index(userRank, " ")
userName := userRank
score := 0
+ label := ""
if tmpIndex != -1 {
userName = userRank[0:tmpIndex]
- tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:])
- if err != nil {
- log.Info("convert to int error.")
+ left := userRank[tmpIndex+1:]
+ tmpIndex1 := strings.Index(left, " ")
+ if tmpIndex1 != -1 {
+ tmpScore, err := strconv.Atoi(left[0:tmpIndex1])
+ if err != nil {
+ log.Info("convert to int error.")
+ }
+ score = tmpScore
+ label = left[tmpIndex1+1:]
+ } else {
+ tmpScore, err := strconv.Atoi(left[tmpIndex+1:])
+ if err != nil {
+ log.Info("convert to int error.")
+ }
+ score = tmpScore
}
- score = tmpScore
}
user, err := models.GetUserByName(userName)
if err == nil {
@@ -772,6 +785,7 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
userMap["FullName"] = user.FullName
userMap["HomeLink"] = user.HomeLink()
userMap["ID"] = user.ID
+ userMap["Label"] = label
userMap["Avatar"] = user.RelAvatarLink()
userMap["Score"] = score
resultOrg = append(resultOrg, userMap)
@@ -792,25 +806,54 @@ func GetUserRankFromPromote(ctx *context.Context) {
ctx.JSON(200, resultUserRank)
}
+func getMapContent(fileName string) []map[string]string {
+ url := setting.RecommentRepoAddr + fileName
+ result, err := repository.RecommendContentFromPromote(url)
+ remap := make([]map[string]string, 0)
+ if err == nil {
+ json.Unmarshal([]byte(result), &remap)
+ }
+ return remap
+}
+
+func HomeNoticeTmpl(ctx *context.Context) {
+ ctx.Data["url_params"] = ""
+ ctx.HTML(200, "notice")
+}
+
func RecommendHomeInfo(ctx *context.Context) {
resultOrg, err := getRecommendOrg()
if err != nil {
log.Info("error." + err.Error())
}
- resultRepo, err := repository.GetRecommendRepoFromPromote("projects")
+ repoMap := getMapContent("home/projects")
+ resultRepo, err := repository.GetRecommendRepoFromPromote(repoMap)
if err != nil {
log.Info("error." + err.Error())
}
- resultImage, err := getImageInfo("picture_info")
- if err != nil {
- log.Info("error." + err.Error())
- }
-
+ resultActivityInfo := getMapContent("home/activity_info")
mapInterface := make(map[string]interface{})
mapInterface["org"] = resultOrg
mapInterface["repo"] = resultRepo
- mapInterface["image"] = resultImage
- //mapInterface["cloudbrain"] = resultCloudBrain
+ mapInterface["activity"] = resultActivityInfo
+
+ user_experience := getMapContent("home/user_experience")
+ for _, amap := range user_experience {
+ userId := amap["userid"]
+ userIntId, _ := strconv.Atoi(userId)
+ user, err := models.GetUserByID(int64(userIntId))
+ if err == nil {
+ amap["name"] = user.Name
+ amap["fullname"] = user.FullName
+ amap["detail"] = user.Description
+ amap["avatar"] = user.AvatarLink()
+ }
+ }
+ mapInterface["user_experience"] = user_experience
+ dataset, err := models.QueryDatasetGroupByTask()
+ if err == nil {
+ mapInterface["dataset"] = dataset
+ }
ctx.JSON(http.StatusOK, mapInterface)
}
@@ -824,4 +867,4 @@ func HomePrivacy(ctx *context.Context) {
func HomeResoruceDesc(ctx *context.Context) {
ctx.HTML(200, tplResoruceDesc)
-}
\ No newline at end of file
+}
diff --git a/routers/private/internal.go b/routers/private/internal.go
index 3d67afe8f..14b0f05de 100755
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -55,6 +55,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration)
m.Post("/task/history_handle/aicenter", repo.HandleTaskWithAiCenter)
m.Post("/resources/specification/handle_historical_task", admin.RefreshHistorySpec)
+ m.Post("/duration_statisctic/history_handle", repo.CloudbrainUpdateHistoryData)
}, CheckInternalToken)
}
diff --git a/routers/repo/ai_model_convert.go b/routers/repo/ai_model_convert.go
index 962c76aae..9839a5041 100644
--- a/routers/repo/ai_model_convert.go
+++ b/routers/repo/ai_model_convert.go
@@ -49,7 +49,7 @@ const (
//TensorFlowNpuBootFile = "convert_tensorflow.py"
//TensorFlowGpuBootFile = "convert_tensorflow_gpu.py"
- //ConvertRepoPath = "https://git.openi.org.cn/zouap/npu_test"
+ //ConvertRepoPath = "https://openi.pcl.ac.cn/zouap/npu_test"
CONVERT_FORMAT_ONNX = 0
CONVERT_FORMAT_TRT = 1
@@ -573,13 +573,10 @@ func deleteCloudBrainTask(task *models.AiModelConvert) {
}
}
-func StopModelConvert(ctx *context.Context) {
- id := ctx.Params(":id")
- log.Info("stop model convert start.id=" + id)
+func stopModelConvert(id string) error {
job, err := models.QueryModelConvertById(id)
if err != nil {
- ctx.ServerError("Not found task.", err)
- return
+ return err
}
if job.IsGpuTrainTask() {
err = cloudbrain.StopJob(job.CloudBrainTaskId)
@@ -600,6 +597,35 @@ func StopModelConvert(ctx *context.Context) {
err = models.UpdateModelConvert(job)
if err != nil {
log.Error("UpdateModelConvert failed:", err)
+ return err
+ }
+ return nil
+}
+
+func StopModelConvertApi(ctx *context.Context) {
+ id := ctx.Params(":id")
+ log.Info("stop model convert start.id=" + id)
+ err := stopModelConvert(id)
+ if err == nil {
+ ctx.JSON(200, map[string]string{
+ "code": "0",
+ "msg": "succeed",
+ })
+ } else {
+ ctx.JSON(200, map[string]string{
+ "code": "1",
+ "msg": err.Error(),
+ })
+ }
+}
+
+func StopModelConvert(ctx *context.Context) {
+ id := ctx.Params(":id")
+ log.Info("stop model convert start.id=" + id)
+ err := stopModelConvert(id)
+ if err != nil {
+ ctx.ServerError("Not found task.", err)
+ return
}
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelmanage/convert_model")
}
@@ -620,7 +646,7 @@ func ShowModelConvertInfo(ctx *context.Context) {
return
}
ctx.Data["Name"] = job.Name
- ctx.Data["canDownload"] = isOper(ctx, job.UserId)
+ ctx.Data["canDownload"] = isOperModifyOrDelete(ctx, job.UserId)
user, err := models.GetUserByID(job.UserId)
if err == nil {
job.UserName = user.Name
@@ -732,6 +758,11 @@ func GetModelConvertById(ctx *context.Context) (*models.AiModelConvert, error) {
return models.QueryModelConvertById(id)
}
+func GetModelConvertByName(ctx *context.Context) ([]*models.AiModelConvert, error) {
+ name := ctx.Query("name")
+ return models.QueryModelConvertByName(name, ctx.Repo.Repository.ID)
+}
+
func GetModelConvertPageData(ctx *context.Context) ([]*models.AiModelConvert, int64, error) {
page := ctx.QueryInt("page")
if page <= 0 {
@@ -755,7 +786,7 @@ func GetModelConvertPageData(ctx *context.Context) ([]*models.AiModelConvert, in
}
userIds := make([]int64, len(modelResult))
for i, model := range modelResult {
- model.IsCanOper = isOper(ctx, model.UserId)
+ model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId)
model.IsCanDelete = isCanDelete(ctx, model.UserId)
userIds[i] = model.UserId
}
@@ -828,5 +859,4 @@ func ModelConvertDownloadModel(ctx *context.Context) {
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
}
}
-
}
diff --git a/routers/repo/ai_model_manage.go b/routers/repo/ai_model_manage.go
index 7eedb9bc4..6e6889c32 100644
--- a/routers/repo/ai_model_manage.go
+++ b/routers/repo/ai_model_manage.go
@@ -93,7 +93,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
log.Info("accuracyJson=" + string(accuracyJson))
aiTask.ContainerIp = ""
aiTaskJson, _ := json.Marshal(aiTask)
-
+ isPrivate := ctx.QueryBool("isPrivate")
model := &models.AiModelManage{
ID: id,
Version: version,
@@ -114,6 +114,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
TrainTaskInfo: string(aiTaskJson),
Accuracy: string(accuracyJson),
Status: STATUS_COPY_MODEL,
+ IsPrivate: isPrivate,
}
err = models.SaveModelToDb(model)
@@ -216,6 +217,7 @@ func SaveLocalModel(ctx *context.Context) {
description := ctx.Query("description")
engine := ctx.QueryInt("engine")
taskType := ctx.QueryInt("type")
+ isPrivate := ctx.QueryBool("isPrivate")
modelActualPath := ""
if taskType == models.TypeCloudBrainOne {
destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(id) + "/"
@@ -262,6 +264,7 @@ func SaveLocalModel(ctx *context.Context) {
TrainTaskInfo: "",
Accuracy: "",
Status: STATUS_FINISHED,
+ IsPrivate: isPrivate,
}
err := models.SaveModelToDb(model)
@@ -554,20 +557,6 @@ func deleteModelByID(ctx *context.Context, id string) error {
return err
}
-func QueryModelByParameters(repoId int64, page int) ([]*models.AiModelManage, int64, error) {
-
- return models.QueryModel(&models.AiModelQueryOptions{
- ListOptions: models.ListOptions{
- Page: page,
- PageSize: setting.UI.IssuePagingNum,
- },
- RepoID: repoId,
- Type: -1,
- New: MODEL_LATEST,
- Status: -1,
- })
-}
-
func DownloadMultiModelFile(ctx *context.Context) {
log.Info("DownloadMultiModelFile start.")
id := ctx.Query("id")
@@ -578,7 +567,7 @@ func DownloadMultiModelFile(ctx *context.Context) {
ctx.ServerError("no such model:", err)
return
}
- if !isOper(ctx, task.UserId) {
+ if !isCanDownload(ctx, task) {
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
@@ -806,7 +795,7 @@ func DownloadSingleModelFile(ctx *context.Context) {
ctx.ServerError("no such model:", err)
return
}
- if !isOper(ctx, task.UserId) {
+ if !isCanDownload(ctx, task) {
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
@@ -874,8 +863,9 @@ func QueryModelById(ctx *context.Context) {
id := ctx.Query("id")
model, err := models.QueryModelById(id)
if err == nil {
- model.IsCanOper = isOper(ctx, model.UserId)
+ model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId)
model.IsCanDelete = isCanDelete(ctx, model.UserId)
+ model.IsCanDownload = isCanDownload(ctx, model)
removeIpInfo(model)
ctx.JSON(http.StatusOK, model)
} else {
@@ -891,7 +881,8 @@ func ShowSingleModel(ctx *context.Context) {
userIds := make([]int64, len(models))
for i, model := range models {
- model.IsCanOper = isOper(ctx, model.UserId)
+ model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId)
+ model.IsCanDownload = isCanDownload(ctx, model)
model.IsCanDelete = isCanDelete(ctx, model.UserId)
userIds[i] = model.UserId
}
@@ -941,7 +932,8 @@ func ShowOneVersionOtherModel(ctx *context.Context) {
userIds := make([]int64, len(aimodels))
for i, model := range aimodels {
- model.IsCanOper = isOper(ctx, model.UserId)
+ model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId)
+ model.IsCanDownload = isCanDownload(ctx, model)
model.IsCanDelete = isCanDelete(ctx, model.UserId)
userIds[i] = model.UserId
}
@@ -964,6 +956,7 @@ func ShowOneVersionOtherModel(ctx *context.Context) {
}
func SetModelCount(ctx *context.Context) {
+ isQueryPrivate := isQueryPrivateModel(ctx)
repoId := ctx.Repo.Repository.ID
Type := -1
_, count, _ := models.QueryModel(&models.AiModelQueryOptions{
@@ -971,10 +964,12 @@ func SetModelCount(ctx *context.Context) {
Page: 1,
PageSize: 2,
},
- RepoID: repoId,
- Type: Type,
- New: MODEL_LATEST,
- Status: -1,
+ RepoID: repoId,
+ Type: Type,
+ New: MODEL_LATEST,
+ IsOnlyThisRepo: true,
+ Status: -1,
+ IsQueryPrivate: isQueryPrivate,
})
ctx.Data["MODEL_COUNT"] = count
}
@@ -1001,27 +996,87 @@ func isQueryRight(ctx *context.Context) bool {
}
}
+func isCanDownload(ctx *context.Context, task *models.AiModelManage) bool {
+ if ctx.User == nil {
+ return false
+ }
+ isCollaborator, err := ctx.Repo.Repository.IsCollaborator(ctx.User.ID)
+ if err != nil {
+ log.Info("query error.")
+ }
+ isTeamMember, err := ctx.Repo.Repository.IsInRepoTeam(ctx.User.ID)
+ if err != nil {
+ log.Info("query IsInRepoTeam error." + err.Error())
+ }
+ if ctx.User.IsAdmin || ctx.User.ID == task.UserId || isCollaborator || isTeamMember {
+ return true
+ }
+ if ctx.Repo.IsOwner() {
+ return true
+ }
+ if !task.IsPrivate {
+ return true
+ }
+ return false
+}
+
+func isQueryPrivateModel(ctx *context.Context) bool {
+ if ctx.User == nil {
+ return false
+ }
+ isCollaborator, err := ctx.Repo.Repository.IsCollaborator(ctx.User.ID)
+ if err != nil {
+ log.Info("query IsCollaborator error." + err.Error())
+ }
+ isTeamMember, err := ctx.Repo.Repository.IsInRepoTeam(ctx.User.ID)
+ if err != nil {
+ log.Info("query IsInRepoTeam error." + err.Error())
+ }
+ if ctx.User.IsAdmin || isCollaborator || isTeamMember {
+ return true
+ }
+ if ctx.Repo.IsOwner() {
+ return true
+ }
+ return false
+}
+
func isCanDelete(ctx *context.Context, modelUserId int64) bool {
if ctx.User == nil {
return false
}
- if ctx.User.IsAdmin || ctx.User.ID == modelUserId {
+ if ctx.User.ID == modelUserId {
+ return true
+ }
+ return isAdminRight(ctx)
+}
+
+func isAdminRight(ctx *context.Context) bool {
+ if ctx.User.IsAdmin {
return true
}
if ctx.Repo.IsOwner() {
return true
}
+ permission, err := models.GetUserRepoPermission(ctx.Repo.Repository, ctx.User)
+ if err != nil {
+ log.Error("GetUserRepoPermission failed:%v", err.Error())
+ return false
+ }
+ if permission.AccessMode >= models.AccessModeAdmin {
+ return true
+ }
return false
}
-func isOper(ctx *context.Context, modelUserId int64) bool {
+func isOperModifyOrDelete(ctx *context.Context, modelUserId int64) bool {
if ctx.User == nil {
return false
}
if ctx.User.IsAdmin || ctx.User.ID == modelUserId {
return true
}
- return false
+ return isAdminRight(ctx)
}
func ShowModelPageInfo(ctx *context.Context) {
@@ -1038,6 +1093,7 @@ func ShowModelPageInfo(ctx *context.Context) {
if pageSize <= 0 {
pageSize = setting.UI.IssuePagingNum
}
+ isQueryPrivate := isQueryPrivateModel(ctx)
repoId := ctx.Repo.Repository.ID
Type := -1
modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{
@@ -1045,10 +1101,12 @@ func ShowModelPageInfo(ctx *context.Context) {
Page: page,
PageSize: pageSize,
},
- RepoID: repoId,
- Type: Type,
- New: MODEL_LATEST,
- Status: -1,
+ RepoID: repoId,
+ Type: Type,
+ New: MODEL_LATEST,
+ IsOnlyThisRepo: true,
+ Status: -1,
+ IsQueryPrivate: isQueryPrivate,
})
if err != nil {
ctx.ServerError("Cloudbrain", err)
@@ -1057,8 +1115,9 @@ func ShowModelPageInfo(ctx *context.Context) {
userIds := make([]int64, len(modelResult))
for i, model := range modelResult {
- model.IsCanOper = isOper(ctx, model.UserId)
+ model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId)
model.IsCanDelete = isCanDelete(ctx, model.UserId)
+ model.IsCanDownload = isCanDownload(ctx, model)
userIds[i] = model.UserId
}
@@ -1089,6 +1148,37 @@ func ModifyModel(id string, description string) error {
return err
}
+func ModifyModelPrivate(ctx *context.Context) {
+ id := ctx.Query("id")
+ isPrivate := ctx.QueryBool("isPrivate")
+ re := map[string]string{
+ "code": "-1",
+ }
+ task, err := models.QueryModelById(id)
+ if err != nil || task == nil {
+ re["msg"] = err.Error()
+ log.Error("no such model!", err.Error())
+ ctx.JSON(200, re)
+ return
+ }
+ if !isOperModifyOrDelete(ctx, task.UserId) {
+ re["msg"] = "No right to operation."
+ ctx.JSON(200, re)
+ return
+ }
+ err = models.ModifyModelPrivate(id, isPrivate)
+ if err == nil {
+ re["code"] = "0"
+ ctx.JSON(200, re)
+ log.Info("modify success.")
+ } else {
+ re["msg"] = err.Error()
+ ctx.JSON(200, re)
+ log.Info("Failed to modify.id=" + id + " isprivate=" + fmt.Sprint(isPrivate) + " error:" + err.Error())
+ }
+
+}
+
func ModifyModelInfo(ctx *context.Context) {
log.Info("modify model start.")
id := ctx.Query("id")
@@ -1102,7 +1192,7 @@ func ModifyModelInfo(ctx *context.Context) {
ctx.JSON(200, re)
return
}
- if !isOper(ctx, task.UserId) {
+ if !isOperModifyOrDelete(ctx, task.UserId) {
re["msg"] = "No right to operation."
ctx.JSON(200, re)
return
@@ -1112,6 +1202,7 @@ func ModifyModelInfo(ctx *context.Context) {
label := ctx.Query("label")
description := ctx.Query("description")
engine := ctx.QueryInt("engine")
+ isPrivate := ctx.QueryBool("isPrivate")
aimodels := models.QueryModelByName(name, task.RepoId)
if aimodels != nil && len(aimodels) > 0 {
if len(aimodels) == 1 {
@@ -1126,14 +1217,14 @@ func ModifyModelInfo(ctx *context.Context) {
return
}
}
- err = models.ModifyLocalModel(id, name, label, description, engine)
+ err = models.ModifyLocalModel(id, name, label, description, engine, isPrivate)
} else {
label := ctx.Query("label")
description := ctx.Query("description")
engine := task.Engine
name := task.Name
- err = models.ModifyLocalModel(id, name, label, description, int(engine))
+ err = models.ModifyLocalModel(id, name, label, description, int(engine), task.IsPrivate)
}
if err != nil {
@@ -1148,15 +1239,27 @@ func ModifyModelInfo(ctx *context.Context) {
func QueryModelListForPredict(ctx *context.Context) {
repoId := ctx.Repo.Repository.ID
+ page := ctx.QueryInt("page")
+ if page <= 0 {
+ page = -1
+ }
+ pageSize := ctx.QueryInt("pageSize")
+ if pageSize <= 0 {
+ pageSize = -1
+ }
+ isQueryPrivate := isQueryPrivateModel(ctx)
+ //IsOnlyThisRepo := ctx.QueryBool("isOnlyThisRepo")
modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{
ListOptions: models.ListOptions{
- Page: -1,
- PageSize: -1,
+ Page: page,
+ PageSize: pageSize,
},
- RepoID: repoId,
- Type: ctx.QueryInt("type"),
- New: -1,
- Status: 0,
+ RepoID: repoId,
+ Type: ctx.QueryInt("type"),
+ New: -1,
+ Status: 0,
+ IsOnlyThisRepo: true,
+ IsQueryPrivate: isQueryPrivate,
})
if err != nil {
ctx.ServerError("Cloudbrain", err)
@@ -1168,7 +1271,9 @@ func QueryModelListForPredict(ctx *context.Context) {
nameMap := make(map[string][]*models.AiModelManage)
for _, model := range modelResult {
- removeIpInfo(model)
+ model.TrainTaskInfo = ""
+ model.Accuracy = ""
+ //removeIpInfo(model)
if _, value := nameMap[model.Name]; !value {
models := make([]*models.AiModelManage, 0)
models = append(models, model)
diff --git a/routers/repo/aisafety.go b/routers/repo/aisafety.go
index b638a486b..6176fcda5 100644
--- a/routers/repo/aisafety.go
+++ b/routers/repo/aisafety.go
@@ -11,7 +11,8 @@ import (
"os"
"strconv"
"strings"
- "time"
+
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/aisafety"
@@ -483,7 +484,6 @@ func isTaskNotFinished(status string) bool {
}
func AiSafetyCreateForGetGPU(ctx *context.Context) {
- t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainOne
@@ -497,7 +497,7 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
log.Info("GPUBaseDataSetUUID=" + setting.ModelSafetyTest.GPUBaseDataSetUUID)
log.Info("GPUCombatDataSetName=" + setting.ModelSafetyTest.GPUCombatDataSetName)
log.Info("GPUCombatDataSetUUID=" + setting.ModelSafetyTest.GPUCombatDataSetUUID)
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
prepareCloudbrainOneSpecs(ctx)
queuesDetail, _ := cloudbrain.GetQueuesDetail()
@@ -514,12 +514,11 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
}
func AiSafetyCreateForGetNPU(ctx *context.Context) {
- t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainTwo
ctx.Data["compute_resource"] = models.NPUResource
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
ctx.Data["BaseDataSetName"] = setting.ModelSafetyTest.NPUBaseDataSetName
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index 7d96d1b58..a23cd5462 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+
"code.gitea.io/gitea/modules/urfs_client/urchin"
"code.gitea.io/gitea/modules/dataset"
@@ -92,28 +94,9 @@ func MustEnableCloudbrain(ctx *context.Context) {
}
}
-func cutString(str string, lens int) string {
- if len(str) < lens {
- return str
- }
- return str[:lens]
-}
-
-func jobNamePrefixValid(s string) string {
- lowStr := strings.ToLower(s)
- re := regexp.MustCompile(`[^a-z0-9_\\-]+`)
-
- removeSpecial := re.ReplaceAllString(lowStr, "")
-
- re = regexp.MustCompile(`^[_\\-]+`)
- return re.ReplaceAllString(removeSpecial, "")
-
-}
-
func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
ctx.Data["command"] = cloudbrain.GetCloudbrainDebugCommand()
@@ -687,6 +670,13 @@ func CloudBrainRestart(ctx *context.Context) {
break
}
+ if _, err := os.Stat(getOldJobPath(task)); err != nil {
+ log.Error("Can not find job minio path", err)
+ resultCode = "-1"
+ errorMsg = ctx.Tr("cloudbrain.result_cleared")
+ break
+ }
+
count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug))
if err != nil {
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
@@ -696,7 +686,7 @@ func CloudBrainRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
- resultCode = "-1"
+ resultCode = "2"
errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
@@ -721,6 +711,11 @@ func CloudBrainRestart(ctx *context.Context) {
})
}
+
+func getOldJobPath(task *models.Cloudbrain) string {
+ return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + task.JobName
+}
+
func CloudBrainBenchMarkShow(ctx *context.Context) {
cloudBrainShow(ctx, tplCloudBrainBenchmarkShow, models.JobTypeBenchmark)
}
@@ -759,43 +754,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
return
}
if task.Status == string(models.JobWaiting) || task.Status == string(models.JobRunning) {
- result, err := cloudbrain.GetJob(task.JobID)
+ task, err = cloudbrainTask.SyncCloudBrainOneStatus(task)
if err != nil {
log.Info("error:" + err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
- if result != nil {
- jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
- taskRoles := jobRes.TaskRoles
- taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
- ctx.Data["taskRes"] = taskRes
- ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
- oldStatus := task.Status
- task.Status = taskRes.TaskStatuses[0].State
- task.ContainerIp = ""
- task.ContainerID = taskRes.TaskStatuses[0].ContainerID
- models.ParseAndSetDurationFromCloudBrainOne(jobRes, task)
-
- if task.DeletedAt.IsZero() { //normal record
- if oldStatus != task.Status {
- notification.NotifyChangeCloudbrainStatus(task, oldStatus)
- }
- err = models.UpdateJob(task)
- if err != nil {
- ctx.Data["error"] = err.Error()
- return
- }
- } else { //deleted record
-
- }
-
- ctx.Data["result"] = jobRes
- } else {
- log.Info("error:" + err.Error())
- return
- }
}
user, err := models.GetUserByID(task.UserID)
@@ -889,7 +854,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
func CloudBrainDebug(ctx *context.Context) {
task := ctx.Cloudbrain
debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
- ctx.Redirect(debugUrl)
+ if task.BootFile!=""{
+ ctx.Redirect(getFileUrl(debugUrl,task.BootFile))
+
+ }else{
+ ctx.Redirect(debugUrl)
+ }
+
}
func prepareSpec4Show(ctx *context.Context, task *models.Cloudbrain) {
diff --git a/routers/repo/cloudbrain_statistic.go b/routers/repo/cloudbrain_statistic.go
index 3814c2daf..6ff377491 100644
--- a/routers/repo/cloudbrain_statistic.go
+++ b/routers/repo/cloudbrain_statistic.go
@@ -1,118 +1,180 @@
package repo
import (
+ "net/http"
"strings"
"time"
"code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
)
func CloudbrainDurationStatisticHour() {
+ if setting.IsCloudbrainTimingEnabled {
+ var statisticTime time.Time
+ var count int64
+ recordDurationUpdateTime, err := models.GetDurationRecordUpdateTime()
+ if err != nil {
+ log.Error("Can not get GetDurationRecordBeginTime", err)
+ }
+ now := time.Now()
+ currentTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
+ if err == nil && len(recordDurationUpdateTime) > 0 {
+ statisticTime = time.Unix(int64(recordDurationUpdateTime[0].DateTimeUnix), 0).Add(+1 * time.Hour)
+ } else {
+ statisticTime = currentTime
+ }
- dateTime := time.Now().Format("2006-01-02 15:04:05")
- dayTime := time.Now().Format("2006-01-02")
- now := time.Now()
+ err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(statisticTime.Add(-1*time.Hour).Unix()), timeutil.TimeStamp(currentTime.Unix()))
+ if err != nil {
+ log.Error("DeleteCloudbrainDurationStatistic failed", err)
+ }
- currentTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
+ for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
+ countEach := summaryDurationStat(statisticTime)
+ count += countEach
+ statisticTime = statisticTime.Add(+1 * time.Hour)
+ }
+ log.Info("summaryDurationStat count: %v", count)
+ }
+}
+func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time) int64 {
+ var count int64
+ statisticTime := beginTime
+ currentTime := endTime
+ for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
+ countEach := summaryDurationStat(statisticTime)
+ count += countEach
+ statisticTime = statisticTime.Add(+1 * time.Hour)
+ }
+ return count
+}
- m, _ := time.ParseDuration("-1h")
- beginTime := currentTime.Add(m).Unix()
- endTime := currentTime.Unix()
- hourTime := currentTime.Add(m).Hour()
+//statisticTime是当前的时辰,比如当前是2019-01-01 12:01:01,那么statisticTime就是2019-01-01 12:00:00
+func summaryDurationStat(statisticTime time.Time) int64 {
+ var count int64
+ dateTimeUnix := timeutil.TimeStamp(statisticTime.Add(-1 * time.Hour).Unix())
+ beginTime := statisticTime.Add(-1 * time.Hour).Unix()
+ dayTime := statisticTime.Add(-1 * time.Hour).Format("2006-01-02")
+ hourTime := statisticTime.Add(-1 * time.Hour).Hour()
+ endTime := statisticTime.Unix()
ciTasks, err := models.GetCloudbrainByTime(beginTime, endTime)
if err != nil {
log.Info("GetCloudbrainByTime err: %v", err)
- return
+ return 0
}
- specMap := make(map[string]*models.Specification)
models.LoadSpecs4CloudbrainInfo(ciTasks)
- for _, cloudbrain := range ciTasks {
- if _, ok := specMap[cloudbrain.Cloudbrain.Spec.AiCenterCode+"/"+cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
- if cloudbrain.Cloudbrain.Spec != nil {
- specMap[cloudbrain.Cloudbrain.Spec.AiCenterCode+"/"+cloudbrain.Cloudbrain.Spec.AccCardType] = cloudbrain.Cloudbrain.Spec
- }
- }
- }
-
- cloudBrainCenterCodeAndCardTypeInfo := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
+ cloudBrainCenterCodeAndCardTypeInfo, cloudbrainMap := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
log.Info("GetCanUseCardInfo err: %v", err)
- return
+ return 0
}
+
cardsTotalDurationMap := make(map[string]int)
for _, resourceQueue := range resourceQueues {
- cardsTotalDurationMap[resourceQueue.Cluster+"/"+resourceQueue.AiCenterName+"/"+resourceQueue.AiCenterCode+"/"+resourceQueue.AccCardType+"/"+resourceQueue.ComputeResource] = resourceQueue.CardsTotalNum * 1 * 60 * 60
+ if _, ok := cardsTotalDurationMap[resourceQueue.Cluster+"/"+resourceQueue.AiCenterCode+"/"+resourceQueue.AccCardType]; !ok {
+ cardsTotalDurationMap[resourceQueue.Cluster+"/"+resourceQueue.AiCenterCode+"/"+resourceQueue.AccCardType] = resourceQueue.CardsTotalNum * 1 * 60 * 60
+ } else {
+ cardsTotalDurationMap[resourceQueue.Cluster+"/"+resourceQueue.AiCenterCode+"/"+resourceQueue.AccCardType] += resourceQueue.CardsTotalNum * 1 * 60 * 60
+ }
}
- for centerCode, CardTypeInfo := range cloudBrainCenterCodeAndCardTypeInfo {
- for cardType, cardDuration := range CardTypeInfo {
- spec := specMap[centerCode+"/"+cardType]
- if spec != nil {
- if err := models.DeleteCloudbrainDurationStatisticHour(dayTime, hourTime, centerCode, cardType); err != nil {
- log.Error("DeleteCloudbrainDurationStatisticHour failed: %v", err.Error())
- return
- }
- if _, ok := cardsTotalDurationMap[spec.Cluster+"/"+spec.AiCenterName+"/"+centerCode+"/"+cardType+"/"+spec.ComputeResource]; !ok {
- cardsTotalDurationMap[spec.Cluster+"/"+spec.AiCenterName+"/"+centerCode+"/"+cardType+"/"+spec.ComputeResource] = 0
+ for centerCode, CardTypes := range cloudBrainCenterCodeAndCardTypeInfo {
+ for cardType, cardDuration := range CardTypes {
+ cloudbrainTable := cloudbrainMap[centerCode+"/"+cardType]
+ if cloudbrainTable != nil {
+ if _, ok := cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType]; !ok {
+ cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType] = 0
}
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
- DateTime: dateTime,
+ DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
- Cluster: spec.Cluster,
- AiCenterName: spec.AiCenterName,
+ Cluster: cloudbrainTable.Cluster,
+ AiCenterName: GetAiCenterNameByCode(centerCode, "zh-CN"),
AiCenterCode: centerCode,
AccCardType: cardType,
- ComputeResource: spec.ComputeResource,
CardsUseDuration: cardDuration,
- CardsTotalDuration: cardsTotalDurationMap[spec.Cluster+"/"+spec.AiCenterName+"/"+centerCode+"/"+cardType+"/"+spec.ComputeResource],
+ CardsTotalDuration: cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType],
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
}
- delete(cardsTotalDurationMap, spec.Cluster+"/"+spec.AiCenterName+"/"+centerCode+"/"+cardType+"/"+spec.ComputeResource)
+ count++
+ delete(cardsTotalDurationMap, cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType)
}
}
}
for key, cardsTotalDuration := range cardsTotalDurationMap {
- if err := models.DeleteCloudbrainDurationStatisticHour(dayTime, hourTime, strings.Split(key, "/")[2], strings.Split(key, "/")[3]); err != nil {
- log.Error("DeleteCloudbrainDurationStatisticHour failed: %v", err.Error())
- return
- }
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
- DateTime: dateTime,
+ DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
- AiCenterName: strings.Split(key, "/")[1],
- AiCenterCode: strings.Split(key, "/")[2],
- AccCardType: strings.Split(key, "/")[3],
- ComputeResource: strings.Split(key, "/")[4],
+ AiCenterName: GetAiCenterNameByCode(strings.Split(key, "/")[1], "zh-CN"),
+ AiCenterCode: strings.Split(key, "/")[1],
+ AccCardType: strings.Split(key, "/")[2],
CardsUseDuration: 0,
CardsTotalDuration: cardsTotalDuration,
+ CardsTotalNum: cardsTotalDuration / 1 / 60 / 60,
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
}
+ count++
}
log.Info("finish summary cloudbrainDurationStat")
+ return count
+}
+
+func GetAiCenterNameByCode(centerCode string, language string) string {
+ var aiCenterName string
+ aiCenterInfo := cloudbrainService.GetAiCenterInfoByCenterCode(centerCode)
+ if aiCenterInfo != nil {
+ if language == "zh-CN" {
+ aiCenterName = aiCenterInfo.Content
+ } else {
+ aiCenterName = aiCenterInfo.ContentEN
+ }
+ } else {
+ aiCenterName = centerCode
+ }
+ return aiCenterName
}
-func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, beginTime int64, endTime int64) map[string]map[string]int {
+func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, beginTime int64, endTime int64) (map[string]map[string]int, map[string]*models.Cloudbrain) {
var WorkServerNumber int
var AccCardsNum int
+ cloudbrainMap := make(map[string]*models.Cloudbrain)
cloudBrainCenterCodeAndCardType := make(map[string]map[string]int)
for _, cloudbrain := range ciTasks {
+ if cloudbrain.Cloudbrain.StartTime == 0 {
+ cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
+ }
+ if cloudbrain.Cloudbrain.EndTime == 0 {
+ cloudbrain.Cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
+ }
+ cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
+ if cloudbrain.Cloudbrain.Spec != nil {
+ if _, ok := cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
+ if cloudbrain.Cloudbrain.Spec != nil {
+ cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType] = &cloudbrain.Cloudbrain
+ }
+ }
+ }
+ cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
}
@@ -129,41 +191,77 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
} else {
AccCardsNum = cloudbrain.Cloudbrain.Spec.AccCardsNum
}
- if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode]; !ok {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode] = make(map[string]int)
+ if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter]; !ok {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter] = make(map[string]int)
}
-
- if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) {
- if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
- if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ if cloudbrain.Cloudbrain.Spec != nil {
+ if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) && cloudbrain.Cloudbrain.DeletedAt.IsZero() {
+ if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
+ if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) < endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ } else if int64(cloudbrain.Cloudbrain.StartTime) >= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = 0
+ }
} else {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) < endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ } else if int64(cloudbrain.Cloudbrain.StartTime) >= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += 0
+ }
}
} else {
- if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
+ if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
+ } else if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ }
} else {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
+ } else if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
+ } else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
+ cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
+ }
}
}
- } else {
- if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
- if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
- } else {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
- }
- } else {
- if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
- } else {
- cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Spec.AiCenterCode][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
- }
- }
-
}
}
- return cloudBrainCenterCodeAndCardType
+ return cloudBrainCenterCodeAndCardType, cloudbrainMap
+}
+
+func CloudbrainUpdateHistoryData(ctx *context.Context) {
+ beginTimeStr := ctx.QueryTrim("beginTime")
+ endTimeStr := ctx.QueryTrim("endTime")
+ var count int64
+ var err error
+ if beginTimeStr != "" && endTimeStr != "" {
+ beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local)
+ endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local)
+ if time.Now().Before(endTime) {
+ endTime = time.Now()
+ }
+ beginTimeUnix := timeutil.TimeStamp(beginTime.Unix())
+ endTimeUnix := timeutil.TimeStamp(endTime.Unix())
+
+ err = models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix)
+ count = UpdateDurationStatisticHistoryData(beginTime.Add(+1*time.Hour), endTime.Add(+1*time.Hour))
+ }
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "message": 0,
+ "count": count,
+ "err": err,
+ })
}
diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go
index 581a1fbfb..8f3182758 100755
--- a/routers/repo/grampus.go
+++ b/routers/repo/grampus.go
@@ -10,7 +10,6 @@ import (
"path"
"strconv"
"strings"
- "time"
"code.gitea.io/gitea/modules/urfs_client/urchin"
"code.gitea.io/gitea/routers/response"
@@ -77,8 +76,7 @@ func GrampusTrainJobNPUNew(ctx *context.Context) {
func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
//get valid images
@@ -1144,7 +1142,7 @@ func HandleTaskWithAiCenter(ctx *context.Context) {
log.Error("GetJob failed:" + err.Error())
continue
}
- if result != nil {
+ if len(result.JobInfo.Tasks) != 0 {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index fabf7e555..4e30e625d 100755
--- a/routers/repo/modelarts.go
+++ b/routers/repo/modelarts.go
@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+
"code.gitea.io/gitea/services/cloudbrain/cloudbrainTask"
"code.gitea.io/gitea/modules/dataset"
@@ -128,8 +130,7 @@ func NotebookNew(ctx *context.Context) {
func notebookNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
@@ -239,9 +240,9 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
}
if setting.ModelartsCD.Enabled {
- err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec)
+ _, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
} else {
- err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec)
+ _, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
}
if err != nil {
@@ -387,8 +388,31 @@ func NotebookDebug2(ctx *context.Context) {
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
return
}
+ if task.BootFile != "" {
+ ctx.Redirect(getFileUrl(result.Url, task.BootFile) + "?token=" + result.Token)
+ } else {
+ ctx.Redirect(result.Url + "?token=" + result.Token)
+ }
- ctx.Redirect(result.Url + "?token=" + result.Token)
+}
+
+func getFileUrl(url string, filename string) string {
+ middle := ""
+ if url[len(url)-3:] == "lab" || url[len(url)-4:] == "lab/" {
+ if url[len(url)-1] == '/' {
+ middle = "tree/"
+ } else {
+ middle = "/tree/"
+ }
+ } else {
+ if url[len(url)-1] == '/' {
+ middle = "lab/tree/"
+ } else {
+ middle = "/lab/tree/"
+ }
+ }
+
+ return url + middle + path.Base(filename)
}
func NotebookRestart(ctx *context.Context) {
@@ -420,7 +444,8 @@ func NotebookRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
- errorMsg = "you have already a running or waiting task, can not create more"
+ resultCode = "2"
+ errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
}
@@ -714,8 +739,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
// return
//}
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
@@ -2313,7 +2337,7 @@ func InferenceJobIndex(ctx *context.Context) {
tasks[i].ComputeResource = models.NPUResource
}
}
-
+ isQueryPrivate := isQueryPrivateModel(ctx)
repoId := ctx.Repo.Repository.ID
Type := -1
_, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{
@@ -2321,10 +2345,12 @@ func InferenceJobIndex(ctx *context.Context) {
Page: 1,
PageSize: 2,
},
- RepoID: repoId,
- Type: Type,
- New: MODEL_LATEST,
- Status: 0,
+ RepoID: repoId,
+ Type: Type,
+ New: MODEL_LATEST,
+ IsOnlyThisRepo: true,
+ Status: 0,
+ IsQueryPrivate: isQueryPrivate,
})
ctx.Data["MODEL_COUNT"] = model_count
@@ -2351,8 +2377,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["newInference"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
@@ -2394,7 +2419,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
return err
}
ctx.Data["config_list"] = configList.ParaConfigs
-
+ isQueryPrivate := isQueryPrivateModel(ctx)
repoId := ctx.Repo.Repository.ID
Type := -1
_, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{
@@ -2402,10 +2427,12 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
Page: 1,
PageSize: 2,
},
- RepoID: repoId,
- Type: Type,
- New: MODEL_LATEST,
- Status: 0,
+ RepoID: repoId,
+ Type: Type,
+ New: MODEL_LATEST,
+ IsOnlyThisRepo: true,
+ Status: 0,
+ IsQueryPrivate: isQueryPrivate,
})
ctx.Data["MODEL_COUNT"] = model_count
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 2c8c2f45b..4919b2487 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -414,7 +414,9 @@ func Action(ctx *context.Context) {
var err error
switch ctx.Params(":action") {
case "watch":
- err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
+ err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.ReceiveAllNotification)
+ case "watch_but_reject":
+ err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.RejectAllNotification)
case "unwatch":
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
case "star":
diff --git a/routers/repo/user_data_analysis.go b/routers/repo/user_data_analysis.go
index 508addf75..a6de283a4 100755
--- a/routers/repo/user_data_analysis.go
+++ b/routers/repo/user_data_analysis.go
@@ -907,3 +907,9 @@ func QueryUserLoginInfo(ctx *context.Context) {
log.Info("writer exel error." + err.Error())
}
}
+
+func QueryUserAnnualReport(ctx *context.Context) {
+ log.Info("start to QueryUserAnnualReport ")
+ result := models.QueryUserAnnualReport(ctx.User.ID)
+ ctx.JSON(http.StatusOK, result)
+}
diff --git a/routers/repo/user_invitation.go b/routers/repo/user_invitation.go
index a2752a481..6e7207bce 100644
--- a/routers/repo/user_invitation.go
+++ b/routers/repo/user_invitation.go
@@ -49,9 +49,10 @@ func getInvitationDetailExcelHeader(ctx *context.Context) map[string]string {
excelHeader := make([]string, 0)
excelHeader = append(excelHeader, ctx.Tr("user.static.id"))
excelHeader = append(excelHeader, ctx.Tr("user.static.name"))
- excelHeader = append(excelHeader, ctx.Tr("user.static.srcUserId"))
+ excelHeader = append(excelHeader, ctx.Tr("user.static.email"))
excelHeader = append(excelHeader, ctx.Tr("user.static.phone"))
excelHeader = append(excelHeader, ctx.Tr("user.static.registdate"))
+ excelHeader = append(excelHeader, ctx.Tr("user.static.srcUserId"))
excelHeaderMap := make(map[string]string, 0)
var i byte
@@ -92,8 +93,7 @@ func writeInvitationDetailExcel(row int, xlsx *excelize.File, sheetName string,
tmp = tmp + 1
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name)
tmp = tmp + 1
-
- xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID)
+ xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Email)
tmp = tmp + 1
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone)
@@ -101,7 +101,9 @@ func writeInvitationDetailExcel(row int, xlsx *excelize.File, sheetName string,
formatTime := userRecord.CreatedUnix.Format("2006-01-02 15:04:05")
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3])
+ tmp = tmp + 1
+ xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID)
}
func DownloadInvitationDetail(ctx *context.Context) {
@@ -413,6 +415,7 @@ func queryData(ctx *context.Context, startTime time.Time, endTime time.Time) {
invi.Name = tmpUser.Name
invi.Phone = tmpUser.PhoneNumber
invi.CreatedUnix = tmpUser.CreatedUnix
+ invi.Email = tmpUser.Email
} else {
invi.Name = "已注销"
}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 2b361b507..80ff96364 100755
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -359,6 +359,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/all/dosearch/", routers.SearchApi)
m.Post("/user/login/kanban", user.SignInPostAPI)
m.Get("/home/term", routers.HomeTerm)
+ m.Get("/home/notice", routers.HomeNoticeTmpl)
m.Get("/home/privacy", routers.HomePrivacy)
m.Get("/extension/tuomin/upload", modelapp.ProcessImageUI)
m.Post("/extension/tuomin/upload", reqSignIn, modelapp.ProcessImage)
@@ -518,6 +519,7 @@ func RegisterRoutes(m *macaron.Macaron) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
m.Any("/activate", user.Activate, reqSignIn)
m.Any("/activate_email", user.ActivateEmail)
+ m.Post("/update_email", bindIgnErr(auth.UpdateEmailForm{}), user.UpdateEmailPost)
m.Get("/avatar/:username/:size", user.Avatar)
m.Get("/email2user", user.Email2User)
m.Get("/recover_account", user.ResetPasswd)
@@ -1249,6 +1251,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/delete_model_convert/:id", repo.DeleteModelConvert)
m.Post("/convert_stop/:id", repo.StopModelConvert)
m.Put("/modify_model", repo.ModifyModelInfo)
+ m.Put("/modify_model_status", repo.ModifyModelPrivate)
m.Get("/show_model", reqRepoModelManageReader, repo.ShowModelTemplate)
m.Get("/convert_model", reqRepoModelManageReader, repo.ConvertModelTemplate)
m.Get("/show_model_info", repo.ShowModelInfo)
@@ -1272,8 +1275,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/modelsafety", func() {
m.Group("/:id", func() {
- m.Get("/show", reqRepoCloudBrainWriter, repo.GetAiSafetyTaskTmpl)
- m.Get("", reqRepoCloudBrainWriter, repo.GetAiSafetyTask)
+ m.Get("/show", reqRepoCloudBrainReader, repo.GetAiSafetyTaskTmpl)
+ m.Get("", reqRepoCloudBrainReader, repo.GetAiSafetyTask)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.StopAiSafetyTask)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelAiSafetyTask)
})
diff --git a/routers/user/Invitation.go b/routers/user/Invitation.go
index 8491390b2..0eb8ae2f4 100644
--- a/routers/user/Invitation.go
+++ b/routers/user/Invitation.go
@@ -63,7 +63,7 @@ func InviationTpl(ctx *context.Context) {
ctx.HTML(200, tplInvitation)
}
-func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhoneNumber string) error {
+func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhoneNumber string, email string) error {
user := parseInvitaionCode(invitationcode)
if user == nil {
return errors.New("The invitated user not existed.")
@@ -85,6 +85,7 @@ func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhone
SrcUserID: user.ID,
UserID: newUserId,
Phone: newPhoneNumber,
+ Email: email,
}
err := models.InsertInvitaion(invitation)
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 57ffb1710..5314571d2 100755
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -1368,7 +1368,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
log.Info("enter here, and form.InvitaionCode =" + invitationCode)
if invitationCode != "" {
- RegisteUserByInvitaionCode(invitationCode, u.ID, u.PhoneNumber)
+ RegisteUserByInvitaionCode(invitationCode, u.ID, u.PhoneNumber, u.Email)
}
err := models.AddEmailAddress(&models.EmailAddress{
@@ -1413,6 +1413,34 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
handleSignInFull(ctx, u, false, true)
}
+//update user emailAddress
+func UpdateEmailPost(ctx *context.Context, form auth.UpdateEmailForm) {
+ newEmailAddress := ctx.Query("NewEmail")
+ if newEmailAddress == "" {
+ log.Error("please input the newEmail")
+ return
+ }
+ if used, _ := models.IsEmailUsed(newEmailAddress); used {
+ ctx.RenderWithErr(ctx.Tr("form.email_been_used"), TplActivate, &form)
+ return
+ }
+ user := ctx.User
+ email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email)
+ if err != nil {
+ ctx.ServerError("GetEmailAddressByIDAndEmail failed", err)
+ return
+ }
+ err = email.UpdateEmailAddress(newEmailAddress)
+ if err != nil {
+ ctx.ServerError("UpdateEmailAddress failed", err)
+ return
+ }
+ ctx.Data["SignedUser.Email"] = newEmailAddress
+ ctx.User.Email = newEmailAddress
+ Activate(ctx)
+
+}
+
// Activate render activate user page
func Activate(ctx *context.Context) {
code := ctx.Query("code")
diff --git a/routers/user/home.go b/routers/user/home.go
index b6ab28f95..62b0357ad 100755
--- a/routers/user/home.go
+++ b/routers/user/home.go
@@ -23,6 +23,8 @@ import (
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
+ "code.gitea.io/gitea/routers/repo"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
issue_service "code.gitea.io/gitea/services/issue"
pull_service "code.gitea.io/gitea/services/pull"
@@ -837,6 +839,8 @@ func Cloudbrains(ctx *context.Context) {
}
models.LoadSpecs4CloudbrainInfo(ciTasks)
for i, _ := range ciTasks {
+ ciTasks[i] = cloudbrainService.UpdateCloudbrainAiCenter(ciTasks[i])
+ ciTasks[i].Cloudbrain.AiCenter = repo.GetAiCenterNameByCode(ciTasks[i].Cloudbrain.AiCenter, ctx.Language())
ciTasks[i].CanDebug = true
ciTasks[i].CanDel = true
ciTasks[i].Cloudbrain.ComputeResource = ciTasks[i].ComputeResource
diff --git a/services/cloudbrain/clear.go b/services/cloudbrain/clear.go
new file mode 100644
index 000000000..44613ee3c
--- /dev/null
+++ b/services/cloudbrain/clear.go
@@ -0,0 +1,151 @@
+package cloudbrain
+
+import (
+ "io/ioutil"
+ "os"
+ "sort"
+ "time"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/storage"
+)
+
+func ClearCloudbrainResultSpace() {
+ log.Info("clear cloudbrain one result space begin.")
+ if !setting.ClearStrategy.Enabled{
+ return
+ }
+
+ tasks, err := models.GetCloudBrainOneStoppedNotDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.BatchSize)
+ if err != nil {
+ log.Warn("Failed to get cloudbrain, clear result failed.", err)
+ return
+ }
+ debugTasks, err := models.GetCloudBrainOneStoppedDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.DebugJobSize)
+ if err != nil {
+ log.Warn("Failed to get debug cloudbrain.", err)
+
+ }
+ tasks=append(tasks,debugTasks...)
+
+ if err != nil {
+ log.Warn("Failed to get cloudbrain, clear result failed.", err)
+ return
+ }
+ var ids []int64
+ for _, task := range tasks {
+ err := DeleteCloudbrainOneJobStorage(task.JobName)
+ if err == nil {
+ log.Info("clear job in cloudbrain table:"+task.JobName)
+ ids = append(ids, task.ID)
+ }
+ }
+
+ err = models.UpdateCloudBrainRecordsCleared(ids)
+ if err != nil {
+ log.Warn("Failed to set cloudbrain cleared status", err)
+ }
+ //如果云脑表处理完了,通过遍历minio对象处理历史垃圾数据,如果存在的话
+ if len(tasks) < setting.ClearStrategy.BatchSize+setting.ClearStrategy.DebugJobSize {
+ clearLocalHistoryTrashFile()
+ clearMinioHistoryTrashFile()
+
+ }
+ log.Info("clear cloudbrain one result space end.")
+
+}
+
+func clearMinioHistoryTrashFile() {
+ JobRealPrefix := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix
+
+ miniofiles, err := ioutil.ReadDir(JobRealPrefix)
+
+ processCount := 0
+ if err != nil {
+ log.Warn("Can not browser minio job path.")
+ } else {
+ SortModTimeAscend(miniofiles)
+ for _, file := range miniofiles {
+
+ if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {
+
+ has,err:=models.IsCloudbrainExistByJobName(file.Name())
+ if err==nil && !has {
+ dirPath := setting.CBCodePathPrefix + file.Name() + "/"
+ log.Info("clear job in minio trash:" + file.Name())
+ storage.Attachments.DeleteDir(dirPath)
+ processCount++
+ }
+ if processCount == setting.ClearStrategy.BatchSize {
+ break
+ }
+ } else {
+ break
+ }
+
+ }
+
+ }
+}
+
+func clearLocalHistoryTrashFile() {
+ files, err := ioutil.ReadDir(setting.JobPath)
+ processCount := 0
+ if err != nil {
+ log.Warn("Can not browser local job path.")
+ } else {
+ SortModTimeAscend(files)
+ for _, file := range files {
+ //清理n天前的历史垃圾数据,清理job目录
+ if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {
+ has,err:=models.IsCloudbrainExistByJobName(file.Name())
+ if err==nil && !has{
+ os.RemoveAll(setting.JobPath + file.Name())
+ log.Info("clear job in local trash:"+file.Name())
+ processCount++
+ }
+ if processCount == setting.ClearStrategy.BatchSize {
+ break
+ }
+ } else {
+ break
+ }
+
+ }
+
+ }
+
+}
+
+func SortModTimeAscend(files []os.FileInfo) {
+ sort.Slice(files, func(i, j int) bool {
+ return files[i].ModTime().Before(files[j].ModTime())
+ })
+}
+
+func DeleteCloudbrainOneJobStorage(jobName string) error {
+
+ if jobName==""{
+ return nil
+ }
+ //delete local
+ localJobPath := setting.JobPath + jobName
+ err := os.RemoveAll(localJobPath)
+ if err != nil {
+ log.Error("RemoveAll(%s) failed:%v", localJobPath, err)
+ }
+
+ dirPath := setting.CBCodePathPrefix + jobName + "/"
+ err1 := storage.Attachments.DeleteDir(dirPath)
+
+ if err1 != nil {
+ log.Error("DeleteDir(%s) failed:%v", localJobPath, err)
+ }
+ if err == nil {
+ err = err1
+ }
+
+ return err
+}
diff --git a/services/cloudbrain/cloudbrainTask/notebook.go b/services/cloudbrain/cloudbrainTask/notebook.go
new file mode 100644
index 000000000..6b2fcf707
--- /dev/null
+++ b/services/cloudbrain/cloudbrainTask/notebook.go
@@ -0,0 +1,362 @@
+package cloudbrainTask
+
+import (
+ "fmt"
+ "net/http"
+ "path"
+
+ "code.gitea.io/gitea/modules/modelarts"
+ "code.gitea.io/gitea/modules/modelarts_cd"
+
+ "code.gitea.io/gitea/modules/git"
+
+ "code.gitea.io/gitea/modules/cloudbrain"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/redis/redis_key"
+ "code.gitea.io/gitea/modules/redis/redis_lock"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/services/cloudbrain/resource"
+ "code.gitea.io/gitea/services/reward/point/account"
+
+ "code.gitea.io/gitea/modules/setting"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+ repo_service "code.gitea.io/gitea/services/repository"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+)
+
+const NoteBookExtension = ".ipynb"
+
+func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption) {
+
+ if ctx.Written() {
+ return
+ }
+
+ if path.Ext(option.File) != NoteBookExtension {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
+ return
+ }
+
+ isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
+ if !isNotebookFileExist {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+
+ sourceRepo, err := models.GetRepositoryByOwnerAndName(option.OwnerName, option.ProjectName)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+
+ permission, err := models.GetUserRepoPermission(sourceRepo, ctx.User)
+ if err != nil {
+ log.Error("Get permission failed", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
+ return
+ }
+
+ if !permission.CanRead(models.UnitTypeCode) {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
+ return
+ }
+
+ //create repo if not exist
+ repo, err := models.GetRepositoryByName(ctx.User.ID, setting.FileNoteBook.ProjectName)
+ if repo == nil {
+ repo, err = repo_service.CreateRepository(ctx.User, ctx.User, models.CreateRepoOptions{
+ Name: setting.FileNoteBook.ProjectName,
+ Alias: "",
+ Description: "",
+ IssueLabels: "",
+ Gitignores: "",
+ License: "",
+ Readme: "Default",
+ IsPrivate: false,
+ AutoInit: true,
+ DefaultBranch: "master",
+ })
+ }
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo",setting.FileNoteBook.ProjectName)))
+ return
+ }
+ if option.Type <= 1 {
+ cloudBrainFileNoteBookCreate(ctx, option, repo, sourceRepo)
+ } else {
+ modelartsFileNoteBookCreate(ctx, option, repo, sourceRepo)
+ }
+
+}
+
+func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
+
+ displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
+ jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
+ jobType := string(models.JobTypeDebug)
+
+ lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), jobType, displayJobName))
+ defer lock.UnLock()
+ isOk, err := lock.Lock(models.CloudbrainKeyDuration)
+ if !isOk {
+ log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+
+ tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName)
+ if err == nil {
+ if len(tasks) != 0 {
+ log.Error("the job name did already exist", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ } else {
+ if !models.IsErrJobNotExist(err) {
+ log.Error("system error, %v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ }
+ }
+
+ count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType)
+ if err != nil {
+ log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK,models.BaseMessageApi{
+ Code: 2,
+ Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
+ })
+ return
+ }
+ }
+
+ errStr := uploadCodeFile(sourceRepo, getCodePath(jobName), option.BranchName, option.File, jobName)
+ if errStr != "" {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+ command := cloudbrain.GetCloudbrainDebugCommand()
+ specId := setting.FileNoteBook.SpecIdGPU
+ if option.Type == 0 {
+ specId = setting.FileNoteBook.SpecIdCPU
+ }
+ spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
+ JobType: models.JobType(jobType),
+ ComputeResource: models.GPU,
+ Cluster: models.OpenICluster,
+ AiCenterCode: models.AICenterOfCloudBrainOne})
+ if err != nil || spec == nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
+ return
+ }
+
+ if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
+ log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
+ return
+ }
+ ctx.Repo = &context.Repository{
+ Repository: repo,
+ }
+
+ req := cloudbrain.GenerateCloudBrainTaskReq{
+ Ctx: ctx,
+ DisplayJobName: displayJobName,
+ JobName: jobName,
+ Image: setting.FileNoteBook.ImageGPU,
+ Command: command,
+ Uuids: "",
+ DatasetNames: "",
+ DatasetInfos: nil,
+ CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
+ ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
+ BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
+ Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
+ BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
+ JobType: jobType,
+ Description: getDescription(option),
+ BranchName: option.BranchName,
+ BootFile: option.File,
+ Params: "{\"parameter\":[]}",
+ CommitID: "",
+ BenchmarkTypeID: 0,
+ BenchmarkChildTypeID: 0,
+ ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"),
+ Spec: spec,
+ }
+
+ jobId, err := cloudbrain.GenerateTask(req)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
+ return
+ }
+ ctx.JSON(http.StatusOK, models.BaseMessageApi{
+ Code: 0,
+ Message: jobId,
+ })
+
+}
+
+func getCodePath(jobName string) string {
+ return setting.JobPath + jobName + cloudbrain.CodeMountPath
+}
+
+func getDescription(option api.CreateFileNotebookJobOption) string {
+ return option.OwnerName + "/" + option.ProjectName + "/" + option.File
+}
+
+func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
+ displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
+ jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
+
+ lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), string(models.JobTypeDebug), displayJobName))
+ isOk, err := lock.Lock(models.CloudbrainKeyDuration)
+ if !isOk {
+ log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ defer lock.UnLock()
+
+ count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug))
+
+ if err != nil {
+ log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
+
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK,models.BaseMessageApi{
+ Code: 2,
+ Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
+ })
+ return
+ }
+ }
+
+ tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName)
+ if err == nil {
+ if len(tasks) != 0 {
+ log.Error("the job name did already exist", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ } else {
+ if !models.IsErrJobNotExist(err) {
+ log.Error("system error, %v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ }
+ }
+
+ err = downloadCode(sourceRepo, getCodePath(jobName), option.BranchName)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
+ return
+ }
+
+ var aiCenterCode = models.AICenterOfCloudBrainTwo
+ var specId = setting.FileNoteBook.SpecIdNPU
+ if setting.ModelartsCD.Enabled {
+ aiCenterCode = models.AICenterOfChengdu
+ specId = setting.FileNoteBook.SpecIdNPUCD
+ }
+ spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
+ JobType: models.JobTypeDebug,
+ ComputeResource: models.NPU,
+ Cluster: models.OpenICluster,
+ AiCenterCode: aiCenterCode})
+ if err != nil || spec == nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
+ return
+ }
+ if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
+ log.Error("point balance is not enough,userId=%d specId=%d ", ctx.User.ID, spec.ID)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
+ return
+ }
+ ctx.Repo = &context.Repository{
+ Repository: repo,
+ }
+
+ var jobId string
+ if setting.ModelartsCD.Enabled {
+ jobId, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPUCD, spec, option.File,modelarts.AutoStopDurationMs/4)
+ } else {
+ jobId, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPU, spec, option.File,modelarts.AutoStopDurationMs/4)
+ }
+
+ if err != nil {
+ log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"])
+
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
+
+ return
+ }
+
+ ctx.JSON(http.StatusOK, models.BaseMessageApi{
+ Code: 0,
+ Message: jobId,
+ })
+
+}
+
+func isNoteBookFileExist(ctx *context.Context, option api.CreateFileNotebookJobOption) (bool, error) {
+ repoPathOfNoteBook := models.RepoPath(option.OwnerName, option.ProjectName)
+
+ gitRepoOfNoteBook, err := git.OpenRepository(repoPathOfNoteBook)
+ if err != nil {
+ log.Error("RepoRef Invalid repo "+repoPathOfNoteBook, err.Error())
+ return false, err
+ }
+ // We opened it, we should close it
+ defer func() {
+ // If it's been set to nil then assume someone else has closed it.
+ if gitRepoOfNoteBook != nil {
+ gitRepoOfNoteBook.Close()
+ }
+ }()
+ fileExist, err := fileExists(gitRepoOfNoteBook, option.File, option.BranchName)
+ if err != nil || !fileExist {
+ log.Error("Get file error:", err, ctx.Data["MsgID"])
+
+ return false, err
+ }
+ return true, nil
+}
+
+func uploadCodeFile(repo *models.Repository, codePath string, branchName string, filePath string, jobName string) string {
+ err := downloadCode(repo, codePath, branchName)
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+
+ err = uploadOneFileToMinio(codePath, filePath, jobName, cloudbrain.CodeMountPath+"/")
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+ return ""
+}
+
+func fileExists(gitRepo *git.Repository, path string, branch string) (bool, error) {
+
+ commit, err := gitRepo.GetBranchCommit(branch)
+ if err != nil {
+ return false, err
+ }
+ if _, err := commit.GetTreeEntryByPath(path); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/services/cloudbrain/cloudbrainTask/sync_status.go b/services/cloudbrain/cloudbrainTask/sync_status.go
index 67dc4d3b7..973b9bbc2 100644
--- a/services/cloudbrain/cloudbrainTask/sync_status.go
+++ b/services/cloudbrain/cloudbrainTask/sync_status.go
@@ -1,20 +1,21 @@
package cloudbrainTask
import (
- "net/http"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
- "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
+ "net/http"
+ "strconv"
)
var noteBookOKMap = make(map[int64]int, 20)
+var noteBookFailMap = make(map[int64]int, 20)
-//if a task notebook url can get two times, the notebook can browser.
+//if a task notebook url can get successfulCount times, the notebook can browser.
const successfulCount = 3
+const maxSuccessfulCount=10
func SyncCloudBrainOneStatus(task *models.Cloudbrain) (*models.Cloudbrain, error) {
jobResult, err := cloudbrain.GetJob(task.JobID)
@@ -62,21 +63,29 @@ func isNoteBookReady(task *models.Cloudbrain) bool {
return true
}
noteBookUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
- r := httplib.Get(noteBookUrl)
- res, err := r.Response()
+ res,err := http.Get(noteBookUrl)
if err != nil {
return false
}
+ log.Info("notebook success count:"+strconv.Itoa(noteBookOKMap[task.ID])+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
if res.StatusCode == http.StatusOK {
count := noteBookOKMap[task.ID]
- if count < successfulCount-1 {
+ if count==0{ //如果是第一次成功,把失败数重置为0
+ noteBookFailMap[task.ID]=0
+ }
+
+ if count < successfulCount-1 || (noteBookFailMap[task.ID]==0 && count < maxSuccessfulCount-1) {
noteBookOKMap[task.ID] = count + 1
return false
} else {
+ log.Info("notebook success count:"+strconv.Itoa(count)+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
delete(noteBookOKMap, task.ID)
+ delete(noteBookFailMap, task.ID)
return true
}
+ }else{
+ noteBookFailMap[task.ID]+=1
}
return false
diff --git a/services/cloudbrain/cloudbrainTask/train.go b/services/cloudbrain/cloudbrainTask/train.go
index 8e4673d66..00d01a7ce 100644
--- a/services/cloudbrain/cloudbrainTask/train.go
+++ b/services/cloudbrain/cloudbrainTask/train.go
@@ -810,6 +810,18 @@ func uploadCodeToMinio(codePath, jobName, parentDir string) error {
return nil
}
+func uploadOneFileToMinio(codePath, filePath, jobName, parentDir string) error {
+ destObject := setting.CBCodePathPrefix + jobName + parentDir + path.Base(filePath)
+ sourceFile := codePath + "/" + filePath
+ err := storage.Attachments.UploadObject(destObject, sourceFile)
+ if err != nil {
+ log.Error("UploadObject(%s) failed: %s", filePath, err.Error())
+ return err
+ }
+ return nil
+
+}
+
func readDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
diff --git a/services/cloudbrain/resource/resource_specification.go b/services/cloudbrain/resource/resource_specification.go
index 8f4182d87..5070d7c1e 100644
--- a/services/cloudbrain/resource/resource_specification.go
+++ b/services/cloudbrain/resource/resource_specification.go
@@ -246,10 +246,10 @@ func FindAvailableSpecs(userId int64, opts models.FindSpecsOptions) ([]*models.S
return nil, err
}
//filter exclusive specs
- specs := filterExclusiveSpecs(r, userId)
+ specs := models.FilterExclusiveSpecs(r, userId)
//distinct by sourceSpecId
- specs = distinctSpecs(specs)
+ specs = models.DistinctSpecs(specs)
return specs, err
}
@@ -265,50 +265,6 @@ func FindAvailableSpecs4Show(userId int64, opts models.FindSpecsOptions) ([]*api
return result, nil
}
-func filterExclusiveSpecs(r []*models.Specification, userId int64) []*models.Specification {
- specs := make([]*models.Specification, 0, len(r))
- specMap := make(map[int64]string, 0)
- for i := 0; i < len(r); i++ {
- spec := r[i]
- if _, has := specMap[spec.ID]; has {
- continue
- }
- if !spec.IsExclusive {
- specs = append(specs, spec)
- specMap[spec.ID] = ""
- continue
- }
- orgs := strings.Split(spec.ExclusiveOrg, ";")
- for _, org := range orgs {
- isMember, _ := models.IsOrganizationMemberByOrgName(org, userId)
- if isMember {
- specs = append(specs, spec)
- specMap[spec.ID] = ""
- break
- }
- }
- }
- return specs
-}
-
-func distinctSpecs(r []*models.Specification) []*models.Specification {
- specs := make([]*models.Specification, 0, len(r))
- sourceSpecIdMap := make(map[string]string, 0)
- for i := 0; i < len(r); i++ {
- spec := r[i]
- if spec.SourceSpecId == "" {
- specs = append(specs, spec)
- continue
- }
- if _, has := sourceSpecIdMap[spec.SourceSpecId]; has {
- continue
- }
- specs = append(specs, spec)
- sourceSpecIdMap[spec.SourceSpecId] = ""
- }
- return specs
-}
-
func GetAndCheckSpec(userId int64, specId int64, opts models.FindSpecsOptions) (*models.Specification, error) {
if specId == 0 {
return nil, nil
diff --git a/services/cloudbrain/util.go b/services/cloudbrain/util.go
index ab738927e..0a3096e3f 100644
--- a/services/cloudbrain/util.go
+++ b/services/cloudbrain/util.go
@@ -1,27 +1,33 @@
package cloudbrain
import (
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+
+
+ "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
- "strings"
)
-func GetAiCenterShow(aiCenter string,ctx *context.Context) string{
+func GetAiCenterShow(aiCenter string, ctx *context.Context) string {
aiCenterInfo := strings.Split(aiCenter, "+")
- if len(aiCenterInfo) == 2{
- if setting.C2NetMapInfo!=nil {
- if info,ok:=setting.C2NetMapInfo[aiCenterInfo[0]];ok {
+ if len(aiCenterInfo) == 2 {
+ if setting.C2NetMapInfo != nil {
+ if info, ok := setting.C2NetMapInfo[aiCenterInfo[0]]; ok {
if ctx.Language() == "zh-CN" {
return info.Content
} else {
return info.ContentEN
}
- }else{
+ } else {
return aiCenterInfo[1]
}
- }else{
+ } else {
return aiCenterInfo[1]
}
@@ -29,5 +35,64 @@ func GetAiCenterShow(aiCenter string,ctx *context.Context) string{
return ""
+}
+
+func GetDisplayJobName(username string) string {
+ t := time.Now()
+ return jobNamePrefixValid(cutString(username, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+}
+
+func cutString(str string, lens int) string {
+ if len(str) < lens {
+ return str
+ }
+ return str[:lens]
+}
+
+func jobNamePrefixValid(s string) string {
+ lowStr := strings.ToLower(s)
+ re := regexp.MustCompile(`[^a-z0-9_\\-]+`)
+
+ removeSpecial := re.ReplaceAllString(lowStr, "")
+
+ re = regexp.MustCompile(`^[_\\-]+`)
+ return re.ReplaceAllString(removeSpecial, "")
+}
+
+func GetAiCenterInfoByCenterCode(aiCenterCode string) *setting.C2NetSequenceInfo {
+ if setting.AiCenterCodeAndNameMapInfo != nil {
+ if info, ok := setting.AiCenterCodeAndNameMapInfo[aiCenterCode]; ok {
+ return info
+ } else {
+ return nil
+ }
+ } else {
+ return nil
+ }
+}
+
+func getAiCenterCode(aiCenter string) string {
+ aiCenterInfo := strings.Split(aiCenter, "+")
+ return aiCenterInfo[0]
+}
+
+func UpdateCloudbrainAiCenter(cloudbrain *models.CloudbrainInfo) *models.CloudbrainInfo {
+ if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
+ cloudbrain.Cloudbrain.AiCenter = models.AICenterOfCloudBrainOne
+ cloudbrain.Cloudbrain.Cluster = models.OpenICluster
+ }
+ if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
+ cloudbrain.Cloudbrain.AiCenter = models.AICenterOfCloudBrainTwo
+ cloudbrain.Cloudbrain.Cluster = models.OpenICluster
+ }
+ if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
+ cloudbrain.Cloudbrain.AiCenter = models.AICenterOfChengdu
+ cloudbrain.Cloudbrain.Cluster = models.OpenICluster
+ }
+ if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
+ cloudbrain.Cloudbrain.AiCenter = getAiCenterCode(cloudbrain.Cloudbrain.AiCenter)
+ cloudbrain.Cloudbrain.Cluster = models.C2NetCluster
+ }
+ return cloudbrain
}
diff --git a/services/repository/repository.go b/services/repository/repository.go
index b4c047392..db25010ea 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -107,18 +107,13 @@ func GetRecommendCourseKeyWords() ([]string, error) {
}
-func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, error) {
+func GetRecommendRepoFromPromote(repoMap []map[string]string) ([]map[string]interface{}, error) {
resultRepo := make([]map[string]interface{}, 0)
- url := setting.RecommentRepoAddr + filename
- result, err := RecommendFromPromote(url)
-
- if err != nil {
-
- return resultRepo, err
- }
//resultRepo := make([]*models.Repository, 0)
- for _, repoName := range result {
+ for _, record := range repoMap {
+ repoName := record["project_url"]
+ //log.Info("repoName=" + repoName + " tmpIndex1=" + fmt.Sprint(tmpIndex1) + " len(repoName)=" + fmt.Sprint(len(repoName)))
tmpIndex := strings.Index(repoName, "/")
if tmpIndex == -1 {
log.Info("error repo name format.")
@@ -131,7 +126,8 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err
repoMap["ID"] = fmt.Sprint(repo.ID)
repoMap["Name"] = repo.Name
repoMap["Alias"] = repo.Alias
-
+ repoMap["Label"] = record["class"]
+ repoMap["Label_en"] = record["class_en"]
repoMap["OwnerName"] = repo.OwnerName
repoMap["NumStars"] = repo.NumStars
repoMap["NumForks"] = repo.NumForks
diff --git a/templates/admin/cloudbrain/list.tmpl b/templates/admin/cloudbrain/list.tmpl
index b6dfec77d..94f80c0fa 100755
--- a/templates/admin/cloudbrain/list.tmpl
+++ b/templates/admin/cloudbrain/list.tmpl
@@ -170,7 +170,7 @@