mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-27 20:49:03 +08:00
feat: 容器支持自定义控制台交互方式 (#2434)
This commit is contained in:
parent
dc86cbc1ee
commit
bca9777a43
@ -222,13 +222,13 @@ func (b *BaseApi) ContainerInfo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Summary Load container limis
|
||||
// @Summary Load container limits
|
||||
// @Description 获取容器限制
|
||||
// @Success 200 {object} dto.ResourceLimit
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/limit [get]
|
||||
func (b *BaseApi) LoadResouceLimit(c *gin.Context) {
|
||||
data, err := containerService.LoadResouceLimit()
|
||||
func (b *BaseApi) LoadResourceLimit(c *gin.Context) {
|
||||
data, err := containerService.LoadResourceLimit()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -44,6 +44,8 @@ type ContainerOperate struct {
|
||||
Network string `json:"network"`
|
||||
PublishAllPorts bool `json:"publishAllPorts"`
|
||||
ExposedPorts []PortHelper `json:"exposedPorts"`
|
||||
Tty bool `json:"tty"`
|
||||
OpenStdin bool `json:"openStdin"`
|
||||
Cmd []string `json:"cmd"`
|
||||
Entrypoint []string `json:"entrypoint"`
|
||||
CPUShares int64 `json:"cpuShares"`
|
||||
@ -70,7 +72,7 @@ type ContainerListStats struct {
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
PercpuUsage int `json:"percpuUsage"`
|
||||
|
||||
MemroyCache uint64 `json:"memoryCache"`
|
||||
MemoryCache uint64 `json:"memoryCache"`
|
||||
MemoryUsage uint64 `json:"memoryUsage"`
|
||||
MemoryLimit uint64 `json:"memoryLimit"`
|
||||
MemoryPercent float64 `json:"memoryPercent"`
|
||||
|
@ -51,7 +51,7 @@ type IContainerService interface {
|
||||
ContainerUpgrade(req dto.ContainerUpgrade) error
|
||||
ContainerInfo(req dto.OperationWithName) (*dto.ContainerOperate, error)
|
||||
ContainerListStats() ([]dto.ContainerListStats, error)
|
||||
LoadResouceLimit() (*dto.ResourceLimit, error)
|
||||
LoadResourceLimit() (*dto.ResourceLimit, error)
|
||||
ContainerLogClean(req dto.OperationWithName) error
|
||||
ContainerOperation(req dto.ContainerOperation) error
|
||||
ContainerLogs(wsConn *websocket.Conn, container, since, tail string, follow bool) error
|
||||
@ -288,7 +288,7 @@ func (u *ContainerService) Prune(req dto.ContainerPrune) (dto.ContainerPruneRepo
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) LoadResouceLimit() (*dto.ResourceLimit, error) {
|
||||
func (u *ContainerService) LoadResourceLimit() (*dto.ResourceLimit, error) {
|
||||
cpuCounts, err := cpu.Counts(true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load cpu limit failed, err: %v", err)
|
||||
@ -368,6 +368,8 @@ func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.Contai
|
||||
}
|
||||
}
|
||||
data.Cmd = oldContainer.Config.Cmd
|
||||
data.OpenStdin = oldContainer.Config.OpenStdin
|
||||
data.Tty = oldContainer.Config.Tty
|
||||
data.Entrypoint = oldContainer.Config.Entrypoint
|
||||
data.Env = oldContainer.Config.Env
|
||||
data.CPUShares = oldContainer.HostConfig.CPUShares
|
||||
@ -441,7 +443,7 @@ func (u *ContainerService) ContainerUpdate(req dto.ContainerOperate) error {
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, &networkConf, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings)
|
||||
return fmt.Errorf("update contianer failed, err: %v", err)
|
||||
return fmt.Errorf("update container failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Infof("update container %s successful! now check if the container is started.", req.Name)
|
||||
if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil {
|
||||
@ -487,7 +489,7 @@ func (u *ContainerService) ContainerUpgrade(req dto.ContainerUpgrade) error {
|
||||
container, err := client.ContainerCreate(ctx, config, hostConf, &networkConf, &v1.Platform{}, req.Name)
|
||||
if err != nil {
|
||||
reCreateAfterUpdate(req.Name, client, oldContainer.Config, oldContainer.HostConfig, oldContainer.NetworkSettings)
|
||||
return fmt.Errorf("upgrade contianer failed, err: %v", err)
|
||||
return fmt.Errorf("upgrade container failed, err: %v", err)
|
||||
}
|
||||
global.LOG.Infof("upgrade container %s successful! now check if the container is started.", req.Name)
|
||||
if err := client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil {
|
||||
@ -683,14 +685,14 @@ func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) s
|
||||
}
|
||||
|
||||
func stringsToMap(list []string) map[string]string {
|
||||
var lableMap = make(map[string]string)
|
||||
var labelMap = make(map[string]string)
|
||||
for _, label := range list {
|
||||
if strings.Contains(label, "=") {
|
||||
sps := strings.SplitN(label, "=", 2)
|
||||
lableMap[sps[0]] = sps[1]
|
||||
labelMap[sps[0]] = sps[1]
|
||||
}
|
||||
}
|
||||
return lableMap
|
||||
return labelMap
|
||||
}
|
||||
|
||||
func calculateCPUPercentUnix(stats *types.StatsJSON) float64 {
|
||||
@ -791,7 +793,7 @@ func loadCpuAndMem(client *client.Client, container string) dto.ContainerListSta
|
||||
data.CPUPercent = calculateCPUPercentUnix(stats)
|
||||
data.PercpuUsage = len(stats.CPUStats.CPUUsage.PercpuUsage)
|
||||
|
||||
data.MemroyCache = stats.MemoryStats.Stats["cache"]
|
||||
data.MemoryCache = stats.MemoryStats.Stats["cache"]
|
||||
data.MemoryUsage = stats.MemoryStats.Usage
|
||||
data.MemoryLimit = stats.MemoryStats.Limit
|
||||
data.MemoryPercent = calculateMemPercentUnix(stats.MemoryStats)
|
||||
@ -849,16 +851,18 @@ func loadConfigInfo(req dto.ContainerOperate, config *container.Config, hostConf
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exposeds := make(nat.PortSet)
|
||||
exposed := make(nat.PortSet)
|
||||
for port := range portMap {
|
||||
exposeds[port] = struct{}{}
|
||||
exposed[port] = struct{}{}
|
||||
}
|
||||
config.Image = req.Image
|
||||
config.Cmd = req.Cmd
|
||||
config.Entrypoint = req.Entrypoint
|
||||
config.Env = req.Env
|
||||
config.Labels = stringsToMap(req.Labels)
|
||||
config.ExposedPorts = exposeds
|
||||
config.ExposedPorts = exposed
|
||||
config.OpenStdin = req.OpenStdin
|
||||
config.Tty = req.Tty
|
||||
|
||||
if len(req.Network) != 0 {
|
||||
networkConf.EndpointsConfig = map[string]*network.EndpointSettings{req.Network: {}}
|
||||
|
@ -26,7 +26,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
|
||||
baRouter.POST("/list", baseApi.ListContainer)
|
||||
baRouter.GET("/list/stats", baseApi.ContainerListStats)
|
||||
baRouter.GET("/search/log", baseApi.ContainerLogs)
|
||||
baRouter.GET("/limit", baseApi.LoadResouceLimit)
|
||||
baRouter.GET("/limit", baseApi.LoadResourceLimit)
|
||||
baRouter.POST("/clean/log", baseApi.CleanContainerLog)
|
||||
baRouter.POST("/load/log", baseApi.LoadContainerLog)
|
||||
baRouter.POST("/inspect", baseApi.Inspect)
|
||||
|
@ -1233,7 +1233,7 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"/containers/compose/search/log": {
|
||||
"post": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
@ -2037,7 +2037,7 @@ const docTemplate = `{
|
||||
}
|
||||
],
|
||||
"description": "获取容器限制",
|
||||
"summary": "Load container limis",
|
||||
"summary": "Load container limits",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
@ -12549,12 +12549,18 @@ const docTemplate = `{
|
||||
"network": {
|
||||
"type": "string"
|
||||
},
|
||||
"openStdin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"publishAllPorts": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"restartPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"tty": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -16649,6 +16655,9 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -16734,6 +16743,9 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"rebuild": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
@ -1226,7 +1226,7 @@
|
||||
}
|
||||
},
|
||||
"/containers/compose/search/log": {
|
||||
"post": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
@ -2030,7 +2030,7 @@
|
||||
}
|
||||
],
|
||||
"description": "获取容器限制",
|
||||
"summary": "Load container limis",
|
||||
"summary": "Load container limits",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
@ -12542,12 +12542,18 @@
|
||||
"network": {
|
||||
"type": "string"
|
||||
},
|
||||
"openStdin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"publishAllPorts": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"restartPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"tty": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -16642,6 +16648,9 @@
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -16727,6 +16736,9 @@
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"rebuild": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
@ -403,10 +403,14 @@ definitions:
|
||||
type: number
|
||||
network:
|
||||
type: string
|
||||
openStdin:
|
||||
type: boolean
|
||||
publishAllPorts:
|
||||
type: boolean
|
||||
restartPolicy:
|
||||
type: string
|
||||
tty:
|
||||
type: boolean
|
||||
volumes:
|
||||
items:
|
||||
$ref: '#/definitions/dto.VolumeHelper'
|
||||
@ -3152,6 +3156,8 @@ definitions:
|
||||
params:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
port:
|
||||
type: integer
|
||||
resource:
|
||||
type: string
|
||||
source:
|
||||
@ -3208,6 +3214,8 @@ definitions:
|
||||
params:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
port:
|
||||
type: integer
|
||||
rebuild:
|
||||
type: boolean
|
||||
source:
|
||||
@ -4909,7 +4917,7 @@ paths:
|
||||
tags:
|
||||
- Container Compose
|
||||
/containers/compose/search/log:
|
||||
post:
|
||||
get:
|
||||
description: docker-compose 日志
|
||||
parameters:
|
||||
- description: compose 文件地址
|
||||
@ -5426,7 +5434,7 @@ paths:
|
||||
$ref: '#/definitions/dto.ResourceLimit'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Load container limis
|
||||
summary: Load container limits
|
||||
/containers/list:
|
||||
post:
|
||||
consumes:
|
||||
|
@ -27,6 +27,8 @@ export namespace Container {
|
||||
entrypointStr: string;
|
||||
memoryItem: number;
|
||||
cmd: Array<string>;
|
||||
openStdin: boolean;
|
||||
tty: boolean;
|
||||
entrypoint: Array<string>;
|
||||
publishAllPorts: boolean;
|
||||
exposedPorts: Array<Port>;
|
||||
|
@ -544,6 +544,9 @@ const message = {
|
||||
'The default CPU share for a container is 1024, which can be increased to give the container more CPU time.',
|
||||
|
||||
command: 'Command',
|
||||
console: 'Console Interaction',
|
||||
tty: 'TTY (-t)',
|
||||
openStdin: 'OpenStdin (-i)',
|
||||
custom: 'Custom',
|
||||
emptyUser: 'When empty, you will log in as default',
|
||||
containerTerminal: 'Terminal',
|
||||
|
@ -529,6 +529,9 @@ const message = {
|
||||
cpuShareHelper: '容器默認份額為 1024 個 CPU,增大可使當前容器獲得更多的 CPU 時間',
|
||||
|
||||
command: '命令',
|
||||
console: '控製臺交互',
|
||||
tty: '偽終端 ( -t )',
|
||||
openStdin: '標準輸入 ( -i )',
|
||||
custom: '自定義',
|
||||
containerTerminal: '終端',
|
||||
emptyUser: '為空時,將使用容器默認的用戶登錄',
|
||||
|
@ -529,6 +529,9 @@ const message = {
|
||||
cpuShareHelper: '容器默认份额为 1024 个 CPU,增大可使当前容器获得更多的 CPU 时间',
|
||||
|
||||
command: '命令',
|
||||
console: '控制台交互',
|
||||
tty: '伪终端 ( -t )',
|
||||
openStdin: '标准输入 ( -i )',
|
||||
custom: '自定义',
|
||||
containerTerminal: '终端',
|
||||
emptyUser: '为空时,将使用容器默认的用户登录',
|
||||
|
@ -176,6 +176,12 @@
|
||||
{{ $t('container.autoRemove') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.console')">
|
||||
<el-checkbox v-model="dialogData.rowData!.tty">{{ $t('container.tty') }}</el-checkbox>
|
||||
<el-checkbox v-model="dialogData.rowData!.openStdin">
|
||||
{{ $t('container.openStdin') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('container.restartPolicy')" prop="restartPolicy">
|
||||
<el-radio-group v-model="dialogData.rowData!.restartPolicy">
|
||||
<el-radio label="no">{{ $t('container.no') }}</el-radio>
|
||||
|
Loading…
Reference in New Issue
Block a user