feat: 概览界面增加服务重启以及面板重启功能 (#2579)

Refs #328
pull/2587/head
ssongliu 1 year ago committed by GitHub
parent e9eea9c795
commit 3ff09c8b7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -56,6 +56,28 @@ func (b *BaseApi) LoadDashboardCurrentInfo(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error netOption in path"))
return
}
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
helper.SuccessWithData(c, data)
}
// @Tags Dashboard
// @Summary System restart
// @Description 重启服务器/面板
// @Accept json
// @Param operation path string true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /dashboard/system/restart/:operation [post]
func (b *BaseApi) SystemRestart(c *gin.Context) {
operation, ok := c.Params.Get("operation")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error operation in path"))
return
}
if err := dashboardService.Restart(operation); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}

@ -2,10 +2,12 @@ package service
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk"
@ -20,11 +22,31 @@ type DashboardService struct{}
type IDashboardService interface {
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
Restart(operation string) error
}
func NewIDashboardService() IDashboardService {
return &DashboardService{}
}
func (u *DashboardService) Restart(operation string) error {
if operation != "1panel" && operation != "system" {
return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation)
}
itemCmd := fmt.Sprintf("%s 1pctl restart", cmd.SudoHandleCmd())
if operation == "system" {
itemCmd = fmt.Sprintf("%s reboot", cmd.SudoHandleCmd())
}
go func() {
stdout, err := cmd.Exec(itemCmd)
if err != nil {
global.LOG.Errorf("handle %s failed, err: %v", itemCmd, stdout)
}
}()
return nil
}
func (u *DashboardService) LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) {
var baseInfo dto.DashboardBase
hostInfo, err := host.Info()

@ -18,5 +18,6 @@ func (s *CronjobRouter) InitDashboardRouter(Router *gin.RouterGroup) {
{
cmdRouter.GET("/base/:ioOption/:netOption", baseApi.LoadDashboardBaseInfo)
cmdRouter.GET("/current/:ioOption/:netOption", baseApi.LoadDashboardCurrentInfo)
cmdRouter.POST("/system/restart/:operation", baseApi.SystemRestart)
}
}

@ -3718,6 +3718,37 @@ const docTemplate = `{
}
}
},
"/dashboard/system/restart/:operation": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "重启服务器/面板",
"consumes": [
"application/json"
],
"tags": [
"Dashboard"
],
"summary": "System restart",
"parameters": [
{
"type": "string",
"description": "request",
"name": "operation",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/databases": {
"post": {
"security": [

@ -3711,6 +3711,37 @@
}
}
},
"/dashboard/system/restart/:operation": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "重启服务器/面板",
"consumes": [
"application/json"
],
"tags": [
"Dashboard"
],
"summary": "System restart",
"parameters": [
{
"type": "string",
"description": "request",
"name": "operation",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/databases": {
"post": {
"security": [

@ -6536,6 +6536,25 @@ paths:
summary: Load dashboard current info
tags:
- Dashboard
/dashboard/system/restart/:operation:
post:
consumes:
- application/json
description: 重启服务器/面板
parameters:
- description: request
in: path
name: operation
required: true
type: string
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: System restart
tags:
- Dashboard
/databases:
post:
consumes:

@ -8,3 +8,7 @@ export const loadBaseInfo = (ioOption: string, netOption: string) => {
export const loadCurrentInfo = (ioOption: string, netOption: string) => {
return http.get<Dashboard.CurrentInfo>(`/dashboard/current/${ioOption}/${netOption}`);
};
export const systemRestart = (operation: string) => {
return http.post(`/dashboard/system/restart/${operation}`);
};

@ -13,6 +13,7 @@
</el-badge>
</el-radio-button>
</el-radio-group>
<slot name="route-button"></slot>
</el-card>
</template>

@ -277,6 +277,11 @@ const message = {
supervisor: 'Supervisor',
},
home: {
restart_1panel: 'Restart Panel',
restart_system: 'Restart Server',
restartHelper:
'Do you want to perform the operation [{0}] on this machine? This action will temporarily disable the service. Do you want to continue?',
operationSuccess: 'Operation successful! Restarting, please wait...',
overview: 'Overview',
entranceHelper:
'Enabling a secure entrance can help improve system security. If necessary, go to the Control Panel settings, select Security, and enable the secure entrance.',

@ -275,6 +275,10 @@ const message = {
supervisor: '',
},
home: {
restart_1panel: '',
restart_system: '',
restartHelper: ' [{0}] 使',
operationSuccess: '...',
overview: '',
entranceHelper: ' - ',
appInstalled: '',

@ -275,6 +275,10 @@ const message = {
supervisor: '',
},
home: {
restart_1panel: '',
restart_system: '',
restartHelper: ' [{0}] ',
operationSuccess: '...',
overview: '',
entranceHelper: ' - ',
appInstalled: '',

@ -376,4 +376,10 @@ html {
.limit-height-popover {
max-height: 300px;
overflow: auto;
}
.router-button {
margin-top: 12px;
float: right;
margin-right: 50px;
}

@ -7,7 +7,19 @@
path: '/',
},
]"
/>
>
<template #route-button>
<div class="router-button">
<el-button link type="primary" @click="restart('1panel')">
{{ $t('home.restart_1panel') }}
</el-button>
<el-divider direction="vertical" />
<el-button link type="primary" @click="restart('system')">
{{ $t('home.restart_system') }}
</el-button>
</div>
</template>
</RouterButton>
<el-alert
v-if="!isSafety && globalStore.showEntranceWarn"
style="margin-top: 20px"
@ -231,10 +243,11 @@ import i18n from '@/lang';
import { Dashboard } from '@/api/interface/dashboard';
import { dateFormatForSecond, computeSize } from '@/utils/util';
import { useRouter } from 'vue-router';
import { loadBaseInfo, loadCurrentInfo } from '@/api/modules/dashboard';
import { loadBaseInfo, loadCurrentInfo, systemRestart } from '@/api/modules/dashboard';
import { getIOOptions, getNetworkOptions } from '@/api/modules/monitor';
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';
import { GlobalStore } from '@/store';
import { MsgSuccess } from '@/utils/message';
const router = useRouter();
const globalStore = GlobalStore();
@ -527,6 +540,21 @@ const loadSafeStatus = async () => {
isSafety.value = res.data.securityEntrance;
};
const restart = async (type: string) => {
ElMessageBox.confirm(
i18n.global.t('home.restartHelper', [i18n.global.t('home.restart_' + type)]),
i18n.global.t('commons.msg.operate'),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
).then(async () => {
MsgSuccess(i18n.global.t('home.operationSuccess'));
await systemRestart(type);
});
};
const onFocus = () => {
isActive.value = true;
};

Loading…
Cancel
Save