mirror of
https://github.com/XShengTech/MEGREZ.git
synced 2026-05-03 13:02:38 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cbc426c180 | |||
| 1a3a126388 | |||
| 1133650632 | |||
| 9d561cb63a | |||
| 1f55ecb649 |
@@ -49,9 +49,12 @@
|
|||||||
> 查看文档 [**>>> 🚧 正在施工中 <<<**]()
|
> 查看文档 [**>>> 🚧 正在施工中 <<<**]()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 📌 效果展示
|
## 📌 效果展示
|
||||||
|
|
||||||
|
### 视频演示
|
||||||
|
|
||||||
|
[Bilibili - MEGREZ——你的新一代开源GPU管理系统](https://www.bilibili.com/video/BV1EnfWY9ECC/)
|
||||||
|
|
||||||
### 登录注册
|
### 登录注册
|
||||||
|
|
||||||
| 登录 | 注册 |
|
| 登录 | 注册 |
|
||||||
|
|||||||
@@ -70,12 +70,11 @@
|
|||||||
:href="'http://' + data.code_server_address" target="_blank" v-tooltip.top="'VSCode Web'" />
|
:href="'http://' + data.code_server_address" target="_blank" v-tooltip.top="'VSCode Web'" />
|
||||||
<Button v-else icon="pi pi-code" aria-label="Filter" v-tooltip.top="'VSCode Web'" disabled />
|
<Button v-else icon="pi pi-code" aria-label="Filter" v-tooltip.top="'VSCode Web'" disabled />
|
||||||
<Button v-if="data.status == statusRunning" severity="info" icon="pi pi-inbox" aria-label="Filter" as="a"
|
<Button v-if="data.status == statusRunning" severity="info" icon="pi pi-inbox" aria-label="Filter" as="a"
|
||||||
:href="'http://' + data.jupyter_address + '/lab'" target="_blank" v-tooltip.top="'Jupter Lab'" />
|
:href="'http://' + data.jupyter_address" target="_blank" v-tooltip.top="'Jupyter Lab'" />
|
||||||
<Button v-else severity="info" icon="pi pi-inbox" aria-label="Filter" v-tooltip.top="'Jupter Lab'"
|
<Button v-else severity="info" icon="pi pi-inbox" aria-label="Filter" v-tooltip.top="'Jupyter Lab'"
|
||||||
disabled />
|
disabled />
|
||||||
<Button v-if="data.status == statusRunning" severity="contrast" icon="pi pi-chart-bar" as="a"
|
<Button v-if="data.status == statusRunning" severity="contrast" icon="pi pi-chart-bar" as="a"
|
||||||
:href="'http://' + data.grafana_address + '/public-dashboards/2c510f203876465ba76617510ce3e219'"
|
:href="'http://' + data.grafana_address" target="_blank" v-tooltip.top="'监控'" />
|
||||||
target="_blank" v-tooltip.top="'监控'" />
|
|
||||||
<Button v-else severity="contrast" icon="pi pi-chart-bar" v-tooltip.top="'监控'" disabled />
|
<Button v-else severity="contrast" icon="pi pi-chart-bar" v-tooltip.top="'监控'" disabled />
|
||||||
<Button v-if="!isAdmin" icon="pi pi-ellipsis-h" severity="secondary" aria-label="Bookmark"
|
<Button v-if="!isAdmin" icon="pi pi-ellipsis-h" severity="secondary" aria-label="Bookmark"
|
||||||
@click="showMenu($event, data)" />
|
@click="showMenu($event, data)" />
|
||||||
|
|||||||
@@ -74,12 +74,11 @@
|
|||||||
:href="'http://' + data.code_server_address" target="_blank" v-tooltip.top="'VSCode Web'" />
|
:href="'http://' + data.code_server_address" target="_blank" v-tooltip.top="'VSCode Web'" />
|
||||||
<Button v-else icon="pi pi-code" aria-label="Filter" v-tooltip.top="'VSCode Web'" disabled />
|
<Button v-else icon="pi pi-code" aria-label="Filter" v-tooltip.top="'VSCode Web'" disabled />
|
||||||
<Button v-if="data.status == statusRunning" severity="info" icon="pi pi-inbox" aria-label="Filter" as="a"
|
<Button v-if="data.status == statusRunning" severity="info" icon="pi pi-inbox" aria-label="Filter" as="a"
|
||||||
:href="'http://' + data.jupyter_address + '/lab'" target="_blank" v-tooltip.top="'Jupter Lab'" />
|
:href="'http://' + data.jupyter_address" target="_blank" v-tooltip.top="'Jupyter Lab'" />
|
||||||
<Button v-else severity="info" icon="pi pi-inbox" aria-label="Filter" v-tooltip.top="'Jupter Lab'"
|
<Button v-else severity="info" icon="pi pi-inbox" aria-label="Filter" v-tooltip.top="'Jupyter Lab'"
|
||||||
disabled />
|
disabled />
|
||||||
<Button v-if="data.status == statusRunning" severity="contrast" icon="pi pi-chart-bar" as="a"
|
<Button v-if="data.status == statusRunning" severity="contrast" icon="pi pi-chart-bar" as="a"
|
||||||
:href="'http://' + data.grafana_address + '/public-dashboards/2c510f203876465ba76617510ce3e219'"
|
:href="'http://' + data.grafana_address" target="_blank" v-tooltip.top="'监控'" />
|
||||||
target="_blank" v-tooltip.top="'监控'" />
|
|
||||||
<Button v-else severity="contrast" icon="pi pi-chart-bar" v-tooltip.top="'监控'" disabled />
|
<Button v-else severity="contrast" icon="pi pi-chart-bar" v-tooltip.top="'监控'" disabled />
|
||||||
<Button icon="pi pi-ellipsis-h" severity="secondary" aria-label="Bookmark"
|
<Button icon="pi pi-ellipsis-h" severity="secondary" aria-label="Bookmark"
|
||||||
@click="showMenu($event, data)" />
|
@click="showMenu($event, data)" />
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package index
|
||||||
|
|
||||||
|
import "github.com/kataras/iris/v12"
|
||||||
|
|
||||||
|
func cors(ctx iris.Context) {
|
||||||
|
ctx.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
ctx.Header("Access-Control-Allow-Methods", "GET")
|
||||||
|
ctx.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||||
|
ctx.Header("Access-Control-Max-Age", "86400")
|
||||||
|
ctx.Header("Access-Control-Allow-Credentials", "true")
|
||||||
|
ctx.Next()
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func InitIndex(app *iris.Application) {
|
func InitIndex(app *iris.Application) {
|
||||||
|
app.Use(cors)
|
||||||
app.HandleDir("/", GetWebFS(), iris.DirOptions{
|
app.HandleDir("/", GetWebFS(), iris.DirOptions{
|
||||||
IndexName: "/index.html",
|
IndexName: "/index.html",
|
||||||
Compress: true,
|
Compress: true,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func Create(instance *models.Instances) (containerName, volumeName string, err e
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
SetJupterPassword(server.IP, server.Port, server.Apikey, containerName, instance.SshPasswd)
|
SetJupyterPassword(server.IP, server.Port, server.Apikey, containerName, instance.SshPasswd)
|
||||||
SetCodeServerPassword(server.IP, server.Port, server.Apikey, containerName, instance.SshPasswd)
|
SetCodeServerPassword(server.IP, server.Port, server.Apikey, containerName, instance.SshPasswd)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -64,9 +64,9 @@ func Create(instance *models.Instances) (containerName, volumeName string, err e
|
|||||||
|
|
||||||
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
||||||
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
||||||
instance.JupyterAddress = server.IP + ":" + portBindings["8888"]
|
instance.JupyterAddress = server.IP + ":" + portBindings["80"] + "/jupyter"
|
||||||
instance.GrafanaAddress = server.IP + ":" + portBindings["3000"]
|
instance.GrafanaAddress = server.IP + ":" + portBindings["80"] + "/monitor/public-dashboards/2c510f203876465ba76617510ce3e219"
|
||||||
instance.CodeServerAddress = server.IP + ":" + portBindings["8080"]
|
instance.CodeServerAddress = server.IP + ":" + portBindings["80"] + "/code-server/"
|
||||||
|
|
||||||
instance.Status = 0
|
instance.Status = 0
|
||||||
result = database.DB.Save(&instance)
|
result = database.DB.Save(&instance)
|
||||||
|
|||||||
@@ -40,10 +40,8 @@ func createInstance(ip string, port int, apikey string,
|
|||||||
Memory: strconv.Itoa(memorySize) + "GB",
|
Memory: strconv.Itoa(memorySize) + "GB",
|
||||||
ContainerPorts: []string{
|
ContainerPorts: []string{
|
||||||
"22", // SSH
|
"22", // SSH
|
||||||
|
"80", // Nginx
|
||||||
"6007", // TensorBoard
|
"6007", // TensorBoard
|
||||||
"8888", // Jupyter Notebook
|
|
||||||
"3000", // Grafana
|
|
||||||
"8080", // Code-Server
|
|
||||||
"34567", // Custom Port
|
"34567", // Custom Port
|
||||||
},
|
},
|
||||||
Env: []string{
|
Env: []string{
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ func SetRootPassword(ip string, port int, apikey string,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetJupterPassword(ip string, port int, apikey string,
|
func SetJupyterPassword(ip string, port int, apikey string,
|
||||||
containerName, password string) (err error) {
|
containerName, password string) (err error) {
|
||||||
l.SetFunction("SetJupterPassword")
|
l.SetFunction("SetJupyterPassword")
|
||||||
|
|
||||||
// Set Jupyter Password
|
// Set Jupyter Password
|
||||||
data := executeReq{
|
data := executeReq{
|
||||||
@@ -85,8 +85,8 @@ func SetJupterPassword(ip string, port int, apikey string,
|
|||||||
c.Do()
|
c.Do()
|
||||||
|
|
||||||
if c.GetStatusCode() != 200 {
|
if c.GetStatusCode() != 200 {
|
||||||
l.Error("set jupter password error: %d", c.GetStatusCode())
|
l.Error("set jupyter password error: %d", c.GetStatusCode())
|
||||||
return errors.New("set jupter password request error")
|
return errors.New("set jupyter password request error")
|
||||||
}
|
}
|
||||||
|
|
||||||
var res resStruct
|
var res resStruct
|
||||||
@@ -97,7 +97,7 @@ func SetJupterPassword(ip string, port int, apikey string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res.Code != 200 {
|
if res.Code != 200 {
|
||||||
l.Error("set jupter password code: %d, error: %s", res.Code, res.Msg)
|
l.Error("set jupyter password code: %d, error: %s", res.Code, res.Msg)
|
||||||
return errors.New(res.Msg)
|
return errors.New(res.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,8 +124,8 @@ func SetJupterPassword(ip string, port int, apikey string,
|
|||||||
c.Do()
|
c.Do()
|
||||||
|
|
||||||
if c.GetStatusCode() != 200 {
|
if c.GetStatusCode() != 200 {
|
||||||
l.Error("restart jupter error: %d", c.GetStatusCode())
|
l.Error("restart jupyter error: %d", c.GetStatusCode())
|
||||||
return errors.New("restart jupter request error")
|
return errors.New("restart jupyter request error")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(c.GetBody(), &res)
|
err = json.Unmarshal(c.GetBody(), &res)
|
||||||
@@ -135,7 +135,7 @@ func SetJupterPassword(ip string, port int, apikey string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if res.Code != 200 {
|
if res.Code != 200 {
|
||||||
l.Error("restart jupter code: %d, error: %s", res.Code, res.Msg)
|
l.Error("restart jupyter code: %d, error: %s", res.Code, res.Msg)
|
||||||
return errors.New(res.Msg)
|
return errors.New(res.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func Patch(instance *models.Instances, gpuCount, volumeSize int, cpuOnly bool) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
SetJupterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetJupyterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -104,8 +104,9 @@ func Patch(instance *models.Instances, gpuCount, volumeSize int, cpuOnly bool) (
|
|||||||
|
|
||||||
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
||||||
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
||||||
instance.JupyterAddress = server.IP + ":" + portBindings["8888"]
|
instance.JupyterAddress = server.IP + ":" + portBindings["80"] + "/jupyter"
|
||||||
instance.GrafanaAddress = server.IP + ":" + portBindings["3000"]
|
instance.GrafanaAddress = server.IP + ":" + portBindings["80"] + "/monitor/public-dashboards/2c510f203876465ba76617510ce3e219"
|
||||||
|
instance.CodeServerAddress = server.IP + ":" + portBindings["80"] + "/code-server/"
|
||||||
|
|
||||||
instance.CpuOnly = true
|
instance.CpuOnly = true
|
||||||
instance.GpuCount = 0
|
instance.GpuCount = 0
|
||||||
@@ -136,7 +137,7 @@ func Patch(instance *models.Instances, gpuCount, volumeSize int, cpuOnly bool) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
SetJupterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetJupyterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -148,9 +149,9 @@ func Patch(instance *models.Instances, gpuCount, volumeSize int, cpuOnly bool) (
|
|||||||
|
|
||||||
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
||||||
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
||||||
instance.JupyterAddress = server.IP + ":" + portBindings["8888"]
|
instance.JupyterAddress = server.IP + ":" + portBindings["80"] + "/jupyter"
|
||||||
instance.GrafanaAddress = server.IP + ":" + portBindings["3000"]
|
instance.GrafanaAddress = server.IP + ":" + portBindings["80"] + "/monitor/public-dashboards/2c510f203876465ba76617510ce3e219"
|
||||||
instance.CodeServerAddress = server.IP + ":" + portBindings["8080"]
|
instance.CodeServerAddress = server.IP + ":" + portBindings["80"] + "/code-server/"
|
||||||
|
|
||||||
instance.CpuOnly = false
|
instance.CpuOnly = false
|
||||||
instance.GpuCount = gpuCount
|
instance.GpuCount = gpuCount
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func Restart(instance *models.Instances) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
SetJupterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetJupyterPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
SetCodeServerPassword(server.IP, server.Port, server.Apikey, instance.ContainerName, instance.SshPasswd)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -57,9 +57,9 @@ func Restart(instance *models.Instances) (err error) {
|
|||||||
|
|
||||||
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
instance.SshAddress = server.IP + ":" + portBindings["22"]
|
||||||
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
instance.TensorBoardAddress = server.IP + ":" + portBindings["6007"]
|
||||||
instance.JupyterAddress = server.IP + ":" + portBindings["8888"]
|
instance.JupyterAddress = server.IP + ":" + portBindings["80"] + "/jupyter"
|
||||||
instance.GrafanaAddress = server.IP + ":" + portBindings["3000"]
|
instance.GrafanaAddress = server.IP + ":" + portBindings["80"] + "/monitor/public-dashboards/2c510f203876465ba76617510ce3e219"
|
||||||
instance.CodeServerAddress = server.IP + ":" + portBindings["8080"]
|
instance.CodeServerAddress = server.IP + ":" + portBindings["80"] + "/code-server/"
|
||||||
|
|
||||||
instance.Status = models.InstanceStatusRunning
|
instance.Status = models.InstanceStatusRunning
|
||||||
result = database.DB.Save(&instance)
|
result = database.DB.Save(&instance)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"megrez/services/database"
|
"megrez/services/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const imagesKey = "images"
|
||||||
|
|
||||||
func systemInit() (err error) {
|
func systemInit() (err error) {
|
||||||
l.SetFunction("systemInit")
|
l.SetFunction("systemInit")
|
||||||
|
|
||||||
@@ -35,6 +37,16 @@ func systemInit() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
st := models.System{
|
||||||
|
Key: imagesKey,
|
||||||
|
Value: "{}",
|
||||||
|
}
|
||||||
|
result = database.DB.Create(&st)
|
||||||
|
if result.Error != nil {
|
||||||
|
l.Error("Create system failed, Error: %v", result.Error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
l.Info("System init success")
|
l.Info("System init success")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user