mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-09 16:00:29 +00:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54b5cee466 | ||
|
|
8607acbb22 | ||
|
|
13f5ac77c2 | ||
|
|
354f0d0753 | ||
|
|
48d4a47ed1 | ||
|
|
0f3ea3f434 | ||
|
|
c90ad0f4ed | ||
|
|
61bbfac3cd | ||
|
|
fcca83b3e9 | ||
|
|
8244b679fe | ||
|
|
604949de18 | ||
|
|
7716df55f9 | ||
|
|
08fe607012 | ||
|
|
4222a985f9 |
@@ -518,7 +518,7 @@ func (a *AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := updateInstallInfoInDB(req.Key, "", "port", true, strconv.FormatInt(req.Port, 10)); err != nil {
|
||||
if err := updateInstallInfoInDB(req.Key, req.Name, "port", true, strconv.FormatInt(req.Port, 10)); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -316,11 +316,6 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
|
||||
return buserr.New(constant.ErrContainerName)
|
||||
}
|
||||
|
||||
config, hostConf, networkConf, err := loadConfigInfo(true, req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
|
||||
if !checkImageExist(client, req.Image) || req.ForcePull {
|
||||
if err := pullImages(ctx, client, req.Image); err != nil {
|
||||
if !req.ForcePull {
|
||||
@@ -329,6 +324,21 @@ func (u *ContainerService) ContainerCreate(req dto.ContainerOperate) error {
|
||||
global.LOG.Errorf("force pull image %s failed, err: %v", req.Image, err)
|
||||
}
|
||||
}
|
||||
imageInfo, _, err := client.ImageInspectWithRaw(ctx, req.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(req.Entrypoint) == 0 {
|
||||
req.Entrypoint = imageInfo.Config.Entrypoint
|
||||
}
|
||||
if len(req.Cmd) == 0 {
|
||||
req.Cmd = imageInfo.Config.Cmd
|
||||
}
|
||||
config, hostConf, networkConf, err := loadConfigInfo(true, req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
global.LOG.Infof("new container info %s has been made, now start to create", req.Name)
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, networkConf, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
_ = client.ContainerRemove(ctx, req.Name, types.ContainerRemoveOptions{RemoveVolumes: true, Force: true})
|
||||
|
||||
@@ -625,7 +625,7 @@ func loadFailedSecureDatas(line string) dto.SSHHistory {
|
||||
return data
|
||||
}
|
||||
index := 0
|
||||
if strings.Contains("line", " invalid user") {
|
||||
if strings.Contains(line, " invalid user") {
|
||||
index = 2
|
||||
}
|
||||
data = dto.SSHHistory{
|
||||
|
||||
@@ -133,3 +133,8 @@ var (
|
||||
var (
|
||||
ErrFirewall = "ErrFirewall"
|
||||
)
|
||||
|
||||
// cronjob
|
||||
var (
|
||||
ErrBashExecute = "ErrBashExecute"
|
||||
)
|
||||
|
||||
@@ -124,4 +124,7 @@ ErrConfigAlreadyExist: "A configuration file with the same name already exists"
|
||||
ErrUserFindErr: "Failed to find user {{ .name }} {{ .err }}"
|
||||
|
||||
#ssh
|
||||
ErrFirewall: "No firewalld or ufw service is detected. Please check and try again!"
|
||||
ErrFirewall: "No firewalld or ufw service is detected. Please check and try again!"
|
||||
|
||||
#cronjob
|
||||
ErrBashExecute: "Script execution error, please check the specific information in the task output text area."
|
||||
@@ -124,4 +124,7 @@ ErrConfigAlreadyExist: "已存在同名配置文件"
|
||||
ErrUserFindErr: "用戶 {{ .name }} 查找失敗 {{ .err }}"
|
||||
|
||||
#ssh
|
||||
ErrFirewall: "當前未檢測到系統 firewalld 或 ufw 服務,請檢查後重試!"
|
||||
ErrFirewall: "當前未檢測到系統 firewalld 或 ufw 服務,請檢查後重試!"
|
||||
|
||||
#cronjob
|
||||
ErrBashExecute: "腳本執行錯誤,請在任務輸出文本域中查看具體信息。"
|
||||
@@ -125,3 +125,6 @@ ErrUserFindErr: "用户 {{ .name }} 查找失败 {{ .err }}"
|
||||
|
||||
#ssh
|
||||
ErrFirewall: "当前未检测到系统 firewalld 或 ufw 服务,请检查后重试!"
|
||||
|
||||
#cronjob
|
||||
ErrBashExecute: "脚本执行错误,请在任务输出文本域中查看具体信息。"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -88,23 +89,16 @@ func ExecCronjobWithTimeOut(cmdStr string, workdir string, timeout time.Duration
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
output := new(bytes.Buffer)
|
||||
cmd.Stdout = io.MultiWriter(output, cmd.Stdout)
|
||||
cmd.Stderr = io.MultiWriter(output, cmd.Stderr)
|
||||
|
||||
err := cmd.Run()
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return "", buserr.New(constant.ErrCmdTimeout)
|
||||
}
|
||||
|
||||
errMsg := ""
|
||||
if len(stderr.String()) != 0 {
|
||||
errMsg = fmt.Sprintf("stderr:\n %s", stderr.String())
|
||||
}
|
||||
if len(stdout.String()) != 0 {
|
||||
if len(errMsg) != 0 {
|
||||
errMsg = fmt.Sprintf("%s \n\n; stdout:\n %s", errMsg, stdout.String())
|
||||
} else {
|
||||
errMsg = fmt.Sprintf("stdout:\n %s", stdout.String())
|
||||
}
|
||||
}
|
||||
return errMsg, err
|
||||
return output.String(), err
|
||||
}
|
||||
|
||||
func Execf(cmdStr string, a ...interface{}) (string, error) {
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package encrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/init/viper"
|
||||
)
|
||||
|
||||
func TestStringEncrypt(t *testing.T) {
|
||||
viper.Init()
|
||||
p, err := StringEncrypt("1Panel@2022")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println(p)
|
||||
}
|
||||
|
||||
func TestStringDecrypt(t *testing.T) {
|
||||
viper.Init()
|
||||
p, err := StringDecrypt("dXn5bVtea+KVLDrLJlpnPIJNfW8TAMmqX1QNMdSGp88=")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println(p)
|
||||
}
|
||||
@@ -269,7 +269,7 @@ func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
if parts[0] == "SCHEMA_NAME" || parts[0] == "information_schema" || parts[0] == "mysql" || parts[0] == "performance_schema" || parts[0] == "sys" || parts[0] == "recycle_bin" {
|
||||
if parts[0] == "SCHEMA_NAME" || parts[0] == "information_schema" || parts[0] == "mysql" || parts[0] == "performance_schema" || parts[0] == "sys" || parts[0] == "__recycle_bin__" || parts[0] == "recycle_bin" {
|
||||
continue
|
||||
}
|
||||
dataItem := SyncDBInfo{
|
||||
|
||||
@@ -279,7 +279,7 @@ func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
if err = rows.Scan(&dbName, &charsetName); err != nil {
|
||||
return datas, err
|
||||
}
|
||||
if dbName == "information_schema" || dbName == "mysql" || dbName == "performance_schema" || dbName == "sys" || dbName == "recycle_bin" {
|
||||
if dbName == "information_schema" || dbName == "mysql" || dbName == "performance_schema" || dbName == "sys" || dbName == "__recycle_bin__" || dbName == "recycle_bin" {
|
||||
continue
|
||||
}
|
||||
dataItem := SyncDBInfo{
|
||||
|
||||
@@ -192,7 +192,7 @@ const language = useI18n().locale.value;
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'app-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: 60,
|
||||
pageSize: Number(localStorage.getItem('app-page-size')) || 60,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
@@ -219,6 +219,7 @@ const search = async (req: App.AppReq) => {
|
||||
loading.value = true;
|
||||
req.pageSize = paginationConfig.pageSize;
|
||||
req.page = paginationConfig.currentPage;
|
||||
localStorage.setItem('app-page-size', req.pageSize + '');
|
||||
await SearchApp(req)
|
||||
.then((res) => {
|
||||
apps.value = res.data.items;
|
||||
|
||||
@@ -337,7 +337,7 @@ let timer: NodeJS.Timer | null = null;
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'app-installed-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
pageSize: Number(localStorage.getItem('app-installed-page-size')) || 20,
|
||||
total: 0,
|
||||
});
|
||||
const open = ref(false);
|
||||
@@ -415,6 +415,7 @@ const search = () => {
|
||||
loading.value = true;
|
||||
searchReq.page = paginationConfig.currentPage;
|
||||
searchReq.pageSize = paginationConfig.pageSize;
|
||||
localStorage.setItem('app-installed', searchReq.pageSize + '');
|
||||
SearchAppInstalled(searchReq)
|
||||
.then((res) => {
|
||||
data.value = res.data.items;
|
||||
|
||||
@@ -166,6 +166,7 @@ const search = async () => {
|
||||
let filterItem = filters.value;
|
||||
let params = {
|
||||
name: '',
|
||||
state: 'all',
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
filters: filterItem,
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('cronjob.cronSpec')" :min-width="120">
|
||||
<el-table-column :label="$t('cronjob.cronSpec')" show-overflow-tooltip :min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.specType.indexOf('N') === -1 || row.specType === 'perWeek'">
|
||||
{{ $t('cronjob.' + row.specType) }}
|
||||
@@ -159,7 +159,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<OperatrDialog @search="search" ref="dialogRef" />
|
||||
<OperateDialog @search="search" ref="dialogRef" />
|
||||
<Records @search="search" ref="dialogRecordRef" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -167,7 +167,7 @@
|
||||
<script lang="ts" setup>
|
||||
import TableSetting from '@/components/table-setting/index.vue';
|
||||
import Tooltip from '@/components/tooltip/index.vue';
|
||||
import OperatrDialog from '@/views/cronjob/operate/index.vue';
|
||||
import OperateDialog from '@/views/cronjob/operate/index.vue';
|
||||
import Records from '@/views/cronjob/record/index.vue';
|
||||
import { loadZero } from '@/utils/util';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
@@ -125,25 +125,30 @@
|
||||
<template #main>
|
||||
<div class="mainClass">
|
||||
<el-row :gutter="20" v-show="hasRecords" class="mainRowClass">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<div>
|
||||
<ul class="infinite-list" style="overflow: auto">
|
||||
<li
|
||||
<el-card
|
||||
v-for="(item, index) in records"
|
||||
:key="index"
|
||||
:class="item.id === currentRecord.id ? 'select-card' : 'primary-card'"
|
||||
@click="forDetail(item)"
|
||||
class="infinite-list-item"
|
||||
>
|
||||
<el-icon v-if="item.status === 'Success'"><Select /></el-icon>
|
||||
<el-icon v-if="item.status === 'Waiting'"><Loading /></el-icon>
|
||||
<el-icon v-if="item.status === 'Failed'"><CloseBold /></el-icon>
|
||||
<span v-if="item.id === currentRecord.id" style="color: red">
|
||||
<el-tag v-if="item.status === 'Success'" type="success">
|
||||
{{ $t('commons.status.success') }}
|
||||
</el-tag>
|
||||
<el-tag v-if="item.status === 'Waiting'" type="info">
|
||||
{{ $t('commons.status.waiting') }}
|
||||
</el-tag>
|
||||
<el-tag v-if="item.status === 'Failed'" type="danger">
|
||||
{{ $t('commons.status.failed') }}
|
||||
</el-tag>
|
||||
<span>
|
||||
{{ dateFormat(0, 0, item.startTime) }}
|
||||
</span>
|
||||
<span v-else>{{ dateFormat(0, 0, item.startTime) }}</span>
|
||||
</li>
|
||||
</el-card>
|
||||
</ul>
|
||||
<div style="margin-top: 10px; font-size: 12px; float: right">
|
||||
<div class="page-item">
|
||||
<el-pagination
|
||||
:page-size="searchInfo.pageSize"
|
||||
:current-page="searchInfo.page"
|
||||
@@ -158,7 +163,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-col :span="18">
|
||||
<el-form label-position="top" :v-key="refresh">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-form-item class="descriptionWide" v-if="isBackup()">
|
||||
@@ -714,36 +719,50 @@ defineExpose({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.infinite-list {
|
||||
height: calc(100vh - 435px);
|
||||
height: calc(100vh - 416px);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.infinite-list .infinite-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 30px;
|
||||
background: var(--el-color-primary-light-9);
|
||||
margin: 10px;
|
||||
color: var(--el-color-primary);
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
.el-card {
|
||||
border: var(--panel-border) !important;
|
||||
&:hover {
|
||||
box-shadow: 2px 2px 2px #888888;
|
||||
}
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 30px;
|
||||
background: var(--el-color-primary-light-9);
|
||||
margin: 10px;
|
||||
font-weight: 500;
|
||||
color: red;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.select-card {
|
||||
color: var(--el-color-primary);
|
||||
border: 1px solid var(--el-color-primary) !important;
|
||||
box-shadow: 2px 2px 2px #888888;
|
||||
&::before {
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
height: 40px;
|
||||
content: '';
|
||||
background: $primary-color;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
.el-tag {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.descriptionWide {
|
||||
width: 40%;
|
||||
}
|
||||
.description {
|
||||
width: 30%;
|
||||
}
|
||||
.page-item {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.mainClass {
|
||||
|
||||
@@ -269,7 +269,7 @@ const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'mysql-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
pageSize: Number(localStorage.getItem('mysql-page-size')) || 10,
|
||||
total: 0,
|
||||
orderBy: 'created_at',
|
||||
order: 'null',
|
||||
|
||||
@@ -59,32 +59,22 @@ onUnmounted(() => {
|
||||
|
||||
<style lang="scss">
|
||||
.router_card {
|
||||
--el-card-border-radius: 8px;
|
||||
--el-card-padding: 0 !important;
|
||||
padding: 0px;
|
||||
padding-bottom: 2px;
|
||||
padding-top: 2px;
|
||||
--el-card-padding: 0;
|
||||
}
|
||||
|
||||
.router_card_button {
|
||||
margin-left: 2px;
|
||||
.el-radio-button__inner {
|
||||
min-width: 100px;
|
||||
height: 100%;
|
||||
border: 0 !important;
|
||||
background-color: var(--panel-button-active) !important;
|
||||
box-shadow: none !important;
|
||||
border: 2px solid transparent !important;
|
||||
}
|
||||
|
||||
.el-radio-button__original-radio:checked + .el-radio-button__inner {
|
||||
border-radius: 3px;
|
||||
color: $primary-color;
|
||||
background-color: var(--panel-button-active);
|
||||
box-shadow: 0 0 0 2px $primary-color !important;
|
||||
}
|
||||
|
||||
.el-radio-button:first-child .el-radio-button__inner {
|
||||
border-radius: 3px;
|
||||
color: $primary-color;
|
||||
background-color: var(--panel-button-active);
|
||||
box-shadow: 0 0 0 2px $primary-color !important;
|
||||
border-color: $primary-color !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -54,11 +54,18 @@
|
||||
prop="varsJson.code"
|
||||
:rules="rules.driveCode"
|
||||
>
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.varsJson['code']">
|
||||
<template #append>
|
||||
<el-button @click="jumpAzure">{{ $t('setting.loadCode') }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<div style="width: 100%">
|
||||
<el-input
|
||||
style="width: calc(100% - 80px)"
|
||||
:autosize="{ minRows: 3, maxRows: 15 }"
|
||||
type="textarea"
|
||||
clearable
|
||||
v-model.trim="dialogData.rowData!.varsJson['code']"
|
||||
/>
|
||||
<el-button class="append-button" @click="jumpAzure">
|
||||
{{ $t('setting.loadCode') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<span class="input-help">
|
||||
{{ $t('setting.codeHelper') }}
|
||||
<el-link
|
||||
@@ -269,7 +276,7 @@ const rules = reactive({
|
||||
driveCode: [{ validator: checkDriveCode, required: true, trigger: 'blur' }],
|
||||
});
|
||||
function checkDriveCode(rule: any, value: any, callback: any) {
|
||||
const reg = /^[A-Za-z0-9_.-]{32,60}$/;
|
||||
const reg = /^[A-Za-z0-9_.-]+$/;
|
||||
if (!reg.test(value)) {
|
||||
return callback(new Error(i18n.global.t('setting.codeWarning')));
|
||||
}
|
||||
@@ -421,3 +428,11 @@ defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.append-button {
|
||||
width: 80px;
|
||||
background-color: var(--el-fill-color-light);
|
||||
color: var(--el-color-info);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -248,7 +248,7 @@ let groups = ref<Group.GroupInfo[]>([]);
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'website-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
pageSize: Number(localStorage.getItem('website-page-size')) || 10,
|
||||
total: 0,
|
||||
});
|
||||
let req = reactive({
|
||||
|
||||
Reference in New Issue
Block a user