mirror of https://github.com/1Panel-dev/1Panel
fix: 升级逻辑调整
parent
bfce9ffc94
commit
f3d6f4ee9b
|
@ -1,43 +1,19 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load upgrade info
|
||||
// @Description 加载系统更新信息
|
||||
// @Description 系统更新信息
|
||||
// @Success 200 {object} dto.UpgradeInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/upgrade [get]
|
||||
func (b *BaseApi) GetUpgradeInfo(c *gin.Context) {
|
||||
client := github.NewClient(nil)
|
||||
stats, _, err := client.Repositories.GetLatestRelease(context.Background(), "KubeOperator", "KubeOperator")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
info := dto.UpgradeInfo{
|
||||
NewVersion: string(*stats.Name),
|
||||
ReleaseNote: string(*stats.Body),
|
||||
CreatedAt: github.Timestamp(*stats.CreatedAt).Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load upgrade info
|
||||
// @Description 从 OSS 加载系统更新信息
|
||||
// @Success 200 {object} dto.UpgradeInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/upgrade [get]
|
||||
func (b *BaseApi) GetUpgradeInfoByOSS(c *gin.Context) {
|
||||
info, err := upgradeService.SearchUpgrade()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
|
@ -61,7 +37,7 @@ func (b *BaseApi) Upgrade(c *gin.Context) {
|
|||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := upgradeService.Upgrade(req.Version); err != nil {
|
||||
if err := upgradeService.Upgrade(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -75,10 +75,12 @@ type SnapshotInfo struct {
|
|||
}
|
||||
|
||||
type UpgradeInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
NewVersion string `json:"newVersion"`
|
||||
ReleaseNote string `json:"releaseNote"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
type Upgrade struct {
|
||||
Source string `json:"source" validate:"required,oneof=github gitee"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
|
|
@ -65,11 +65,10 @@ func (u *SettingService) UpdatePort(port uint) error {
|
|||
if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = settingRepo.Update("SystemStatus", "Restarting")
|
||||
go func() {
|
||||
_, err := cmd.Exec("systemctl restart 1panel.service")
|
||||
if err != nil {
|
||||
global.LOG.Errorf("restart system port failed, err: %v")
|
||||
global.LOG.Errorf("restart system port failed, err: %v", err)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
|
|
|
@ -1,29 +1,27 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitee.com/openeuler/go-gitee/gitee"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
type latestVersion struct {
|
||||
Version string `json:"version"`
|
||||
UpdateTime string `json:"update_time"`
|
||||
}
|
||||
|
||||
type UpgradeService struct{}
|
||||
|
||||
type IUpgradeService interface {
|
||||
Upgrade(version string) error
|
||||
Upgrade(req dto.Upgrade) error
|
||||
SearchUpgrade() (*dto.UpgradeInfo, error)
|
||||
}
|
||||
|
||||
|
@ -32,64 +30,67 @@ func NewIUpgradeService() IUpgradeService {
|
|||
}
|
||||
|
||||
func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
|
||||
res, err := http.Get(global.CONF.System.AppOss + "/releases/latest.json")
|
||||
currentVerion, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resByte, err := ioutil.ReadAll(res.Body)
|
||||
infoFromGithub, err := u.loadLatestFromGithub()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var latest latestVersion
|
||||
if err := json.Unmarshal(resByte, &latest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
setting, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if latest.Version != setting.Value {
|
||||
notes, err := http.Get(global.CONF.System.AppOss + fmt.Sprintf("/releases/%s/release_notes.md", latest.Version))
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
} else {
|
||||
isNew, err := compareVersion(currentVerion.Value, infoFromGithub.NewVersion)
|
||||
if !isNew || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noteBytes, err := ioutil.ReadAll(notes.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.UpgradeInfo{
|
||||
NewVersion: latest.Version,
|
||||
CreatedAt: latest.UpdateTime,
|
||||
ReleaseNote: string(noteBytes),
|
||||
}, nil
|
||||
return infoFromGithub, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
infoFromGitee, err := u.loadLatestFromGitee()
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
isNew, err := compareVersion(currentVerion.Value, infoFromGitee.NewVersion)
|
||||
if !isNew && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return infoFromGitee, nil
|
||||
}
|
||||
|
||||
func (u *UpgradeService) Upgrade(version string) error {
|
||||
func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
||||
global.LOG.Info("start to upgrade now...")
|
||||
fileOp := files.NewFileOp()
|
||||
timeStr := time.Now().Format("20060102150405")
|
||||
filePath := fmt.Sprintf("%s/%s.tar.gz", constant.TmpDir, timeStr)
|
||||
rootDir := constant.TmpDir + "/" + timeStr
|
||||
originalDir := fmt.Sprintf("%s/%s/original", constant.TmpDir, timeStr)
|
||||
downloadPath := fmt.Sprintf("%s/releases/%s/%s.tar.gz", global.CONF.System.AppOss, version, version)
|
||||
rootDir := fmt.Sprintf("%s/upgrade_%s/downloads", constant.TmpDir, timeStr)
|
||||
originalDir := fmt.Sprintf("%s/upgrade_%s/original", constant.TmpDir, timeStr)
|
||||
if err := os.MkdirAll(rootDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(originalDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
downloadPath := fmt.Sprintf("https://gitee.com/%s/%s/releases/download/%s/", "wanghe-fit2cloud", "1Panel", req.Version)
|
||||
if req.Source == "github" {
|
||||
downloadPath = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/", "wanghe-fit2cloud", "1Panel", req.Version)
|
||||
}
|
||||
panelName := fmt.Sprintf("1panel-%s-%s", "linux", runtime.GOARCH)
|
||||
fileName := fmt.Sprintf("1panel-online-installer-%s.tar.gz", req.Version)
|
||||
_ = settingRepo.Update("SystemStatus", "Upgrading")
|
||||
go func() {
|
||||
if err := os.MkdirAll(originalDir, os.ModePerm); err != nil {
|
||||
global.LOG.Error(err.Error())
|
||||
if err := fileOp.DownloadFile(downloadPath+panelName, rootDir+"/1panel"); err != nil {
|
||||
global.LOG.Errorf("download panel file failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := fileOp.DownloadFile(downloadPath, filePath); err != nil {
|
||||
global.LOG.Errorf("download file failed, err: %v", err)
|
||||
if err := fileOp.DownloadFile(downloadPath+fileName, rootDir+"/service.tar.gz"); err != nil {
|
||||
global.LOG.Errorf("download service file failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
global.LOG.Info("download file from oss successful!")
|
||||
global.LOG.Info("download all file successful!")
|
||||
defer func() {
|
||||
_ = os.Remove(filePath)
|
||||
_ = os.Remove(rootDir)
|
||||
}()
|
||||
if err := fileOp.Decompress(filePath, rootDir, files.TarGz); err != nil {
|
||||
if err := fileOp.Decompress(rootDir+"/service.tar.gz", rootDir, files.TarGz); err != nil {
|
||||
global.LOG.Errorf("decompress file failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
@ -105,21 +106,31 @@ func (u *UpgradeService) Upgrade(version string) error {
|
|||
global.LOG.Errorf("upgrade 1panel failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := cpBinary(rootDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil {
|
||||
if err := fileOp.Chmod("/usr/local/bin/1panel", 0755); err != nil {
|
||||
u.handleRollback(fileOp, originalDir, 1)
|
||||
global.LOG.Errorf("chmod 1panel failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := cpBinary(fmt.Sprintf("%s/1panel-online-installer-%s/1pctl", rootDir, req.Version), "/usr/local/bin/1pctl"); err != nil {
|
||||
u.handleRollback(fileOp, originalDir, 2)
|
||||
global.LOG.Errorf("upgrade 1pctl failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := cpBinary(rootDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
|
||||
if err := fileOp.Chmod("/usr/local/bin/1pctl", 0755); err != nil {
|
||||
u.handleRollback(fileOp, originalDir, 1)
|
||||
global.LOG.Errorf("chmod 1pctl failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := cpBinary(fmt.Sprintf("%s/1panel-online-installer-%s/1panel/conf/1panel.service", rootDir, req.Version), "/etc/systemd/system/1panel.service"); err != nil {
|
||||
u.handleRollback(fileOp, originalDir, 3)
|
||||
global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
global.LOG.Info("upgrade successful!")
|
||||
_ = settingRepo.Update("SystemStatus", "Upgrade")
|
||||
_ = settingRepo.Update("SystemVersion", version)
|
||||
_, _ = cmd.Exec("systemctl restart 1panel.service")
|
||||
_ = settingRepo.Update("SystemVersion", req.Version)
|
||||
_ = settingRepo.Update("SystemStatus", "Free")
|
||||
_, _ = cmd.Exec("systemctl daemon-reload && systemctl restart 1panel.service")
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
@ -162,3 +173,75 @@ func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string,
|
|||
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UpgradeService) loadLatestFromGithub() (*dto.UpgradeInfo, error) {
|
||||
client := github.NewClient(nil)
|
||||
ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancle()
|
||||
stats, res, err := client.Repositories.GetLatestRelease(ctx, "wanghe-fit2cloud", "1Panel")
|
||||
if res.StatusCode != 200 || err != nil {
|
||||
return nil, fmt.Errorf("load upgrade info from github failed, err: %v", err)
|
||||
}
|
||||
info := dto.UpgradeInfo{
|
||||
NewVersion: string(*stats.Name),
|
||||
ReleaseNote: string(*stats.Body),
|
||||
CreatedAt: github.Timestamp(*stats.CreatedAt).Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (u *UpgradeService) loadLatestFromGitee() (*dto.UpgradeInfo, error) {
|
||||
client := gitee.NewAPIClient(gitee.NewConfiguration())
|
||||
ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancle()
|
||||
stats, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoReleasesLatest(ctx, "wanghe-fit2cloud", "1Panel", &gitee.GetV5ReposOwnerRepoReleasesLatestOpts{})
|
||||
if res.StatusCode != 200 || err != nil {
|
||||
return nil, fmt.Errorf("load upgrade info from gitee failed, err: %v", err)
|
||||
}
|
||||
info := dto.UpgradeInfo{
|
||||
NewVersion: string(stats.Name),
|
||||
ReleaseNote: string(stats.Body),
|
||||
CreatedAt: stats.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func compareVersion(version, newVersion string) (bool, error) {
|
||||
if version == newVersion {
|
||||
return false, nil
|
||||
}
|
||||
if len(version) == 0 || len(newVersion) == 0 {
|
||||
return false, fmt.Errorf("incorrect version or new version entered %v -- %v", version, newVersion)
|
||||
}
|
||||
versions := strings.Split(strings.ReplaceAll(version, "v", ""), ".")
|
||||
if len(versions) != 3 {
|
||||
return false, fmt.Errorf("incorrect version input %v", version)
|
||||
}
|
||||
newVersions := strings.Split(strings.ReplaceAll(newVersion, "v", ""), ".")
|
||||
if len(newVersions) != 3 {
|
||||
return false, fmt.Errorf("incorrect newVersions input %v", version)
|
||||
}
|
||||
version1, _ := strconv.Atoi(versions[0])
|
||||
newVersion1, _ := strconv.Atoi(newVersions[0])
|
||||
if newVersion1 > version1 {
|
||||
return true, nil
|
||||
} else if newVersion1 == version1 {
|
||||
version2, _ := strconv.Atoi(versions[1])
|
||||
newVersion2, _ := strconv.Atoi(newVersions[1])
|
||||
if newVersion2 > version2 {
|
||||
return true, nil
|
||||
} else if newVersion2 == version2 {
|
||||
version3, _ := strconv.Atoi(versions[2])
|
||||
newVersion3, _ := strconv.Atoi(newVersions[2])
|
||||
if newVersion3 > version3 {
|
||||
return true, nil
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func Init() {
|
||||
stdout, err := cmd.Exec("grep '^BASE_DIR=' /Users/slooop/Downloads/1pctl | cut -d'=' -f2")
|
||||
stdout, err := cmd.Exec("grep '^BASE_DIR=' /usr/bin/1pctl | cut -d'=' -f2")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
|||
settingRouter.POST("/snapshot/rollback", baseApi.RollbackSnapshot)
|
||||
settingRouter.POST("/upgrade", baseApi.Upgrade)
|
||||
settingRouter.GET("/upgrade", baseApi.GetUpgradeInfo)
|
||||
settingRouter.GET("/upgrade/byoss", baseApi.GetUpgradeInfoByOSS)
|
||||
settingRouter.GET("/basedir", baseApi.LoadBaseDir)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ declare module 'vue' {
|
|||
AppLayout: typeof import('./src/components/app-layout/index.vue')['default']
|
||||
AppStatus: typeof import('./src/components/app-status/index.vue')['default']
|
||||
BackButton: typeof import('./src/components/back-button/index.vue')['default']
|
||||
Bread: typeof import('./src/components/bread-crumbs/bread.vue')['default']
|
||||
BreadCrumbs: typeof import('./src/components/bread-crumbs/index.vue')['default']
|
||||
BreadCrumbsItem: typeof import('./src/components/bread-crumbs/bread-crumbs-item.vue')['default']
|
||||
CardWithHeader: typeof import('./src/components/card-with-header/index.vue')['default']
|
||||
|
@ -44,7 +43,6 @@ declare module 'vue' {
|
|||
ElFooter: typeof import('element-plus/es')['ElFooter']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
|
@ -79,7 +77,6 @@ declare module 'vue' {
|
|||
InfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
|
||||
Loading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||
Logo: typeof import('./src/components/app-layout/menu/components/Logo.vue')['default']
|
||||
LogoNew: typeof import('./src/components/app-layout/menu/components/logo-new.vue')['default']
|
||||
Menu: typeof import('./src/components/app-layout/menu/index.vue')['default']
|
||||
Popover: typeof import('element-plus/es')['ElPopoverDirective']
|
||||
RouterButton: typeof import('./src/components/router-button/index.vue')['default']
|
||||
|
|
|
@ -80,4 +80,8 @@ export namespace Setting {
|
|||
releaseNote: string;
|
||||
createdAt: string;
|
||||
}
|
||||
export interface Upgrade {
|
||||
source: string;
|
||||
version: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,6 @@ export const searchSnapshotPage = (param: ReqPage) => {
|
|||
export const loadUpgradeInfo = () => {
|
||||
return http.get<Setting.UpgradeInfo>(`/settings/upgrade`);
|
||||
};
|
||||
export const loadUpgradeInfoByOSS = () => {
|
||||
return http.get<Setting.UpgradeInfo>(`/settings/upgrade/byoss`);
|
||||
};
|
||||
export const upgrade = (version: string) => {
|
||||
return http.post(`/settings/upgrade`, { version: version });
|
||||
export const upgrade = (param: Setting.Upgrade) => {
|
||||
return http.post(`/settings/upgrade`, param);
|
||||
};
|
||||
|
|
|
@ -753,6 +753,7 @@ export default {
|
|||
mfaHelper3: 'Enter six digits from the app',
|
||||
|
||||
snapshot: 'Snapshot',
|
||||
thirdPartySupport: 'Only third-party accounts are supported',
|
||||
recoverDetail: 'Recover detail',
|
||||
createSnapshot: 'Create snapshot',
|
||||
recover: 'Recover',
|
||||
|
@ -776,6 +777,7 @@ export default {
|
|||
upgradeCheck: 'Check for updates',
|
||||
upgradeNotes: 'Release note',
|
||||
upgradeNow: 'Upgrade now',
|
||||
source: 'Download source',
|
||||
|
||||
monitor: 'Monitor',
|
||||
enableMonitor: 'Enable',
|
||||
|
|
|
@ -747,6 +747,7 @@ export default {
|
|||
path: '路径',
|
||||
|
||||
snapshot: '快照',
|
||||
thirdPartySupport: '仅支持第三方账号',
|
||||
recoverDetail: '恢复详情',
|
||||
createSnapshot: '创建快照',
|
||||
recover: '恢复',
|
||||
|
@ -773,6 +774,7 @@ export default {
|
|||
upgradeCheck: '检查更新',
|
||||
upgradeNotes: '更新内容',
|
||||
upgradeNow: '立即更新',
|
||||
source: '下载源',
|
||||
|
||||
safe: '安全',
|
||||
safeEntrance: '安全入口',
|
||||
|
|
|
@ -226,7 +226,24 @@ const search = async (param: string) => {
|
|||
let cpuData = item.value.map(function (item: any) {
|
||||
return item.cpu.toFixed(2);
|
||||
});
|
||||
let yDatasOfCpu = { name: 'CPU', type: 'line', data: cpuData, showSymbol: false };
|
||||
let yDatasOfCpu = {
|
||||
name: 'CPU',
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 94, 235, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 94, 235, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
data: cpuData,
|
||||
showSymbol: false,
|
||||
};
|
||||
initCharts('loadCPUChart', baseDate, yDatasOfCpu, 'CPU', '%');
|
||||
}
|
||||
if (param === 'memory' || param === 'all') {
|
||||
|
@ -236,6 +253,18 @@ const search = async (param: string) => {
|
|||
let yDatasOfMem = {
|
||||
name: i18n.global.t('monitor.memory'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 94, 235, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 94, 235, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
data: memoryData,
|
||||
showSymbol: false,
|
||||
};
|
||||
|
@ -258,6 +287,18 @@ const search = async (param: string) => {
|
|||
let yDatasOfUp = {
|
||||
name: i18n.global.t('monitor.up'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 94, 235, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 94, 235, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
data: networkUp,
|
||||
showSymbol: false,
|
||||
};
|
||||
|
@ -267,6 +308,18 @@ const search = async (param: string) => {
|
|||
let yDatasOfDown = {
|
||||
name: i18n.global.t('monitor.down'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(27, 143, 60, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(27, 143, 60, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
data: networkOut,
|
||||
showSymbol: false,
|
||||
};
|
||||
|
@ -353,6 +406,18 @@ function initLoadCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: '1 ' + i18n.global.t('monitor.min'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 94, 235, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 94, 235, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.cpuLoad1.toFixed(2);
|
||||
|
@ -361,6 +426,18 @@ function initLoadCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: '5 ' + i18n.global.t('monitor.min'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(27, 143, 60, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(27, 143, 60, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.cpuLoad5.toFixed(2);
|
||||
|
@ -369,6 +446,18 @@ function initLoadCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: '15 ' + i18n.global.t('monitor.min'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(249, 199, 79, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(249, 199, 79, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.cpuLoad15.toFixed(2);
|
||||
|
@ -377,6 +466,18 @@ function initLoadCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: i18n.global.t('monitor.resourceUsage'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 173, 177, 0.5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 173, 177, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.loadUsage.toFixed(2);
|
||||
|
@ -446,6 +547,18 @@ function initIOCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: i18n.global.t('monitor.read'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 94, 235, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 94, 235, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return (item.read / 1024).toFixed(2);
|
||||
|
@ -454,6 +567,18 @@ function initIOCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: i18n.global.t('monitor.write'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(27, 143, 60, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(27, 143, 60, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return (item.write / 1024).toFixed(2);
|
||||
|
@ -462,6 +587,18 @@ function initIOCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: i18n.global.t('monitor.readWriteCount'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(249, 199, 79, .5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(249, 199, 79, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.count;
|
||||
|
@ -471,6 +608,18 @@ function initIOCharts(item: Monitor.MonitorData) {
|
|||
{
|
||||
name: i18n.global.t('monitor.readWriteTime'),
|
||||
type: 'line',
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 173, 177, 0.5)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 173, 177, 0)',
|
||||
},
|
||||
]),
|
||||
},
|
||||
showSymbol: false,
|
||||
data: item.value.map(function (item: any) {
|
||||
return item.time;
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@focus="registerButtonFocused = true"
|
||||
@blur="registerButtonFocused = false"
|
||||
@click="register(registerFormRef)"
|
||||
class="login-button"
|
||||
type="primary"
|
||||
|
@ -150,6 +152,8 @@
|
|||
<el-form-item>
|
||||
<el-button
|
||||
@click="login(loginFormRef)"
|
||||
@focus="loginButtonFocused = true"
|
||||
@blur="loginButtonFocused = false"
|
||||
class="login-button"
|
||||
type="primary"
|
||||
size="default"
|
||||
|
@ -167,7 +171,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, onUnmounted } from 'vue';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import type { ElForm } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
@ -177,8 +181,6 @@ import { MenuStore } from '@/store/modules/menu';
|
|||
import i18n from '@/lang';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
let timer: NodeJS.Timer | null = null;
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const menuStore = MenuStore();
|
||||
|
||||
|
@ -189,6 +191,7 @@ const isFirst = ref();
|
|||
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
|
||||
const registerButtonFocused = ref(false);
|
||||
const registerFormRef = ref<FormInstance>();
|
||||
const registerForm = reactive({
|
||||
name: '',
|
||||
|
@ -201,6 +204,7 @@ const registerRules = reactive({
|
|||
rePassword: [Rules.requiredInput, { validator: checkPassword, trigger: 'blur' }],
|
||||
});
|
||||
|
||||
const loginButtonFocused = ref();
|
||||
const loginFormRef = ref<FormInstance>();
|
||||
const loginForm = reactive({
|
||||
name: '',
|
||||
|
@ -321,25 +325,20 @@ function checkPassword(rule: any, value: any, callback: any) {
|
|||
|
||||
onMounted(() => {
|
||||
document.title = globalStore.themeConfig.panelName;
|
||||
timer = setInterval(() => {
|
||||
if (loginForm.captcha === '') {
|
||||
loginVerify();
|
||||
}
|
||||
}, 1000 * 8);
|
||||
checkStatus();
|
||||
document.onkeydown = (e: any) => {
|
||||
e = window.event || e;
|
||||
if (e.code === 'Enter' || e.code === 'enter' || e.code === 'NumpadEnter') {
|
||||
if (e.keyCode === 13) {
|
||||
if (loading.value) return;
|
||||
login(loginFormRef.value);
|
||||
if (isFirst.value && !registerButtonFocused.value) {
|
||||
register(registerFormRef.value);
|
||||
}
|
||||
if (!isFirst.value && !loginButtonFocused.value) {
|
||||
login(loginFormRef.value);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(Number(timer));
|
||||
timer = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -47,7 +47,13 @@
|
|||
<el-tag>{{ upgradeInfo.createdAt }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.upgradeNotes')">
|
||||
<MdEditor style="height: calc(100vh - 260px)" v-model="upgradeInfo.releaseNote" previewOnly />
|
||||
<MdEditor style="height: calc(100vh - 330px)" v-model="upgradeInfo.releaseNote" previewOnly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.source')">
|
||||
<el-radio-group v-model="Source">
|
||||
<el-radio label="gitee">Gitee</el-radio>
|
||||
<el-radio label="github">GitHub</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onUpgrade">{{ $t('setting.upgradeNow') }}</el-button>
|
||||
|
@ -69,6 +75,7 @@ import DrawerHeader from '@/components/drawer-header/index.vue';
|
|||
|
||||
const version = ref();
|
||||
const upgradeInfo = ref();
|
||||
const Source = ref('gitee');
|
||||
const drawerVisiable = ref();
|
||||
const refresh = ref();
|
||||
|
||||
|
@ -98,7 +105,7 @@ const handleClose = () => {
|
|||
const onLoadUpgradeInfo = async () => {
|
||||
const res = await loadUpgradeInfo();
|
||||
if (!res.data) {
|
||||
ElMessage.success(i18n.global.t('setting.noUpgrade'));
|
||||
ElMessage.info(i18n.global.t('setting.noUpgrade'));
|
||||
return;
|
||||
}
|
||||
upgradeInfo.value = res.data;
|
||||
|
@ -111,7 +118,11 @@ const onUpgrade = async () => {
|
|||
type: 'info',
|
||||
}).then(() => {
|
||||
loading.value = true;
|
||||
upgrade(upgradeInfo.value.newVersion)
|
||||
let param = {
|
||||
version: upgradeInfo.value.newVersion,
|
||||
source: Source.value,
|
||||
};
|
||||
upgrade(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
drawerVisiable.value = false;
|
||||
|
|
|
@ -82,7 +82,10 @@
|
|||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('cronjob.target')" prop="from">
|
||||
<el-form-item
|
||||
:label="$t('cronjob.target') + ' ( ' + $t('setting.thirdPartySupport') + ' )'"
|
||||
prop="from"
|
||||
>
|
||||
<el-select v-model="snapInfo.from" clearable>
|
||||
<el-option
|
||||
v-for="item in backupOptions"
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module github.com/1Panel-dev/1Panel
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
gitee.com/openeuler/go-gitee v0.0.0-20220530104019-3af895bc380c
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
|
||||
github.com/aws/aws-sdk-go v1.44.99
|
||||
github.com/compose-spec/compose-go v1.6.0
|
||||
|
@ -62,6 +63,7 @@ require (
|
|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/antihax/optional v1.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
|
@ -152,10 +154,12 @@ require (
|
|||
go.opentelemetry.io/otel/trace v1.3.0 // indirect
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
)
|
||||
|
|
6
go.sum
6
go.sum
|
@ -37,6 +37,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
gitee.com/openeuler/go-gitee v0.0.0-20220530104019-3af895bc380c h1:miClKCIA2Zyqif+Mf0GOdd/1u2q2wW7/vVuHpQprwDw=
|
||||
gitee.com/openeuler/go-gitee v0.0.0-20220530104019-3af895bc380c/go.mod h1:qGJhn1KxC5UE4BUmxCE/hTpFfuKbd3U3V9fNROrspfE=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
|
@ -100,6 +102,7 @@ github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible h1:QoRMR0TCctLDqBCMyOu1e
|
|||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
|
@ -1144,6 +1147,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1370,6 +1375,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
|
Loading…
Reference in New Issue