"
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/api/v1/api.go b/routers/api/v1/api.go
index 2afbb9b7d..8958c55a4 100755
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -614,6 +614,7 @@ func RegisterRoutes(m *macaron.Macaron) {
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() {
@@ -631,7 +632,6 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/overview_resource", repo.GetCloudbrainResourceOverview)
m.Get("/resource_usage_statistic", repo.GetDurationRateStatistic)
m.Get("/resource_usage_rate_detail", repo.GetCloudbrainResourceUsageDetail)
- m.Get("/resource_queues", repo.GetResourceQueues)
m.Get("/apitest_for_statistic", repo.CloudbrainDurationStatisticForTest)
})
}, operationReq)
@@ -737,6 +737,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/my_favorite", repo.MyFavoriteDatasetMultiple)
}, reqToken(), repoAssignment())
+ m.Group("/file_notebook", func() {
+ m.Get("", reqToken(), repo.GetFileNoteBookInfo)
+ m.Post("/create", reqToken(), reqWeChat(), bind(api.CreateFileNotebookJobOption{}), repo.CreateFileNoteBook)
+
+ })
+
m.Group("/repos", func() {
m.Get("/search", repo.Search)
diff --git a/routers/api/v1/repo/cloudbrain.go b/routers/api/v1/repo/cloudbrain.go
index 68baf3287..cd8340c41 100755
--- a/routers/api/v1/repo/cloudbrain.go
+++ b/routers/api/v1/repo/cloudbrain.go
@@ -11,6 +11,7 @@ import (
"io"
"net/http"
"os"
+ "path"
"sort"
"strconv"
"strings"
@@ -78,6 +79,74 @@ func CloudBrainShow(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)})
+}
+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) {
@@ -141,10 +210,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 +557,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 +571,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 +642,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)
@@ -650,7 +725,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
}
}
@@ -865,7 +940,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
}
@@ -896,7 +971,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
}
@@ -941,7 +1016,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 446522fc2..7fe5d603c 100755
--- a/routers/api/v1/repo/cloudbrain_dashboard.go
+++ b/routers/api/v1/repo/cloudbrain_dashboard.go
@@ -11,6 +11,7 @@ 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"
@@ -58,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 {
@@ -123,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)
@@ -138,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(),
@@ -151,22 +141,18 @@ func GetOverviewDuration(ctx *context.Context) {
for _, cloudbrain := range cloudbrains {
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
- CardDurationString := repo.GetCloudbrainCardDuration(cloudbrain.Cloudbrain)
- CardDuration := models.ConvertStrToDuration(CardDurationString)
- // if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
- // worker_server_num = cloudbrain.Cloudbrain.WorkServerNumber
- // } else {
- // worker_server_num = 1
- // }
- // if cloudbrain.Cloudbrain.Spec == nil {
- // cardNum = 1
- // } else {
- // cardNum = cloudbrain.Cloudbrain.Spec.AccCardsNum
- // }
- // duration := cloudbrain.Duration
- // duration := cloudbrain.Duration
+ if cloudbrain.Cloudbrain.Spec != nil {
+ cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum)
+ } else {
+ cardNum = 1
+ }
+ if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
+ workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber)
+ } else {
+ workServerNumber = 1
+ }
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration)
- // CardDuration := cloudbrain.Duration * int64(worker_server_num) * int64(cardNum)
+ CardDuration := workServerNumber * int64(cardNum) * duration
if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration += duration
@@ -1479,12 +1465,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].DateTime
+ 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 {
@@ -1611,6 +1602,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
@@ -1623,7 +1615,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].DateTime.AsTime()
+ if len(recordCloudbrainDuration) > 0 && err == nil {
+ brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
+ } else {
+ brainRecordBeginTime = now
+ }
+
beginTime = brainRecordBeginTime
endTime = now
} else if queryType == "today" {
@@ -1665,7 +1662,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].DateTime.AsTime()
+ if len(recordCloudbrainDuration) > 0 && err == nil {
+ brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
+ } else {
+ brainRecordBeginTime = now
+ }
beginTime = brainRecordBeginTime
endTime = now
} else {
@@ -1696,7 +1697,7 @@ func getAiCenterUsageDuration(beginTime time.Time, endTime time.Time, cloudbrain
usageRate := float64(0)
for _, cloudbrainStatistic := range cloudbrainStatistics {
- if int64(cloudbrainStatistic.DateTime) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTime) < endTime.Unix() {
+ if int64(cloudbrainStatistic.DateTimeUnix) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTimeUnix) < endTime.Unix() {
totalDuration += cloudbrainStatistic.CardsTotalDuration
usageDuration += cloudbrainStatistic.CardsUseDuration
}
@@ -1914,7 +1915,7 @@ func CloudbrainUpdateAiCenter(ctx *context.Context) {
func GetResourceQueues(ctx *context.Context) {
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
- log.Info("GetCanUseCardInfo err: %v", err)
+ log.Error("GetCanUseCardInfo err: %v", err)
return
}
Resource := make([]*models.ResourceQueue, 0)
diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go
index e0db9eda3..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)
diff --git a/routers/home.go b/routers/home.go
index d54a0160f..7378fbc4f 100755
--- a/routers/home.go
+++ b/routers/home.go
@@ -7,6 +7,7 @@ package routers
import (
"bytes"
+ "encoding/json"
"code.gitea.io/gitea/routers/response"
"net/http"
"strconv"
@@ -771,7 +772,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 {
@@ -844,7 +845,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 {
@@ -855,13 +856,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 {
@@ -871,6 +884,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)
@@ -891,25 +905,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)
}
@@ -923,4 +966,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/repo/ai_model_convert.go b/routers/repo/ai_model_convert.go
index 962c76aae..4ba414bff 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
@@ -828,5 +828,4 @@ func ModelConvertDownloadModel(ctx *context.Context) {
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
}
}
-
}
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..d3d76f440 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()
@@ -696,7 +679,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
}
@@ -759,43 +742,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 +842,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 8084614eb..de95babe9 100644
--- a/routers/repo/cloudbrain_statistic.go
+++ b/routers/repo/cloudbrain_statistic.go
@@ -8,6 +8,7 @@ import (
"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"
)
@@ -19,32 +20,33 @@ func CloudbrainDurationStatisticHour() {
return
}
}()
- 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].DateTime), 0).Add(+1 * time.Hour)
- } else {
- statisticTime = currentTime
- }
- deleteBeginTime := time.Unix(int64(recordDurationUpdateTime[0].DateTime), 0)
+ 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
+ }
- err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(deleteBeginTime.Unix()), timeutil.TimeStamp(currentTime.Unix()))
- if err != nil {
- log.Error("DeleteCloudbrainDurationStatistic failed", err)
- }
+ err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(statisticTime.Add(-1*time.Hour).Unix()), timeutil.TimeStamp(currentTime.Unix()))
+ if err != nil {
+ log.Error("DeleteCloudbrainDurationStatistic failed", err)
+ }
- for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
- countEach := summaryDurationStat(statisticTime)
- count += countEach
- statisticTime = statisticTime.Add(+1 * time.Hour)
+ for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
+ countEach := summaryDurationStat(statisticTime)
+ count += countEach
+ statisticTime = statisticTime.Add(+1 * time.Hour)
+ }
+ log.Info("summaryDurationStat count: %v", count)
}
- log.Info("summaryDurationStat count: %v", count)
}
func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time) int64 {
var count int64
@@ -61,7 +63,7 @@ func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time)
//statisticTime是当前的时辰,比如当前是2019-01-01 12:01:01,那么statisticTime就是2019-01-01 12:00:00
func summaryDurationStat(statisticTime time.Time) int64 {
var count int64
- dateTime := timeutil.TimeStamp(statisticTime.Add(-1 * time.Hour).Unix())
+ 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()
@@ -72,27 +74,8 @@ func summaryDurationStat(statisticTime time.Time) int64 {
log.Info("GetCloudbrainByTime err: %v", err)
return 0
}
- cloudbrainMap := make(map[string]*models.Cloudbrain)
models.LoadSpecs4CloudbrainInfo(ciTasks)
-
- for _, cloudbrain := range ciTasks {
- if cloudbrain.Cloudbrain.StartTime == 0 {
- cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
- }
- if cloudbrain.Cloudbrain.EndTime == 0 {
- cloudbrain.Cloudbrain.EndTime = cloudbrain.Cloudbrain.UpdatedUnix
- }
- 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
- }
- }
- }
- }
-
- cloudBrainCenterCodeAndCardTypeInfo := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
+ cloudBrainCenterCodeAndCardTypeInfo, cloudbrainMap := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
@@ -117,7 +100,7 @@ func summaryDurationStat(statisticTime time.Time) int64 {
cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType] = 0
}
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
- DateTime: dateTime,
+ DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: cloudbrainTable.Cluster,
@@ -139,7 +122,7 @@ func summaryDurationStat(statisticTime time.Time) int64 {
for key, cardsTotalDuration := range cardsTotalDurationMap {
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
- DateTime: dateTime,
+ DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
@@ -176,11 +159,27 @@ func GetAiCenterNameByCode(centerCode string, language string) string {
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
@@ -202,7 +201,7 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter] = make(map[string]int)
}
if cloudbrain.Cloudbrain.Spec != nil {
- if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) {
+ 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))
@@ -246,19 +245,26 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
}
}
- return cloudBrainCenterCodeAndCardType
+ return cloudBrainCenterCodeAndCardType, cloudbrainMap
}
func CloudbrainUpdateHistoryData(ctx *context.Context) {
beginTimeStr := ctx.QueryTrim("beginTime")
endTimeStr := ctx.QueryTrim("endTime")
- beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local)
- endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local)
- beginTimeUnix := timeutil.TimeStamp(beginTime.Unix())
- endTimeUnix := timeutil.TimeStamp(endTime.Unix())
+ 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, endTime)
+ 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,
diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go
index de7bb454d..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
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index fabf7e555..01d2e2fa4 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)
@@ -2351,8 +2375,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)
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/routes/routes.go b/routers/routes/routes.go
index 8ecca32e2..b8ea5b2e6 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)
@@ -529,6 +530,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)
@@ -1283,8 +1285,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/auth.go b/routers/user/auth.go
index 57ffb1710..3d74b6ddd 100755
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -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/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/util.go b/services/cloudbrain/util.go
index dc9177ecf..0a3096e3f 100644
--- a/services/cloudbrain/util.go
+++ b/services/cloudbrain/util.go
@@ -1,7 +1,11 @@
package cloudbrain
import (
+ "regexp"
+ "strconv"
"strings"
+ "time"
+
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@@ -33,6 +37,28 @@ func GetAiCenterShow(aiCenter string, ctx *context.Context) string {
}
+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 {
diff --git a/services/repository/repository.go b/services/repository/repository.go
index 02928d855..e9a8570d5 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -106,18 +106,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.")
@@ -130,7 +125,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 20e704a4d..94f80c0fa 100755
--- a/templates/admin/cloudbrain/list.tmpl
+++ b/templates/admin/cloudbrain/list.tmpl
@@ -238,6 +238,7 @@
{{$.i18n.Tr "repo.debug"}}
{{else}}
+ {{if not .BootFile}}
{{end}}
+ {{end}}
{{end}}
diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl
index b4c8518c4..3a35e69a3 100755
--- a/templates/base/footer_content.tmpl
+++ b/templates/base/footer_content.tmpl
@@ -1,15 +1,17 @@
-