| @@ -616,20 +616,20 @@ update-translations: | |||
| generate-images: | |||
| $(eval TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp')) | |||
| mkdir -p $(TMPDIR)/images | |||
| inkscape -f $(PWD)/assets/logo.svg -w 880 -h 880 -e $(PWD)/public/img/gitea-lg.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 512 -h 512 -e $(PWD)/public/img/gitea-512.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 192 -h 192 -e $(PWD)/public/img/gitea-192.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer1 -e $(TMPDIR)/images/sm-1.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer2 -e $(TMPDIR)/images/sm-2.png | |||
| inkscape $(PWD)/assets/logo.svg -w 880 -h 880 --export-filename=$(PWD)/public/img/gitea-lg.png | |||
| inkscape $(PWD)/assets/logo.svg -w 512 -h 512 --export-filename=$(PWD)/public/img/gitea-512.png | |||
| inkscape $(PWD)/assets/logo.svg -w 192 -h 192 --export-filename=$(PWD)/public/img/gitea-192.png | |||
| inkscape $(PWD)/assets/logo.svg -w 120 -h 120 --export-filename=$(TMPDIR)/images/sm-1.png | |||
| inkscape $(PWD)/assets/logo.svg -w 120 -h 120 --export-filename=$(TMPDIR)/images/sm-2.png | |||
| composite -compose atop $(TMPDIR)/images/sm-2.png $(TMPDIR)/images/sm-1.png $(PWD)/public/img/gitea-sm.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 200 -h 200 -e $(PWD)/public/img/avatar_default.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 180 -h 180 -e $(PWD)/public/img/favicon.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 128 -h 128 -e $(TMPDIR)/images/128-raw.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 64 -h 64 -e $(TMPDIR)/images/64-raw.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer1 -e $(TMPDIR)/images/32-1.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer2 -e $(TMPDIR)/images/32-2.png | |||
| inkscape $(PWD)/assets/logo.svg -w 200 -h 200 --export-filename=$(PWD)/public/img/avatar_default.png | |||
| inkscape $(PWD)/assets/logo.svg -w 180 -h 180 --export-filename=$(PWD)/public/img/favicon.png | |||
| inkscape $(PWD)/assets/logo.svg -w 128 -h 128 --export-filename=$(TMPDIR)/images/128-raw.png | |||
| inkscape $(PWD)/assets/logo.svg -w 64 -h 64 --export-filename=$(TMPDIR)/images/64-raw.png | |||
| inkscape $(PWD)/assets/logo.svg -w 32 -h 32 --export-filename=$(TMPDIR)/images/32-1.png | |||
| inkscape $(PWD)/assets/logo.svg -w 32 -h 32 --export-filename=$(TMPDIR)/images/32-2.png | |||
| composite -compose atop $(TMPDIR)/images/32-2.png $(TMPDIR)/images/32-1.png $(TMPDIR)/images/32-raw.png | |||
| inkscape -f $(PWD)/assets/logo.svg -w 16 -h 16 -jC -i layer1 -e $(TMPDIR)/images/16-raw.png | |||
| inkscape $(PWD)/assets/logo.svg -w 16 -h 16 --export-filename=$(TMPDIR)/images/16-raw.png | |||
| zopflipng -m -y $(TMPDIR)/images/128-raw.png $(TMPDIR)/images/128.png | |||
| zopflipng -m -y $(TMPDIR)/images/64-raw.png $(TMPDIR)/images/64.png | |||
| zopflipng -m -y $(TMPDIR)/images/32-raw.png $(TMPDIR)/images/32.png | |||
| @@ -1,160 +1,13 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
| <svg | |||
| xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
| xmlns:cc="http://creativecommons.org/ns#" | |||
| xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
| xmlns:svg="http://www.w3.org/2000/svg" | |||
| xmlns="http://www.w3.org/2000/svg" | |||
| xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
| xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
| width="512" | |||
| height="512" | |||
| viewBox="0 0 135.46667 135.46667" | |||
| version="1.1" | |||
| id="svg8" | |||
| sodipodi:docname="logo.svg" | |||
| inkscape:version="0.92.1 r15371" | |||
| inkscape:export-filename="" | |||
| inkscape:export-xdpi="48.000004" | |||
| inkscape:export-ydpi="48.000004"> | |||
| <defs | |||
| id="defs2" /> | |||
| <sodipodi:namedview | |||
| id="base" | |||
| pagecolor="#ffffff" | |||
| bordercolor="#666666" | |||
| borderopacity="1.0" | |||
| inkscape:pageopacity="0" | |||
| inkscape:pageshadow="2" | |||
| inkscape:zoom="0.70710678" | |||
| inkscape:cx="418.13805" | |||
| inkscape:cy="177.57445" | |||
| inkscape:document-units="mm" | |||
| inkscape:current-layer="layer2" | |||
| showgrid="false" | |||
| units="px" | |||
| width="256px" | |||
| showguides="false" | |||
| inkscape:window-width="1920" | |||
| inkscape:window-height="1137" | |||
| inkscape:window-x="1912" | |||
| inkscape:window-y="-8" | |||
| inkscape:window-maximized="1" | |||
| inkscape:pagecheckerboard="false" | |||
| inkscape:measure-start="283.373,243.952" | |||
| inkscape:measure-end="290.267,236.527"> | |||
| <sodipodi:guide | |||
| position="0,0" | |||
| orientation="0,512" | |||
| id="guide3699" | |||
| inkscape:locked="false" /> | |||
| <sodipodi:guide | |||
| position="135.46667,0" | |||
| orientation="-512,0" | |||
| id="guide3701" | |||
| inkscape:locked="false" /> | |||
| <sodipodi:guide | |||
| position="135.46667,135.46667" | |||
| orientation="0,-512" | |||
| id="guide3703" | |||
| inkscape:locked="false" /> | |||
| <sodipodi:guide | |||
| position="0,135.46667" | |||
| orientation="512,0" | |||
| id="guide3705" | |||
| inkscape:locked="false" /> | |||
| </sodipodi:namedview> | |||
| <metadata | |||
| id="metadata5"> | |||
| <rdf:RDF> | |||
| <cc:Work | |||
| rdf:about=""> | |||
| <dc:format>image/svg+xml</dc:format> | |||
| <dc:type | |||
| rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
| <dc:title></dc:title> | |||
| </cc:Work> | |||
| </rdf:RDF> | |||
| </metadata> | |||
| <g | |||
| inkscape:label="Layer 1" | |||
| inkscape:groupmode="layer" | |||
| id="layer1" | |||
| transform="translate(0,-161.53334)" | |||
| style="display:inline"> | |||
| <path | |||
| style="fill:#609926;fill-opacity:1;stroke:#428f29;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" | |||
| d="m 27.709937,195.15095 c -9.546573,-0.0272 -22.3392732,6.79805 -21.6317552,23.90397 1.105534,26.72889 25.4565952,29.20839 35.1916502,29.42301 1.068023,5.01357 12.521798,22.30563 21.001818,23.21667 h 37.15277 c 22.27763,-1.66785 38.9607,-75.75671 26.59321,-76.03825 -46.781583,2.47691 -49.995146,2.13838 -88.599758,0 -2.495053,-0.0266 -5.972321,-0.49474 -9.707935,-0.5054 z m 2.491319,9.45886 c 1.351378,13.69267 3.555849,21.70359 8.018216,33.94345 -11.382872,-1.50473 -21.069822,-5.22443 -22.851515,-19.10984 -0.950962,-7.4112 2.390428,-15.16769 14.833299,-14.83361 z" | |||
| id="path3722" | |||
| inkscape:connector-curvature="0" | |||
| sodipodi:nodetypes="sscccccsccsc" /> | |||
| </g> | |||
| <g | |||
| inkscape:groupmode="layer" | |||
| id="layer2" | |||
| inkscape:label="Layer 2" | |||
| style="display:inline"> | |||
| <rect | |||
| style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.24757317;stroke-opacity:1" | |||
| id="rect4599" | |||
| width="34.762054" | |||
| height="34.762054" | |||
| x="87.508659" | |||
| y="18.291576" | |||
| transform="rotate(25.914715)" | |||
| ry="5.4825778" /> | |||
| <path | |||
| style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26644793px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | |||
| d="m 79.804947,57.359056 3.241146,1.609954 V 35.255731 h -3.262698 z" | |||
| id="path4525" | |||
| inkscape:connector-curvature="0" | |||
| sodipodi:nodetypes="ccccc" /> | |||
| </g> | |||
| <g | |||
| inkscape:groupmode="layer" | |||
| id="layer3" | |||
| inkscape:label="Layer 3" | |||
| style="display:inline"> | |||
| <g | |||
| style="display:inline" | |||
| id="g4539"> | |||
| <circle | |||
| transform="rotate(-19.796137)" | |||
| r="3.4745038" | |||
| cy="90.077766" | |||
| cx="49.064713" | |||
| id="path4606" | |||
| style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" /> | |||
| <circle | |||
| transform="rotate(-19.796137)" | |||
| r="3.4745038" | |||
| cy="102.1049" | |||
| cx="36.810425" | |||
| id="path4606-3" | |||
| style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" /> | |||
| <circle | |||
| transform="rotate(-19.796137)" | |||
| r="3.4745038" | |||
| cy="111.43928" | |||
| cx="46.484283" | |||
| id="path4606-1" | |||
| style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" /> | |||
| <rect | |||
| transform="rotate(26.024158)" | |||
| y="18.061695" | |||
| x="97.333458" | |||
| height="27.261492" | |||
| width="2.6726954" | |||
| id="rect4629-8" | |||
| style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.27444693;stroke-opacity:1" /> | |||
| <path | |||
| sodipodi:nodetypes="cc" | |||
| inkscape:connector-curvature="0" | |||
| id="path4514" | |||
| d="m 76.558096,68.116343 c 12.97589,6.395378 13.012989,4.101862 4.890858,20.907244" | |||
| style="fill:none;stroke:#609926;stroke-width:2.68000007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |||
| </g> | |||
| </g> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
| <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
| viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve"> | |||
| <style type="text/css"> | |||
| .st0{fill:#036EFF;} | |||
| </style> | |||
| <path class="st0" d="M892.63,193.98L598.19,23.99c-53.06-30.64-118.43-30.64-171.49,0L132.26,193.98 | |||
| C79.2,224.62,46.51,281.23,46.51,342.5v339.99c0,61.27,32.69,117.88,85.75,148.52L426.7,1001c53.06,30.63,118.43,30.63,171.49,0 | |||
| l294.44-169.99c53.06-30.64,85.75-87.25,85.75-148.52V342.5C978.38,281.23,945.69,224.62,892.63,193.98z M587.45,824.49 | |||
| c0,41.43-33.58,75-75,75c-41.43,0-75-33.57-75-75v-624c0-41.42,33.57-75,75-75c20.71,0,39.46,8.39,53.03,21.97 | |||
| c13.58,13.57,21.97,32.32,21.97,53.03V824.49z"/> | |||
| </svg> | |||
| @@ -43,6 +43,8 @@ type Attachment struct { | |||
| DecompressState int32 `xorm:"DEFAULT 0"` | |||
| Type int `xorm:"DEFAULT 0"` | |||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||
| FileChunk *FileChunk `xorm:"-"` | |||
| } | |||
| type AttachmentUsername struct { | |||
| @@ -171,6 +171,7 @@ type TaskInfo struct { | |||
| CodeName string `json:"code_name"` | |||
| BenchmarkCategory []string `json:"selected_category"` | |||
| CodeLink string `json:"code_link"` | |||
| GpuType string `json:"gpu_type"` | |||
| } | |||
| func ConvertToTaskPod(input map[string]interface{}) (TaskPod, error) { | |||
| @@ -280,6 +281,16 @@ type Category struct { | |||
| Value string `json:"value"` | |||
| } | |||
| type GpuInfos struct { | |||
| GpuInfo []*GpuInfo `json:"gpu_type"` | |||
| } | |||
| type GpuInfo struct { | |||
| Id int `json:"id"` | |||
| Value string `json:"value"` | |||
| Queue string `json:"queue"` | |||
| } | |||
| type CommitImageParams struct { | |||
| Ip string `json:"ip"` | |||
| TaskContainerId string `json:"taskContainerId"` | |||
| @@ -235,6 +235,14 @@ func getDatasetAttachments(e Engine, typeCloudBrain int, rels ...*Dataset) (err | |||
| for sortedRels.ID[currentIndex] < attachment.DatasetID { | |||
| currentIndex++ | |||
| } | |||
| fileChunks := make([]*FileChunk, 0, 10) | |||
| err = e. | |||
| Where("uuid = ?", attachment.UUID). | |||
| Find(&fileChunks) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| attachment.FileChunk = fileChunks[0] | |||
| sortedRels.Rel[currentIndex].Attachments = append(sortedRels.Rel[currentIndex].Attachments, attachment) | |||
| } | |||
| @@ -6,14 +6,12 @@ | |||
| package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/blockchain" | |||
| "context" | |||
| "crypto/md5" | |||
| "errors" | |||
| "fmt" | |||
| "html/template" | |||
| "sync" | |||
| "code.gitea.io/gitea/modules/blockchain" | |||
| // Needed for jpeg support | |||
| _ "image/jpeg" | |||
| @@ -2409,15 +2407,6 @@ func (repo *Repository) GetTreePathLock(treePath string) (*LFSLock, error) { | |||
| return nil, nil | |||
| } | |||
| var lck sync.Mutex | |||
| func (repo *Repository) IncreaseCloneCnt() { | |||
| lck.Lock() | |||
| defer lck.Unlock() | |||
| repo.CloneCnt++ | |||
| _ = UpdateRepositoryCols(repo, "clone_cnt") | |||
| } | |||
| func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error { | |||
| _, err := e.ID(repo.ID).Cols(cols...).Update(repo) | |||
| return err | |||
| @@ -2434,3 +2423,21 @@ func GetBlockChainUnSuccessRepos() ([]*Repository, error) { | |||
| Where("block_chain_status != ?", RepoBlockChainSuccess). | |||
| Find(&repos) | |||
| } | |||
| func (repo *Repository) IncreaseCloneCnt() { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| if err := sess.Begin(); err != nil { | |||
| return | |||
| } | |||
| if _, err := sess.Exec("UPDATE `repository` SET clone_cnt = clone_cnt + 1 WHERE id = ?", repo.ID); err != nil { | |||
| return | |||
| } | |||
| if err := sess.Commit(); err != nil { | |||
| return | |||
| } | |||
| return | |||
| } | |||
| @@ -12,6 +12,7 @@ type CreateCloudBrainForm struct { | |||
| Attachment string `form:"attachment" binding:"Required"` | |||
| JobType string `form:"job_type" binding:"Required"` | |||
| BenchmarkCategory string `form:"get_benchmark_category"` | |||
| GpuType string `form:"gpu_type"` | |||
| } | |||
| type CommitImageCloudBrainForm struct { | |||
| @@ -31,4 +31,5 @@ type EditDatasetForm struct { | |||
| Private bool | |||
| ReleaseID int64 `xorm:"INDEX"` | |||
| Files []string | |||
| Type string `binding:"Required"` | |||
| } | |||
| @@ -21,6 +21,7 @@ import ( | |||
| "strings" | |||
| "time" | |||
| "unicode" | |||
| "unicode/utf8" | |||
| "code.gitea.io/gitea/modules/git" | |||
| "code.gitea.io/gitea/modules/log" | |||
| @@ -287,19 +288,19 @@ func EllipsisString(str string, length int) string { | |||
| if length <= 3 { | |||
| return "..." | |||
| } | |||
| if len(str) <= length { | |||
| if utf8.RuneCountInString(str) <= length { | |||
| return str | |||
| } | |||
| return str[:length-3] + "..." | |||
| return string([]rune(str)[:length-3]) + "..." | |||
| } | |||
| // TruncateString returns a truncated string with given limit, | |||
| // it returns input string if length is not reached limit. | |||
| func TruncateString(str string, limit int) string { | |||
| if len(str) < limit { | |||
| if utf8.RuneCountInString(str) < limit { | |||
| return str | |||
| } | |||
| return str[:limit] | |||
| return string([]rune(str)[:limit]) | |||
| } | |||
| // StringsToInt64s converts a slice of string to a slice of int64. | |||
| @@ -23,7 +23,7 @@ const ( | |||
| Success = "S000" | |||
| ) | |||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType string) error { | |||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string) error { | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| @@ -32,7 +32,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||
| jobResult, err := CreateJob(jobName, models.CreateJobParams{ | |||
| JobName: jobName, | |||
| RetryCount: 1, | |||
| GpuType: setting.JobType, | |||
| GpuType: gpuQueue, | |||
| Image: image, | |||
| TaskRoles: []models.TaskRole{ | |||
| { | |||
| @@ -1,6 +1,7 @@ | |||
| package cloudbrain | |||
| import ( | |||
| "code.gitea.io/gitea/modules/log" | |||
| "fmt" | |||
| "code.gitea.io/gitea/models" | |||
| @@ -14,6 +15,10 @@ var ( | |||
| TOKEN string | |||
| ) | |||
| const ( | |||
| JobHasBeenStopped = "S410" | |||
| ) | |||
| func getRestyClient() *resty.Client { | |||
| if restyClient == nil { | |||
| restyClient = resty.New() | |||
| @@ -240,7 +245,11 @@ sendjob: | |||
| } | |||
| if result.Code != Success { | |||
| return fmt.Errorf("StopJob err: %s", res.String()) | |||
| if result.Code == JobHasBeenStopped { | |||
| log.Info("StopJob(%s) failed:%s", jobID, result.Msg) | |||
| } else { | |||
| return fmt.Errorf("StopJob err: %s", res.String()) | |||
| } | |||
| } | |||
| return nil | |||
| @@ -67,19 +67,43 @@ func (l *Logger) Log(skip int, level Level, format string, v ...interface{}) err | |||
| caller = fn.Name() + "()" | |||
| } | |||
| } | |||
| msg := format | |||
| if len(v) > 0 { | |||
| msg = ColorSprintf(format, v...) | |||
| } | |||
| stack := "" | |||
| if l.GetStacktraceLevel() <= level { | |||
| stack = Stack(skip + 1) | |||
| } | |||
| return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, stack) | |||
| msg := format | |||
| if len(v) > 0 { | |||
| switch v[len(v)-1].(type) { | |||
| case string: | |||
| if !strings.Contains(v[len(v)-1].(string), "-") { | |||
| //has no msgID | |||
| msg = ColorSprintf(format, v...) | |||
| return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack) | |||
| } else { | |||
| if len(v) > 1 { | |||
| args := make([]interface{}, len(v)-1) | |||
| for i := 0; i < len(v)-1; i++ { | |||
| args[i] = v[i] | |||
| } | |||
| msg = ColorSprintf(format, args...) | |||
| } | |||
| return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, v[len(v)-1].(string), stack) | |||
| } | |||
| default: | |||
| //has no msgID | |||
| msg = ColorSprintf(format, v...) | |||
| return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack) | |||
| } | |||
| } else { | |||
| //has no msgID | |||
| return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack) | |||
| } | |||
| } | |||
| // SendLog sends a log event at the provided level with the information given | |||
| func (l *Logger) SendLog(level Level, caller, filename string, line int, msg string, stack string) error { | |||
| func (l *Logger) SendLog(level Level, caller, filename string, line int, msg, msgID, stack string) error { | |||
| if l.GetLevel() > level { | |||
| return nil | |||
| } | |||
| @@ -88,7 +112,7 @@ func (l *Logger) SendLog(level Level, caller, filename string, line int, msg str | |||
| caller: caller, | |||
| filename: filename, | |||
| line: line, | |||
| msg: msg, | |||
| msg: msg + "[" + msgID + "]", | |||
| time: time.Now(), | |||
| stacktrace: stack, | |||
| } | |||
| @@ -437,6 +437,7 @@ var ( | |||
| RestServerHost string | |||
| JobPath string | |||
| JobType string | |||
| GpuTypes string | |||
| DebugServerHost string | |||
| //benchmark config | |||
| @@ -1146,7 +1147,8 @@ func NewContext() { | |||
| RestServerHost = sec.Key("REST_SERVER_HOST").MustString("http://192.168.202.73") | |||
| JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/") | |||
| DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | |||
| JobType = sec.Key("JOB_TYPE").MustString("debug_openi") | |||
| JobType = sec.Key("GPU_TYPE_DEFAULT").MustString("openidebug") | |||
| GpuTypes = sec.Key("GPU_TYPES").MustString("openidebug,openidgx") | |||
| sec = Cfg.Section("benchmark") | |||
| IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | |||
| @@ -83,7 +83,7 @@ func (m *MinioStorage) PresignedGetURL(path string, fileName string) (string, er | |||
| reqParams.Set("response-content-disposition", "attachment; filename=\""+fileName+"\"") | |||
| var preURL *url.URL | |||
| preURL, err := m.client.PresignedGetObject(m.bucket, m.buildMinioPath(path), PresignedGetUrlExpireTime, reqParams) | |||
| preURL, err := m.client.PresignedGetObject(m.bucket, path, PresignedGetUrlExpireTime, reqParams) | |||
| if err != nil { | |||
| return "", err | |||
| } | |||
| @@ -391,7 +391,8 @@ follow = Follow | |||
| unfollow = Unfollow | |||
| heatmap.loading = Loading Heatmap… | |||
| user_bio = Biography | |||
| own = Own | |||
| all = All | |||
| form.name_reserved = The username '%s' is reserved. | |||
| form.name_pattern_not_allowed = The pattern '%s' is not allowed in a username. | |||
| form.name_chars_not_allowed = User name '%s' contains invalid characters. | |||
| @@ -753,6 +754,7 @@ cloudbrain.new=New cloudbrain | |||
| cloudbrain.desc=cloudbrain | |||
| cloudbrain.cancel=Cancel | |||
| cloudbrain.commit_image = submit | |||
| clone_cnt=download | |||
| balance = balance | |||
| balance.total_view = total balance | |||
| balance.available = available balance: | |||
| @@ -1,4 +1,5 @@ | |||
| home=个人中心 | |||
| index=首页 | |||
| dashboard=个人中心 | |||
| explore=探索 | |||
| datasets=数据集 | |||
| @@ -391,7 +392,8 @@ follow=关注 | |||
| unfollow=取消关注 | |||
| heatmap.loading=正在加载热图... | |||
| user_bio=简历 | |||
| own = 个人 | |||
| all = 所有 | |||
| form.name_reserved='%s' 用户名被保留。 | |||
| form.name_pattern_not_allowed=用户名中不允许使用 "%s"。 | |||
| form.name_chars_not_allowed=用户名 '%s' 包含无效字符。 | |||
| @@ -642,6 +644,7 @@ public=公有 | |||
| dir=目录 | |||
| back=返回 | |||
| copy_url=复制下载链接 | |||
| copy_md5=复制文件MD5 | |||
| directory=查看数据集目录结构 | |||
| visibility=可见性 | |||
| visibility_description=只有组织所有人或拥有权利的组织成员才能看到。 | |||
| @@ -753,6 +756,7 @@ cloudbrain.new=新建任务 | |||
| cloudbrain.desc=云脑功能 | |||
| cloudbrain.cancel=取消 | |||
| cloudbrain.commit_image=提交 | |||
| clone_cnt=次下载 | |||
| balance=余额 | |||
| balance.total_view=余额总览 | |||
| balance.available=可用余额: | |||
| @@ -205,7 +205,7 @@ func GetAttachment(ctx *context.Context) { | |||
| if setting.Attachment.StoreType == storage.MinioStorageType { | |||
| url := "" | |||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||
| url, err = storage.Attachments.PresignedGetURL(attach.RelativePath(), attach.Name) | |||
| url, err = storage.Attachments.PresignedGetURL(setting.Attachment.Minio.BasePath + attach.RelativePath(), attach.Name) | |||
| if err != nil { | |||
| ctx.ServerError("PresignedGetURL", err) | |||
| return | |||
| @@ -28,14 +28,14 @@ const ( | |||
| func BlockChainIndex(ctx *context.Context) { | |||
| repo := ctx.Repo.Repository | |||
| if repo.ContractAddress == "" || ctx.User.PublicKey == "" { | |||
| log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID) | |||
| log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID, ctx.Data["msgID"]) | |||
| ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) | |||
| return | |||
| } | |||
| res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey) | |||
| if err != nil { | |||
| log.Error("GetBalance(%s) failed:%v", ctx.User.PublicKey, err) | |||
| log.Error("GetBalance(%s) failed:%s", ctx.User.PublicKey, err, ctx.Data["msgID"]) | |||
| ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) | |||
| return | |||
| } | |||
| @@ -52,7 +52,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) { | |||
| repo, err := models.GetRepositoryByID(req.RepoId) | |||
| if err != nil { | |||
| log.Error("GetRepositoryByID failed:", err.Error()) | |||
| log.Error("GetRepositoryByID failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "internal error", | |||
| @@ -61,7 +61,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) { | |||
| } | |||
| if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 { | |||
| log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId) | |||
| log.Error("the repo has been RepoBlockChainSuccess:%d", req.RepoId, ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "the repo has been RepoBlockChainSuccess", | |||
| @@ -73,7 +73,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) { | |||
| repo.ContractAddress = req.ContractAddress | |||
| if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { | |||
| log.Error("UpdateRepositoryCols failed:", err.Error()) | |||
| log.Error("UpdateRepositoryCols failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "internal error", | |||
| @@ -91,7 +91,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) { | |||
| var req BlockChainCommitNotify | |||
| data, _ := ctx.Req.Body().Bytes() | |||
| if err := json.Unmarshal(data, &req); err != nil { | |||
| log.Error("json.Unmarshal failed:", err.Error()) | |||
| log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "response data error", | |||
| @@ -101,7 +101,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) { | |||
| blockChain, err := models.GetBlockChainByCommitID(req.CommitID) | |||
| if err != nil { | |||
| log.Error("GetRepositoryByID failed:", err.Error()) | |||
| log.Error("GetRepositoryByID failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "internal error", | |||
| @@ -110,7 +110,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) { | |||
| } | |||
| if blockChain.Status == models.BlockChainCommitSuccess { | |||
| log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID) | |||
| log.Error("the commit has been BlockChainCommitReady:%s", blockChain.RepoID, ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "the commit has been BlockChainCommitReady", | |||
| @@ -122,7 +122,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) { | |||
| blockChain.TransactionHash = req.TransactionHash | |||
| if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil { | |||
| log.Error("UpdateBlockChainCols failed:", err.Error()) | |||
| log.Error("UpdateBlockChainCols failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| "message": "internal error", | |||
| @@ -2,8 +2,10 @@ package repo | |||
| import ( | |||
| "code.gitea.io/gitea/modules/git" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "encoding/json" | |||
| "errors" | |||
| "net/http" | |||
| "os" | |||
| "os/exec" | |||
| "strconv" | |||
| @@ -23,6 +25,12 @@ const ( | |||
| tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | |||
| tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | |||
| tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | |||
| tplCloudBrainShowModels base.TplName = "repo/cloudbrain/models/index" | |||
| ) | |||
| var ( | |||
| gpuInfos *models.GpuInfos | |||
| categories *models.Categories | |||
| ) | |||
| // MustEnableDataset check if repository enable internal cb | |||
| @@ -88,7 +96,7 @@ func CloudBrainNew(ctx *context.Context) { | |||
| result, err := cloudbrain.GetImages() | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| log.Error("cloudbrain.GetImages failed:", err.Error()) | |||
| log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["msgID"]) | |||
| } | |||
| for i, payload := range result.Payload.ImageInfo { | |||
| @@ -104,7 +112,7 @@ func CloudBrainNew(ctx *context.Context) { | |||
| resultPublic, err := cloudbrain.GetPublicImages() | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| log.Error("cloudbrain.GetPublicImages failed:", err.Error()) | |||
| log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["msgID"]) | |||
| } | |||
| for i, payload := range resultPublic.Payload.ImageInfo { | |||
| @@ -131,9 +139,15 @@ func CloudBrainNew(ctx *context.Context) { | |||
| ctx.Data["benchmark_path"] = cloudbrain.BenchMarkMountPath | |||
| ctx.Data["is_benchmark_enabled"] = setting.IsBenchmarkEnabled | |||
| var categories *models.Categories | |||
| json.Unmarshal([]byte(setting.BenchmarkCategory), &categories) | |||
| if categories == nil { | |||
| json.Unmarshal([]byte(setting.BenchmarkCategory), &categories) | |||
| } | |||
| ctx.Data["benchmark_categories"] = categories.Category | |||
| if gpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||
| } | |||
| ctx.Data["gpu_types"] = gpuInfos.GpuInfo | |||
| ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | |||
| ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | |||
| ctx.HTML(200, tplCloudBrainNew) | |||
| @@ -146,10 +160,11 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| command := form.Command | |||
| uuid := form.Attachment | |||
| jobType := form.JobType | |||
| gpuQueue := setting.JobType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) { | |||
| log.Error("jobtype error:", jobType) | |||
| log.Error("jobtype error:", jobType, ctx.Data["msgID"]) | |||
| ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) | |||
| return | |||
| } | |||
| @@ -165,15 +180,22 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath | |||
| if setting.IsBenchmarkEnabled && jobType == string(models.JobTypeBenchmark) { | |||
| downloadRateCode(repo, jobName, setting.BenchmarkCode, benchmarkPath, form.BenchmarkCategory) | |||
| gpuQueue = form.GpuType | |||
| var gpuType string | |||
| for _, gpuInfo := range gpuInfos.GpuInfo { | |||
| if gpuInfo.Queue == gpuQueue { | |||
| gpuType = gpuInfo.Value | |||
| } | |||
| } | |||
| downloadRateCode(repo, jobName, setting.BenchmarkCode, benchmarkPath, form.BenchmarkCategory, gpuType) | |||
| } | |||
| snn4imagenetPath := setting.JobPath + jobName + cloudbrain.Snn4imagenetMountPath | |||
| if setting.IsSnn4imagenetEnabled && jobType == string(models.JobTypeSnn4imagenet) { | |||
| downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "") | |||
| downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "", "") | |||
| } | |||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType) | |||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue) | |||
| if err != nil { | |||
| ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | |||
| return | |||
| @@ -245,7 +267,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain | |||
| ImageTag: form.Tag, | |||
| }) | |||
| if err != nil { | |||
| log.Error("CommitImage(%s) failed:", task.JobName, err.Error()) | |||
| log.Error("CommitImage(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "result_code": "-1", | |||
| "error_msg": "CommitImage failed", | |||
| @@ -268,14 +290,14 @@ func CloudBrainStop(ctx *context.Context) { | |||
| } | |||
| if task.Status == string(models.JobStopped) { | |||
| log.Error("the job(%s) has been stopped", task.JobName) | |||
| 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 | |||
| } | |||
| err = cloudbrain.StopJob(jobID) | |||
| if err != nil { | |||
| log.Error("StopJob(%s) failed:%v", task.JobName, err.Error()) | |||
| log.Error("StopJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("StopJob failed", err) | |||
| return | |||
| } | |||
| @@ -299,7 +321,7 @@ func CloudBrainDel(ctx *context.Context) { | |||
| } | |||
| if task.Status != string(models.JobStopped) { | |||
| log.Error("the job(%s) has not been stopped", task.JobName) | |||
| log.Error("the job(%s) has not been stopped", task.JobName, ctx.Data["msgID"]) | |||
| ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped")) | |||
| return | |||
| } | |||
| @@ -313,6 +335,69 @@ func CloudBrainDel(ctx *context.Context) { | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain") | |||
| } | |||
| func CloudBrainShowModels(ctx *context.Context) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| jobID := ctx.Params(":jobid") | |||
| parentDir := ctx.Query("parentDir") | |||
| dirArray := strings.Split(parentDir, "/") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| log.Error("no such job!", ctx.Data["msgID"]) | |||
| ctx.ServerError("no such job:", err) | |||
| return | |||
| } | |||
| //get dirs | |||
| dirs, err := getModelDirs(task.JobName, parentDir) | |||
| if err != nil { | |||
| log.Error("getModelDirs failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("getModelDirs failed:", err) | |||
| return | |||
| } | |||
| var fileInfos []FileInfo | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return | |||
| } | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["task"] = task | |||
| ctx.Data["JobID"] = jobID | |||
| ctx.HTML(200, tplCloudBrainShowModels) | |||
| } | |||
| func getModelDirs(jobName string, parentDir string) (string, error) { | |||
| var req string | |||
| modelActualPath := setting.JobPath + jobName + "/model/" | |||
| if parentDir == "" { | |||
| req = "baseDir=" + modelActualPath | |||
| } else { | |||
| req = "baseDir=" + modelActualPath + "&parentDir=" + parentDir | |||
| } | |||
| return getDirs(req) | |||
| } | |||
| func CloudBrainDownloadModel(ctx *context.Context) { | |||
| parentDir := ctx.Query("parentDir") | |||
| fileName := ctx.Query("fileName") | |||
| jobName := ctx.Query("jobName") | |||
| filePath := "jobs/" +jobName + "/model/" + parentDir | |||
| url, err := storage.Attachments.PresignedGetURL(filePath, fileName) | |||
| if err != nil { | |||
| log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("PresignedGetURL", err) | |||
| return | |||
| } | |||
| http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) | |||
| } | |||
| func GetRate(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| @@ -322,11 +407,11 @@ func GetRate(ctx *context.Context) { | |||
| } | |||
| if job.JobType == string(models.JobTypeBenchmark) { | |||
| ctx.Redirect(setting.BenchmarkServerHost) | |||
| ctx.Redirect(setting.BenchmarkServerHost + "?username=" + ctx.User.Name) | |||
| } else if job.JobType == string(models.JobTypeSnn4imagenet) { | |||
| ctx.Redirect(setting.Snn4imagenetServerHost) | |||
| } else { | |||
| log.Error("JobType error:", job.JobType) | |||
| log.Error("JobType error:%s", job.JobType, ctx.Data["msgID"]) | |||
| } | |||
| } | |||
| @@ -339,7 +424,7 @@ func downloadCode(repo *models.Repository, codePath string) error { | |||
| return nil | |||
| } | |||
| func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benchmarkCategory string) error { | |||
| func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benchmarkCategory, gpuType string) error { | |||
| err := os.MkdirAll(codePath, os.ModePerm) | |||
| if err != nil { | |||
| log.Error("mkdir codePath failed", err.Error()) | |||
| @@ -370,6 +455,7 @@ func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benc | |||
| CodeName: repo.Name, | |||
| BenchmarkCategory: strings.Split(benchmarkCategory, ","), | |||
| CodeLink: strings.TrimSuffix(repo.CloneLink().HTTPS, ".git"), | |||
| GpuType: gpuType, | |||
| }) | |||
| if err != nil { | |||
| log.Error("json.Marshal failed", err.Error()) | |||
| @@ -49,6 +49,12 @@ func DatasetIndex(ctx *context.Context) { | |||
| ctx.NotFound("GetDatasetByRepo", err) | |||
| return | |||
| } | |||
| if ctx.Query("type") == "" { | |||
| log.Error("not found param type") | |||
| ctx.NotFound("type error", nil) | |||
| return | |||
| } | |||
| err = models.GetDatasetAttachments(ctx.QueryInt("type"), dataset) | |||
| if err != nil { | |||
| ctx.ServerError("GetDatasetAttachments", err) | |||
| @@ -116,5 +122,5 @@ func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | |||
| ctx.HTML(200, tplIndex) | |||
| log.Error("%v", err) | |||
| } | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/datasets") | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/datasets?type=" + form.Type) | |||
| } | |||
| @@ -58,10 +58,10 @@ func DirIndex(ctx *context.Context) { | |||
| dirArray = []string{attachment.Name} | |||
| } | |||
| dirs, err := getDirs(uuid, parentDir) | |||
| dirs, err := getDatasetDirs(uuid, parentDir) | |||
| if err != nil { | |||
| log.Error("getDirs failed:", err.Error()) | |||
| ctx.ServerError("getDirs failed:", err) | |||
| log.Error("getDatasetDirs failed:", err.Error()) | |||
| ctx.ServerError("getDatasetDirs failed:", err) | |||
| return | |||
| } | |||
| @@ -75,20 +75,31 @@ func DirIndex(ctx *context.Context) { | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["Uuid"] = uuid | |||
| ctx.Data["PageIsDataset"] = true | |||
| ctx.HTML(200, tplDirIndex) | |||
| } | |||
| func getDirs(uuid string, parentDir string) (string, error) { | |||
| var dirs string | |||
| func getDatasetDirs(uuid string, parentDir string) (string, error) { | |||
| var req string | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| models.AttachmentRelativePath(uuid) + | |||
| uuid + "/" | |||
| if parentDir == "" { | |||
| req = "uuid=" + uuid | |||
| req = "baseDir=" + dataActualPath | |||
| } else { | |||
| req = "uuid=" + uuid + "&parentDir=" + parentDir | |||
| req = "baseDir=" + dataActualPath + "&parentDir=" + parentDir | |||
| } | |||
| return getDirs(req) | |||
| } | |||
| func getDirs(req string) (string, error) { | |||
| var dirs string | |||
| url := setting.DecompressAddress + "/dirs?" + req | |||
| reqHttp, err := http.NewRequest(http.MethodGet, url, nil) | |||
| if err != nil { | |||
| @@ -127,6 +138,5 @@ func getDirs(uuid string, parentDir string) (string, error) { | |||
| } | |||
| dirs = resp.FileInfos | |||
| return dirs, nil | |||
| } | |||
| @@ -8,6 +8,7 @@ package repo | |||
| import ( | |||
| "fmt" | |||
| "io" | |||
| "net/url" | |||
| "path" | |||
| "strings" | |||
| @@ -32,6 +33,7 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error { | |||
| // Google Chrome dislike commas in filenames, so let's change it to a space | |||
| name = strings.Replace(name, ",", " ", -1) | |||
| name = url.QueryEscape(name) | |||
| if base.IsTextFile(buf) || ctx.QueryBool("render") { | |||
| cs, err := charset.DetectEncoding(buf) | |||
| @@ -49,6 +49,7 @@ import ( | |||
| "gitea.com/macaron/session" | |||
| "gitea.com/macaron/toolbox" | |||
| "github.com/prometheus/client_golang/prometheus" | |||
| gouuid "github.com/satori/go.uuid" | |||
| "github.com/tstranex/u2f" | |||
| ) | |||
| @@ -85,7 +86,7 @@ func setupAccessLogger(m *macaron.Macaron) { | |||
| log.Error("Could not set up macaron access logger: %v", err.Error()) | |||
| } | |||
| err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "") | |||
| err = logger.SendLog(log.INFO, "", "", 0, buf.String(), ctx.Data["msgID"].(string), "") | |||
| if err != nil { | |||
| log.Error("Could not set up macaron access logger: %v", err.Error()) | |||
| } | |||
| @@ -107,6 +108,24 @@ func RouterHandler(level log.Level) func(ctx *macaron.Context) { | |||
| } | |||
| } | |||
| // SetLogMsgID set msgID in Context | |||
| func SetLogMsgID() func(ctx *macaron.Context) { | |||
| return func(ctx *macaron.Context) { | |||
| start := time.Now() | |||
| uuid := gouuid.NewV4().String() | |||
| ctx.Data["MsgID"] = uuid | |||
| log.Info("Started %s %s for %s", log.ColoredMethod(ctx.Req.Method), ctx.Req.URL.RequestURI(), ctx.RemoteAddr(), ctx.Data["MsgID"]) | |||
| rw := ctx.Resp.(macaron.ResponseWriter) | |||
| ctx.Next() | |||
| status := rw.Status() | |||
| log.Info("Completed %s %s %v %s in %v", log.ColoredMethod(ctx.Req.Method), ctx.Req.URL.RequestURI(), log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(rw.Status())), log.ColoredTime(time.Since(start)), ctx.Data["MsgID"]) | |||
| } | |||
| } | |||
| // NewMacaron initializes Macaron instance. | |||
| func NewMacaron() *macaron.Macaron { | |||
| gob.Register(&u2f.Challenge{}) | |||
| @@ -125,6 +144,7 @@ func NewMacaron() *macaron.Macaron { | |||
| m.Use(macaron.Logger()) | |||
| } | |||
| } | |||
| m.Use(SetLogMsgID()) | |||
| // Access Logger is similar to Router Log but more configurable and by default is more like the NCSA Common Log format | |||
| if setting.EnableAccessLog { | |||
| setupAccessLogger(m) | |||
| @@ -285,7 +305,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Head("/", func() string { | |||
| return "" | |||
| }) | |||
| m.Get("/", routers.Home) | |||
| m.Get("/", routers.ExploreRepos) | |||
| m.Get("/dashboard", routers.Dashboard) | |||
| m.Group("/explore", func() { | |||
| m.Get("", func(ctx *context.Context) { | |||
| @@ -910,9 +930,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | |||
| m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | |||
| m.Post("/del", reqRepoCloudBrainWriter, repo.CloudBrainDel) | |||
| m.Get("/rate", reqRepoCloudBrainWriter, repo.GetRate) | |||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | |||
| m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) | |||
| m.Get("/download_model", reqRepoCloudBrainReader, repo.CloudBrainDownloadModel) | |||
| }) | |||
| m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew) | |||
| m.Get("/create", reqRepoCloudBrainReader, repo.CloudBrainNew) | |||
| m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | |||
| }, context.RepoRef()) | |||
| @@ -176,6 +176,15 @@ | |||
| {{end}} | |||
| {{template "custom/header" .}} | |||
| <script> | |||
| var _hmt = _hmt || []; | |||
| (function() { | |||
| var hm = document.createElement("script"); | |||
| hm.src = "https://hm.baidu.com/hm.js?7c4ef0a24be6109ab22e63c832ab21cf"; | |||
| var s = document.getElementsByTagName("script")[0]; | |||
| s.parentNode.insertBefore(hm, s); | |||
| })(); | |||
| </script> | |||
| </head> | |||
| <body> | |||
| {{template "custom/body_outer_pre" .}} | |||
| @@ -9,7 +9,7 @@ | |||
| </div> | |||
| {{if .IsSigned}} | |||
| <a class="item {{if .PageIsDashboard}}active{{end}}" href="/dashboard">{{.i18n.Tr "dashboard"}}</a> | |||
| <a class="item {{if .PageIsDashboard}}active{{end}}" href="/dashboard">{{.i18n.Tr "index"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi"}}</a> | |||
| {{if not .UnitIssuesGlobalDisabled}} | |||
| <a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a> | |||
| @@ -109,10 +109,6 @@ | |||
| </div> | |||
| <div class="divider"></div> | |||
| <a class="item" href="{{AppSubUrl}}/dashboard"> | |||
| {{svg "octicon-info" 16}} | |||
| {{.i18n.Tr "your_dashboard"}}<!-- Your dashboard --> | |||
| </a> | |||
| <a class="item" href="{{AppSubUrl}}/{{.SignedUser.Name}}"> | |||
| {{svg "octicon-person" 16}} | |||
| {{.i18n.Tr "your_profile"}}<!-- Your profile --> | |||
| @@ -25,7 +25,7 @@ | |||
| {{range .Datasets}} | |||
| <div class="item"> | |||
| <div class="ui header"> | |||
| <a class="name" href="{{.Repo.Link}}/datasets"> | |||
| <a class="name" href="{{.Repo.Link}}/datasets?type=0"> | |||
| {{.Repo.OwnerName}} / {{.Title}} | |||
| </a> | |||
| <div class="ui right metas"> | |||
| @@ -248,7 +248,7 @@ | |||
| </div> | |||
| <!--任务状态 --> | |||
| <div class="three wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| <div class="two wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| {{.Status}} | |||
| </div> | |||
| @@ -257,15 +257,6 @@ | |||
| <span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <!-- 查看 --> | |||
| <div class="one wide column"> | |||
| <span class="ui text clipboard"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}"> | |||
| <span class="fitted">查看</span> | |||
| </a> | |||
| </span> | |||
| </div> | |||
| <!-- 评分 --> | |||
| <div class="one wide column"> | |||
| <div class="ui text center clipboard"> | |||
| @@ -304,6 +295,15 @@ | |||
| </div> | |||
| </div> | |||
| <!-- 模型下载 --> | |||
| <div class="two wide column"> | |||
| <span class="ui text clipboard"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}/models"> | |||
| <span class="fitted">模型下载</span> | |||
| </a> | |||
| </span> | |||
| </div> | |||
| <!-- 接收结果 --> | |||
| <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> | |||
| <a class="imageBtn" style="{{if not .CanDebug}}color:#CCCCCC;cursor:pointer;pointer-events:none;{{end}}; font-size:16px; font-weight:bold" value="{{.CanDebug}}">提交镜像</a> | |||
| @@ -88,6 +88,17 @@ | |||
| .inline.required.field.cloudbrain_snn4imagenet { | |||
| display: none; | |||
| } | |||
| .select2-container .select2-selection--single{ | |||
| height:38px !important; | |||
| } | |||
| .select2-container--default .select2-selection--single { | |||
| border : 1px solid rgba(34,36,38,.15) !important; | |||
| } | |||
| .select2-container--default .select2-selection--single .select2-selection__rendered{ | |||
| line-height: 38px !important; | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| @@ -139,9 +150,18 @@ | |||
| </div> | |||
| <input id="store_category" type="hidden" name="get_benchmark_category"> | |||
| <div class="inline required field cloudbrain_benchmark"> | |||
| <label>GPU类型</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||
| {{range .gpu_types}} | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>镜像</label> | |||
| <select class="ui search dropdown" id="cloudbrain_image" placeholder="选择镜像" style='width:385px' name="image"> | |||
| <select class="ui search" id="cloudbrain_image" placeholder="选择镜像" style='width:385px;' name="image"> | |||
| {{range .images}} | |||
| <option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||
| {{end}} | |||
| @@ -198,7 +218,8 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> | |||
| <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> | |||
| <script> | |||
| // 点击按钮后遮罩层显示 | |||
| function showmask() { | |||
| @@ -215,11 +236,17 @@ | |||
| $('#cloudbrain_benchmark_category') | |||
| .dropdown({ | |||
| placeholder: "选择数据集类别", | |||
| }) | |||
| }) | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| $('#cloudbrain_image').select2({ | |||
| placeholder: "选择镜像" | |||
| }); | |||
| $(".ui.button.reset").click(function(e){ | |||
| e.preventDefault() | |||
| $('#cloudbrain_benchmark_category') | |||
| @@ -18,17 +18,21 @@ | |||
| <span class="ui text center clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy">{{svg "octicon-file" 16}}</span> | |||
| </div> | |||
| <div class="one wide column"> | |||
| <span class="ui text center clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span> | |||
| </div> | |||
| <div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}"> | |||
| <a class="ui text center" href="datasets/dirs/{{.UUID}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a> | |||
| </div> | |||
| {{if $.Permission.CanWrite $.UnitTypeDatasets}} | |||
| {{if $.Repository.IsPrivate}} | |||
| <div class="three wide column"> | |||
| <div class="two wide column"> | |||
| <a class="ui button mini" disabled='true' data-tooltip='{{$.i18n.Tr "dataset.how_to_public"}}'>{{$.i18n.Tr "dataset.private"}}</a> | |||
| </div> | |||
| {{ else }} | |||
| <div class="three wide column"> | |||
| <div class="two wide column"> | |||
| <div class="ui buttons mini"> | |||
| <a class="ui button mini {{if .IsPrivate}}positive active{{end}}" href="javascript:void(0)" data-dataset-status="true-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="true" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.private"}}</a> | |||
| <div class="or"></div> | |||
| @@ -6,7 +6,7 @@ | |||
| <td class="name four wide"> | |||
| <span class="truncate"> | |||
| <span class="octicon octicon-file-directory"></span> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/datasets/dirs/{{.UUID}}?parentDir={{.ParenDir}}{{end}}"> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/datasets/dirs/{{$.Uuid}}?parentDir={{.ParenDir}}{{end}}"> | |||
| <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | |||
| </a> | |||
| </span> | |||
| @@ -55,6 +55,7 @@ | |||
| <div class="sixteen wide column"> | |||
| <textarea name="description" rows="3">{{.dataset.Description}}</textarea> | |||
| </div> | |||
| <input name="type" value="{{.Type}}" type="hidden" /> | |||
| <div class="sixteen wide column"> | |||
| <a class="ui button" id="cancel">{{.i18n.Tr "cancel"}}</a> | |||
| <button class="ui primary button" id="submit">{{.i18n.Tr "dataset.update_dataset"}}</button> | |||
| @@ -67,7 +68,7 @@ | |||
| <div class="ui sixteen wide column"> | |||
| <div class="ui two column stackable grid"> | |||
| <div class="column"> | |||
| <h2>{{.i18n.Tr "datasets"}}</h2> | |||
| <h2>{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}</h2> | |||
| </div> | |||
| <div class="column right aligned" style="z-index:1"> | |||
| <div class="ui right dropdown type jump item"> | |||
| @@ -75,8 +76,8 @@ | |||
| {{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> | |||
| </span> | |||
| <div class="menu"> | |||
| <a class="item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||
| <a class="item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||
| <a class="item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||
| <a class="item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -3324,7 +3324,6 @@ function initVueComponents() { | |||
| self.$refs.search.focus(); | |||
| }); | |||
| }, | |||
| methods: { | |||
| changeTab(t) { | |||
| this.tab = t; | |||
| @@ -1299,4 +1299,7 @@ i.icon.centerlock { | |||
| .ui.search.action.input > input { | |||
| width: auto; | |||
| } | |||
| .button.mobile-only { | |||
| background-color: transparent !important; | |||
| } | |||