+
+## 启智社区小白训练营:
+- 结合案例给大家详细讲解如何使用社区平台,帮助无技术背景的小白成长为启智社区达人 (https://git.openi.org.cn/zeizei/OpenI_Learning)
diff --git a/go.mod b/go.mod
index 337aabc8e..d9c12ea3a 100755
--- a/go.mod
+++ b/go.mod
@@ -56,6 +56,7 @@ require (
github.com/gomodule/redigo v2.0.0+incompatible
github.com/google/go-github/v24 v24.0.1
github.com/gorilla/context v1.1.1
+ github.com/gorilla/websocket v1.4.0
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/huandu/xstrings v1.3.0
github.com/issue9/assert v1.3.2 // indirect
diff --git a/go.sum b/go.sum
index 7346b9050..9bae7932d 100755
--- a/go.sum
+++ b/go.sum
@@ -394,6 +394,7 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
diff --git a/models/attachment.go b/models/attachment.go
index d217a61a4..fd1df9e43 100755
--- a/models/attachment.go
+++ b/models/attachment.go
@@ -439,6 +439,19 @@ func GetModelArtsUserAttachments(userID int64) ([]*AttachmentUsername, error) {
return getModelArtsUserAttachments(x, userID)
}
+func getModelArtsTrainAttachments(e Engine, userID int64) ([]*AttachmentUsername, error) {
+ attachments := make([]*AttachmentUsername, 0, 10)
+ if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id "+
+ "= `user`.id").Where("attachment.type = ? and (uploader_id= ? or is_private = ?) and attachment.decompress_state = ?", TypeCloudBrainTwo, userID, false, DecompressStateDone).Find(&attachments); err != nil {
+ return nil, err
+ }
+ return attachments, nil
+}
+
+func GetModelArtsTrainAttachments(userID int64) ([]*AttachmentUsername, error) {
+ return getModelArtsTrainAttachments(x, userID)
+}
+
func CanDelAttachment(isSigned bool, user *User, attach *Attachment) bool {
if !isSigned {
return false
diff --git a/models/cloudbrain.go b/models/cloudbrain.go
index 509f4a9ed..5bf066413 100755
--- a/models/cloudbrain.go
+++ b/models/cloudbrain.go
@@ -19,6 +19,9 @@ type JobType string
type ModelArtsJobStatus string
const (
+ NPUResource = "NPU"
+ GPUResource = "CPU/GPU"
+
JobWaiting CloudbrainStatus = "WAITING"
JobStopped CloudbrainStatus = "STOPPED"
JobSucceeded CloudbrainStatus = "SUCCEEDED"
@@ -88,6 +91,9 @@ type Cloudbrain struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
Duration int64
TrainJobDuration string
+ Image string //GPU镜像名称
+ GpuQueue string //GPU类型即GPU队列
+ ResourceSpecId int //GPU规格id
DeletedAt time.Time `xorm:"deleted"`
CanDebug bool `xorm:"-"`
CanDel bool `xorm:"-"`
@@ -204,6 +210,7 @@ type CloudbrainsOptions struct {
JobType string
VersionName string
IsLatestVersion string
+ JobTypeNot bool
}
type TaskPod struct {
@@ -888,9 +895,15 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
}
if (opts.JobType) != "" {
- cond = cond.And(
- builder.Eq{"cloudbrain.job_type": opts.JobType},
- )
+ if opts.JobTypeNot {
+ cond = cond.And(
+ builder.Neq{"cloudbrain.job_type": opts.JobType},
+ )
+ } else {
+ cond = cond.And(
+ builder.Eq{"cloudbrain.job_type": opts.JobType},
+ )
+ }
}
if (opts.IsLatestVersion) != "" {
diff --git a/models/error.go b/models/error.go
index 9d1c68658..46917e15e 100755
--- a/models/error.go
+++ b/models/error.go
@@ -1999,3 +1999,16 @@ func IsErrJobNotExist(err error) bool {
func (err ErrJobNotExist) Error() string {
return fmt.Sprintf("the job does not exist")
}
+
+type ErrTagNotExist struct {
+ TagID int64
+}
+
+func (err ErrTagNotExist) Error() string {
+ return fmt.Sprintf("the tag does not exist")
+}
+
+func IsErrTagNotExist(err error) bool {
+ _, ok := err.(ErrTagNotExist)
+ return ok
+}
diff --git a/models/issue.go b/models/issue.go
index 7457fcd45..19f00d5f3 100755
--- a/models/issue.go
+++ b/models/issue.go
@@ -1397,6 +1397,8 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
if opts.MilestoneID > 0 {
sess.And("issue.milestone_id = ?", opts.MilestoneID)
+ } else if opts.MilestoneID == -1 { //only search for issues do not have milestone
+ sess.And("issue.milestone_id = ?", 0)
}
if opts.AssigneeID > 0 {
diff --git a/models/issue_milestone.go b/models/issue_milestone.go
index 464827445..a08bbf4dc 100644
--- a/models/issue_milestone.go
+++ b/models/issue_milestone.go
@@ -353,7 +353,7 @@ func GetMilestonesByRepoID(repoID int64, state api.StateType, listOptions ListOp
}
miles := make([]*Milestone, 0, listOptions.PageSize)
- return miles, sess.Asc("deadline_unix").Asc("id").Find(&miles)
+ return miles, sess.Desc("id").Find(&miles)
}
// GetMilestones returns a list of milestones of given repository and status.
diff --git a/models/models.go b/models/models.go
index e8a71bbd8..a72ebe5db 100755
--- a/models/models.go
+++ b/models/models.go
@@ -134,6 +134,8 @@ func init() {
new(BlockChain),
new(RecommendOrg),
new(AiModelManage),
+ new(OfficialTag),
+ new(OfficialTagRepos),
)
tablesStatistic = append(tablesStatistic,
diff --git a/models/repo.go b/models/repo.go
index a4417e4bd..8070d7442 100755
--- a/models/repo.go
+++ b/models/repo.go
@@ -2470,6 +2470,12 @@ func GetBlockChainUnSuccessRepos() ([]*Repository, error) {
Find(&repos)
}
+func (repo *Repository) UpdateBlockChain() error {
+
+ _, err := x.Exec("UPDATE `repository` SET block_chain_status = ?, contract_address=? WHERE id = ?", repo.BlockChainStatus, repo.ContractAddress, repo.ID)
+ return err
+}
+
func (repo *Repository) IncreaseCloneCnt() {
sess := x.NewSession()
defer sess.Close()
diff --git a/models/repo_tag.go b/models/repo_tag.go
new file mode 100644
index 000000000..76740bd76
--- /dev/null
+++ b/models/repo_tag.go
@@ -0,0 +1,163 @@
+package models
+
+import (
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/timeutil"
+ "fmt"
+)
+
+type OfficialTag struct {
+ ID int64 `xorm:"pk autoincr"`
+ Name string `xorm:"NOT NULL"`
+ Code string `xorm:"NOT NULL"`
+ Limit int `xorm:"NOT NULL default(-1)"`
+ Status int `xorm:"NOT NULL default(0)"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
+}
+
+type OfficialTagRepos struct {
+ ID int64 `xorm:"pk autoincr"`
+ OrgID int64 `xorm:"NOT NULL INDEX"`
+ TagID int64 `xorm:"NOT NULL"`
+ RepoID int64 `xorm:"NOT NULL INDEX"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
+}
+
+type TagReposBrief struct {
+ RepoID int64
+ RepoName string
+ TagID int64
+}
+
+type TagReposSelected struct {
+ RepoID int64
+ RepoName string
+ Selected bool
+}
+
+type TagsDetail struct {
+ TagId int64
+ TagName string
+ TagLimit int
+ RepoList []Repository
+}
+
+func GetTagByID(id int64) (*OfficialTag, error) {
+ r := &OfficialTag{
+ ID: id,
+ }
+ has, err := x.Get(r)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, ErrTagNotExist{0}
+ }
+ return r, nil
+}
+
+func UpdateTagReposByID(tagID, orgID int64, repoIdList []int64) error {
+ sess := x.NewSession()
+ defer sess.Close()
+
+ if err := sess.Begin(); err != nil {
+ return fmt.Errorf("UpdateTagReposByID[tagId: %d, orgID: %d,error:%v", tagID, orgID, err)
+ }
+ //delete old tag repos
+ r := &OfficialTagRepos{
+ TagID: tagID,
+ OrgID: orgID,
+ }
+ _, err := sess.Delete(r)
+ if err != nil {
+ return err
+ }
+
+ if len(repoIdList) == 0 {
+ return sess.Commit()
+ }
+
+ //add new tag repos
+ data := make([]*OfficialTagRepos, 0)
+ for _, repoId := range repoIdList {
+ data = append(data, &OfficialTagRepos{
+ OrgID: orgID,
+ TagID: tagID,
+ RepoID: repoId,
+ })
+ }
+ _, err = sess.Insert(&data)
+ if err != nil {
+ sess.Rollback()
+ return err
+ }
+ return sess.Commit()
+}
+
+func GetTagRepos(tagID, orgID int64) ([]TagReposSelected, error) {
+ t := make([]TagReposBrief, 0)
+ const SQLCmd = "select t1.id as repo_id,t1.name as repo_name,t2.id as tag_id from repository t1 left join official_tag_repos t2 on (t1.id = t2.repo_id and t2.tag_id = ?) where t1.owner_id = ? and t1.is_private = false order by t1.updated_unix desc"
+
+ if err := x.SQL(SQLCmd, tagID, orgID).Find(&t); err != nil {
+ return nil, err
+ }
+ r := make([]TagReposSelected, 0)
+ for _, v := range t {
+ selected := false
+ if v.TagID > 0 {
+ selected = true
+ }
+ r = append(r, TagReposSelected{
+ RepoID: v.RepoID,
+ RepoName: v.RepoName,
+ Selected: selected,
+ })
+ }
+ return r, nil
+}
+
+func GetAllOfficialTagRepos(orgID int64, isOwner bool) ([]TagsDetail, error) {
+ result := make([]TagsDetail, 0)
+ tags, err := GetAllOfficialTags()
+ if err != nil {
+ return nil, err
+ }
+ for _, tag := range tags {
+ repos, err := GetOfficialTagDetail(orgID, tag.ID)
+ if err != nil {
+ return nil, err
+ }
+ if len(repos) == 0 && !isOwner {
+ continue
+ }
+ result = append(result, TagsDetail{
+ TagId: tag.ID,
+ TagName: tag.Name,
+ TagLimit: tag.Limit,
+ RepoList: repos,
+ })
+ }
+ return result, nil
+}
+
+func GetOfficialTagDetail(orgID, tagId int64) ([]Repository, error) {
+ t := make([]Repository, 0)
+ const SQLCmd = "select t2.* from official_tag_repos t1 inner join repository t2 on t1.repo_id = t2.id where t1.org_id = ? and t1.tag_id=? order by t2.updated_unix desc"
+
+ if err := x.SQL(SQLCmd, orgID, tagId).Find(&t); err != nil {
+ return nil, err
+ }
+ return t, nil
+}
+
+func GetAllOfficialTags() ([]OfficialTag, error) {
+ //todo redis?
+ o := make([]OfficialTag, 0)
+ err := x.Where("status = ?", 0).OrderBy("updated_unix desc").Find(&o)
+ if err != nil {
+ log.Error("GetAllOfficialTags error,%v", err)
+ return nil, err
+ }
+ return o, nil
+}
diff --git a/models/repo_watch.go b/models/repo_watch.go
index 6bdef9c7f..1d6b7a31c 100644
--- a/models/repo_watch.go
+++ b/models/repo_watch.go
@@ -24,6 +24,8 @@ const (
RepoWatchModeAuto // 3
)
+var ActionChan = make(chan *Action, 200)
+
// Watch is connection request for receiving repository notification.
type Watch struct {
ID int64 `xorm:"pk autoincr"`
@@ -277,9 +279,17 @@ func notifyWatchers(e Engine, actions ...*Action) error {
// NotifyWatchers creates batch of actions for every watcher.
func NotifyWatchers(actions ...*Action) error {
+
+ producer(actions...)
return notifyWatchers(x, actions...)
}
+func producer(actions ...*Action) {
+ for _, action := range actions {
+ ActionChan <- action
+ }
+}
+
// NotifyWatchersActions creates batch of actions for every watcher.
func NotifyWatchersActions(acts []*Action) error {
sess := x.NewSession()
diff --git a/models/user_business_analysis.go b/models/user_business_analysis.go
index 9b9d5e0ad..a15b9db5f 100644
--- a/models/user_business_analysis.go
+++ b/models/user_business_analysis.go
@@ -1,7 +1,6 @@
package models
import (
- "encoding/json"
"fmt"
"sort"
"strconv"
@@ -202,15 +201,7 @@ func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusi
return nil, 0
}
log.Info("query return total:" + fmt.Sprint(allCount))
- if allCount == 0 {
- CommitCodeSizeMap, err := GetAllUserKPIStats()
- if err != nil {
- log.Info("query commit code errr.")
- } else {
- log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap)))
- }
- RefreshUserStaticAllTabel(make(map[string]int), CommitCodeSizeMap)
- }
+
pageSize := 1000
totalPage := int(allCount) / pageSize
userBusinessAnalysisReturnList := UserBusinessAnalysisAllList{}
@@ -370,7 +361,7 @@ func RefreshUserStaticAllTabel(wikiCountMap map[string]int, CommitCodeSizeMap ma
CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
- IssueCountMap := queryAction(start_unix, end_unix, 6)
+ IssueCountMap := queryCreateIssue(start_unix, end_unix)
CommentCountMap := queryComment(start_unix, end_unix)
FocusRepoCountMap := queryWatch(start_unix, end_unix)
@@ -395,7 +386,7 @@ func RefreshUserStaticAllTabel(wikiCountMap map[string]int, CommitCodeSizeMap ma
var indexTotal int64
indexTotal = 0
for {
- sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("`user`.*").Table("user").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userList := make([]*User, 0)
sess.Find(&userList)
for i, userRecord := range userList {
@@ -528,7 +519,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,
DataDate := startTime.Format("2006-01-02")
CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
- IssueCountMap := queryAction(start_unix, end_unix, 6)
+ IssueCountMap := queryCreateIssue(start_unix, end_unix)
CommentCountMap := queryComment(start_unix, end_unix)
FocusRepoCountMap := queryWatch(start_unix, end_unix)
@@ -559,7 +550,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,
var indexTotal int64
indexTotal = 0
for {
- sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("`user`.*").Table("user").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userList := make([]*User, 0)
sess.Find(&userList)
@@ -709,7 +700,7 @@ func querySolveIssue(start_unix int64, end_unix int64) map[int64]int {
issueAssigneesList := make([]*IssueAssignees, 0)
sess.Select("issue_assignees.*").Table("issue_assignees").
Join("inner", "issue", "issue.id=issue_assignees.issue_id").
- Where(cond).Limit(Page_SIZE, int(indexTotal))
+ Where(cond).OrderBy("issue_assignees.id asc").Limit(Page_SIZE, int(indexTotal))
sess.Find(&issueAssigneesList)
@@ -744,7 +735,7 @@ func queryPullRequest(start_unix int64, end_unix int64) map[int64]int {
indexTotal = 0
for {
issueList := make([]*Issue, 0)
- sess.Select("issue.*").Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("issue.*").Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).OrderBy("issue.id asc").Limit(Page_SIZE, int(indexTotal))
sess.Find(&issueList)
log.Info("query issue(PR) size=" + fmt.Sprint(len(issueList)))
for _, issueRecord := range issueList {
@@ -777,7 +768,7 @@ func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[i
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
actionList := make([]*Action, 0)
sess.Find(&actionList)
@@ -799,29 +790,30 @@ func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[i
return resultMap
}
-func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]int {
+func queryCreateIssue(start_unix int64, end_unix int64) map[int64]int {
+
sess := x.NewSession()
defer sess.Close()
resultMap := make(map[int64]int)
- cond := "op_type=" + fmt.Sprint(actionType) + " and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
+ cond := "is_pull=false and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
- count, err := sess.Where(cond).Count(new(Action))
+ count, err := sess.Where(cond).Count(new(Issue))
if err != nil {
- log.Info("query Action error. return.")
+ log.Info("query Issue error. return.")
return resultMap
}
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
- actionList := make([]*Action, 0)
- sess.Find(&actionList)
- log.Info("query action size=" + fmt.Sprint(len(actionList)))
- for _, actionRecord := range actionList {
- if _, ok := resultMap[actionRecord.UserID]; !ok {
- resultMap[actionRecord.UserID] = 1
+ sess.Select("id,poster_id").Table("issue").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
+ issueList := make([]*Issue, 0)
+ sess.Find(&issueList)
+ log.Info("query issue size=" + fmt.Sprint(len(issueList)))
+ for _, issueRecord := range issueList {
+ if _, ok := resultMap[issueRecord.PosterID]; !ok {
+ resultMap[issueRecord.PosterID] = 1
} else {
- resultMap[actionRecord.UserID] += 1
+ resultMap[issueRecord.PosterID] += 1
}
}
indexTotal += Page_SIZE
@@ -830,6 +822,7 @@ func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]i
}
}
return resultMap
+
}
func queryComment(start_unix int64, end_unix int64) map[int64]int {
@@ -846,7 +839,7 @@ func queryComment(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,type,poster_id").Table("comment").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,type,poster_id").Table("comment").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
commentList := make([]*Comment, 0)
sess.Find(&commentList)
log.Info("query Comment size=" + fmt.Sprint(len(commentList)))
@@ -882,7 +875,7 @@ func queryWatch(start_unix int64, end_unix int64) map[int64]int {
indexTotal = 0
for {
watchList := make([]*Watch, 0)
- sess.Select("id,user_id,repo_id").Table("watch").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,user_id,repo_id").Table("watch").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
sess.Find(&watchList)
log.Info("query Watch size=" + fmt.Sprint(len(watchList)))
@@ -920,7 +913,7 @@ func queryStar(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,uid,repo_id").Table("star").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,uid,repo_id").Table("star").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
starList := make([]*Star, 0)
sess.Find(&starList)
@@ -956,7 +949,7 @@ func queryFollow(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,user_id,follow_id").Table("follow").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,user_id,follow_id").Table("follow").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
followList := make([]*Follow, 0)
sess.Find(&followList)
@@ -992,7 +985,7 @@ func queryDatasetSize(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,uploader_id,size").Table("attachment").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,uploader_id,size").Table("attachment").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
attachmentList := make([]*Attachment, 0)
sess.Find(&attachmentList)
@@ -1028,7 +1021,7 @@ func queryUserCreateRepo(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- sess.Select("id,owner_id,name").Table("repository").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ sess.Select("id,owner_id,name").Table("repository").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
repoList := make([]*Repository, 0)
sess.Find(&repoList)
log.Info("query Repository size=" + fmt.Sprint(len(repoList)))
@@ -1099,8 +1092,7 @@ func queryUserRepoOpenIIndex(start_unix int64, end_unix int64) map[int64]float64
}
}
- userMapJson, _ := json.Marshal(userMap)
- log.Info("userMapJson=" + string(userMapJson))
+ log.Info("user openi index size=" + fmt.Sprint(len(userMap)))
return userMap
}
@@ -1119,7 +1111,7 @@ func queryLoginCount(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64
indexTotal = 0
for {
- statictisSess.Select("id,u_id").Table("user_login_log").Where(cond).Limit(Page_SIZE, int(indexTotal))
+ statictisSess.Select("id,u_id").Table("user_login_log").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userLoginLogList := make([]*UserLoginLog, 0)
statictisSess.Find(&userLoginLogList)
log.Info("query user login size=" + fmt.Sprint(len(userLoginLogList)))
@@ -1135,7 +1127,7 @@ func queryLoginCount(start_unix int64, end_unix int64) map[int64]int {
break
}
}
-
+ log.Info("user login size=" + fmt.Sprint(len(resultMap)))
return resultMap
}
diff --git a/modules/auth/org.go b/modules/auth/org.go
index 20e2b0999..9642e1ce6 100644
--- a/modules/auth/org.go
+++ b/modules/auth/org.go
@@ -70,3 +70,7 @@ type CreateTeamForm struct {
func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
+
+type SubmitReposOfTagForm struct {
+ RepoList []int64
+}
diff --git a/modules/cloudbrain/cloudbrain.go b/modules/cloudbrain/cloudbrain.go
index 0f1c700d2..b8aa2e143 100755
--- a/modules/cloudbrain/cloudbrain.go
+++ b/modules/cloudbrain/cloudbrain.go
@@ -1,6 +1,8 @@
package cloudbrain
import (
+ "code.gitea.io/gitea/modules/storage"
+ "encoding/json"
"errors"
"strconv"
@@ -107,6 +109,9 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
uuid
var resourceSpec *models.ResourceSpec
+ if ResourceSpecs == nil {
+ json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs)
+ }
for _, spec := range ResourceSpecs.ResourceSpec {
if resourceSpecId == spec.Id {
resourceSpec = spec
@@ -185,28 +190,143 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
},
})
if err != nil {
- log.Error("CreateJob failed:", err.Error())
+ log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
return err
}
if jobResult.Code != Success {
- log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg)
+ log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg, ctx.Data["MsgID"])
return errors.New(jobResult.Msg)
}
var jobID = jobResult.Payload["jobId"].(string)
err = models.CreateCloudbrain(&models.Cloudbrain{
- Status: string(models.JobWaiting),
- UserID: ctx.User.ID,
- RepoID: ctx.Repo.Repository.ID,
- JobID: jobID,
- JobName: jobName,
- SubTaskName: SubTaskName,
- JobType: jobType,
- Type: models.TypeCloudBrainOne,
- Uuid: uuid,
+ Status: string(models.JobWaiting),
+ UserID: ctx.User.ID,
+ RepoID: ctx.Repo.Repository.ID,
+ JobID: jobID,
+ JobName: jobName,
+ SubTaskName: SubTaskName,
+ JobType: jobType,
+ Type: models.TypeCloudBrainOne,
+ Uuid: uuid,
+ Image: image,
+ GpuQueue: gpuQueue,
+ ResourceSpecId: resourceSpecId,
+ ComputeResource: models.GPUResource,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func RestartTask(ctx *context.Context, task *models.Cloudbrain) error {
+ dataActualPath := setting.Attachment.Minio.RealPath +
+ setting.Attachment.Minio.Bucket + "/" +
+ setting.Attachment.Minio.BasePath +
+ models.AttachmentRelativePath(task.Uuid) +
+ task.Uuid
+ jobName := task.JobName
+
+ var resourceSpec *models.ResourceSpec
+ if ResourceSpecs == nil {
+ json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs)
+ }
+ for _, spec := range ResourceSpecs.ResourceSpec {
+ if task.ResourceSpecId == spec.Id {
+ resourceSpec = spec
+ }
+ }
+
+ if resourceSpec == nil {
+ log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"])
+ return errors.New("no such resourceSpec")
+ }
+
+ jobResult, err := CreateJob(jobName, models.CreateJobParams{
+ JobName: jobName,
+ RetryCount: 1,
+ GpuType: task.GpuQueue,
+ Image: task.Image,
+ TaskRoles: []models.TaskRole{
+ {
+ Name: SubTaskName,
+ TaskNumber: 1,
+ MinSucceededTaskCount: 1,
+ MinFailedTaskCount: 1,
+ CPUNumber: resourceSpec.CpuNum,
+ GPUNumber: resourceSpec.GpuNum,
+ MemoryMB: resourceSpec.MemMiB,
+ ShmMB: resourceSpec.ShareMemMiB,
+ Command: Command,
+ NeedIBDevice: false,
+ IsMainRole: false,
+ UseNNI: false,
+ },
+ },
+ Volumes: []models.Volume{
+ {
+ HostPath: models.StHostPath{
+ Path: storage.GetMinioPath(jobName, CodeMountPath + "/"),
+ MountPath: CodeMountPath,
+ ReadOnly: false,
+ },
+ },
+ {
+ HostPath: models.StHostPath{
+ Path: dataActualPath,
+ MountPath: DataSetMountPath,
+ ReadOnly: true,
+ },
+ },
+ {
+ HostPath: models.StHostPath{
+ Path: storage.GetMinioPath(jobName, ModelMountPath + "/"),
+ MountPath: ModelMountPath,
+ ReadOnly: false,
+ },
+ },
+ {
+ HostPath: models.StHostPath{
+ Path: storage.GetMinioPath(jobName, BenchMarkMountPath + "/"),
+ MountPath: BenchMarkMountPath,
+ ReadOnly: true,
+ },
+ },
+ {
+ HostPath: models.StHostPath{
+ Path: storage.GetMinioPath(jobName, Snn4imagenetMountPath + "/"),
+ MountPath: Snn4imagenetMountPath,
+ ReadOnly: true,
+ },
+ },
+ {
+ HostPath: models.StHostPath{
+ Path: storage.GetMinioPath(jobName, BrainScoreMountPath + "/"),
+ MountPath: BrainScoreMountPath,
+ ReadOnly: true,
+ },
+ },
+ },
})
+ if err != nil {
+ log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
+ return err
+ }
+ if jobResult.Code != Success {
+ log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg, ctx.Data["MsgID"])
+ return errors.New(jobResult.Msg)
+ }
+
+ var jobID = jobResult.Payload["jobId"].(string)
+ task.JobID = jobID
+ task.Status = string(models.JobWaiting)
+ err = models.UpdateJob(task)
if err != nil {
+ log.Error("UpdateJob(%s) failed:%v", jobName, err.Error(), ctx.Data["MsgID"])
return err
}
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 772f1d149..f72f5df7e 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -445,8 +445,12 @@ type Contributor struct {
Email string
}
-func GetContributors(repoPath string) ([]Contributor, error){
- cmd := NewCommand("shortlog", "-sne", "--all")
+func GetContributors(repoPath string, branchOrTag ...string) ([]Contributor, error) {
+ targetBranchOrTag := "HEAD"
+ if len(branchOrTag) > 0 && branchOrTag[0] != "" {
+ targetBranchOrTag = branchOrTag[0]
+ }
+ cmd := NewCommand("shortlog", "-sne", targetBranchOrTag)
stdout, err := cmd.RunInDir(repoPath)
if err != nil {
return nil, err
@@ -462,9 +466,9 @@ func GetContributors(repoPath string) ([]Contributor, error){
}
number := oneCount[0:strings.Index(oneCount, "\t")]
commitCnt, _ := strconv.Atoi(number)
- committer := oneCount[strings.Index(oneCount, "\t")+1:strings.LastIndex(oneCount, " ")]
+ committer := oneCount[strings.Index(oneCount, "\t")+1 : strings.LastIndex(oneCount, " ")]
committer = strings.Trim(committer, " ")
- email := oneCount[strings.Index(oneCount, "<")+1:strings.Index(oneCount, ">")]
+ email := oneCount[strings.Index(oneCount, "<")+1 : strings.Index(oneCount, ">")]
contributorsInfo[i] = Contributor{
commitCnt, committer, email,
}
diff --git a/modules/modelarts/modelarts.go b/modules/modelarts/modelarts.go
index 273d59012..06eac1665 100755
--- a/modules/modelarts/modelarts.go
+++ b/modules/modelarts/modelarts.go
@@ -48,12 +48,8 @@ const (
PerPage = 10
IsLatestVersion = "1"
NotLatestVersion = "0"
- // ComputeResource = "NPU"
- NPUResource = "NPU"
- GPUResource = "CPU/GPU"
- AllResource = "all"
- DebugType = -1
- VersionCount = 1
+ DebugType = -1
+ VersionCount = 1
SortByCreateTime = "create_time"
ConfigTypeCustom = "custom"
@@ -215,14 +211,15 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin
}
err = models.CreateCloudbrain(&models.Cloudbrain{
- Status: string(models.JobWaiting),
- UserID: ctx.User.ID,
- RepoID: ctx.Repo.Repository.ID,
- JobID: jobResult.ID,
- JobName: jobName,
- JobType: string(models.JobTypeDebug),
- Type: models.TypeCloudBrainTwo,
- Uuid: uuid,
+ Status: string(models.JobWaiting),
+ UserID: ctx.User.ID,
+ RepoID: ctx.Repo.Repository.ID,
+ JobID: jobResult.ID,
+ JobName: jobName,
+ JobType: string(models.JobTypeDebug),
+ Type: models.TypeCloudBrainTwo,
+ Uuid: uuid,
+ ComputeResource: models.NPUResource,
})
if err != nil {
@@ -277,7 +274,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
DatasetName: attach.Name,
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
- ComputeResource: NPUResource,
+ ComputeResource: models.NPUResource,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,
BranchName: req.BranchName,
@@ -360,7 +357,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
PreVersionName: req.PreVersionName,
- ComputeResource: NPUResource,
+ ComputeResource: models.GPUResource,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,
BranchName: req.BranchName,
diff --git a/modules/modelarts/resty.go b/modules/modelarts/resty.go
index 2cc9e34be..07f26ceb7 100755
--- a/modules/modelarts/resty.go
+++ b/modules/modelarts/resty.go
@@ -174,7 +174,7 @@ sendjob:
return &result, nil
}
-func StopJob(jobID string, param models.NotebookAction) (*models.NotebookActionResult, error) {
+func ManageNotebook(jobID string, param models.NotebookAction) (*models.NotebookActionResult, error) {
checkSetting()
client := getRestyClient()
var result models.NotebookActionResult
@@ -207,8 +207,8 @@ sendjob:
}
if len(response.ErrorCode) != 0 {
- log.Error("StopJob failed(%s): %s", response.ErrorCode, response.ErrorMsg)
- return &result, fmt.Errorf("StopJob failed(%s): %s", response.ErrorCode, response.ErrorMsg)
+ log.Error("ManageNotebook failed(%s): %s", response.ErrorCode, response.ErrorMsg)
+ return &result, fmt.Errorf("ManageNotebook failed(%s): %s", response.ErrorCode, response.ErrorMsg)
}
return &result, nil
diff --git a/modules/repository/elk_pagedata.go b/modules/repository/elk_pagedata.go
index 1454f0364..ecdbff078 100644
--- a/modules/repository/elk_pagedata.go
+++ b/modules/repository/elk_pagedata.go
@@ -21,7 +21,8 @@ type Fields struct {
Format string `json:"format"`
}
type MatchPhrase struct {
- Message string `json:"message"`
+ Message string `json:"message,omitempty"`
+ TagName string `json:"tagName.keyword,omitempty"`
}
type Should struct {
MatchPhrase MatchPhrase `json:"match_phrase"`
@@ -144,7 +145,7 @@ func ProjectViewInit(User string, Project string, Gte string, Lte string) (proje
inputStruct.Batch[0].Request.Params.Body.Fields = make([]Fields, 1)
inputStruct.Batch[0].Request.Params.Body.Fields[0].Field = setting.TimeField
inputStruct.Batch[0].Request.Params.Body.Fields[0].Format = setting.ElkTimeFormat
- inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter = make([]Filter, 3)
+ inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter = make([]Filter, 4)
//限定查询时间
var timeRange Range
timeRange.Timestamptest.Gte = Gte
@@ -159,6 +160,24 @@ func ProjectViewInit(User string, Project string, Gte string, Lte string) (proje
var projectName FilterMatchPhrase
projectName.ProjectName = Project
inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[2].FilterMatchPhrase = &projectName
+ //限定页面
+ var bool Bool
+ bool.Should = make([]Should, 14)
+ bool.Should[0].MatchPhrase.TagName = "%{[request][3]}"
+ bool.Should[1].MatchPhrase.TagName = "datasets?type=0"
+ bool.Should[2].MatchPhrase.TagName = "datasets?type=1"
+ bool.Should[3].MatchPhrase.TagName = "issues"
+ bool.Should[4].MatchPhrase.TagName = "labels"
+ bool.Should[5].MatchPhrase.TagName = "pulls"
+ bool.Should[6].MatchPhrase.TagName = "wiki"
+ bool.Should[7].MatchPhrase.TagName = "activity"
+ bool.Should[8].MatchPhrase.TagName = "cloudbrain"
+ bool.Should[9].MatchPhrase.TagName = "modelarts"
+ bool.Should[10].MatchPhrase.TagName = "blockchain"
+ bool.Should[11].MatchPhrase.TagName = "watchers"
+ bool.Should[12].MatchPhrase.TagName = "stars"
+ bool.Should[13].MatchPhrase.TagName = "forks"
+ inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[3].Bool = &bool
return inputStruct
}
diff --git a/modules/storage/local.go b/modules/storage/local.go
old mode 100644
new mode 100755
index d46a5528d..df5807f87
--- a/modules/storage/local.go
+++ b/modules/storage/local.go
@@ -80,3 +80,7 @@ func (l *LocalStorage) HasObject(path string) (bool, error) {
func (l *LocalStorage) UploadObject(fileName, filePath string) error {
return nil
}
+
+func (l *LocalStorage) DeleteDir(dir string) error {
+ return nil
+}
diff --git a/modules/storage/minio.go b/modules/storage/minio.go
index 664e58d1b..c6f704df5 100755
--- a/modules/storage/minio.go
+++ b/modules/storage/minio.go
@@ -11,6 +11,9 @@ import (
"strings"
"time"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+
"github.com/minio/minio-go"
)
@@ -76,6 +79,29 @@ func (m *MinioStorage) Delete(path string) error {
return m.client.RemoveObject(m.bucket, m.buildMinioPath(path))
}
+// Delete delete a file
+func (m *MinioStorage) DeleteDir(dir string) error {
+ objectsCh := make(chan string)
+
+ // Send object names that are needed to be removed to objectsCh
+ go func() {
+ defer close(objectsCh)
+ // List all objects from a bucket-name with a matching prefix.
+ for object := range m.client.ListObjects(m.bucket, dir, true, nil) {
+ if object.Err != nil {
+ log.Error("ListObjects failed:%v", object.Err)
+ }
+ objectsCh <- object.Key
+ }
+ }()
+
+ for rErr := range m.client.RemoveObjects(m.bucket, objectsCh) {
+ log.Error("Error detected during deletion: ", rErr)
+ }
+
+ return nil
+}
+
//Get Presigned URL for get object
func (m *MinioStorage) PresignedGetURL(path string, fileName string) (string, error) {
// Set request parameters for content-disposition.
@@ -128,3 +154,7 @@ func (m *MinioStorage) UploadObject(fileName, filePath string) error {
_, err := m.client.FPutObject(m.bucket, fileName, filePath, minio.PutObjectOptions{})
return err
}
+
+func GetMinioPath(jobName, suffixPath string) string {
+ return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + jobName + suffixPath
+}
diff --git a/modules/storage/storage.go b/modules/storage/storage.go
index d364346f0..fc9d38020 100755
--- a/modules/storage/storage.go
+++ b/modules/storage/storage.go
@@ -23,6 +23,7 @@ type ObjectStorage interface {
Save(path string, r io.Reader) (int64, error)
Open(path string) (io.ReadCloser, error)
Delete(path string) error
+ DeleteDir(dir string) error
PresignedGetURL(path string, fileName string) (string, error)
PresignedPutURL(path string) (string, error)
HasObject(path string) (bool, error)
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index d58a61756..35f0a98bf 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -222,6 +222,7 @@ contributors = Contributors
[explore]
repos = Repositories
+select_repos = Select the project
users = Users
organizations = Organizations
images = CloudImages
@@ -234,6 +235,8 @@ org_no_results = No matching organizations found.
code_no_results = No source code matching your search term found.
code_search_results = Search results for '%s'
code_last_indexed_at = Last indexed %s
+save=save
+cancel=cancel
[auth]
create_new_account = Register Account
@@ -778,6 +781,10 @@ datasets = Datasets
datasets.desc = Enable Dataset
cloudbrain_helper=Use GPU/NPU resources to open notebooks, model training tasks, etc.
+model_manager = Model
+model_noright=No right
+model_rename=Duplicate model name, please modify model name.
+
debug=Debug
stop=Stop
delete=Delete
@@ -896,6 +903,8 @@ model.manage.F1 = F1
model.manage.Precision = Precision
model.manage.Recall = Recall
model.manage.sava_model = Sava Model
+model.manage.model_manage = ModelManage
+model.manage.model_accuracy = Model Accuracy
template.items = Template Items
template.git_content = Git Content (Default Branch)
@@ -1127,6 +1136,7 @@ issues.filter_label_exclude = `Use alt + click/enter t
issues.filter_label_no_select = All labels
issues.filter_milestone = Milestone
issues.filter_milestone_no_select = All milestones
+issues.filter_milestone_no_add = Not add milestones
issues.filter_assignee = Assignee
issues.filter_assginee_no_select = All assignees
issues.filter_type = Type
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 45cabda8f..0389471c2 100755
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -224,6 +224,7 @@ contributors=贡献者
[explore]
repos=项目
+select_repos=精选项目
users=用户
organizations=组织
images = 云脑镜像
@@ -238,6 +239,8 @@ org_no_results=未找到匹配的组织。
code_no_results=未找到与搜索字词匹配的源代码。
code_search_results=“%s” 的搜索结果是
code_last_indexed_at=最后索引于 %s
+save=保存
+cancel=取消
[auth]
create_new_account=注册帐号
@@ -784,8 +787,10 @@ cloudbrain_helper=使用GPU/NPU资源,开启Notebook、模型训练任务等
model_manager = 模型
model_noright=无权限操作
+model_rename=模型名称重复,请修改模型名称
debug=调试
+debug_again=再次调试
stop=停止
delete=删除
model_download=模型下载
@@ -908,6 +913,8 @@ model.manage.F1 = F1值
model.manage.Precision = 精确率
model.manage.Recall = 召回率
model.manage.sava_model = 保存模型
+model.manage.model_manage = 模型管理
+model.manage.model_accuracy = 模型精度
template.items=模板选项
template.git_content=Git数据(默认分支)
@@ -1140,6 +1147,7 @@ issues.filter_label_exclude=`使用 alt + 鼠标左键 / 回
issues.filter_label_no_select=所有标签
issues.filter_milestone=里程碑筛选
issues.filter_milestone_no_select=所有里程碑
+issues.filter_milestone_no_add=未添加里程碑
issues.filter_assignee=指派人筛选
issues.filter_assginee_no_select=所有指派成员
issues.filter_type=类型筛选
diff --git a/package-lock.json b/package-lock.json
index d45f8c6f8..a8e5e3e25 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11655,6 +11655,11 @@
"autolinker": "~0.28.0"
}
},
+ "remixicon": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/remixicon/-/remixicon-2.5.0.tgz",
+ "integrity": "sha512-q54ra2QutYDZpuSnFjmeagmEiN9IMo56/zz5dDNitzKD23oFRw77cWo4TsrAdmdkPiEn8mxlrTqxnkujDbEGww=="
+ },
"remove-bom-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
diff --git a/package.json b/package.json
index 7147bea0d..ba5459a07 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "4.0.2",
"qs": "6.9.4",
+ "remixicon": "2.5.0",
"spark-md5": "3.0.1",
"svg-sprite-loader": "5.0.0",
"svgo": "1.3.2",
diff --git a/routers/actionnotification.go b/routers/actionnotification.go
new file mode 100644
index 000000000..b3e151c1c
--- /dev/null
+++ b/routers/actionnotification.go
@@ -0,0 +1,53 @@
+package routers
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/services/socketwrap"
+ "github.com/gorilla/websocket"
+)
+
+var upgrader = websocket.Upgrader{
+ ReadBufferSize: 1024,
+ WriteBufferSize: 1024,
+}
+
+var SocketManager = socketwrap.NewClientsManager()
+
+func ActionNotification(ctx *context.Context) {
+
+ conn, err := upgrader.Upgrade(ctx.Resp, ctx.Req.Request, nil)
+ if err != nil {
+ log.Warn("can not create connection.", err)
+ return
+ }
+ client := &socketwrap.Client{Manager: SocketManager, Conn: conn, Send: make(chan *models.Action, 256)}
+
+ WriteLastTenActionsIfHave(conn)
+
+ client.Manager.Register <- client
+
+ go client.WritePump()
+
+}
+
+func WriteLastTenActionsIfHave(conn *websocket.Conn) {
+ socketwrap.LastTenActionsQueue.Mutex.RLock()
+ {
+ size := socketwrap.LastTenActionsQueue.Queue.Len()
+ if size > 0 {
+ tempE := socketwrap.LastTenActionsQueue.Queue.Front()
+ conn.WriteJSON(tempE)
+ for i := 1; i < size; i++ {
+ tempE = tempE.Next()
+ conn.WriteJSON(tempE)
+
+ }
+ }
+
+ }
+ socketwrap.LastTenActionsQueue.Mutex.RUnlock()
+}
+
+
diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go
index a18da3fe5..283696007 100755
--- a/routers/api/v1/repo/modelarts.go
+++ b/routers/api/v1/repo/modelarts.go
@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/storage"
+ routerRepo "code.gitea.io/gitea/routers/repo"
)
func GetModelArtsNotebook(ctx *context.APIContext) {
@@ -237,7 +238,7 @@ func DelTrainJobVersion(ctx *context.APIContext) {
JobID: jobID,
})
if err != nil {
- ctx.ServerError("get VersionListCount faild", err)
+ ctx.ServerError("get VersionListCount failed", err)
return
}
if VersionListCount > 0 {
@@ -255,6 +256,8 @@ func DelTrainJobVersion(ctx *context.APIContext) {
return
}
}
+ } else { //已删除该任务下的所有版本
+ routerRepo.DeleteJobStorage(task.JobName)
}
ctx.JSON(http.StatusOK, map[string]interface{}{
diff --git a/routers/org/home.go b/routers/org/home.go
index b11c179c1..df600d96d 100755
--- a/routers/org/home.go
+++ b/routers/org/home.go
@@ -130,5 +130,13 @@ func Home(ctx *context.Context) {
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager
+ //find org tag info
+ tags, err := models.GetAllOfficialTagRepos(org.ID, ctx.Org.IsOwner)
+ if err != nil {
+ ctx.ServerError("GetAllOfficialTagRepos", err)
+ return
+ }
+
+ ctx.Data["tags"] = tags
ctx.HTML(200, tplOrgHome)
}
diff --git a/routers/org/tag.go b/routers/org/tag.go
new file mode 100644
index 000000000..37d5b1c8f
--- /dev/null
+++ b/routers/org/tag.go
@@ -0,0 +1,90 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Copyright 2020 The Gitea Authors.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package org
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/auth"
+ "code.gitea.io/gitea/modules/context"
+ "errors"
+ "strconv"
+)
+
+const DefaultOrgTagLimit = -1
+
+// SubmitTags submit repos of org tag
+func SubmitTags(ctx *context.Context, form auth.SubmitReposOfTagForm) {
+ if !ctx.Org.IsOwner {
+ ctx.ServerError("UpdateTagReposByID", errors.New("no access to submit tags"))
+ return
+ }
+ tag := getTagFromContext(ctx)
+ if ctx.Written() {
+ return
+ }
+ if tag.Limit != DefaultOrgTagLimit && len(form.RepoList) > tag.Limit {
+ ctx.ServerError("UpdateTagReposByID", errors.New("tags size over limit"))
+ return
+ }
+ err := models.UpdateTagReposByID(tag.ID, ctx.Org.Organization.ID, form.RepoList)
+ if err != nil {
+ ctx.ServerError("UpdateTagReposByID", err)
+ return
+ }
+
+ ctx.JSON(200, map[string]interface{}{
+ "code": "00",
+ "msg": "success",
+ })
+}
+
+// GetTagRepos get repos under org tag
+func GetTagRepos(ctx *context.Context) {
+ if !ctx.Org.IsOwner {
+ ctx.ServerError("GetTagRepos", errors.New("no access to get tags"))
+ return
+ }
+ tag := getTagFromContext(ctx)
+ if ctx.Written() {
+ return
+ }
+
+ r, err := models.GetTagRepos(tag.ID, ctx.Org.Organization.ID)
+ if err != nil {
+ ctx.ServerError("GetTagRepos", err)
+ return
+ }
+
+ ctx.JSON(200, map[string]interface{}{
+ "code": "00",
+ "msg": "success",
+ "data": r,
+ })
+}
+
+// getTagFromContext finds out tag info From context.
+func getTagFromContext(ctx *context.Context) *models.OfficialTag {
+ var tag *models.OfficialTag
+ var err error
+
+ tagIdStr := ctx.Query("tagId")
+ if len(tagIdStr) == 0 {
+ ctx.ServerError("GetTagInfo", errors.New("tag is not exist"))
+ return nil
+ }
+ tagId, _ := strconv.ParseInt(tagIdStr, 10, 32)
+ tag, err = models.GetTagByID(tagId)
+ if err != nil {
+ if models.IsErrTagNotExist(err) {
+ ctx.NotFound("GetTagInfo", err)
+ } else {
+ ctx.ServerError("GetTagInfo", err)
+ }
+ return nil
+ }
+
+ return tag
+}
diff --git a/routers/repo/ai_model_manage.go b/routers/repo/ai_model_manage.go
index ad68f5b99..669bdf9fa 100644
--- a/routers/repo/ai_model_manage.go
+++ b/routers/repo/ai_model_manage.go
@@ -105,6 +105,23 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
return nil
}
+func SaveNewNameModel(ctx *context.Context) {
+ name := ctx.Query("Name")
+ if name == "" {
+ ctx.Error(500, fmt.Sprintf("name or version is null."))
+ return
+ }
+
+ aimodels := models.QueryModelByName(name, ctx.Repo.Repository.ID)
+ if len(aimodels) > 0 {
+ ctx.Error(500, ctx.Tr("repo.model_rename"))
+ return
+ }
+ SaveModel(ctx)
+
+ log.Info("save model end.")
+}
+
func SaveModel(ctx *context.Context) {
log.Info("save model start.")
JobId := ctx.Query("JobId")
diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go
index dc3fcd848..6bd546ce6 100755
--- a/routers/repo/blockchain.go
+++ b/routers/repo/blockchain.go
@@ -72,7 +72,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {
repo.BlockChainStatus = models.RepoBlockChainSuccess
repo.ContractAddress = req.ContractAddress
- if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil {
+ if err = repo.UpdateBlockChain(); err != nil {
log.Error("UpdateRepositoryCols failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{
"code": "-1",
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index 3f5fce013..ab3303408 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -206,7 +206,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
}
repo := ctx.Repo.Repository
downloadCode(repo, codePath)
- uploadCodeToMinio(codePath+"/", jobName, "/code/")
+ uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/")
modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/"
mkModelPath(modelPath)
@@ -236,15 +236,89 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/")
}
- err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, getMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
- getMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), getMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
- getMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, resourceSpecId)
+ err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
+ storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
+ storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
+ storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, resourceSpecId)
if err != nil {
cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
return
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+ ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
+}
+
+func CloudBrainRestart(ctx *context.Context) {
+ var jobID = ctx.Params(":jobid")
+ var resultCode = "0"
+ var errorMsg = ""
+ var status = ""
+
+ for {
+ task, err := models.GetCloudbrainByJobID(jobID)
+ if err != nil {
+ log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error(), ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
+
+ if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) {
+ log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "the job is not stopped"
+ break
+ }
+
+ if task.Image == "" || task.GpuQueue == "" || task.Type != models.TypeCloudBrainOne {
+ log.Error("the job(%s) version is too old", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "the job's version is too old and can not be restarted"
+ break
+ }
+
+ if !ctx.IsSigned || (ctx.User.ID != task.UserID && !ctx.IsUserSiteAdmin()){
+ log.Error("the user has no right ro restart the job", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "you have no right to restart the job"
+ break
+ }
+
+ count, err := models.GetCloudbrainCountByUserID(ctx.User.ID)
+ if err != nil {
+ log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "you have already a running or waiting task, can not create more"
+ break
+ }
+ }
+
+ err = cloudbrain.RestartTask(ctx, task)
+ if err != nil {
+ log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
+
+ status = task.Status
+ jobID = task.JobID
+
+ break
+ }
+
+ ctx.JSON(200, map[string]string{
+ "result_code": resultCode,
+ "error_msg": errorMsg,
+ "status": status,
+ "job_id": jobID,
+ })
}
func CloudBrainShow(ctx *context.Context) {
@@ -351,32 +425,53 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain
func CloudBrainStop(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
+ var resultCode = "0"
+ var errorMsg = ""
+ var status = ""
- if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) {
- log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
- ctx.ServerError("the job has been stopped", errors.New("the job has been stopped"))
- return
- }
+ for {
+ task, err := models.GetCloudbrainByJobID(jobID)
+ if err != nil {
+ log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
- err = cloudbrain.StopJob(jobID)
- if err != nil {
- log.Error("StopJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"])
- ctx.ServerError("StopJob failed", err)
- return
- }
+ if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) {
+ log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
- task.Status = string(models.JobStopped)
- err = models.UpdateJob(task)
- if err != nil {
- ctx.ServerError("UpdateJob failed", err)
- return
+ err = cloudbrain.StopJob(jobID)
+ if err != nil {
+ log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
+
+ task.Status = string(models.JobStopped)
+ err = models.UpdateJob(task)
+ if err != nil {
+ log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
+
+ status = task.Status
+ break
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+
+ ctx.JSON(200, map[string]string{
+ "result_code": resultCode,
+ "error_msg": errorMsg,
+ "status": status,
+ "job_id": jobID,
+ })
}
func StopJobsByUserID(userID int64) {
@@ -423,7 +518,7 @@ func StopJobs(cloudBrains []*models.Cloudbrain) {
Action: models.ActionStop,
}
err := retry(3, time.Second*30, func() error {
- _, err := modelarts.StopJob(taskInfo.JobID, param)
+ _, err := modelarts.ManageNotebook(taskInfo.JobID, param)
return err
})
logErrorAndUpdateJobStatus(err, taskInfo)
@@ -478,7 +573,9 @@ func CloudBrainDel(ctx *context.Context) {
ctx.ServerError("DeleteJob failed", err)
return
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+
+ deleteJobStorage(task.JobName, models.TypeCloudBrainOne)
+ ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}
func CloudBrainShowModels(ctx *context.Context) {
@@ -560,7 +657,7 @@ func getImages(ctx *context.Context, imageType string) {
func GetModelDirs(jobName string, parentDir string) (string, error) {
var req string
- modelActualPath := getMinioPath(jobName, cloudbrain.ModelMountPath+"/")
+ modelActualPath := storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/")
if parentDir == "" {
req = "baseDir=" + modelActualPath
} else {
@@ -570,10 +667,6 @@ func GetModelDirs(jobName string, parentDir string) (string, error) {
return getDirs(req)
}
-func getMinioPath(jobName, suffixPath string) string {
- return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + jobName + suffixPath
-}
-
func CloudBrainDownloadModel(ctx *context.Context) {
parentDir := ctx.Query("parentDir")
fileName := ctx.Query("fileName")
@@ -756,6 +849,35 @@ func mkModelPath(modelPath string) error {
return nil
}
+func deleteJobStorage(jobName string, cloudbrainType int) error {
+ //delete local
+ localJobPath := setting.JobPath + jobName
+ err := os.RemoveAll(localJobPath)
+ if err != nil {
+ log.Error("RemoveAll(%s) failed:%v", localJobPath, err)
+ }
+
+ //delete oss
+ if cloudbrainType == models.TypeCloudBrainOne {
+ dirPath := setting.CBCodePathPrefix + jobName + "/"
+ err = storage.Attachments.DeleteDir(dirPath)
+ if err != nil {
+ log.Error("DeleteDir(%s) failed:%v", localJobPath, err)
+ }
+ } else if cloudbrainType == models.TypeCloudBrainTwo {
+ //dirPath := setting.CodePathPrefix + jobName + "/"
+ //err = storage.ObsRemoveObject(setting.Bucket, dirPath)
+ //if err != nil {
+ // log.Error("ObsRemoveObject(%s) failed:%v", localJobPath, err)
+ //}
+ log.Info("no need to delete")
+ } else {
+ log.Error("cloudbrainType(%d) error", cloudbrainType)
+ }
+
+ return nil
+}
+
func SyncCloudbrainStatus() {
cloudBrains, err := models.GetCloudBrainUnStoppedJob()
if err != nil {
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 77ed0251d..7ab5eb283 100755
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -193,6 +193,8 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
var mileIDs []int64
if milestoneID > 0 {
mileIDs = []int64{milestoneID}
+ } else if milestoneID == -1 { //only search no milestone
+ mileIDs = []int64{0}
}
var issues []*models.Issue
@@ -355,7 +357,8 @@ func Issues(ctx *context.Context) {
var err error
// Get milestones.
- ctx.Data["Milestones"], err = models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateType(ctx.Query("state")), models.ListOptions{})
+ ctx.Data["OpenMilestones"], err = models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateOpen, models.ListOptions{})
+ ctx.Data["ClosedMilestones"], err = models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateClosed, models.ListOptions{})
if err != nil {
ctx.ServerError("GetAllRepoMilestones", err)
return
diff --git a/routers/repo/milestone.go b/routers/repo/milestone.go
index e30e6371f..41f1f88bc 100644
--- a/routers/repo/milestone.go
+++ b/routers/repo/milestone.go
@@ -268,6 +268,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWriteIssuesOrPulls(false)
ctx.Data["CanWritePulls"] = ctx.Repo.CanWriteIssuesOrPulls(true)
+ ctx.Data["PageIsIssueList"] = true
ctx.HTML(200, tplMilestoneIssues)
}
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index d2a094bc8..a907aca01 100755
--- a/routers/repo/modelarts.go
+++ b/routers/repo/modelarts.go
@@ -11,11 +11,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/cloudbrain"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@@ -42,6 +41,7 @@ const (
func DebugJobIndex(ctx *context.Context) {
debugListType := ctx.Query("debugListType")
+ ctx.Data["ListType"] = debugListType
MustEnableCloudbrain(ctx)
repo := ctx.Repo.Repository
page := ctx.QueryInt("page")
@@ -49,12 +49,9 @@ func DebugJobIndex(ctx *context.Context) {
page = 1
}
debugType := modelarts.DebugType
- jobType := string(models.JobTypeDebug)
- if debugListType == modelarts.GPUResource {
+ if debugListType == models.GPUResource {
debugType = models.TypeCloudBrainOne
- jobType = ""
- }
- if debugListType == modelarts.NPUResource {
+ } else if debugListType == models.NPUResource {
debugType = models.TypeCloudBrainTwo
}
@@ -63,9 +60,10 @@ func DebugJobIndex(ctx *context.Context) {
Page: page,
PageSize: setting.UI.IssuePagingNum,
},
- RepoID: repo.ID,
- Type: debugType,
- JobType: jobType,
+ RepoID: repo.ID,
+ Type: debugType,
+ JobTypeNot: true,
+ JobType: string(models.JobTypeTrain),
})
if err != nil {
ctx.ServerError("Get debugjob faild:", err)
@@ -73,21 +71,13 @@ func DebugJobIndex(ctx *context.Context) {
}
for i, task := range ciTasks {
- if task.Cloudbrain.Type == models.TypeCloudBrainOne {
- ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
- ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
- ciTasks[i].Cloudbrain.ComputeResource = modelarts.GPUResource
- }
- if task.Cloudbrain.Type == models.TypeCloudBrainTwo {
- ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
- ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
- ciTasks[i].Cloudbrain.ComputeResource = modelarts.NPUResource
- }
-
+ ciTasks[i].CanDebug = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
+ ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
+ ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource
}
pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
- pager.SetDefaultParams(ctx)
+ pager.AddParam(ctx, "debugListType", "ListType")
ctx.Data["Page"] = pager
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["Tasks"] = ciTasks
@@ -156,7 +146,7 @@ func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm)
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookNew, &form)
return
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+ ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}
func NotebookShow(ctx *context.Context) {
@@ -232,38 +222,105 @@ func NotebookDebug(ctx *context.Context) {
ctx.Redirect(debugUrl)
}
-func NotebookStop(ctx *context.Context) {
+func NotebookManage(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- log.Info(jobID)
- task, err := models.GetCloudbrainByJobID(jobID)
- if err != nil {
- ctx.ServerError("GetCloudbrainByJobID failed", err)
- return
- }
+ var action = ctx.Params(":action")
+ var resultCode = "0"
+ var errorMsg = ""
+ var status = ""
- if task.Status != string(models.JobRunning) {
- log.Error("the job(%s) is not running", task.JobName)
- ctx.ServerError("the job is not running", errors.New("the job is not running"))
- return
- }
+ for {
+ task, err := models.GetCloudbrainByJobID(jobID)
+ if err != nil {
+ log.Error("GetCloudbrainByJobID failed:%v", err, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
- param := models.NotebookAction{
- Action: models.ActionStop,
- }
- res, err := modelarts.StopJob(jobID, param)
- if err != nil {
- log.Error("StopJob(%s) failed:%v", task.JobName, err.Error())
- ctx.ServerError("StopJob failed", err)
- return
- }
+ if action == models.ActionStop {
+ if task.Status != string(models.ModelArtsRunning) {
+ log.Error("the job(%s) is not running", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "the job is not running"
+ break
+ }
- task.Status = res.CurrentStatus
- err = models.UpdateJob(task)
- if err != nil {
- ctx.ServerError("UpdateJob failed", err)
- return
+ if !ctx.IsSigned || (ctx.User.ID != task.UserID && !ctx.IsUserSiteAdmin() && !ctx.IsUserRepoOwner()) {
+ log.Error("the user has no right ro stop the job", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "you have no right to stop the job"
+ break
+ }
+ } else if action == models.ActionRestart {
+ if task.Status != string(models.ModelArtsStopped) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsCreateFailed) {
+ log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "the job is not stopped"
+ break
+ }
+
+ if !ctx.IsSigned || (ctx.User.ID != task.UserID && !ctx.IsUserSiteAdmin()) {
+ log.Error("the user has no right ro restart the job", task.JobName, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "you have no right to restart the job"
+ break
+ }
+
+ count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID)
+ if err != nil {
+ log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "you have already a running or waiting task, can not create more"
+ break
+ }
+ }
+
+ action = models.ActionStart
+ } else {
+ log.Error("the action(%s) is illegal", action, ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "非法操作"
+ break
+ }
+
+ param := models.NotebookAction{
+ Action: action,
+ }
+ res, err := modelarts.ManageNotebook(jobID, param)
+ if err != nil {
+ log.Error("ManageNotebook(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "启动失败"
+ break
+ }
+
+ task.Status = res.CurrentStatus
+ err = models.UpdateJob(task)
+ if err != nil {
+ log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
+ resultCode = "-1"
+ errorMsg = "system error"
+ break
+ }
+
+ status = task.Status
+
+ break
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+
+ ctx.JSON(200, map[string]string{
+ "result_code": resultCode,
+ "error_msg": errorMsg,
+ "status": status,
+ "job_id": jobID,
+ })
}
func NotebookDel(ctx *context.Context) {
@@ -274,7 +331,7 @@ func NotebookDel(ctx *context.Context) {
return
}
- if task.Status != string(models.JobStopped) {
+ if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) {
log.Error("the job(%s) has not been stopped", task.JobName)
ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
return
@@ -293,7 +350,7 @@ func NotebookDel(ctx *context.Context) {
return
}
- ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
+ ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}
func TrainJobIndex(ctx *context.Context) {
@@ -312,6 +369,7 @@ func TrainJobIndex(ctx *context.Context) {
},
RepoID: repo.ID,
Type: models.TypeCloudBrainTwo,
+ JobTypeNot: false,
JobType: string(models.JobTypeTrain),
IsLatestVersion: modelarts.IsLatestVersion,
})
@@ -323,6 +381,7 @@ func TrainJobIndex(ctx *context.Context) {
for i, task := range tasks {
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
+ tasks[i].ComputeResource = models.NPUResource
}
pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
@@ -364,7 +423,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
ctx.Data["job_name"] = jobName
- attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
+ attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
if err != nil {
ctx.ServerError("GetAllUserAttachments failed:", err)
return err
@@ -433,7 +492,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts
var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
ctx.Data["job_name"] = jobName
- attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
+ attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
if err != nil {
ctx.ServerError("GetAllUserAttachments failed:", err)
return err
@@ -521,7 +580,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error {
var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
ctx.Data["job_name"] = task.JobName
- attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
+ attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
if err != nil {
ctx.ServerError("GetAllUserAttachments failed:", err)
return err
@@ -610,7 +669,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai
var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
ctx.Data["job_name"] = task.JobName
- attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
+ attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
if err != nil {
ctx.ServerError("GetAllUserAttachments failed:", err)
return err
@@ -1352,6 +1411,11 @@ func TrainJobDel(ctx *context.Context) {
}
}
+ //删除存储
+ if len(VersionListTasks) > 0 {
+ DeleteJobStorage(VersionListTasks[0].JobName)
+ }
+
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
}
@@ -1477,3 +1541,21 @@ func ModelDownload(ctx *context.Context) {
}
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
}
+
+func DeleteJobStorage(jobName string) error {
+ //delete local
+ localJobPath := setting.JobPath + jobName
+ err := os.RemoveAll(localJobPath)
+ if err != nil {
+ log.Error("RemoveAll(%s) failed:%v", localJobPath, err)
+ }
+
+ //delete oss
+ dirPath := setting.CodePathPrefix + jobName + "/"
+ err = storage.ObsRemoveObject(setting.Bucket, dirPath)
+ if err != nil {
+ log.Error("ObsRemoveObject(%s) failed:%v", localJobPath, err)
+ }
+
+ return nil
+}
diff --git a/routers/repo/view.go b/routers/repo/view.go
index a5f2e1477..b08243240 100755
--- a/routers/repo/view.go
+++ b/routers/repo/view.go
@@ -605,7 +605,7 @@ func getContributorInfo(contributorInfos []*ContributorInfo, email string) *Cont
func Home(ctx *context.Context) {
if len(ctx.Repo.Units) > 0 {
//get repo contributors info
- contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath())
+ contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), ctx.Repo.BranchName)
if err == nil && contributors != nil {
startTime := time.Now()
var contributorInfos []*ContributorInfo
@@ -924,7 +924,9 @@ func ContributorsAPI(ctx *context.Context) {
count := 0
errorCode := 0
errorMsg := ""
- contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath())
+
+ branchOrTag := ctx.Query("name")
+ contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), branchOrTag)
var contributorInfos []*ContributorInfo
if err == nil && contributors != nil {
contributorInfoHash := make(map[string]*ContributorInfo)
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 30e486b98..95931c723 100755
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -315,6 +315,8 @@ func RegisterRoutes(m *macaron.Macaron) {
})
m.Get("/", routers.Home)
m.Get("/dashboard", routers.Dashboard)
+ go routers.SocketManager.Run()
+ m.Get("/action/notification", routers.ActionNotification)
m.Get("/recommend/org", routers.RecommendOrgFromPromote)
m.Get("/recommend/repo", routers.RecommendRepoFromPromote)
m.Group("/explore", func() {
@@ -625,6 +627,10 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/org", func() {
m.Group("/:org", func() {
m.Get("/members", org.Members)
+ m.Group("/org_tag", func() {
+ m.Get("/repo_list", org.GetTagRepos)
+ m.Post("/repo_submit", bindIgnErr(auth.SubmitReposOfTagForm{}), org.SubmitTags)
+ })
}, context.OrgAssignment())
})
m.Group("/org", func() {
@@ -962,10 +968,11 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/cloudbrain", func() {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow)
- m.Get("/debug", reqRepoCloudBrainWriter, repo.CloudBrainDebug)
+ m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug)
m.Post("/commit_image", cloudbrain.AdminOrOwnerOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel)
+ m.Post("/restart", reqRepoCloudBrainWriter, repo.CloudBrainRestart)
m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate)
m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels)
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDownloadModel)
@@ -975,6 +982,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}, context.RepoRef())
m.Group("/modelmanage", func() {
m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel)
+ m.Post("/create_new_model", reqRepoModelManageWriter, repo.SaveNewNameModel)
m.Delete("/delete_model", repo.DeleteModel)
m.Put("/modify_model", repo.ModifyModelInfo)
m.Get("/show_model", reqRepoModelManageReader, repo.ShowModelTemplate)
@@ -999,8 +1007,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/notebook", func() {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.NotebookShow)
- m.Get("/debug", reqRepoCloudBrainWriter, repo.NotebookDebug)
- m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookStop)
+ m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug)
+ m.Post("/:action", reqRepoCloudBrainWriter, repo.NotebookManage)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookDel)
})
m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew)
diff --git a/services/socketwrap/client.go b/services/socketwrap/client.go
new file mode 100644
index 000000000..ce8dbb5e8
--- /dev/null
+++ b/services/socketwrap/client.go
@@ -0,0 +1,50 @@
+package socketwrap
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/log"
+ "github.com/gorilla/websocket"
+)
+
+type Client struct {
+ Manager *ClientsManager
+
+ Conn *websocket.Conn
+
+ Send chan *models.Action
+}
+
+func (c *Client) WritePump() {
+
+ defer func() {
+ c.Manager.Unregister <- c
+ c.Conn.Close()
+ }()
+ for {
+ select {
+ case message, ok := <-c.Send:
+
+ if !ok {
+ c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
+ log.Warn("send socket is closed")
+ return
+ }
+ log.Warn("socket:", message)
+ err := c.Conn.WriteJSON(message)
+ if err != nil {
+ log.Warn("can not send message", err)
+ return
+ }
+
+ n := len(c.Send)
+ for i := 0; i < n; i++ {
+ err = c.Conn.WriteJSON(<-c.Send)
+ if err != nil {
+ log.Warn("can not send message", err)
+ return
+ }
+ }
+
+ }
+ }
+}
diff --git a/services/socketwrap/clientManager.go b/services/socketwrap/clientManager.go
new file mode 100644
index 000000000..ac6ca0bed
--- /dev/null
+++ b/services/socketwrap/clientManager.go
@@ -0,0 +1,46 @@
+package socketwrap
+
+import (
+ "code.gitea.io/gitea/models"
+)
+
+type ClientsManager struct {
+ Clients map[*Client]bool
+ Register chan *Client
+ Unregister chan *Client
+}
+
+func NewClientsManager() *ClientsManager {
+ return &ClientsManager{
+ Register: make(chan *Client),
+ Unregister: make(chan *Client),
+ Clients: make(map[*Client]bool),
+ }
+}
+
+var LastTenActionsQueue = NewSyncQueue(10)
+
+func (h *ClientsManager) Run() {
+ for {
+ select {
+ case client := <-h.Register:
+ h.Clients[client] = true
+ case client := <-h.Unregister:
+ if _, ok := h.Clients[client]; ok {
+ delete(h.Clients, client)
+ close(client.Send)
+ }
+ case message := <-models.ActionChan:
+ LastTenActionsQueue.Push(message)
+ for client := range h.Clients {
+ select {
+ case client.Send <- message:
+ default:
+ close(client.Send)
+ delete(h.Clients, client)
+ }
+ }
+
+ }
+ }
+}
diff --git a/services/socketwrap/syncqueue.go b/services/socketwrap/syncqueue.go
new file mode 100644
index 000000000..c366ac23b
--- /dev/null
+++ b/services/socketwrap/syncqueue.go
@@ -0,0 +1,34 @@
+package socketwrap
+
+import (
+ "container/list"
+ "sync"
+)
+
+type SyncQueue struct {
+ Queue *list.List
+ Mutex *sync.RWMutex
+ MaxSize int
+}
+
+func (q *SyncQueue) Push(value interface{}) {
+ q.Mutex.Lock()
+ {
+ if q.Queue.Len() < q.MaxSize {
+ q.Queue.PushBack(value)
+ } else {
+ q.Queue.PushBack(value)
+ q.Queue.Remove(q.Queue.Front())
+ }
+ }
+
+ q.Mutex.Unlock()
+}
+
+func NewSyncQueue(maxSize int) *SyncQueue {
+ return &SyncQueue{
+ list.New(),
+ &sync.RWMutex{},
+ maxSize,
+ }
+}
diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl
index 7e9970d2b..e03c28a9e 100755
--- a/templates/org/home.tmpl
+++ b/templates/org/home.tmpl
@@ -20,10 +20,11 @@
-
- {{template "org/navber" .}}
-
-
+ {{template "org/navber" .}}
+ {{template "org/select_pro" .}}
+
+
+
{{if .CanCreateOrgRepo}}
diff --git a/templates/org/member/members.tmpl b/templates/org/member/members.tmpl
index 810a9eabb..87189c015 100644
--- a/templates/org/member/members.tmpl
+++ b/templates/org/member/members.tmpl
@@ -3,10 +3,11 @@
{{template "org/header" .}}
{{template "base/alert" .}}
+ {{template "org/navber" .}}
- {{template "org/navber" .}}
+
-
+
{{ range .Members}}
diff --git a/templates/org/navber.tmpl b/templates/org/navber.tmpl
index 7bb2ff69c..f7e88c1e9 100755
--- a/templates/org/navber.tmpl
+++ b/templates/org/navber.tmpl
@@ -1,4 +1,4 @@
-
+
-
+
\ No newline at end of file
+ -->
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/org/select_pro.tmpl b/templates/org/select_pro.tmpl
new file mode 100755
index 000000000..647bccd57
--- /dev/null
+++ b/templates/org/select_pro.tmpl
@@ -0,0 +1,319 @@
+
+
+
+ {{if .tags}}
+
+ 精选项目
+
+
+ {{if .IsOrganizationOwner}}
+ {{svg "octicon-gear" 16}}自定义
+ {{end}}
+ {{end}}
+
+
+
+ {{ range .tags}}
+ {{if eq .TagName "精选项目"}}
+
+
+ {{ range .RepoList}}
+
+
+
+
+
+ {{end}}
+
+
+ {{end}}
+ {{end}}
+
+
+
+
+
+
+
+ 自定义精选项目
+
+
+ 最多可选9个公开项目
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl
index 21bd47e9e..e7081b58f 100644
--- a/templates/org/team/teams.tmpl
+++ b/templates/org/team/teams.tmpl
@@ -3,12 +3,12 @@
{{template "org/header" .}}
{{template "base/alert" .}}
-
+ {{template "org/navber" .}}
- {{template "org/navber" .}}
+
-
+
{{range .Teams}}
diff --git a/templates/repo/cloudbrain/new.tmpl b/templates/repo/cloudbrain/new.tmpl
index 82f761c07..eb7805a23 100755
--- a/templates/repo/cloudbrain/new.tmpl
+++ b/templates/repo/cloudbrain/new.tmpl
@@ -93,6 +93,14 @@
display: none;
}
+ .icons{
+ /* position: absolute !important;
+ right: 150px;
+ top: 14px;
+ z-index: 2; */
+ }
+
+
@@ -182,9 +190,10 @@
-
+
+