mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-09 16:00:29 +00:00
Compare commits
44
Commits
v1.5.0
...
release-1.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7145d4ca07 | ||
|
|
9683a23fda | ||
|
|
5e182d84d0 | ||
|
|
9800e7e03d | ||
|
|
cbf4f8ec36 | ||
|
|
3e3b1f2c56 | ||
|
|
e5a7f104f1 | ||
|
|
17062da52e | ||
|
|
512c7daeee | ||
|
|
ff120c421e | ||
|
|
4d5993c6ab | ||
|
|
627e1e3755 | ||
|
|
0eee2d9807 | ||
|
|
f0e78c4b7c | ||
|
|
6da64f2c8f | ||
|
|
d572c28d1c | ||
|
|
7fac0fcbe8 | ||
|
|
cb1b6742d4 | ||
|
|
27bd4a63ef | ||
|
|
62d628c1aa | ||
|
|
06f81fc7f7 | ||
|
|
23c72c8301 | ||
|
|
280e74e01b | ||
|
|
b7dada93da | ||
|
|
9447936cc3 | ||
|
|
5e7429cd51 | ||
|
|
7a3716a363 | ||
|
|
5e38723cc1 | ||
|
|
a0456d0f7a | ||
|
|
35b8532eaa | ||
|
|
b78b0e67ac | ||
|
|
384fc84039 | ||
|
|
7ad6e607fe | ||
|
|
27100594a4 | ||
|
|
0d687daa13 | ||
|
|
ad78edda64 | ||
|
|
3e6cd1cab1 | ||
|
|
98df3806f5 | ||
|
|
18e8af6234 | ||
|
|
5bbda8f842 | ||
|
|
85f8c1e634 | ||
|
|
85c935ee46 | ||
|
|
b4033471e7 | ||
|
|
8dca519068 |
@@ -189,6 +189,21 @@ func (b *BaseApi) GetProcess(c *gin.Context) {
|
||||
helper.SuccessWithData(c, configs)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Load Supervisor process status
|
||||
// @Description 获取 Supervisor 进程状态
|
||||
// @Success 200 {array} response.ProcessStatus
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process/load [post]
|
||||
func (b *BaseApi) LoadProcessStatus(c *gin.Context) {
|
||||
datas, err := hostToolService.LoadProcessStatus()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, datas)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get Supervisor process config
|
||||
// @Description 操作 Supervisor 进程文件
|
||||
|
||||
@@ -34,6 +34,28 @@ func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Check remote database
|
||||
// @Description 检测远程数据库连接性
|
||||
// @Accept json
|
||||
// @Param request body dto.RemoteDBCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/check [post]
|
||||
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测远程数据库 [name][type] 连接性","formatEN":"check if remote database [name][type] is connectable"}
|
||||
func (b *BaseApi) CheckeRemoteDB(c *gin.Context) {
|
||||
var req dto.RemoteDBCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, remoteDBService.CheckeRemoteDB(req))
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Page remote databases
|
||||
// @Description 获取远程数据库列表分页
|
||||
|
||||
@@ -67,7 +67,8 @@ type LocalAppInstallDefine struct {
|
||||
}
|
||||
|
||||
type ExtraProperties struct {
|
||||
Tags []Tag `json:"tags"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type AppProperty struct {
|
||||
|
||||
@@ -668,6 +668,21 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
|
||||
res.CanUpdate = true
|
||||
return res, err
|
||||
}
|
||||
if err = getAppFromRepo(fmt.Sprintf("%s/%s/1panel.json.zip", global.CONF.System.AppRepo, global.CONF.System.Mode)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listFile := path.Join(constant.ResourceDir, "1panel.json")
|
||||
content, err := os.ReadFile(listFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := &dto.AppList{}
|
||||
if err = json.Unmarshal(content, list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list.Extra.Version != "" && setting.SystemVersion != list.Extra.Version && !common.CompareVersion(setting.SystemVersion, list.Extra.Version) {
|
||||
return nil, buserr.New("ErrVersionTooLow")
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -766,7 +781,8 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
version := v.Name
|
||||
detail := detailsMap[version]
|
||||
|
||||
dockerComposeUrl := fmt.Sprintf("%s/%s/%s/%s", baseRemoteUrl, app.Key, version, "docker-compose.yml")
|
||||
remoteVersionUrl := fmt.Sprintf("%s/%s/%s", baseRemoteUrl, app.Key, version)
|
||||
dockerComposeUrl := fmt.Sprintf("%s/%s", remoteVersionUrl, "docker-compose.yml")
|
||||
composeRes, err := http.Get(dockerComposeUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -779,7 +795,7 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
||||
|
||||
paramByte, _ := json.Marshal(v.AppForm)
|
||||
detail.Params = string(paramByte)
|
||||
detail.DownloadUrl = v.DownloadUrl
|
||||
detail.DownloadUrl = fmt.Sprintf("%s/%s", remoteVersionUrl, version+".tar.gz")
|
||||
detail.DownloadCallBackUrl = v.DownloadCallBackUrl
|
||||
detail.Update = true
|
||||
detail.LastModified = v.LastModified
|
||||
|
||||
@@ -341,6 +341,24 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
|
||||
install.Version = detail.Version
|
||||
install.AppDetailId = detailId
|
||||
|
||||
images, err := getImages(install)
|
||||
if err != nil {
|
||||
upErr = err
|
||||
return
|
||||
}
|
||||
dockerCli, err := composeV2.NewClient()
|
||||
if err != nil {
|
||||
upErr = err
|
||||
return
|
||||
}
|
||||
|
||||
for _, image := range images {
|
||||
if err = dockerCli.PullImage(image, true); err != nil {
|
||||
upErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if out, err := compose.Down(install.GetComposePath()); err != nil {
|
||||
if out != "" {
|
||||
upErr = errors.New(out)
|
||||
@@ -398,6 +416,26 @@ func getContainerNames(install model.AppInstall) ([]string, error) {
|
||||
return containerNames, nil
|
||||
}
|
||||
|
||||
func getImages(install model.AppInstall) ([]string, error) {
|
||||
envStr, err := coverEnvJsonToStr(install.Env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
project, err := composeV2.GetComposeProject(install.Name, install.GetPath(), []byte(install.DockerCompose), []byte(envStr), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imagesMap := make(map[string]struct{})
|
||||
for _, service := range project.AllServices() {
|
||||
imagesMap[service.Image] = struct{}{}
|
||||
}
|
||||
var images []string
|
||||
for k := range imagesMap {
|
||||
images = append(images, k)
|
||||
}
|
||||
return images, nil
|
||||
}
|
||||
|
||||
func coverEnvJsonToStr(envJson string) (string, error) {
|
||||
envMap := make(map[string]interface{})
|
||||
_ = json.Unmarshal([]byte(envJson), &envMap)
|
||||
@@ -802,6 +840,10 @@ func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]respons
|
||||
}
|
||||
versions = common.GetSortedVersions(versions)
|
||||
if len(versions) == 0 {
|
||||
if !updated {
|
||||
installDTO.CanUpdate = false
|
||||
res = append(res, installDTO)
|
||||
}
|
||||
continue
|
||||
}
|
||||
lastVersion := versions[0]
|
||||
|
||||
@@ -531,11 +531,15 @@ func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
container, err := client.ContainerInspect(context.Background(), req.Name)
|
||||
ctx := context.Background()
|
||||
containerItem, err := client.ContainerInspect(ctx, req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.OpenFile(container.LogPath, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err := client.ContainerStop(ctx, containerItem.ID, container.StopOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.OpenFile(containerItem.LogPath, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -545,10 +549,14 @@ func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
|
||||
}
|
||||
_, _ = file.Seek(0, 0)
|
||||
|
||||
files, _ := filepath.Glob(fmt.Sprintf("%s.*", container.LogPath))
|
||||
files, _ := filepath.Glob(fmt.Sprintf("%s.*", containerItem.LogPath))
|
||||
for _, file := range files {
|
||||
_ = os.Remove(file)
|
||||
}
|
||||
|
||||
if err := client.ContainerStart(ctx, containerItem.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -631,9 +639,9 @@ func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error
|
||||
func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) string {
|
||||
filePath := ""
|
||||
switch req.Type {
|
||||
case "image-pull", "image-push", "image-build":
|
||||
case "image-pull", "image-push", "image-build", "compose-create":
|
||||
filePath = path.Join(global.CONF.System.TmpDir, fmt.Sprintf("docker_logs/%s", req.Name))
|
||||
case "compose-detail", "compose-create":
|
||||
case "compose-detail":
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return ""
|
||||
|
||||
@@ -159,8 +159,15 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error)
|
||||
if req.From == "path" {
|
||||
req.Name = path.Base(path.Dir(req.Path))
|
||||
}
|
||||
logName := path.Dir(req.Path) + "/compose.log"
|
||||
file, err := os.OpenFile(logName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
|
||||
dockerLogDir := path.Join(global.CONF.System.TmpDir, "docker_logs")
|
||||
if _, err := os.Stat(dockerLogDir); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(dockerLogDir, os.ModePerm); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
logItem := fmt.Sprintf("%s/compose_create_%s_%s.log", dockerLogDir, req.Name, time.Now().Format("20060102150405"))
|
||||
file, err := os.OpenFile(logItem, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -181,7 +188,7 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error)
|
||||
_, _ = file.WriteString("docker-compose up successful!")
|
||||
}()
|
||||
|
||||
return req.Name, nil
|
||||
return path.Base(logItem), nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
||||
|
||||
@@ -221,12 +221,14 @@ func handleTar(sourceDir, targetDir, name, exclusionRules string) error {
|
||||
path = sourceDir
|
||||
}
|
||||
|
||||
commands := fmt.Sprintf("tar zcvf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
commands := fmt.Sprintf("tar --warning=no-file-changed -zcf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
global.LOG.Debug(commands)
|
||||
stdout, err := cmd.ExecWithTimeOut(commands, 24*time.Hour)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("do handle tar failed, stdout: %s, err: %v", stdout, err)
|
||||
return errors.New(stdout)
|
||||
if len(stdout) != 0 {
|
||||
global.LOG.Errorf("do handle tar failed, stdout: %s, err: %v", stdout, err)
|
||||
return fmt.Errorf("do handle tar failed, stdout: %s, err: %v", stdout, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -166,59 +166,52 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protos := strings.Split(req.Protocol, "/")
|
||||
if client.Name() == "ufw" {
|
||||
req.Port = strings.ReplaceAll(req.Port, "-", ":")
|
||||
if req.Operation == "remove" && req.Protocol == "tcp/udp" {
|
||||
req.Protocol = ""
|
||||
return u.operatePort(client, req)
|
||||
if len(req.Address) == 0 {
|
||||
req.Address = "Anywhere"
|
||||
}
|
||||
if strings.Contains(req.Port, ",") || strings.Contains(req.Port, "-") {
|
||||
for _, proto := range protos {
|
||||
req.Port = strings.ReplaceAll(req.Port, "-", ":")
|
||||
req.Protocol = proto
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if req.Protocol == "tcp/udp" {
|
||||
req.Protocol = ""
|
||||
}
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if req.Protocol == "tcp/udp" {
|
||||
if client.Name() == "firewalld" && strings.Contains(req.Port, ",") {
|
||||
ports := strings.Split(req.Port, ",")
|
||||
|
||||
itemPorts := req.Port
|
||||
for _, proto := range protos {
|
||||
if strings.Contains(req.Port, "-") {
|
||||
req.Protocol = proto
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ports := strings.Split(itemPorts, ",")
|
||||
for _, port := range ports {
|
||||
if len(port) == 0 {
|
||||
continue
|
||||
}
|
||||
req.Port = port
|
||||
req.Protocol = "tcp"
|
||||
req.Protocol = proto
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Protocol = "udp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
req.Protocol = "tcp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Protocol = "udp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if strings.Contains(req.Port, ",") {
|
||||
ports := strings.Split(req.Port, ",")
|
||||
for _, port := range ports {
|
||||
req.Port = port
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if reload {
|
||||
return client.Reload()
|
||||
}
|
||||
return nil
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func (u *FirewallService) OperateAddressRule(req dto.AddrRuleOperate, reload bool) error {
|
||||
|
||||
@@ -3,6 +3,14 @@ package service
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
@@ -14,11 +22,6 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/systemctl"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/ini.v1"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HostToolService struct{}
|
||||
@@ -31,6 +34,7 @@ type IHostToolService interface {
|
||||
GetToolLog(req request.HostToolLogReq) (string, error)
|
||||
OperateSupervisorProcess(req request.SupervisorProcessConfig) error
|
||||
GetSupervisorProcessConfig() ([]response.SupervisorProcessConfig, error)
|
||||
LoadProcessStatus() ([]response.ProcessStatus, error)
|
||||
OperateSupervisorProcessFile(req request.SupervisorProcessFileReq) (string, error)
|
||||
}
|
||||
|
||||
@@ -323,7 +327,10 @@ func (h *HostToolService) OperateSupervisorProcess(req request.SupervisorProcess
|
||||
if err = configFile.SaveTo(iniPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return operateSupervisorCtl("reload", "", "")
|
||||
if err := operateSupervisorCtl("reread", "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return operateSupervisorCtl("update", "", "")
|
||||
case "update":
|
||||
configFile, err := ini.Load(iniPath)
|
||||
if err != nil {
|
||||
@@ -346,7 +353,10 @@ func (h *HostToolService) OperateSupervisorProcess(req request.SupervisorProcess
|
||||
if err = configFile.SaveTo(iniPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return operateSupervisorCtl("reload", "", "")
|
||||
if err := operateSupervisorCtl("reread", "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return operateSupervisorCtl("update", "", "")
|
||||
case "restart":
|
||||
return operateSupervisorCtl("restart", req.Name, "")
|
||||
case "start":
|
||||
@@ -358,12 +368,65 @@ func (h *HostToolService) OperateSupervisorProcess(req request.SupervisorProcess
|
||||
_ = files.NewFileOp().DeleteFile(iniPath)
|
||||
_ = files.NewFileOp().DeleteFile(outLog)
|
||||
_ = files.NewFileOp().DeleteFile(errLog)
|
||||
_ = operateSupervisorCtl("reload", "", "")
|
||||
if err := operateSupervisorCtl("reread", "", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
return operateSupervisorCtl("update", "", "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *HostToolService) LoadProcessStatus() ([]response.ProcessStatus, error) {
|
||||
var res []response.ProcessStatus
|
||||
statusLines, _ := cmd.Exec("supervisorctl status")
|
||||
if len(statusLines) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
lines := strings.Split(statusLines, "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) > 1 {
|
||||
res = append(res, response.ProcessStatus{Name: fields[0]})
|
||||
}
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(res))
|
||||
for i := 0; i < len(res); i++ {
|
||||
go func(index int) {
|
||||
for t := 0; t < 3; t++ {
|
||||
status, err := cmd.ExecWithTimeOut(fmt.Sprintf("supervisorctl status %s", res[index].Name), 2*time.Second)
|
||||
if err != nil {
|
||||
time.Sleep(2 * time.Second)
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(status)
|
||||
if len(fields) < 5 {
|
||||
time.Sleep(2 * time.Second)
|
||||
continue
|
||||
}
|
||||
res[index].Name = fields[0]
|
||||
res[index].Status = fields[1]
|
||||
if fields[1] != "RUNNING" {
|
||||
res[index].Msg = strings.Join(fields[2:], " ")
|
||||
break
|
||||
}
|
||||
res[index].PID = strings.TrimSuffix(fields[3], ",")
|
||||
res[index].Uptime = fields[5]
|
||||
break
|
||||
}
|
||||
if len(res[index].Status) == 0 {
|
||||
res[index].Status = "FATAL"
|
||||
res[index].Msg = "Timeout for getting process status"
|
||||
}
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (h *HostToolService) GetSupervisorProcessConfig() ([]response.SupervisorProcessConfig, error) {
|
||||
var (
|
||||
result []response.SupervisorProcessConfig
|
||||
@@ -400,7 +463,6 @@ func (h *HostToolService) GetSupervisorProcessConfig() ([]response.SupervisorPro
|
||||
if numprocs, _ := section.GetKey("numprocs"); numprocs != nil {
|
||||
config.Numprocs = numprocs.Value()
|
||||
}
|
||||
_ = getProcessStatus(&config)
|
||||
result = append(result, config)
|
||||
}
|
||||
}
|
||||
@@ -528,29 +590,3 @@ func getProcessName(name, numprocs string) []string {
|
||||
}
|
||||
return processNames
|
||||
}
|
||||
|
||||
func getProcessStatus(config *response.SupervisorProcessConfig) error {
|
||||
var (
|
||||
processNames = []string{"status"}
|
||||
)
|
||||
processNames = append(processNames, getProcessName(config.Name, config.Numprocs)...)
|
||||
output, _ := exec.Command("supervisorctl", processNames...).Output()
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 5 {
|
||||
status := response.ProcessStatus{
|
||||
Name: fields[0],
|
||||
Status: fields[1],
|
||||
}
|
||||
if fields[1] == "RUNNING" {
|
||||
status.PID = strings.TrimSuffix(fields[3], ",")
|
||||
status.Uptime = fields[5]
|
||||
} else {
|
||||
status.Msg = strings.Join(fields[2:], " ")
|
||||
}
|
||||
config.Status = append(config.Status, status)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -123,7 +123,6 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
fileName := "Dockerfile"
|
||||
dockerLogDir := path.Join(global.CONF.System.TmpDir, "docker_logs")
|
||||
if req.From == "edit" {
|
||||
dir := fmt.Sprintf("%s/docker/build/%s", constant.DataDir, strings.ReplaceAll(req.Name, ":", "_"))
|
||||
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
||||
@@ -158,6 +157,12 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
||||
Labels: stringsToMap(req.Tags),
|
||||
}
|
||||
|
||||
dockerLogDir := path.Join(global.CONF.System.TmpDir, "docker_logs")
|
||||
if _, err := os.Stat(dockerLogDir); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(dockerLogDir, os.ModePerm); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
logItem := fmt.Sprintf("%s/image_build_%s_%s.log", dockerLogDir, strings.ReplaceAll(req.Name, ":", "_"), time.Now().Format("20060102150405"))
|
||||
file, err := os.OpenFile(logItem, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,6 +16,7 @@ type RemoteDBService struct{}
|
||||
type IRemoteDBService interface {
|
||||
Get(name string) (dto.RemoteDBInfo, error)
|
||||
SearchWithPage(search dto.RemoteDBSearch) (int64, interface{}, error)
|
||||
CheckeRemoteDB(req dto.RemoteDBCreate) bool
|
||||
Create(req dto.RemoteDBCreate) error
|
||||
Update(req dto.RemoteDBUpdate) error
|
||||
Delete(id uint) error
|
||||
@@ -68,6 +69,20 @@ func (u *RemoteDBService) List(dbType string) ([]dto.RemoteDBOption, error) {
|
||||
return datas, err
|
||||
}
|
||||
|
||||
func (u *RemoteDBService) CheckeRemoteDB(req dto.RemoteDBCreate) bool {
|
||||
if _, err := mysql.NewMysqlClient(client.DBInfo{
|
||||
From: "remote",
|
||||
Address: req.Address,
|
||||
Port: req.Port,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Timeout: 6,
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (u *RemoteDBService) Create(req dto.RemoteDBCreate) error {
|
||||
db, _ := remoteDBRepo.Get(commonRepo.WithByName(req.Name))
|
||||
if db.ID != 0 {
|
||||
@@ -79,7 +94,7 @@ func (u *RemoteDBService) Create(req dto.RemoteDBCreate) error {
|
||||
Port: req.Port,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Timeout: 300,
|
||||
Timeout: 6,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -61,3 +61,18 @@ func WithMap(Key string, maps map[string]interface{}, err error) BusinessError {
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func WithNameAndErr(Key string, name string, err error) BusinessError {
|
||||
paramMap := map[string]interface{}{}
|
||||
if name != "" {
|
||||
paramMap["name"] = name
|
||||
}
|
||||
if err != nil {
|
||||
paramMap["err"] = err.Error()
|
||||
}
|
||||
return BusinessError{
|
||||
Msg: Key,
|
||||
Map: paramMap,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ ErrImagePullTimeOut: 'Image pull timeout'
|
||||
ErrContainerNotFound: '{{ .name }} container does not exist'
|
||||
ErrContainerMsg: '{{ .name }} container is abnormal, please check the log on the container page for details'
|
||||
ErrAppBackup: '{{ .name }} application backup failed err {{.err}}'
|
||||
ErrImagePull: '{{ .name }} image pull failed err {{.err}}'
|
||||
ErrVersionTooLow: 'The current 1Panel version is too low to update the app store, please upgrade the version'
|
||||
|
||||
#file
|
||||
ErrFileCanNotRead: "File can not read"
|
||||
|
||||
@@ -45,6 +45,8 @@ ErrImagePullTimeOut: "鏡像拉取超時"
|
||||
ErrContainerNotFound: '{{ .name }} 容器不存在'
|
||||
ErrContainerMsg: '{{ .name }} 容器異常,具體請在容器頁面查看日誌'
|
||||
ErrAppBackup: '{{ .name }} 應用備份失敗 err {{.err}}'
|
||||
ErrImagePull: '{{ .name }} 鏡像拉取失敗 err {{.err}}'
|
||||
ErrVersionTooLow: '當前 1Panel 版本過低,無法更新應用商店,請升級版本之後操作'
|
||||
|
||||
#file
|
||||
ErrFileCanNotRead: "此文件不支持預覽"
|
||||
|
||||
@@ -45,6 +45,8 @@ ErrImagePullTimeOut: '镜像拉取超时'
|
||||
ErrContainerNotFound: '{{ .name }} 容器不存在'
|
||||
ErrContainerMsg: '{{ .name }} 容器异常,具体请在容器页面查看日志'
|
||||
ErrAppBackup: '{{ .name }} 应用备份失败 err {{.err}}'
|
||||
ErrImagePull: '镜像拉取失败 {{.err}}'
|
||||
ErrVersionTooLow: '当前 1Panel 版本过低,无法更新应用商店,请升级版本之后操作'
|
||||
|
||||
#file
|
||||
ErrFileCanNotRead: "此文件不支持预览"
|
||||
|
||||
@@ -43,6 +43,7 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
|
||||
cmdRouter.POST("/redis/conffile/update", baseApi.UpdateRedisConfByFile)
|
||||
cmdRouter.POST("/redis/persistence/update", baseApi.UpdateRedisPersistenceConf)
|
||||
|
||||
cmdRouter.POST("/remote/check", baseApi.CheckeRemoteDB)
|
||||
cmdRouter.POST("/remote", baseApi.CreateRemoteDB)
|
||||
cmdRouter.GET("/remote/:name", baseApi.GetRemoteDB)
|
||||
cmdRouter.GET("/remote/list/:type", baseApi.ListRemoteDB)
|
||||
|
||||
@@ -54,6 +54,7 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
||||
hostRouter.POST("/tool/operate", baseApi.OperateTool)
|
||||
hostRouter.POST("/tool/config", baseApi.OperateToolConfig)
|
||||
hostRouter.POST("/tool/log", baseApi.GetToolLog)
|
||||
hostRouter.POST("/tool/supervisor/process/load", baseApi.LoadProcessStatus)
|
||||
hostRouter.POST("/tool/supervisor/process", baseApi.OperateProcess)
|
||||
hostRouter.GET("/tool/supervisor/process", baseApi.GetProcess)
|
||||
hostRouter.POST("/tool/supervisor/process/file", baseApi.GetProcessFile)
|
||||
|
||||
@@ -4,11 +4,7 @@ import (
|
||||
"context"
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/compose"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/joho/godotenv"
|
||||
"path"
|
||||
"regexp"
|
||||
@@ -21,24 +17,6 @@ type ComposeService struct {
|
||||
project *types.Project
|
||||
}
|
||||
|
||||
func NewComposeService(ops ...command.DockerCliOption) (*ComposeService, error) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ops = append(ops, command.WithAPIClient(apiClient), command.WithDefaultContextStoreConfig())
|
||||
cli, err := command.NewDockerCli(ops...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cliOp := flags.NewClientOptions()
|
||||
if err := cli.Initialize(cliOp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service := compose.NewComposeService(cli)
|
||||
return &ComposeService{service, nil}, nil
|
||||
}
|
||||
|
||||
func (s *ComposeService) SetProject(project *types.Project) {
|
||||
s.project = project
|
||||
for i, s := range project.Services {
|
||||
|
||||
@@ -72,6 +72,22 @@ func (c Client) DeleteImage(imageID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Client) PullImage(imageName string, force bool) error {
|
||||
if !force {
|
||||
exist, err := c.CheckImageExist(imageName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if _, err := c.cli.ImagePull(context.Background(), imageName, types.ImagePullOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Client) GetImageIDByName(imageName string) (string, error) {
|
||||
filter := filters.NewArgs()
|
||||
filter.Add("reference", imageName)
|
||||
@@ -87,6 +103,18 @@ func (c Client) GetImageIDByName(imageName string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (c Client) CheckImageExist(imageName string) (bool, error) {
|
||||
filter := filters.NewArgs()
|
||||
filter.Add("reference", imageName)
|
||||
list, err := c.cli.ImageList(context.Background(), types.ImageListOptions{
|
||||
Filters: filter,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(list) > 0, nil
|
||||
}
|
||||
|
||||
func (c Client) NetworkExist(name string) bool {
|
||||
var options types.NetworkListOptions
|
||||
options.Filters = filters.NewArgs(filters.Arg("name", name))
|
||||
|
||||
@@ -518,6 +518,13 @@ func (f FileOp) Decompress(srcFile string, dst string, cType CompressType) error
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
parentDir := path.Dir(filePath)
|
||||
if !f.Stat(parentDir) {
|
||||
if err := f.Fs.MkdirAll(parentDir, info.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
fr, err := archFile.Open()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/mysql/client"
|
||||
)
|
||||
|
||||
@@ -26,9 +27,6 @@ type MysqlClient interface {
|
||||
|
||||
func NewMysqlClient(conn client.DBInfo) (MysqlClient, error) {
|
||||
if conn.From == "local" {
|
||||
if cmd.CheckIllegal(conn.Address, conn.Username, conn.Password) {
|
||||
return nil, buserr.New(constant.ErrCmdIllegal)
|
||||
}
|
||||
connArgs := []string{"exec", conn.Address, "mysql", "-u" + conn.Username, "-p" + conn.Password, "-e"}
|
||||
return client.NewLocal(connArgs, conn.Address, conn.Password, conn.From), nil
|
||||
}
|
||||
@@ -38,9 +36,16 @@ func NewMysqlClient(conn client.DBInfo) (MysqlClient, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Ping(); err != nil {
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conn.Timeout)*time.Second)
|
||||
defer cancel()
|
||||
if err := db.PingContext(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return nil, buserr.New(constant.ErrExecTimeOut)
|
||||
}
|
||||
|
||||
return client.NewRemote(client.Remote{
|
||||
Client: db,
|
||||
From: conn.From,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
)
|
||||
|
||||
type DBInfo struct {
|
||||
From string `json:"from"`
|
||||
Address string `json:"address"`
|
||||
@@ -85,3 +91,16 @@ var formatMap = map[string]string{
|
||||
"gbk": "gbk_chinese_ci",
|
||||
"big5": "big5_chinese_ci",
|
||||
}
|
||||
|
||||
func loadNameByDB(name, version string) string {
|
||||
if strings.HasPrefix(version, "5.6") {
|
||||
if len(name) <= 16 {
|
||||
return name
|
||||
}
|
||||
return strings.TrimSuffix(name[:10], "_") + "_" + common.RandStr(5)
|
||||
}
|
||||
if len(name) <= 32 {
|
||||
return name
|
||||
}
|
||||
return strings.TrimSuffix(name[:25], "_") + "_" + common.RandStr(5)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func (r *Local) Create(info CreateInfo) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := r.CreateUser(info); err != nil {
|
||||
if err := r.CreateUser(info, true); err != nil {
|
||||
_ = r.ExecSQL(fmt.Sprintf("drop database if exists `%s`", info.Name), info.Timeout)
|
||||
return err
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func (r *Local) Create(info CreateInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Local) CreateUser(info CreateInfo) error {
|
||||
func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error {
|
||||
var userlist []string
|
||||
if strings.Contains(info.Permission, ",") {
|
||||
ips := strings.Split(info.Permission, ",")
|
||||
@@ -147,7 +147,7 @@ func (r *Local) ChangePassword(info PasswordChangeInfo) error {
|
||||
for _, user := range userlist {
|
||||
passwordChangeSql := fmt.Sprintf("set password for %s = password('%s')", user, info.Password)
|
||||
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
|
||||
passwordChangeSql = fmt.Sprintf("ALTER USER %s IDENTIFIED WITH mysql_native_password BY '%s';", user, info.Password)
|
||||
passwordChangeSql = fmt.Sprintf("alter user %s identified by '%s';", user, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(passwordChangeSql, info.Timeout); err != nil {
|
||||
return err
|
||||
@@ -201,7 +201,7 @@ func (r *Local) ChangeAccess(info AccessChangeInfo) error {
|
||||
Password: info.Password,
|
||||
Permission: info.Permission,
|
||||
Timeout: info.Timeout,
|
||||
}); err != nil {
|
||||
}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.ExecSQL("flush privileges", 300); err != nil {
|
||||
@@ -276,7 +276,7 @@ func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
From: r.From,
|
||||
Format: parts[1],
|
||||
}
|
||||
userLines, err := r.ExecSQLForRows(fmt.Sprintf("SELECT USER,HOST FROM mysql.DB WHERE DB = '%s'", parts[0]), 300)
|
||||
userLines, err := r.ExecSQLForRows(fmt.Sprintf("select user,host from mysql.db where db = '%s'", parts[0]), 300)
|
||||
if err != nil {
|
||||
return datas, err
|
||||
}
|
||||
@@ -305,18 +305,18 @@ func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
}
|
||||
}
|
||||
if len(dataItem.Username) == 0 {
|
||||
dataItem.Username = loadNameByDB(parts[0], version)
|
||||
if err := r.CreateUser(CreateInfo{
|
||||
Name: parts[0],
|
||||
Format: parts[1],
|
||||
Version: version,
|
||||
Username: parts[0],
|
||||
Username: dataItem.Username,
|
||||
Password: common.RandStr(16),
|
||||
Permission: "%",
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
}, false); err != nil {
|
||||
global.LOG.Errorf("sync from remote server failed, err: create user failed %v", err)
|
||||
}
|
||||
dataItem.Username = parts[0]
|
||||
dataItem.Permission = "%"
|
||||
} else {
|
||||
if isLocal {
|
||||
|
||||
@@ -39,7 +39,7 @@ func (r *Remote) Create(info CreateInfo) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := r.CreateUser(info); err != nil {
|
||||
if err := r.CreateUser(info, true); err != nil {
|
||||
_ = r.ExecSQL(fmt.Sprintf("drop database if exists `%s`", info.Name), info.Timeout)
|
||||
return err
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func (r *Remote) Create(info CreateInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) CreateUser(info CreateInfo) error {
|
||||
func (r *Remote) CreateUser(info CreateInfo, withDeleteDB bool) error {
|
||||
var userlist []string
|
||||
if strings.Contains(info.Permission, ",") {
|
||||
ips := strings.Split(info.Permission, ",")
|
||||
@@ -62,15 +62,17 @@ func (r *Remote) CreateUser(info CreateInfo) error {
|
||||
|
||||
for _, user := range userlist {
|
||||
if err := r.ExecSQL(fmt.Sprintf("create user %s identified by '%s';", user, info.Password), info.Timeout); err != nil {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
Username: info.Username,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
if strings.Contains(err.Error(), "ERROR 1396") {
|
||||
return buserr.New(constant.ErrUserIsExist)
|
||||
if withDeleteDB {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
Username: info.Username,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
if strings.Contains(err.Error(), "ERROR 1396") {
|
||||
return buserr.New(constant.ErrUserIsExist)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -82,13 +84,15 @@ func (r *Remote) CreateUser(info CreateInfo) error {
|
||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(grantStr, info.Timeout); err != nil {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
Username: info.Username,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
if withDeleteDB {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
Username: info.Username,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -202,7 +206,7 @@ func (r *Remote) ChangeAccess(info AccessChangeInfo) error {
|
||||
Password: info.Password,
|
||||
Permission: info.Permission,
|
||||
Timeout: info.Timeout,
|
||||
}); err != nil {
|
||||
}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.ExecSQL("flush privileges", 300); err != nil {
|
||||
@@ -263,7 +267,7 @@ func (r *Remote) Recover(info RecoverInfo) error {
|
||||
|
||||
func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
var datas []SyncDBInfo
|
||||
rows, err := r.Client.Query("SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA")
|
||||
rows, err := r.Client.Query("select schema_name, default_character_set_name from information_schema.SCHEMATA")
|
||||
if err != nil {
|
||||
return datas, err
|
||||
}
|
||||
@@ -283,7 +287,7 @@ func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
MysqlName: r.From,
|
||||
Format: charsetName,
|
||||
}
|
||||
userRows, err := r.Client.Query("SELECT USER,HOST FROM mysql.DB WHERE DB = ?", dbName)
|
||||
userRows, err := r.Client.Query("select user,host from mysql.db where db = ?", dbName)
|
||||
if err != nil {
|
||||
return datas, err
|
||||
}
|
||||
@@ -312,18 +316,18 @@ func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
i++
|
||||
}
|
||||
if len(dataItem.Username) == 0 {
|
||||
dataItem.Username = loadNameByDB(dbName, version)
|
||||
if err := r.CreateUser(CreateInfo{
|
||||
Name: dbName,
|
||||
Format: charsetName,
|
||||
Version: version,
|
||||
Username: dbName,
|
||||
Username: dataItem.Username,
|
||||
Password: common.RandStr(16),
|
||||
Permission: "%",
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
global.LOG.Errorf("sync from remote server failed, err: create user failed %v", err)
|
||||
}, false); err != nil {
|
||||
return datas, fmt.Errorf("sync db from remote server failed, err: create user failed %v", err)
|
||||
}
|
||||
dataItem.Username = dbName
|
||||
dataItem.Permission = "%"
|
||||
} else {
|
||||
if isLocal {
|
||||
|
||||
@@ -3,11 +3,12 @@ package cmd
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/cmd/server/app"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,6 +32,10 @@ var initCmd = &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "初始化应用",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl app init 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
if len(args) > 0 {
|
||||
appKey = args[0]
|
||||
if len(args) > 1 {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -22,6 +24,10 @@ var resetMFACmd = &cobra.Command{
|
||||
Use: "mfa",
|
||||
Short: "取消 1Panel 两步验证",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl reset mfa 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -34,6 +40,10 @@ var resetSSLCmd = &cobra.Command{
|
||||
Use: "https",
|
||||
Short: "取消 1Panel https 方式登录",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl reset https 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -46,6 +56,10 @@ var resetEntranceCmd = &cobra.Command{
|
||||
Use: "entrance",
|
||||
Short: "取消 1Panel 安全入口",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl reset entrance 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -58,6 +72,10 @@ var resetBindIpsCmd = &cobra.Command{
|
||||
Use: "ips",
|
||||
Short: "取消 1Panel 授权 IP 限制",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl reset ips 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -70,6 +88,10 @@ var resetDomainCmd = &cobra.Command{
|
||||
Use: "domain",
|
||||
Short: "取消 1Panel 访问域名绑定",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl reset domain 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/user"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -61,3 +62,11 @@ func getSettingByKey(db *gorm.DB, key string) string {
|
||||
func setSettingByKey(db *gorm.DB, key, value string) error {
|
||||
return db.Model(&setting{}).Where("key = ?", key).Updates(map[string]interface{}{"value": value}).Error
|
||||
}
|
||||
|
||||
func isRoot() bool {
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return currentUser.Uid == "0"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ var userinfoCmd = &cobra.Command{
|
||||
Use: "user-info",
|
||||
Short: "获取用户信息",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl user-info 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return fmt.Errorf("init my db conn failed, err: %v \n", err)
|
||||
|
||||
@@ -18,6 +18,10 @@ var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "获取系统版本信息",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !isRoot() {
|
||||
fmt.Println("请使用 sudo 1pctl version 或者切换到 root 用户")
|
||||
return nil
|
||||
}
|
||||
db, err := loadDBConn()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+96
-5
@@ -4410,6 +4410,49 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/remote/check": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "检测远程数据库连接性",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database"
|
||||
],
|
||||
"summary": "Check remote database",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.RemoteDBCreate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"formatEN": "check if remote database [name][type] is connectable",
|
||||
"formatZH": "检测远程数据库 [name][type] 连接性",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/remote/del": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -6297,6 +6340,31 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/host/tool/supervisor/process/load": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取 Supervisor 进程状态",
|
||||
"tags": [
|
||||
"Host tool"
|
||||
],
|
||||
"summary": "Load Supervisor process status",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/response.ProcessStatus"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/hosts": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -11621,7 +11689,6 @@ const docTemplate = `{
|
||||
"dto.ChangeDBInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"from",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
@@ -12923,13 +12990,15 @@ const docTemplate = `{
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13776,7 +13845,8 @@ const docTemplate = `{
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
@@ -13817,7 +13887,8 @@ const docTemplate = `{
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
@@ -16978,6 +17049,26 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.ProcessStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"PID": {
|
||||
"type": "string"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"uptime": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.WebsiteAcmeAccountDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -4403,6 +4403,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/remote/check": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "检测远程数据库连接性",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database"
|
||||
],
|
||||
"summary": "Check remote database",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.RemoteDBCreate"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"formatEN": "check if remote database [name][type] is connectable",
|
||||
"formatZH": "检测远程数据库 [name][type] 连接性",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/remote/del": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -6290,6 +6333,31 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/host/tool/supervisor/process/load": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "获取 Supervisor 进程状态",
|
||||
"tags": [
|
||||
"Host tool"
|
||||
],
|
||||
"summary": "Load Supervisor process status",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/response.ProcessStatus"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/hosts": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -11614,7 +11682,6 @@
|
||||
"dto.ChangeDBInfo": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"from",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
@@ -12916,13 +12983,15 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13769,7 +13838,8 @@
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
@@ -13810,7 +13880,8 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
@@ -16971,6 +17042,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.ProcessStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"PID": {
|
||||
"type": "string"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"uptime": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.WebsiteAcmeAccountDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -127,7 +127,6 @@ definitions:
|
||||
value:
|
||||
type: string
|
||||
required:
|
||||
- from
|
||||
- value
|
||||
type: object
|
||||
dto.ChangeHostGroup:
|
||||
@@ -1000,10 +999,12 @@ definitions:
|
||||
id:
|
||||
type: integer
|
||||
password:
|
||||
maxLength: 256
|
||||
type: string
|
||||
protocol:
|
||||
type: string
|
||||
username:
|
||||
maxLength: 256
|
||||
type: string
|
||||
type: object
|
||||
dto.ImageSave:
|
||||
@@ -1565,6 +1566,7 @@ definitions:
|
||||
- remote
|
||||
type: string
|
||||
name:
|
||||
maxLength: 256
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
@@ -1599,6 +1601,7 @@ definitions:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
maxLength: 256
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
@@ -3711,6 +3714,19 @@ definitions:
|
||||
uploadMaxSize:
|
||||
type: string
|
||||
type: object
|
||||
response.ProcessStatus:
|
||||
properties:
|
||||
PID:
|
||||
type: string
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
uptime:
|
||||
type: string
|
||||
type: object
|
||||
response.WebsiteAcmeAccountDTO:
|
||||
properties:
|
||||
createdAt:
|
||||
@@ -6648,6 +6664,34 @@ paths:
|
||||
summary: Get remote databases
|
||||
tags:
|
||||
- Database
|
||||
/databases/remote/check:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 检测远程数据库连接性
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.RemoteDBCreate'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Check remote database
|
||||
tags:
|
||||
- Database
|
||||
x-panel-log:
|
||||
BeforeFuntions: []
|
||||
bodyKeys:
|
||||
- name
|
||||
- type
|
||||
formatEN: check if remote database [name][type] is connectable
|
||||
formatZH: 检测远程数据库 [name][type] 连接性
|
||||
paramKeys: []
|
||||
/databases/remote/del:
|
||||
post:
|
||||
consumes:
|
||||
@@ -7849,6 +7893,21 @@ paths:
|
||||
formatEN: '[operate] Supervisor Process Config file'
|
||||
formatZH: '[operate] Supervisor 进程文件 '
|
||||
paramKeys: []
|
||||
/host/tool/supervisor/process/load:
|
||||
post:
|
||||
description: 获取 Supervisor 进程状态
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/response.ProcessStatus'
|
||||
type: array
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Load Supervisor process status
|
||||
tags:
|
||||
- Host tool
|
||||
/hosts:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/public/favicon.png" />
|
||||
|
||||
@@ -100,11 +100,14 @@ export const searchRemoteDBs = (params: Database.SearchRemoteDBPage) => {
|
||||
export const listRemoteDBs = (type: string) => {
|
||||
return http.get<Array<Database.RemoteDBOption>>(`/databases/remote/list/${type}`);
|
||||
};
|
||||
export const checkRemoteDB = (params: Database.RemoteDBCreate) => {
|
||||
return http.post<boolean>(`/databases/remote/check`, params, 40000);
|
||||
};
|
||||
export const addRemoteDB = (params: Database.RemoteDBCreate) => {
|
||||
return http.post(`/databases/remote`, params);
|
||||
return http.post(`/databases/remote`, params, 40000);
|
||||
};
|
||||
export const editRemoteDB = (params: Database.RemoteDBUpdate) => {
|
||||
return http.post(`/databases/remote/update`, params);
|
||||
return http.post(`/databases/remote/update`, params, 40000);
|
||||
};
|
||||
export const deleteRemoteDB = (id: number) => {
|
||||
return http.post(`/databases/remote/del`, { id: id });
|
||||
|
||||
@@ -29,6 +29,10 @@ export const OperateSupervisorProcess = (req: HostTool.ProcessReq) => {
|
||||
return http.post<any>(`/hosts/tool/supervisor/process`, req, 100000);
|
||||
};
|
||||
|
||||
export const LoadProcessStatus = () => {
|
||||
return http.post<Array<HostTool.ProcessStatus>>(`/hosts/tool/supervisor/process/load`, {}, 40000);
|
||||
};
|
||||
|
||||
export const GetSupervisorProcess = () => {
|
||||
return http.get<HostTool.SupersivorProcess>(`/hosts/tool/supervisor/process`);
|
||||
};
|
||||
|
||||
@@ -3,24 +3,10 @@
|
||||
<div class="complex-table__header" v-if="$slots.header || header">
|
||||
<slot name="header">{{ header }}</slot>
|
||||
</div>
|
||||
<div v-if="$slots.toolbar && !searchConfig" style="margin-bottom: 10px">
|
||||
<div v-if="$slots.toolbar" style="margin-bottom: 10px">
|
||||
<slot name="toolbar"></slot>
|
||||
</div>
|
||||
|
||||
<template v-if="searchConfig">
|
||||
<fu-filter-bar v-bind="searchConfig" @exec="search">
|
||||
<template #tl>
|
||||
<slot name="toolbar"></slot>
|
||||
</template>
|
||||
<template #default>
|
||||
<slot name="complex"></slot>
|
||||
</template>
|
||||
<template #buttons>
|
||||
<slot name="buttons"></slot>
|
||||
</template>
|
||||
</fu-filter-bar>
|
||||
</template>
|
||||
|
||||
<div class="complex-table__body">
|
||||
<fu-table v-bind="$attrs" ref="tableRef" @selection-change="handleSelectionChange">
|
||||
<slot></slot>
|
||||
@@ -30,13 +16,14 @@
|
||||
</fu-table>
|
||||
</div>
|
||||
|
||||
<div class="complex-table__pagination" v-if="$slots.pagination || paginationConfig">
|
||||
<div class="complex-table__pagination" v-if="props.paginationConfig">
|
||||
<slot name="pagination">
|
||||
<fu-table-pagination
|
||||
v-model:current-page="paginationConfig.currentPage"
|
||||
v-model:page-size="paginationConfig.pageSize"
|
||||
v-bind="paginationConfig"
|
||||
@change="search"
|
||||
:total="paginationConfig.total"
|
||||
@size-change="sizeChange"
|
||||
@current-change="currentChange"
|
||||
:small="mobile"
|
||||
:layout="mobile ? 'total, prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
|
||||
/>
|
||||
@@ -49,15 +36,15 @@ import { ref, computed } from 'vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
|
||||
defineOptions({ name: 'ComplexTable' });
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
header: String,
|
||||
searchConfig: Object,
|
||||
paginationConfig: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['search', 'update:selects']);
|
||||
const emit = defineEmits(['search', 'update:selects', 'update:paginationConfig']);
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
@@ -65,13 +52,15 @@ const mobile = computed(() => {
|
||||
return globalStore.isMobile();
|
||||
});
|
||||
|
||||
const condition = ref({});
|
||||
const tableRef = ref();
|
||||
function search(conditions: any, e: any) {
|
||||
if (conditions) {
|
||||
condition.value = conditions;
|
||||
}
|
||||
emit('search', condition.value, e);
|
||||
|
||||
function currentChange() {
|
||||
emit('search');
|
||||
}
|
||||
|
||||
function sizeChange() {
|
||||
props.paginationConfig.currentPage = 1;
|
||||
emit('search');
|
||||
}
|
||||
|
||||
function handleSelectionChange(row: any) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display: flex; flex-wrap: wrap">
|
||||
<el-select @change="searchLogs" v-model="logSearch.mode" style="width: 100px">
|
||||
<el-select @change="searchLogs" v-model="logSearch.mode" style="width: 150px">
|
||||
<template #prefix>{{ $t('container.fetch') }}</template>
|
||||
<el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" />
|
||||
</el-select>
|
||||
@@ -130,7 +130,7 @@ const acceptParams = (props: DialogProps): void => {
|
||||
};
|
||||
|
||||
const onClean = async () => {
|
||||
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('container.cleanLog'), {
|
||||
ElMessageBox.confirm(i18n.global.t('container.cleanLogHelper'), i18n.global.t('container.cleanLog'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
|
||||
@@ -13,20 +13,7 @@ const terminalElement = ref<HTMLDivElement | null>(null);
|
||||
const fitAddon = new FitAddon();
|
||||
const termReady = ref(false);
|
||||
const webSocketReady = ref(false);
|
||||
const term = ref(
|
||||
new Terminal({
|
||||
lineHeight: 1.2,
|
||||
fontSize: 12,
|
||||
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
|
||||
theme: {
|
||||
background: '#000000',
|
||||
},
|
||||
cursorBlink: true,
|
||||
cursorStyle: 'underline',
|
||||
scrollback: 100,
|
||||
tabStopWidth: 4,
|
||||
}),
|
||||
);
|
||||
const term = ref();
|
||||
const terminalSocket = ref<WebSocket>();
|
||||
const heartbeatTimer = ref<number>();
|
||||
const latency = ref(0);
|
||||
@@ -56,6 +43,21 @@ const acceptParams = (props: WsProps) => {
|
||||
});
|
||||
};
|
||||
|
||||
const newTerm = () => {
|
||||
term.value = new Terminal({
|
||||
lineHeight: 1.2,
|
||||
fontSize: 12,
|
||||
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
|
||||
theme: {
|
||||
background: '#000000',
|
||||
},
|
||||
cursorBlink: true,
|
||||
cursorStyle: 'underline',
|
||||
scrollback: 100,
|
||||
tabStopWidth: 4,
|
||||
});
|
||||
};
|
||||
|
||||
const init = (endpoint: string, args: string) => {
|
||||
if (initTerminal(true)) {
|
||||
initWebSocket(endpoint, args);
|
||||
@@ -78,11 +80,13 @@ function onClose(isKeepShow: boolean = false) {
|
||||
term.value.dispose();
|
||||
} catch {}
|
||||
}
|
||||
terminalElement.value.innerHTML = '';
|
||||
}
|
||||
|
||||
// terminal 相关代码 start
|
||||
|
||||
const initTerminal = (online: boolean = false): boolean => {
|
||||
newTerm();
|
||||
if (terminalElement.value) {
|
||||
term.value.open(terminalElement.value);
|
||||
term.value.loadAddon(fitAddon);
|
||||
|
||||
@@ -479,7 +479,10 @@ const message = {
|
||||
rename: 'Rename',
|
||||
remove: 'Remove',
|
||||
containerPrune: 'Container prune',
|
||||
containerPruneHelper: 'Remove all stopped containers. Do you want to continue?',
|
||||
containerPruneHelper1: 'Cleaning containers will delete all containers that are in a stopped state.',
|
||||
containerPruneHelper2:
|
||||
'If the containers are from the app store, after performing the cleanup, you need to go to the [Installed] list in the [App Store] and click the [Rebuild] button to reinstall them.',
|
||||
containerPruneHelper3: 'This operation cannot be rolled back. Do you want to continue?',
|
||||
imagePrune: 'Image prune',
|
||||
imagePruneSome: 'Clean unlabeled',
|
||||
imagePruneSomeHelper: 'Remove all unused and unlabeled container images。',
|
||||
@@ -504,6 +507,8 @@ const message = {
|
||||
lastHour: 'Last Hour',
|
||||
last10Min: 'Last 10 Minutes',
|
||||
cleanLog: 'Clean log',
|
||||
cleanLogHelper:
|
||||
'Clearing logs requires restarting the container, and this operation cannot be rolled back. Do you want to continue?',
|
||||
newName: 'New name',
|
||||
source: 'Resource rate',
|
||||
cpuShare: 'CPU Share',
|
||||
@@ -533,7 +538,7 @@ const message = {
|
||||
exposePort: 'Expose port',
|
||||
exposeAll: 'Expose all',
|
||||
cmd: 'Command',
|
||||
cmdHelper: 'Example: echo "hello"',
|
||||
cmdHelper: "Separate multiple commands with ' ' as delimiter, such as 'nginx' '-g' 'daemon off;'",
|
||||
autoRemove: 'Auto remove',
|
||||
cpuQuota: 'NacosCPU',
|
||||
memoryLimit: 'Memory',
|
||||
@@ -1460,12 +1465,12 @@ const message = {
|
||||
certificatePath: 'Certificate file',
|
||||
ipWhiteListHelper: 'The role of IP whitelist: all rules are invalid for IP whitelist',
|
||||
redirect: 'redirect',
|
||||
sourceDomain: 'source domain name/path',
|
||||
sourceDomain: 'Source domain',
|
||||
targetURL: 'Target URL address',
|
||||
keepPath: 'Keep URI parameters',
|
||||
keepPath: 'URI params',
|
||||
path: 'path',
|
||||
redirectType: 'redirection type',
|
||||
redirectWay: 'way',
|
||||
redirectWay: 'Way',
|
||||
keep: 'keep',
|
||||
notKeep: 'Do not keep',
|
||||
redirectRoot: 'Redirect to the homepage',
|
||||
@@ -1663,15 +1668,16 @@ const message = {
|
||||
},
|
||||
tool: {
|
||||
supervisor: {
|
||||
loadStatusErr: 'Failed to retrieve process status, please check the status of the supervisor service.',
|
||||
notSupport: 'Supervisor is not detected, please refer to the official document for installation',
|
||||
list: 'Daemon process',
|
||||
config: 'Supervisor configuration',
|
||||
primaryConfig: 'Main configuration file location',
|
||||
notSupportCrl: 'The supervisorctl is not detected, please refer to the official document for installation',
|
||||
user: 'start user',
|
||||
command: 'start command',
|
||||
dir: 'run directory',
|
||||
numprocs: 'Number of processes',
|
||||
user: 'User',
|
||||
command: 'Command',
|
||||
dir: 'Directory',
|
||||
numprocs: 'Numprocs',
|
||||
initWarn:
|
||||
'The initialization operation needs to modify the [include] files parameter of the configuration file, the directory where the modified service configuration file is located: 1panel installation directory/1panel/tools/supervisord/supervisor.d/',
|
||||
operatorHelper: 'Operation {1} will be performed on {0}, continue? ',
|
||||
@@ -1684,6 +1690,14 @@ const message = {
|
||||
restartHelper:
|
||||
'Initialization will restart the service, causing all the original daemon processes to close',
|
||||
msg: 'Message',
|
||||
RUNNING: 'Running',
|
||||
STOPPED: 'Stopped',
|
||||
STOPPING: 'Stopping',
|
||||
STARTING: 'Starting',
|
||||
FATAL: 'Failed to start',
|
||||
BACKOFF: 'Start exception',
|
||||
statusCode: 'Status code',
|
||||
manage: 'Management',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -469,7 +469,10 @@ const message = {
|
||||
rename: '重命名',
|
||||
remove: '刪除',
|
||||
containerPrune: '清理容器',
|
||||
containerPruneHelper: '清理容器 將刪除所有處於停止狀態的容器,該操作無法回滾,是否繼續?',
|
||||
containerPruneHelper1: '清理容器 將刪除所有處於停止狀態的容器。',
|
||||
containerPruneHelper2:
|
||||
'若容器來自於應用商店,在執行清理操作後,您需要前往 [應用商店] 的 [已安裝] 列表,點擊 [重建] 按鈕進行重新安裝。',
|
||||
containerPruneHelper3: '該操作無法回滾,是否繼續?',
|
||||
imagePrune: '清理鏡像',
|
||||
imagePruneSome: '未標簽鏡像',
|
||||
imagePruneSomeHelper: '清理標簽為 none 且未被任何容器使用的鏡像。',
|
||||
@@ -493,6 +496,7 @@ const message = {
|
||||
lastHour: '最近 1 小時',
|
||||
last10Min: '最近 10 分鐘',
|
||||
cleanLog: '清空日誌',
|
||||
cleanLogHelper: '清空日誌需要重啟容器,該操作無法回滾,是否繼續?',
|
||||
newName: '新名稱',
|
||||
source: '資源使用率',
|
||||
cpuShare: 'CPU 權重',
|
||||
@@ -519,7 +523,7 @@ const message = {
|
||||
exposePort: '暴露端口',
|
||||
exposeAll: '暴露所有',
|
||||
cmd: '啟動命令',
|
||||
cmdHelper: '例:echo "hello"',
|
||||
cmdHelper: "多個命令間請用 ' ' 分隔開,如 'nginx' '-g' 'daemon off;'",
|
||||
autoRemove: '容器退出後自動刪除容器',
|
||||
cpuQuota: 'CPU 限製',
|
||||
memoryLimit: '內存限製',
|
||||
@@ -1577,6 +1581,7 @@ const message = {
|
||||
},
|
||||
tool: {
|
||||
supervisor: {
|
||||
loadStatusErr: '獲取進程狀態失敗,請檢查 supervisor 服務狀態',
|
||||
notSupport: '未檢測到 Supervisor,請參考官方文檔進行安裝',
|
||||
list: '守護進程',
|
||||
config: 'Supervisor 配置',
|
||||
@@ -1596,6 +1601,14 @@ const message = {
|
||||
serviceNameHelper: 'systemctl 管理的 Supervisor 服務名稱,一般為 supervisor 或 supervisord',
|
||||
restartHelper: '初始化會重啟服務,導致原有的守護進程全部關閉',
|
||||
msg: '信息',
|
||||
RUNNING: '運行中',
|
||||
STOPPED: '已停止',
|
||||
STOPPING: '停止中',
|
||||
STARTING: '啟動中',
|
||||
FATAL: '啟動失敗',
|
||||
BACKOFF: '啟動異常',
|
||||
statusCode: '狀態碼',
|
||||
manage: '管理',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -469,7 +469,10 @@ const message = {
|
||||
rename: '重命名',
|
||||
remove: '删除',
|
||||
containerPrune: '清理容器',
|
||||
containerPruneHelper: '清理容器 将删除所有处于停止状态的容器,该操作无法回滚,是否继续?',
|
||||
containerPruneHelper1: '清理容器 将删除所有处于停止状态的容器。',
|
||||
containerPruneHelper2:
|
||||
'若容器来自于应用商店,在执行清理操作后,您需要前往 [应用商店] 的 [已安装] 列表,点击 [重建] 按钮进行重新安装。',
|
||||
containerPruneHelper3: '该操作无法回滚,是否继续?',
|
||||
imagePrune: '清理镜像',
|
||||
imagePruneSome: '未标签镜像',
|
||||
imagePruneSomeHelper: '清理标签为 none 且未被任何容器使用的镜像。',
|
||||
@@ -493,6 +496,7 @@ const message = {
|
||||
lastHour: '最近 1 小时',
|
||||
last10Min: '最近 10 分钟',
|
||||
cleanLog: '清空日志',
|
||||
cleanLogHelper: '清空日志需要重启容器,该操作无法回滚,是否继续?',
|
||||
newName: '新名称',
|
||||
source: '资源使用率',
|
||||
cpuShare: 'CPU 权重',
|
||||
@@ -519,7 +523,7 @@ const message = {
|
||||
exposePort: '暴露端口',
|
||||
exposeAll: '暴露所有',
|
||||
cmd: '启动命令',
|
||||
cmdHelper: '例:echo "hello"',
|
||||
cmdHelper: "多个命令间请用 ' ' 分隔开,如 'nginx' '-g' 'daemon off;'",
|
||||
autoRemove: '容器退出后自动删除容器',
|
||||
cpuQuota: 'CPU 限制',
|
||||
memoryLimit: '内存限制',
|
||||
@@ -1579,6 +1583,7 @@ const message = {
|
||||
},
|
||||
tool: {
|
||||
supervisor: {
|
||||
loadStatusErr: '获取进程状态失败,请检查 supervisor 服务状态',
|
||||
notSupport: '未检测到 Supervisor,请参考官方文档进行安装',
|
||||
list: '守护进程',
|
||||
config: 'Supervisor 配置',
|
||||
@@ -1598,6 +1603,14 @@ const message = {
|
||||
serviceNameHelper: 'systemctl 管理的 Supervisor 服务名称,一般为 supervisor、supervisord',
|
||||
restartHelper: '初始化会重启服务,导致原有的守护进程全部关闭',
|
||||
msg: '信息',
|
||||
RUNNING: '运行中',
|
||||
STOPPED: '已停止',
|
||||
STOPPING: '停止中',
|
||||
STARTING: '启动中',
|
||||
FATAL: '启动失败',
|
||||
BACKOFF: '启动异常',
|
||||
statusCode: '状态码',
|
||||
manage: '管理',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
background-color: var(--el-menu-item-bg-color-active);;
|
||||
background-color: var(--el-menu-item-bg-color-active);
|
||||
border: 2px solid $primary-color;
|
||||
|
||||
&::before {
|
||||
@@ -81,3 +81,7 @@
|
||||
padding: 4px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-sub-menu__title {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,6 @@ onMounted(() => {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -178,6 +177,7 @@ onMounted(() => {
|
||||
transition: transform 0.28s;
|
||||
width: var(--panel-menu-width) !important;
|
||||
background: #ffffff;
|
||||
z-index: 9999;
|
||||
}
|
||||
.app-footer {
|
||||
display: block;
|
||||
|
||||
@@ -27,6 +27,16 @@ const databaseRouter = {
|
||||
requiresAuth: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'mysql/setting',
|
||||
name: 'MySQL-Setting',
|
||||
component: () => import('@/views/database/mysql/setting/index.vue'),
|
||||
hidden: true,
|
||||
meta: {
|
||||
activeMenu: '/databases',
|
||||
requiresAuth: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'mysql/remote',
|
||||
name: 'MySQL-Remote',
|
||||
|
||||
@@ -181,7 +181,7 @@ html {
|
||||
|
||||
.mask-prompt {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
z-index: 9998;
|
||||
top: 220px;
|
||||
left: 45%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
@@ -119,7 +119,6 @@
|
||||
v-model:page-size="paginationConfig.pageSize"
|
||||
v-bind="paginationConfig"
|
||||
@change="search(req)"
|
||||
:page-sizes="[30, 60, 90]"
|
||||
:layout="mobile ? 'total, prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
|
||||
/>
|
||||
</div>
|
||||
@@ -259,14 +258,14 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.app-desc {
|
||||
margin-top: 5px;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
height: 45px;
|
||||
height: 43px;
|
||||
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
</LayoutContent>
|
||||
|
||||
<CodemirrorDialog ref="mydetail" />
|
||||
<PruneDialog @search="search" ref="dialogPruneRef" />
|
||||
|
||||
<ReNameDialog @search="search" ref="dialogReNameRef" />
|
||||
<ContainerLogDialog ref="dialogContainerLogRef" />
|
||||
@@ -172,6 +173,7 @@
|
||||
<script lang="ts" setup>
|
||||
import Tooltip from '@/components/tooltip/index.vue';
|
||||
import TableSetting from '@/components/table-setting/index.vue';
|
||||
import PruneDialog from '@/views/container/container/prune/index.vue';
|
||||
import ReNameDialog from '@/views/container/container/rename/index.vue';
|
||||
import OperateDialog from '@/views/container/container/operate/index.vue';
|
||||
import UpgraeDialog from '@/views/container/container/upgrade/index.vue';
|
||||
@@ -185,7 +187,6 @@ import { reactive, onMounted, ref, computed } from 'vue';
|
||||
import {
|
||||
containerListStats,
|
||||
containerOperator,
|
||||
containerPrune,
|
||||
inspect,
|
||||
loadContainerInfo,
|
||||
loadDockerStatus,
|
||||
@@ -196,7 +197,6 @@ import { ElMessageBox } from 'element-plus';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
import { MsgSuccess, MsgWarning } from '@/utils/message';
|
||||
import { computeSize } from '@/utils/util';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
@@ -264,6 +264,7 @@ const mydetail = ref();
|
||||
|
||||
const dialogContainerLogRef = ref();
|
||||
const dialogReNameRef = ref();
|
||||
const dialogPruneRef = ref();
|
||||
|
||||
const search = async (column?: any) => {
|
||||
let filterItem = props.filters ? props.filters : '';
|
||||
@@ -360,31 +361,7 @@ const onInspect = async (id: string) => {
|
||||
};
|
||||
|
||||
const onClean = () => {
|
||||
ElMessageBox.confirm(i18n.global.t('container.containerPruneHelper'), i18n.global.t('container.containerPrune'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
}).then(async () => {
|
||||
loading.value = true;
|
||||
let params = {
|
||||
pruneType: 'container',
|
||||
withTagAll: false,
|
||||
};
|
||||
await containerPrune(params)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
MsgSuccess(
|
||||
i18n.global.t('container.cleanSuccessWithSpace', [
|
||||
res.data.deletedNumber,
|
||||
computeSize(res.data.spaceReclaimed),
|
||||
]),
|
||||
);
|
||||
search();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
dialogPruneRef.value!.acceptParams();
|
||||
};
|
||||
|
||||
const checkStatus = (operation: string, row: Container.ContainerInfo | null) => {
|
||||
|
||||
@@ -161,7 +161,7 @@ const onDownload = async () => {
|
||||
};
|
||||
|
||||
const onClean = async () => {
|
||||
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('container.cleanLog'), {
|
||||
ElMessageBox.confirm(i18n.global.t('container.cleanLogHelper'), i18n.global.t('container.cleanLog'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
|
||||
@@ -110,7 +110,8 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.cmd')" prop="cmdStr">
|
||||
<el-input :placeholder="$t('container.cmdHelper')" v-model="dialogData.rowData!.cmdStr" />
|
||||
<el-input v-model="dialogData.rowData!.cmdStr" />
|
||||
<span class="input-help">{{ $t('container.cmdHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item prop="autoRemove">
|
||||
<el-checkbox v-model="dialogData.rowData!.autoRemove">
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisiable" :title="$t('container.containerPrune')" :destroy-on-close="true" width="30%">
|
||||
<div>
|
||||
<ul class="help-ul">
|
||||
<li lineClass style="color: red">{{ $t('container.containerPruneHelper1') }}</li>
|
||||
<li class="lineClass">{{ $t('container.containerPruneHelper2') }}</li>
|
||||
<li class="lineClass">{{ $t('container.containerPruneHelper3') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="dialogVisiable = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onClean()">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { containerPrune } from '@/api/modules/container';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { ref } from 'vue';
|
||||
import { computeSize } from '@/utils/util';
|
||||
|
||||
const loading = ref(false);
|
||||
const dialogVisiable = ref<boolean>(false);
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const onClean = async () => {
|
||||
loading.value = true;
|
||||
let params = {
|
||||
pruneType: 'container',
|
||||
withTagAll: false,
|
||||
};
|
||||
await containerPrune(params)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
MsgSuccess(
|
||||
i18n.global.t('container.cleanSuccessWithSpace', [
|
||||
res.data.deletedNumber,
|
||||
computeSize(res.data.spaceReclaimed),
|
||||
]),
|
||||
);
|
||||
dialogVisiable.value = false;
|
||||
emit('search');
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const acceptParams = (): void => {
|
||||
dialogVisiable.value = true;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lineClass {
|
||||
line-height: 30px;
|
||||
}
|
||||
</style>
|
||||
@@ -43,7 +43,7 @@
|
||||
<el-button v-if="!terminalOpen" @click="initTerm(formRef)">
|
||||
{{ $t('commons.button.conn') }}
|
||||
</el-button>
|
||||
<el-button v-else @click="handleClose()">{{ $t('commons.button.disconn') }}</el-button>
|
||||
<el-button v-else @click="onClose()">{{ $t('commons.button.disconn') }}</el-button>
|
||||
<Terminal style="height: calc(100vh - 302px)" ref="terminalRef"></Terminal>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
@@ -99,10 +99,14 @@ const initTerm = (formEl: FormInstance | undefined) => {
|
||||
});
|
||||
};
|
||||
|
||||
function handleClose() {
|
||||
const onClose = () => {
|
||||
terminalRef.value?.onClose();
|
||||
terminalVisiable.value = false;
|
||||
terminalOpen.value = false;
|
||||
};
|
||||
|
||||
function handleClose() {
|
||||
onClose();
|
||||
terminalVisiable.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
</el-table-column>
|
||||
<el-table-column width="90">
|
||||
<template #default="{ row }">
|
||||
<el-tag effect="dark" round v-if="row.isSystem">system</el-tag>
|
||||
<el-tag effect="dark" round v-if="row.isSystem || row.name === '1panel-network'">
|
||||
system
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -78,11 +80,12 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
show-overflow-tooltip
|
||||
min-width="90"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFormat"
|
||||
/>
|
||||
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
|
||||
<fu-table-operations width="100" :buttons="buttons" :label="$t('commons.table.operate')" fix />
|
||||
</ComplexTable>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
@@ -222,7 +225,7 @@ const onInspect = async (id: string) => {
|
||||
};
|
||||
|
||||
function isSystem(val: string) {
|
||||
return val === 'bridge' || val === '1panel-network' || val === 'none' || val === 'host';
|
||||
return val === 'bridge' || val === 'none' || val === 'host';
|
||||
}
|
||||
|
||||
const buttons = [
|
||||
|
||||
@@ -16,7 +16,15 @@
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.remoteConn')">
|
||||
<el-tag>{{ form.systemIP + ':' + form.port }}</el-tag>
|
||||
<el-tooltip v-if="loadConnInfo(true).length > 48" :content="loadConnInfo(true)" placement="top">
|
||||
<el-tag>{{ loadConnInfo(true).substring(0, 48) }}...</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-else>{{ loadConnInfo(true) }}</el-tag>
|
||||
<el-button
|
||||
@click="onCopy(form.systemIP + ':' + form.port)"
|
||||
icon="DocumentCopy"
|
||||
link
|
||||
></el-button>
|
||||
<span class="input-help">{{ $t('database.remoteConnHelper2') }}</span>
|
||||
</el-form-item>
|
||||
|
||||
@@ -42,13 +50,27 @@
|
||||
<el-row type="flex" justify="center" v-if="form.from !== 'local'">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('database.remoteConn')">
|
||||
<el-tag>{{ form.remoteIP + ':' + form.port }}</el-tag>
|
||||
<el-tooltip
|
||||
v-if="loadConnInfo(false).length > 48"
|
||||
:content="loadConnInfo(false)"
|
||||
placement="top"
|
||||
>
|
||||
<el-tag>{{ loadConnInfo(false).substring(0, 48) }}...</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-else>{{ loadConnInfo(false) }}</el-tag>
|
||||
<el-button
|
||||
@click="onCopy(form.remoteIP + ':' + form.port)"
|
||||
icon="DocumentCopy"
|
||||
link
|
||||
></el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.username')">
|
||||
<el-tag>{{ form.username }}</el-tag>
|
||||
<el-button @click="onCopy(form.username)" icon="DocumentCopy" link></el-button>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.password')">
|
||||
<el-tag>{{ form.password }}</el-tag>
|
||||
<el-button @click="onCopy(form.password)" icon="DocumentCopy" link></el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -121,6 +143,12 @@ const acceptParams = (param: DialogProps): void => {
|
||||
dialogVisiable.value = true;
|
||||
};
|
||||
|
||||
function loadConnInfo(isLocal: boolean) {
|
||||
let ip = isLocal ? form.systemIP : form.remoteIP;
|
||||
let info = ip + ':' + form.port;
|
||||
return info;
|
||||
}
|
||||
|
||||
const random = async () => {
|
||||
form.password = getRandomStr(16);
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
></AppStatus>
|
||||
</template>
|
||||
|
||||
<template v-if="!isOnSetting" #search>
|
||||
<template #search>
|
||||
<el-select v-model="paginationConfig.from" @change="search()">
|
||||
<template #prefix>{{ $t('commons.table.type') }}</template>
|
||||
<el-option-group>
|
||||
@@ -28,7 +28,7 @@
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<template #toolbar v-if="!isOnSetting">
|
||||
<template #toolbar>
|
||||
<el-row>
|
||||
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20">
|
||||
<el-button
|
||||
@@ -77,7 +77,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<template #main v-if="(mysqlIsExist && !isOnSetting) || !isLocal()">
|
||||
<template #main v-if="mysqlIsExist || !isLocal()">
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
@sort-change="search"
|
||||
@@ -162,14 +162,10 @@
|
||||
</LayoutContent>
|
||||
</div>
|
||||
|
||||
<el-card
|
||||
v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist && !loading && maskShow && isLocal"
|
||||
class="mask-prompt"
|
||||
>
|
||||
<el-card v-if="mysqlStatus != 'Running' && mysqlIsExist && !loading && maskShow && isLocal" class="mask-prompt">
|
||||
<span>{{ $t('commons.service.serviceNotStarted', ['MySQL']) }}</span>
|
||||
</el-card>
|
||||
|
||||
<Setting ref="settingRef" style="margin-top: 20px" />
|
||||
<el-dialog
|
||||
v-model="phpVisiable"
|
||||
:title="$t('app.checkTitle')"
|
||||
@@ -208,7 +204,6 @@ import DeleteDialog from '@/views/database/mysql/delete/index.vue';
|
||||
import PasswordDialog from '@/views/database/mysql/password/index.vue';
|
||||
import RootPasswordDialog from '@/views/database/mysql/conn/index.vue';
|
||||
import AppResources from '@/views/database/mysql/check/index.vue';
|
||||
import Setting from '@/views/database/mysql/setting/index.vue';
|
||||
import AppStatus from '@/components/app-status/index.vue';
|
||||
import Backups from '@/components/backup/index.vue';
|
||||
import UploadDialog from '@/components/upload/index.vue';
|
||||
@@ -238,7 +233,6 @@ const maskShow = ref(true);
|
||||
const dbOptions = ref<Array<Database.RemoteDBOption>>([]);
|
||||
|
||||
const mysqlName = ref();
|
||||
const isOnSetting = ref<boolean>();
|
||||
|
||||
const checkRef = ref();
|
||||
const deleteRef = ref();
|
||||
@@ -292,15 +286,8 @@ function isLocal() {
|
||||
|
||||
const passwordRef = ref();
|
||||
|
||||
const settingRef = ref();
|
||||
const onSetting = async () => {
|
||||
isOnSetting.value = true;
|
||||
let params = {
|
||||
status: mysqlStatus.value,
|
||||
mysqlName: mysqlName.value,
|
||||
mysqlVersion: mysqlVersion.value,
|
||||
};
|
||||
settingRef.value!.acceptParams(params);
|
||||
router.push({ name: 'MySQL-Setting' });
|
||||
};
|
||||
|
||||
const search = async (column?: any) => {
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
</template>
|
||||
<template #main>
|
||||
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" sortable />
|
||||
<el-table-column :label="$t('database.address')" prop="address" />
|
||||
<el-table-column show-overflow-tooltip :label="$t('commons.table.name')" prop="name" sortable />
|
||||
<el-table-column show-overflow-tooltip :label="$t('database.address')" prop="address" />
|
||||
<el-table-column :label="$t('commons.login.username')" prop="username" />
|
||||
<el-table-column :label="$t('commons.login.password')" prop="password">
|
||||
<template #default="{ row }">
|
||||
@@ -74,7 +74,7 @@
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<fu-table-operations
|
||||
width="370px"
|
||||
width="170px"
|
||||
:buttons="buttons"
|
||||
:ellipsis="10"
|
||||
:label="$t('commons.table.operate')"
|
||||
@@ -138,7 +138,7 @@ const onOpenDialog = async (
|
||||
version: '5.6',
|
||||
address: '',
|
||||
port: 3306,
|
||||
username: '',
|
||||
username: 'root',
|
||||
password: '',
|
||||
description: '',
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:back="handleClose"
|
||||
/>
|
||||
</template>
|
||||
<el-form ref="formRef" label-position="top" :model="dialogData.rowData" :rules="rules">
|
||||
<el-form ref="formRef" v-loading="loading" label-position="top" :model="dialogData.rowData" :rules="rules">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('commons.table.name')" prop="name">
|
||||
@@ -20,7 +20,7 @@
|
||||
<el-tag v-else>{{ dialogData.rowData!.name }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.version')" prop="version">
|
||||
<el-select v-model="dialogData.rowData!.version">
|
||||
<el-select @change="isOK = false" v-model="dialogData.rowData!.version">
|
||||
<el-option value="5.6" label="5.6" />
|
||||
<el-option value="5.7" label="5.7" />
|
||||
<el-option value="8.0" label="8.0" />
|
||||
@@ -28,17 +28,23 @@
|
||||
<span class="input-help">{{ $t('database.versionHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.address')" prop="address">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.address" />
|
||||
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.table.port')" prop="port">
|
||||
<el-input clearable v-model.number="dialogData.rowData!.port" />
|
||||
<el-input @change="isOK = false" clearable v-model.number="dialogData.rowData!.port" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.username')" prop="username">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.username" />
|
||||
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.username" />
|
||||
<span class="input-help">{{ $t('database.userHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.password')" prop="password">
|
||||
<el-input type="password" clearable show-password v-model.trim="dialogData.rowData!.password" />
|
||||
<el-input
|
||||
@change="isOK = false"
|
||||
type="password"
|
||||
clearable
|
||||
show-password
|
||||
v-model.trim="dialogData.rowData!.password"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.table.description')" prop="description">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.description" />
|
||||
@@ -49,7 +55,10 @@
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit(formRef)">
|
||||
<el-button @click="onSubmit(formRef, 'check')">
|
||||
{{ $t('terminal.testConn') }}
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="!isOK" @click="onSubmit(formRef, dialogData.title)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
@@ -63,9 +72,9 @@ import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { Database } from '@/api/interface/database';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { addRemoteDB, editRemoteDB } from '@/api/modules/database';
|
||||
import { addRemoteDB, checkRemoteDB, editRemoteDB } from '@/api/modules/database';
|
||||
|
||||
interface DialogProps {
|
||||
title: string;
|
||||
@@ -77,6 +86,9 @@ const drawerVisiable = ref(false);
|
||||
const dialogData = ref<DialogProps>({
|
||||
title: '',
|
||||
});
|
||||
const isOK = ref(false);
|
||||
const loading = ref();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
dialogData.value = params;
|
||||
title.value = i18n.global.t('database.' + dialogData.value.title + 'RemoteDB');
|
||||
@@ -91,7 +103,7 @@ const handleClose = () => {
|
||||
const rules = reactive({
|
||||
name: [Rules.requiredInput],
|
||||
version: [Rules.requiredSelect],
|
||||
address: [Rules.ip],
|
||||
address: [Rules.host],
|
||||
port: [Rules.port],
|
||||
username: [Rules.requiredInput],
|
||||
password: [Rules.requiredInput],
|
||||
@@ -100,40 +112,65 @@ const rules = reactive({
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
const onSubmit = async (formEl: FormInstance | undefined, operation: string) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
if (dialogData.value.title === 'create') {
|
||||
let param = {
|
||||
name: dialogData.value.rowData.name,
|
||||
type: 'mysql',
|
||||
version: dialogData.value.rowData.version,
|
||||
from: 'remote',
|
||||
address: dialogData.value.rowData.address,
|
||||
port: dialogData.value.rowData.port,
|
||||
username: dialogData.value.rowData.username,
|
||||
password: dialogData.value.rowData.password,
|
||||
description: dialogData.value.rowData.description,
|
||||
};
|
||||
await addRemoteDB(param);
|
||||
}
|
||||
if (dialogData.value.title === 'edit') {
|
||||
let param = {
|
||||
id: dialogData.value.rowData.id,
|
||||
version: dialogData.value.rowData.version,
|
||||
address: dialogData.value.rowData.address,
|
||||
port: dialogData.value.rowData.port,
|
||||
username: dialogData.value.rowData.username,
|
||||
password: dialogData.value.rowData.password,
|
||||
description: dialogData.value.rowData.description,
|
||||
};
|
||||
await editRemoteDB(param);
|
||||
let param = {
|
||||
id: dialogData.value.rowData.id,
|
||||
name: dialogData.value.rowData.name,
|
||||
type: 'mysql',
|
||||
version: dialogData.value.rowData.version,
|
||||
from: 'remote',
|
||||
address: dialogData.value.rowData.address,
|
||||
port: dialogData.value.rowData.port,
|
||||
username: dialogData.value.rowData.username,
|
||||
password: dialogData.value.rowData.password,
|
||||
description: dialogData.value.rowData.description,
|
||||
};
|
||||
loading.value = true;
|
||||
|
||||
if (operation === 'check') {
|
||||
await checkRemoteDB(param)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
if (res.data) {
|
||||
isOK.value = true;
|
||||
MsgSuccess(i18n.global.t('terminal.connTestOk'));
|
||||
} else {
|
||||
MsgError(i18n.global.t('terminal.connTestFailed'));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
MsgError(i18n.global.t('terminal.connTestFailed'));
|
||||
});
|
||||
}
|
||||
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
if (operation === 'create') {
|
||||
await addRemoteDB(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
if (operation === 'edit') {
|
||||
await editRemoteDB(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
emit('search');
|
||||
drawerVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div v-show="onSetting" v-loading="loading">
|
||||
<LayoutContent :title="'MySQL ' + $t('commons.button.set')" :reload="true">
|
||||
<template #buttons>
|
||||
<div v-loading="loading">
|
||||
<LayoutContent>
|
||||
<template #title>
|
||||
<back-button name="MySQL" :header="'MySQL ' + $t('commons.button.set')" />
|
||||
</template>
|
||||
|
||||
<template #toolbar>
|
||||
<el-button type="primary" :plain="activeName !== 'conf'" @click="jumpToConf">
|
||||
{{ $t('database.confChange') }}
|
||||
</el-button>
|
||||
@@ -115,12 +119,12 @@ import Status from '@/views/database/mysql/setting/status/index.vue';
|
||||
import Variables from '@/views/database/mysql/setting/variables/index.vue';
|
||||
import SlowLog from '@/views/database/mysql/setting/slow-log/index.vue';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import { loadDatabaseFile, loadMysqlBaseInfo, loadMysqlVariables, updateMysqlConfByFile } from '@/api/modules/database';
|
||||
import { ChangePort, GetAppDefaultConfig } from '@/api/modules/app';
|
||||
import { ChangePort, CheckAppInstalled, GetAppDefaultConfig } from '@/api/modules/app';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
@@ -146,34 +150,12 @@ const statusRef = ref();
|
||||
const variablesRef = ref();
|
||||
const slowLogRef = ref();
|
||||
|
||||
const onSetting = ref<boolean>(false);
|
||||
const mysqlName = ref();
|
||||
const mysqlStatus = ref();
|
||||
const mysqlVersion = ref();
|
||||
const variables = ref();
|
||||
|
||||
interface DialogProps {
|
||||
mysqlName: string;
|
||||
mysqlVersion: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
const dialogContainerLogRef = ref();
|
||||
const acceptParams = (props: DialogProps): void => {
|
||||
onSetting.value = true;
|
||||
mysqlStatus.value = props.status;
|
||||
mysqlVersion.value = props.mysqlVersion;
|
||||
loadBaseInfo();
|
||||
if (mysqlStatus.value === 'Running') {
|
||||
loadVariables();
|
||||
loadSlowLogs();
|
||||
statusRef.value!.acceptParams({ mysqlName: props.mysqlName });
|
||||
}
|
||||
};
|
||||
const onClose = (): void => {
|
||||
onSetting.value = false;
|
||||
};
|
||||
|
||||
const jumpToConf = async () => {
|
||||
activeName.value = 'conf';
|
||||
loadMysqlConf();
|
||||
@@ -303,8 +285,21 @@ const loadMysqlConf = async () => {
|
||||
mysqlConf.value = res.data;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
onClose,
|
||||
const onLoadInfo = async () => {
|
||||
await CheckAppInstalled('mysql').then((res) => {
|
||||
mysqlName.value = res.data.name;
|
||||
mysqlStatus.value = res.data.status;
|
||||
mysqlVersion.value = res.data.version;
|
||||
loadBaseInfo();
|
||||
if (mysqlStatus.value === 'Running') {
|
||||
loadVariables();
|
||||
loadSlowLogs();
|
||||
statusRef.value!.acceptParams({ mysqlName: mysqlName.value });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onLoadInfo();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -374,9 +374,10 @@ const onLoadCurrentInfo = async () => {
|
||||
const res = await loadCurrentInfo(searchInfo.ioOption, searchInfo.netOption);
|
||||
currentInfo.value.timeSinceUptime = res.data.timeSinceUptime;
|
||||
|
||||
let timeInterval = Number(res.data.uptime - currentInfo.value.uptime) || 3;
|
||||
currentChartInfo.netBytesSent =
|
||||
res.data.netBytesSent - currentInfo.value.netBytesSent > 0
|
||||
? Number(((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / 3).toFixed(2))
|
||||
? Number(((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / timeInterval).toFixed(2))
|
||||
: 0;
|
||||
netBytesSents.value.push(currentChartInfo.netBytesSent);
|
||||
if (netBytesSents.value.length > 20) {
|
||||
@@ -385,7 +386,7 @@ const onLoadCurrentInfo = async () => {
|
||||
|
||||
currentChartInfo.netBytesRecv =
|
||||
res.data.netBytesRecv - currentInfo.value.netBytesRecv > 0
|
||||
? Number(((res.data.netBytesRecv - currentInfo.value.netBytesRecv) / 1024 / 3).toFixed(2))
|
||||
? Number(((res.data.netBytesRecv - currentInfo.value.netBytesRecv) / 1024 / timeInterval).toFixed(2))
|
||||
: 0;
|
||||
netBytesRecvs.value.push(currentChartInfo.netBytesRecv);
|
||||
if (netBytesRecvs.value.length > 20) {
|
||||
@@ -394,7 +395,7 @@ const onLoadCurrentInfo = async () => {
|
||||
|
||||
currentChartInfo.ioReadBytes =
|
||||
res.data.ioReadBytes - currentInfo.value.ioReadBytes > 0
|
||||
? Number(((res.data.ioReadBytes - currentInfo.value.ioReadBytes) / 1024 / 1024 / 3).toFixed(2))
|
||||
? Number(((res.data.ioReadBytes - currentInfo.value.ioReadBytes) / 1024 / 1024 / timeInterval).toFixed(2))
|
||||
: 0;
|
||||
ioReadBytes.value.push(currentChartInfo.ioReadBytes);
|
||||
if (ioReadBytes.value.length > 20) {
|
||||
@@ -403,17 +404,17 @@ const onLoadCurrentInfo = async () => {
|
||||
|
||||
currentChartInfo.ioWriteBytes =
|
||||
res.data.ioWriteBytes - currentInfo.value.ioWriteBytes > 0
|
||||
? Number(((res.data.ioWriteBytes - currentInfo.value.ioWriteBytes) / 1024 / 1024 / 3).toFixed(2))
|
||||
? Number(((res.data.ioWriteBytes - currentInfo.value.ioWriteBytes) / 1024 / 1024 / timeInterval).toFixed(2))
|
||||
: 0;
|
||||
ioWriteBytes.value.push(currentChartInfo.ioWriteBytes);
|
||||
if (ioWriteBytes.value.length > 20) {
|
||||
ioWriteBytes.value.splice(0, 1);
|
||||
}
|
||||
currentChartInfo.ioCount = Math.round(Number((res.data.ioCount - currentInfo.value.ioCount) / 3));
|
||||
currentChartInfo.ioCount = Math.round(Number((res.data.ioCount - currentInfo.value.ioCount) / timeInterval));
|
||||
let ioReadTime = res.data.ioReadTime - currentInfo.value.ioReadTime;
|
||||
let ioWriteTime = res.data.ioWriteTime - currentInfo.value.ioWriteTime;
|
||||
let ioChoose = ioReadTime > ioWriteTime ? ioReadTime : ioWriteTime;
|
||||
currentChartInfo.ioTime = Math.round(Number(ioChoose / 3));
|
||||
currentChartInfo.ioTime = Math.round(Number(ioChoose / timeInterval));
|
||||
|
||||
timeIODatas.value.push(dateFormatForSecond(res.data.shotTime));
|
||||
if (timeIODatas.value.length > 20) {
|
||||
|
||||
@@ -247,7 +247,7 @@ const onDelete = async (row: Host.RuleIP | null) => {
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
await batchOperateRule({ type: 'port', rules: rules })
|
||||
await batchOperateRule({ type: 'address', rules: rules })
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
@search="search"
|
||||
:data="data"
|
||||
>
|
||||
<el-table-column type="selection" :selectable="selectable" fix />
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column :label="$t('commons.table.protocol')" :min-width="90" prop="protocol" />
|
||||
<el-table-column :label="$t('commons.table.port')" :min-width="120" prop="port" />
|
||||
<el-table-column :label="$t('commons.table.status')" :min-width="120">
|
||||
@@ -87,7 +87,6 @@
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="row.strategy === 'accept'"
|
||||
:disabled="row.appName === '1panel'"
|
||||
@click="onChangeStatus(row, 'drop')"
|
||||
link
|
||||
type="success"
|
||||
@@ -303,28 +302,18 @@ const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
});
|
||||
};
|
||||
|
||||
function selectable(row) {
|
||||
return row.appName !== '1panel';
|
||||
}
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: (row: Host.RulePort) => {
|
||||
onOpenDialog('edit', row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.appName === '1panel';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Host.RuleInfo) => {
|
||||
onDelete(row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.appName === '1panel';
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ const handleReady = (payload) => {
|
||||
};
|
||||
let timer: NodeJS.Timer | null = null;
|
||||
|
||||
const em = defineEmits(['search']);
|
||||
|
||||
const getContent = () => {
|
||||
loading.value = true;
|
||||
OperateSupervisorProcessFile(req)
|
||||
@@ -114,8 +116,9 @@ const submit = () => {
|
||||
loading.value = true;
|
||||
OperateSupervisorProcessFile(updateReq)
|
||||
.then(() => {
|
||||
em('search');
|
||||
open.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
|
||||
getContent();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
|
||||
@@ -20,35 +20,84 @@
|
||||
</template>
|
||||
<template #main v-if="showTable">
|
||||
<ComplexTable :data="data" :class="{ mask: !supervisorStatus.isRunning }">
|
||||
<el-table-column :label="$t('commons.table.name')" fix prop="name" width="150px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
fix
|
||||
prop="name"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('tool.supervisor.command')"
|
||||
prop="command"
|
||||
min-width="100px"
|
||||
fix
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('tool.supervisor.dir')"
|
||||
prop="dir"
|
||||
min-width="100px"
|
||||
fix
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column :label="$t('tool.supervisor.user')" prop="user" width="100px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('tool.supervisor.user')"
|
||||
prop="user"
|
||||
show-overflow-tooltip
|
||||
min-width="50px"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('tool.supervisor.numprocs')"
|
||||
prop="numprocs"
|
||||
width="100px"
|
||||
min-width="60px"
|
||||
></el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" width="100px">
|
||||
<el-table-column :label="$t('tool.supervisor.manage')" min-width="80px">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.status">
|
||||
<div v-if="row.status && row.status.length > 0 && row.hasLoad">
|
||||
<el-button
|
||||
v-if="checkStatus(row.status) === 'RUNNING'"
|
||||
link
|
||||
type="success"
|
||||
:icon="VideoPlay"
|
||||
@click="operate('stop', row.name)"
|
||||
>
|
||||
{{ $t('commons.status.running') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else-if="checkStatus(row.status) === 'WARNING'"
|
||||
link
|
||||
type="warning"
|
||||
:icon="RefreshRight"
|
||||
@click="operate('restart', row.name)"
|
||||
>
|
||||
{{ $t('commons.status.unhealthy') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
link
|
||||
type="danger"
|
||||
:icon="VideoPause"
|
||||
@click="operate('start', row.name)"
|
||||
>
|
||||
{{ $t('commons.status.stopped') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="!row.hasLoad">
|
||||
<el-button link loading></el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" min-width="60px">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.hasLoad">
|
||||
<el-popover placement="bottom" :width="600" trigger="hover">
|
||||
<template #reference>
|
||||
<el-button type="primary" link v-if="row.status.length > 1">
|
||||
{{ $t('website.check') }}
|
||||
</el-button>
|
||||
<el-button type="primary" link v-else>
|
||||
<span>{{ row.status[0].status }}</span>
|
||||
<span>{{ $t('tool.supervisor.' + row.status[0].status) }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table :data="row.status">
|
||||
@@ -60,7 +109,7 @@
|
||||
/>
|
||||
<el-table-column
|
||||
property="status"
|
||||
:label="$t('commons.table.status')"
|
||||
:label="$t('tool.supervisor.statusCode')"
|
||||
width="100px"
|
||||
/>
|
||||
<el-table-column property="PID" label="PID" width="100px" />
|
||||
@@ -78,6 +127,9 @@
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div v-if="!row.hasLoad">
|
||||
<el-button link loading></el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
@@ -85,7 +137,7 @@
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
:fixed="mobile ? false : 'right'"
|
||||
width="350px"
|
||||
width="280px"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
@@ -93,7 +145,7 @@
|
||||
<ConfigSuperVisor v-if="setSuperVisor" />
|
||||
</LayoutContent>
|
||||
<Create ref="createRef" @close="search"></Create>
|
||||
<File ref="fileRef"></File>
|
||||
<File ref="fileRef" @search="search"></File>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,11 +157,12 @@ import ConfigSuperVisor from './config/index.vue';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import Create from './create/index.vue';
|
||||
import File from './file/index.vue';
|
||||
import { GetSupervisorProcess, OperateSupervisorProcess } from '@/api/modules/host-tool';
|
||||
import { GetSupervisorProcess, LoadProcessStatus, OperateSupervisorProcess } from '@/api/modules/host-tool';
|
||||
import { GlobalStore } from '@/store';
|
||||
import i18n from '@/lang';
|
||||
import { HostTool } from '@/api/interface/host-tool';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { VideoPlay, VideoPause, RefreshRight } from '@element-plus/icons-vue';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const loading = ref(false);
|
||||
@@ -131,6 +184,7 @@ const setting = () => {
|
||||
|
||||
const getStatus = (status: any) => {
|
||||
supervisorStatus.value = status;
|
||||
search();
|
||||
};
|
||||
|
||||
const showStopped = computed((): boolean => {
|
||||
@@ -158,7 +212,11 @@ const openCreate = () => {
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
if (!supervisorStatus.value.isExist) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
loadStatus();
|
||||
try {
|
||||
const res = await GetSupervisorProcess();
|
||||
data.value = res.data;
|
||||
@@ -166,10 +224,46 @@ const search = async () => {
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
await LoadProcessStatus()
|
||||
.then((res) => {
|
||||
let stats = res.data || [];
|
||||
for (const process of data.value) {
|
||||
process.status = [];
|
||||
for (const item of stats) {
|
||||
if (process.name === item.name.split(':')[0]) {
|
||||
process.status.push(item);
|
||||
}
|
||||
}
|
||||
process.hasLoad = true;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
for (const process of data.value) {
|
||||
process.status = [{ name: '-', status: 'FATAL', msg: i18n.global.t('tool.supervisor.loadStatusErr') }];
|
||||
process.hasLoad = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const mobile = computed(() => {
|
||||
return globalStore.isMobile();
|
||||
});
|
||||
|
||||
const checkStatus = (status: HostTool.ProcessStatus[]): string => {
|
||||
if (!status || status.length === 0) return 'STOPPED';
|
||||
|
||||
const statusCounts = status.reduce((acc, curr) => {
|
||||
acc[curr.status] = (acc[curr.status] || 0) + 1;
|
||||
return acc;
|
||||
}, {} as Record<string, number>);
|
||||
|
||||
if (statusCounts['STARTING']) return 'STARTING';
|
||||
if (statusCounts['RUNNING'] === status.length) return 'RUNNING';
|
||||
if (statusCounts['RUNNING'] > 0) return 'WARNING';
|
||||
return 'STOPPED';
|
||||
};
|
||||
|
||||
const operate = async (operation: string, name: string) => {
|
||||
try {
|
||||
ElMessageBox.confirm(
|
||||
@@ -224,42 +318,11 @@ const buttons = [
|
||||
getFile(row.name, 'out.log');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('app.start'),
|
||||
click: function (row: HostTool.SupersivorProcess) {
|
||||
operate('start', row.name);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
if (row.status == undefined) {
|
||||
return true;
|
||||
} else {
|
||||
return row.status && row.status[0].status == 'RUNNING';
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('app.stop'),
|
||||
click: function (row: HostTool.SupersivorProcess) {
|
||||
operate('stop', row.name);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
if (row.status == undefined) {
|
||||
return true;
|
||||
}
|
||||
return row.status && row.status[0].status != 'RUNNING';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.restart'),
|
||||
click: function (row: HostTool.SupersivorProcess) {
|
||||
operate('restart', row.name);
|
||||
},
|
||||
disabled: (row: any): boolean => {
|
||||
if (row.status == undefined) {
|
||||
return true;
|
||||
}
|
||||
return row.status && row.status[0].status != 'RUNNING';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import type { ElForm } from 'element-plus';
|
||||
import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage } from '@/api/modules/auth';
|
||||
@@ -182,9 +182,10 @@ const loginForm = reactive({
|
||||
agreeLicense: false,
|
||||
language: 'zh',
|
||||
});
|
||||
|
||||
const loginRules = reactive({
|
||||
name: [{ required: true, message: i18n.global.t('commons.rule.username'), trigger: 'blur' }],
|
||||
password: [{ required: true, message: i18n.global.t('commons.rule.password'), trigger: 'blur' }],
|
||||
name: computed(() => [{ required: true, message: i18n.global.t('commons.rule.username'), trigger: 'blur' }]),
|
||||
password: computed(() => [{ required: true, message: i18n.global.t('commons.rule.password'), trigger: 'blur' }]),
|
||||
});
|
||||
|
||||
const mfaButtonFocused = ref();
|
||||
|
||||
@@ -4,10 +4,17 @@
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('setting.systemIP')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
@submit.prevent
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('setting.systemIP')" prop="systemIP" :rules="Rules.ipV4V6OrDomain">
|
||||
<el-form-item :label="$t('setting.systemIP')" prop="systemIP">
|
||||
<el-input clearable v-model="form.systemIP" />
|
||||
<span class="input-help">{{ $t('commons.rule.hostHelper') }}</span>
|
||||
</el-form-item>
|
||||
@@ -31,8 +38,8 @@ import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { updateSetting } from '@/api/modules/setting';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { checkDomain, checkIpV4V6 } from '@/utils/util';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
@@ -47,6 +54,18 @@ const form = reactive({
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const rules = reactive({
|
||||
systemIP: [{ validator: checkSystemIP, trigger: 'blur' }],
|
||||
});
|
||||
|
||||
function checkSystemIP(rule: any, value: any, callback: any) {
|
||||
if (form.systemIP !== '') {
|
||||
if (checkIpV4V6(form.systemIP) && checkDomain(form.systemIP)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.host')));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.systemIP = params.systemIP;
|
||||
|
||||
@@ -234,16 +234,13 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
};
|
||||
|
||||
const getProtocolAndHost = (url: string): { protocol: string; host: string } | null => {
|
||||
const regex = /^(https?:\/\/)([^\/]+)/;
|
||||
const match = url.match(regex);
|
||||
if (match) {
|
||||
return {
|
||||
protocol: match[1],
|
||||
host: match[2],
|
||||
};
|
||||
if (url.startsWith('https://')) {
|
||||
return { protocol: 'https://', host: url.replaceAll('https://', '') };
|
||||
}
|
||||
console.log('err');
|
||||
return null;
|
||||
if (url.startsWith('http://')) {
|
||||
return { protocol: 'http://', host: url.replaceAll('http://', '') };
|
||||
}
|
||||
return { protocol: '', host: url };
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
|
||||
@@ -5,28 +5,28 @@
|
||||
{{ $t('commons.button.create') + $t('website.redirect') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
|
||||
<el-table-column :label="$t('website.sourceDomain')" prop="domain" min-width="150px">
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" min-width="60px" show-overflow-tooltip />
|
||||
<el-table-column :label="$t('website.sourceDomain')" prop="domain" min-width="80px" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.type === 'domain'">{{ row.domains.join(',') }}</span>
|
||||
<span v-else>{{ row.path }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.type')" prop="type" width="80px">
|
||||
<el-table-column :label="$t('commons.table.type')" prop="type" min-width="60px">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.type != 404">{{ $t('website.' + row.type) }}</span>
|
||||
<span v-else>{{ 404 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('website.redirectWay')" prop="redirect" width="80px"></el-table-column>
|
||||
<el-table-column :label="$t('website.targetURL')" prop="target"></el-table-column>
|
||||
<el-table-column :label="$t('website.keepPath')" prop="keepPath">
|
||||
<el-table-column :label="$t('website.redirectWay')" prop="redirect" min-width="50px"></el-table-column>
|
||||
<el-table-column :label="$t('website.targetURL')" prop="target" min-width="100px" show-overflow-tooltip />
|
||||
<el-table-column :label="$t('website.keepPath')" prop="keepPath" min-width="80px" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.type != '404'">{{ row.keepPath ? $t('website.keep') : $t('website.notKeep') }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="enable">
|
||||
<el-table-column :label="$t('commons.table.status')" prop="enable" min-width="50px">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.enable" link type="success" :icon="VideoPlay" @click="opProxy(row)">
|
||||
{{ $t('commons.status.running') }}
|
||||
@@ -38,7 +38,7 @@
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
:ellipsis="10"
|
||||
width="220px"
|
||||
width="180px"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
:fixed="mobile ? false : 'right'"
|
||||
|
||||
@@ -8,7 +8,6 @@ require (
|
||||
github.com/compose-spec/compose-go v1.13.2
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/dgraph-io/badger/v4 v4.1.0
|
||||
github.com/docker/cli v23.0.1+incompatible
|
||||
github.com/docker/compose/v2 v2.17.2
|
||||
github.com/docker/docker v23.0.3+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
@@ -62,7 +61,6 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
@@ -70,22 +68,10 @@ 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/aws/aws-sdk-go-v2 v1.16.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 // indirect
|
||||
github.com/aws/smithy-go v1.11.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bodgit/plumbing v1.2.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.3.0 // indirect
|
||||
github.com/bodgit/windows v1.0.0 // indirect
|
||||
github.com/buger/goterm v1.0.4 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@@ -102,6 +88,7 @@ require (
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230223072852-e5d5810851d1 // indirect
|
||||
github.com/docker/buildx v0.10.4 // indirect
|
||||
github.com/docker/cli v23.0.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
@@ -110,7 +97,6 @@ require (
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fsnotify/fsevents v0.1.1 // indirect
|
||||
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
@@ -131,7 +117,6 @@ require (
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/glog v1.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/flatbuffers v1.12.1 // indirect
|
||||
@@ -139,7 +124,6 @@ require (
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
@@ -155,10 +139,8 @@ require (
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.3.1-0.20230117163003-a89700cec744 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
@@ -166,12 +148,9 @@ require (
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
@@ -180,11 +159,8 @@ require (
|
||||
github.com/moby/buildkit v0.11.5 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/patternmatcher v0.5.0 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/sys/symlink v0.2.0 // indirect
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
@@ -204,9 +180,7 @@ require (
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.5 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -214,7 +188,6 @@ require (
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa // indirect
|
||||
@@ -233,10 +206,7 @@ require (
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.29.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect
|
||||
go.opentelemetry.io/otel v1.15.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.27.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.4.1 // indirect
|
||||
|
||||
@@ -39,8 +39,6 @@ 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=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
@@ -59,8 +57,6 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Microsoft/hcsshim v0.9.7 h1:mKNHW/Xvv1aFH87Jb6ERDzXTJTLPlmzfZ28VBFD/bfg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
@@ -84,28 +80,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.44.99 h1:ITZ9q/fmH+Ksaz2TbyMU2d19vOOWs/hAlt8NbXAieHw=
|
||||
github.com/aws/aws-sdk-go v1.44.99/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3 h1:0W1TSJ7O6OzwuEvIXAtJGvOeQ0SGAhcpxPN2/NK5EhM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5 h1:P+xwhr6kabhxDTXTVH9YoHkqjLJ0wVVpIUHtFNr2hjU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5/go.mod h1:ZijHHh0xd/A+ZY53az0qzC5tT46kt4JVCePf2NX9Lk4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 h1:4R/NqlcRFSkR0wxOhgHi+agGpbEr5qMCjn7VqUIJY+E=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0/go.mod h1:9YWk7VW+eyKsoIL6/CljkTrNVWBSK9pkqOPUuijid4A=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 h1:FP8gquGeGHHdfY6G5llaMQDF+HAf20VKc8opRwmjf04=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4/go.mod h1:u/s5/Z+ohUQOPXl00m2yJVyioWDECsbpXTQlaqSlufc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 h1:uFWgo6mGJI1n17nbcvSc6fxVuR3xLNqvXt12JCnEcT8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 h1:cnsvEKSoHN4oAN7spMMr0zhEW2MHnhAVpmqQg8E6UcM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 h1:6cZRymlLEIlDTEB0+5+An6Zj1CKt6rSE69tOmFeu1nk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11/go.mod h1:0MR+sS1b/yxsfAPvAESrw8NfwUoxMinDyw6EYR9BS2U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 h1:b16QW0XWl0jWjLABFc1A+uh145Oqv+xDcObNk0iQgUk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4/go.mod h1:uKkN7qmSIsNJVyMtxNQoCEYMvFEXbOg9fwCJPdfp2u8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 h1:Uw5wBybFQ1UeA9ts0Y07gbv0ncZnIAyw858tDW0NP2o=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4/go.mod h1:cPDwJwsP4Kff9mldCXAmddjJL6JGQqtA3Mzer2zyr88=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 h1:+xtV90n3abQmgzk1pS++FdxZTrPEDgQng6e4/56WR2A=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4/go.mod h1:lfSYenAXtavyX2A1LsViglqlG9eEFYxNryTZS5rn3QE=
|
||||
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
|
||||
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
||||
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -120,8 +94,6 @@ github.com/bodgit/sevenzip v1.3.0 h1:1ljgELgtHqvgIp8W8kgeEGHIWP4ch3xGI8uOBZgLVKY
|
||||
github.com/bodgit/sevenzip v1.3.0/go.mod h1:omwNcgZTEooWM8gA/IJ2Nk/+ZQ94+GsytRzOJJ8FBlM=
|
||||
github.com/bodgit/windows v1.0.0 h1:rLQ/XjsleZvx4fR1tB/UxQrK+SJ2OFHzfPjLWWOhDIA=
|
||||
github.com/bodgit/windows v1.0.0/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=
|
||||
github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY=
|
||||
github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE=
|
||||
github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/bugsnag-go v1.5.0 h1:tP8hiPv1pGGW3LA6LKy5lW6WG+y9J2xWUdPd3WC452k=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
@@ -184,7 +156,6 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
@@ -236,7 +207,6 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@@ -254,8 +224,6 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/fsnotify/fsevents v0.1.1 h1:/125uxJvvoSDDBPen6yUZbil8J9ydKZnnl3TWWmvnkw=
|
||||
github.com/fsnotify/fsevents v0.1.1/go.mod h1:+d+hS27T6k5J8CRaPLKFgwKYcpS7GwW3Ule9+SC2ZRc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
@@ -376,7 +344,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -450,7 +417,6 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -487,8 +453,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@@ -524,8 +488,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jonboulle/clockwork v0.3.1-0.20230117163003-a89700cec744 h1:fJ+REXDOpsMqA2spt3wAq3HGJJvWnNitGK2KVZTos+8=
|
||||
github.com/jonboulle/clockwork v0.3.1-0.20230117163003-a89700cec744/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
@@ -544,8 +506,6 @@ github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVE
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
@@ -588,17 +548,11 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -606,8 +560,6 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
@@ -632,17 +584,13 @@ github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
|
||||
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||
github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc=
|
||||
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -759,8 +707,6 @@ github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@@ -775,8 +721,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 h1:ka9QPuQg2u4LGipiZGsgkg3rJCo4iIUCy75FddM0GRQ=
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
|
||||
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
|
||||
github.com/shirou/gopsutil/v3 v3.23.4 h1:hZwmDxZs7Ewt75DV81r4pFMqbq+di2cbt9FsQBqLD2o=
|
||||
github.com/shirou/gopsutil/v3 v3.23.4/go.mod h1:ZcGxyfzAMRevhUR2+cfhXDH6gQdFYE/t8j1nsU4mPI8=
|
||||
@@ -854,8 +798,6 @@ github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+x
|
||||
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
|
||||
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
||||
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA=
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
@@ -924,14 +866,9 @@ go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtB
|
||||
go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4=
|
||||
go.opentelemetry.io/otel v1.15.1 h1:3Iwq3lfRByPaws0f6bU3naAqOR1n5IeDWd9390kWHa8=
|
||||
go.opentelemetry.io/otel v1.15.1/go.mod h1:mHHGEHVDLal6YrKMmk9LqC4a3sF5g+fHfrttQIB1NTc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 h1:imIM3vRDMyZK1ypQlQlO+brE22I9lRhJsBDXpDWjlz8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 h1:WPpPsAAs8I2rA47v5u0558meKmmwm1Dj99ZbqCV8sZ8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 h1:AxqDiGk8CorEXStMDZF5Hz9vo9Z7ZZ+I5m8JRl/ko40=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1 h1:8qOago/OqoFclMUUj/184tZyRdDZFpcejSjbk5Jrl6Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1/go.mod h1:VwYo0Hak6Efuy0TXsZs8o1hnV3dHDPNtDbycG0hI8+M=
|
||||
go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk=
|
||||
go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw=
|
||||
go.opentelemetry.io/otel/metric v0.27.0 h1:HhJPsGhJoKRSegPQILFbODU56NS/L1UE4fS1sC5kIwQ=
|
||||
@@ -946,8 +883,6 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
|
||||
go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c=
|
||||
go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
@@ -1046,7 +981,6 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1092,7 +1026,6 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1106,13 +1039,9 @@ golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1124,7 +1053,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
@@ -1195,8 +1123,6 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
Reference in New Issue
Block a user