mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 17:17:13 +08:00
feat: 完善容器接口
This commit is contained in:
@@ -5,10 +5,15 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
|
||||
commonrequests "panel/app/http/requests/common"
|
||||
requests "panel/app/http/requests/container"
|
||||
"panel/internal/services"
|
||||
)
|
||||
@@ -23,17 +28,61 @@ func NewContainerController() *ContainerController {
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerList
|
||||
//
|
||||
// @Summary 获取容器列表
|
||||
// @Description 获取所有容器列表
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/list [get]
|
||||
func (r *ContainerController) ContainerList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
containers, err := r.container.ContainerListAll()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, containers)
|
||||
startIndex := (request.Page - 1) * request.Limit
|
||||
endIndex := request.Page * request.Limit
|
||||
if startIndex > len(containers) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []types.Container{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(containers) {
|
||||
endIndex = len(containers)
|
||||
}
|
||||
paged := containers[startIndex:endIndex]
|
||||
if paged == nil {
|
||||
paged = []types.Container{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(containers),
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
// ContainerSearch
|
||||
//
|
||||
// @Summary 搜索容器
|
||||
// @Description 根据容器名称搜索容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param name query string true "容器名称"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/search [get]
|
||||
func (r *ContainerController) ContainerSearch(ctx http.Context) http.Response {
|
||||
fields := strings.Fields(ctx.Request().Query("names"))
|
||||
fields := strings.Fields(ctx.Request().Query("name"))
|
||||
containers, err := r.container.ContainerListByNames(fields)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -42,6 +91,17 @@ func (r *ContainerController) ContainerSearch(ctx http.Context) http.Response {
|
||||
return Success(ctx, containers)
|
||||
}
|
||||
|
||||
// ContainerCreate
|
||||
//
|
||||
// @Summary 创建容器
|
||||
// @Description 创建一个容器
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ContainerCreate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/create [post]
|
||||
func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
|
||||
var request requests.ContainerCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -125,6 +185,16 @@ func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
|
||||
return Success(ctx, id)
|
||||
}
|
||||
|
||||
// ContainerRemove
|
||||
//
|
||||
// @Summary 删除容器
|
||||
// @Description 删除一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/remove [post]
|
||||
func (r *ContainerController) ContainerRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -138,6 +208,16 @@ func (r *ContainerController) ContainerRemove(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerStart
|
||||
//
|
||||
// @Summary 启动容器
|
||||
// @Description 启动一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/start [post]
|
||||
func (r *ContainerController) ContainerStart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -151,6 +231,16 @@ func (r *ContainerController) ContainerStart(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerStop
|
||||
//
|
||||
// @Summary 停止容器
|
||||
// @Description 停止一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/stop [post]
|
||||
func (r *ContainerController) ContainerStop(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -164,6 +254,16 @@ func (r *ContainerController) ContainerStop(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerRestart
|
||||
//
|
||||
// @Summary 重启容器
|
||||
// @Description 重启一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/restart [post]
|
||||
func (r *ContainerController) ContainerRestart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -177,6 +277,15 @@ func (r *ContainerController) ContainerRestart(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerPause
|
||||
//
|
||||
// @Summary 暂停容器
|
||||
// @Description 暂停一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
func (r *ContainerController) ContainerPause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -190,6 +299,17 @@ func (r *ContainerController) ContainerPause(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerUnpause
|
||||
//
|
||||
// @Summary 取消暂停容器
|
||||
// @Description 取消暂停一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
//
|
||||
// @Router /panel/container/unpause [post]
|
||||
func (r *ContainerController) ContainerUnpause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -203,6 +323,16 @@ func (r *ContainerController) ContainerUnpause(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerInspect
|
||||
//
|
||||
// @Summary 查看容器
|
||||
// @Description 查看一个容器的详细信息
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/inspect [get]
|
||||
func (r *ContainerController) ContainerInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -217,6 +347,16 @@ func (r *ContainerController) ContainerInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// ContainerKill
|
||||
//
|
||||
// @Summary 杀死容器
|
||||
// @Description 杀死一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/kill [post]
|
||||
func (r *ContainerController) ContainerKill(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -230,6 +370,16 @@ func (r *ContainerController) ContainerKill(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerRename
|
||||
//
|
||||
// @Summary 重命名容器
|
||||
// @Description 重命名一个容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ContainerRename true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/rename [post]
|
||||
func (r *ContainerController) ContainerRename(ctx http.Context) http.Response {
|
||||
var request requests.ContainerRename
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -243,6 +393,16 @@ func (r *ContainerController) ContainerRename(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ContainerStats
|
||||
//
|
||||
// @Summary 查看容器状态
|
||||
// @Description 查看一个容器的状态信息
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/stats [get]
|
||||
func (r *ContainerController) ContainerStats(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -257,6 +417,16 @@ func (r *ContainerController) ContainerStats(ctx http.Context) http.Response {
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// ContainerExist
|
||||
//
|
||||
// @Summary 检查容器是否存在
|
||||
// @Description 检查一个容器是否存在
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/exist [get]
|
||||
func (r *ContainerController) ContainerExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -271,6 +441,16 @@ func (r *ContainerController) ContainerExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, exist)
|
||||
}
|
||||
|
||||
// ContainerLogs
|
||||
//
|
||||
// @Summary 查看容器日志
|
||||
// @Description 查看一个容器的日志
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/logs [get]
|
||||
func (r *ContainerController) ContainerLogs(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
@@ -285,6 +465,15 @@ func (r *ContainerController) ContainerLogs(ctx http.Context) http.Response {
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// ContainerPrune
|
||||
//
|
||||
// @Summary 清理容器
|
||||
// @Description 清理无用的容器
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/prune [post]
|
||||
func (r *ContainerController) ContainerPrune(ctx http.Context) http.Response {
|
||||
if err := r.container.ContainerPrune(); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -293,92 +482,517 @@ func (r *ContainerController) ContainerPrune(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// NetworkList
|
||||
//
|
||||
// @Summary 获取网络列表
|
||||
// @Description 获取所有网络列表
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/list [get]
|
||||
func (r *ContainerController) NetworkList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
networks, err := r.container.NetworkList()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, networks)
|
||||
startIndex := (request.Page - 1) * request.Limit
|
||||
endIndex := request.Page * request.Limit
|
||||
if startIndex > len(networks) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []types.NetworkResource{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(networks) {
|
||||
endIndex = len(networks)
|
||||
}
|
||||
paged := networks[startIndex:endIndex]
|
||||
if paged == nil {
|
||||
paged = []types.NetworkResource{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(networks),
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
// NetworkCreate
|
||||
//
|
||||
// @Summary 创建网络
|
||||
// @Description 创建一个网络
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.NetworkCreate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/create [post]
|
||||
func (r *ContainerController) NetworkCreate(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.NetworkCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
id, err := r.container.NetworkCreate(request)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, id)
|
||||
}
|
||||
|
||||
// NetworkRemove
|
||||
//
|
||||
// @Summary 删除网络
|
||||
// @Description 删除一个网络
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/remove [post]
|
||||
func (r *ContainerController) NetworkRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.NetworkRemove(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// NetworkExist
|
||||
//
|
||||
// @Summary 检查网络是否存在
|
||||
// @Description 检查一个网络是否存在
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/exist [get]
|
||||
func (r *ContainerController) NetworkExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
exist, err := r.container.NetworkExist(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, exist)
|
||||
}
|
||||
|
||||
// NetworkInspect
|
||||
//
|
||||
// @Summary 查看网络
|
||||
// @Description 查看一个网络的详细信息
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/inspect [get]
|
||||
func (r *ContainerController) NetworkInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.NetworkInspect(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// NetworkConnect
|
||||
//
|
||||
// @Summary 连接容器到网络
|
||||
// @Description 连接一个容器到一个网络
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.NetworkConnectDisConnect true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/connect [post]
|
||||
func (r *ContainerController) NetworkConnect(ctx http.Context) http.Response {
|
||||
var request requests.NetworkConnectDisConnect
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.NetworkConnect(request.Network, request.Container); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// NetworkDisconnect
|
||||
//
|
||||
// @Summary 从网络断开容器
|
||||
// @Description 从一个网络断开一个容器
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.NetworkConnectDisConnect true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/disconnect [post]
|
||||
func (r *ContainerController) NetworkDisconnect(ctx http.Context) http.Response {
|
||||
var request requests.NetworkConnectDisConnect
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.NetworkDisconnect(request.Network, request.Container); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// NetworkPrune
|
||||
//
|
||||
// @Summary 清理网络
|
||||
// @Description 清理无用的网络
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/network/prune [post]
|
||||
func (r *ContainerController) NetworkPrune(ctx http.Context) http.Response {
|
||||
if err := r.container.NetworkPrune(); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ImageList
|
||||
//
|
||||
// @Summary 获取镜像列表
|
||||
// @Description 获取所有镜像列表
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/list [get]
|
||||
func (r *ContainerController) ImageList(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
images, err := r.container.ImageList()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
startIndex := (request.Page - 1) * request.Limit
|
||||
endIndex := request.Page * request.Limit
|
||||
if startIndex > len(images) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []image.Summary{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(images) {
|
||||
endIndex = len(images)
|
||||
}
|
||||
paged := images[startIndex:endIndex]
|
||||
if paged == nil {
|
||||
paged = []image.Summary{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(images),
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
// ImageExist
|
||||
//
|
||||
// @Summary 检查镜像是否存在
|
||||
// @Description 检查一个镜像是否存在
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/exist [get]
|
||||
func (r *ContainerController) ImageExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
exist, err := r.container.ImageExist(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, exist)
|
||||
}
|
||||
|
||||
// ImagePull
|
||||
//
|
||||
// @Summary 拉取镜像
|
||||
// @Description 拉取一个镜像
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ImagePull true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/pull [post]
|
||||
func (r *ContainerController) ImagePull(ctx http.Context) http.Response {
|
||||
var request requests.ImagePull
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ImagePull(request); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ImageRemove
|
||||
//
|
||||
// @Summary 删除镜像
|
||||
// @Description 删除一个镜像
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/remove [post]
|
||||
func (r *ContainerController) ImageRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ImageRemove(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ImagePrune
|
||||
//
|
||||
// @Summary 清理镜像
|
||||
// @Description 清理无用的镜像
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/prune [post]
|
||||
func (r *ContainerController) ImagePrune(ctx http.Context) http.Response {
|
||||
if err := r.container.ImagePrune(); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ImageInspect
|
||||
//
|
||||
// @Summary 查看镜像
|
||||
// @Description 查看一个镜像的详细信息
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/image/inspect [get]
|
||||
func (r *ContainerController) ImageInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.ImageInspect(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// VolumeList
|
||||
//
|
||||
// @Summary 获取卷列表
|
||||
// @Description 获取所有卷列表
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/list [get]
|
||||
func (r *ContainerController) VolumeList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
volumes, err := r.container.VolumeList()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, volumes)
|
||||
startIndex := (request.Page - 1) * request.Limit
|
||||
endIndex := request.Page * request.Limit
|
||||
if startIndex > len(volumes) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []*volume.Volume{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(volumes) {
|
||||
endIndex = len(volumes)
|
||||
}
|
||||
paged := volumes[startIndex:endIndex]
|
||||
if paged == nil {
|
||||
paged = []*volume.Volume{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(volumes),
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
// VolumeCreate
|
||||
//
|
||||
// @Summary 创建卷
|
||||
// @Description 创建一个卷
|
||||
// @Tags 容器
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.VolumeCreate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/create [post]
|
||||
func (r *ContainerController) VolumeCreate(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.VolumeCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.VolumeCreate(request)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data.Name)
|
||||
}
|
||||
|
||||
// VolumeExist
|
||||
//
|
||||
// @Summary 检查卷是否存在
|
||||
// @Description 检查一个卷是否存在
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/exist [get]
|
||||
func (r *ContainerController) VolumeExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
exist, err := r.container.VolumeExist(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, exist)
|
||||
}
|
||||
|
||||
// VolumeInspect
|
||||
//
|
||||
// @Summary 查看卷
|
||||
// @Description 查看一个卷的详细信息
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/inspect [get]
|
||||
func (r *ContainerController) VolumeInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.VolumeInspect(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
// VolumeRemove
|
||||
//
|
||||
// @Summary 删除卷
|
||||
// @Description 删除一个卷
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/remove [post]
|
||||
func (r *ContainerController) VolumeRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.VolumeRemove(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// VolumePrune
|
||||
//
|
||||
// @Summary 清理卷
|
||||
// @Description 清理无用的卷
|
||||
// @Tags 容器
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/container/volume/prune [post]
|
||||
func (r *ContainerController) VolumePrune(ctx http.Context) http.Response {
|
||||
if err := r.container.VolumePrune(); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
38
app/http/requests/container/image_pull.go
Normal file
38
app/http/requests/container/image_pull.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type ImagePull struct {
|
||||
Name string `form:"name" json:"name"`
|
||||
Auth bool `form:"auth" json:"auth"`
|
||||
Username string `form:"username" json:"username"`
|
||||
Password string `form:"password" json:"password"`
|
||||
}
|
||||
|
||||
func (r *ImagePull) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ImagePull) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|string",
|
||||
"auth": "bool",
|
||||
"username": "string",
|
||||
"password": "string",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ImagePull) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ImagePull) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ImagePull) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
34
app/http/requests/container/network_connect_disconnect.go
Normal file
34
app/http/requests/container/network_connect_disconnect.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type NetworkConnectDisConnect struct {
|
||||
Network string `form:"network" json:"network"`
|
||||
Container string `form:"container" json:"container"`
|
||||
}
|
||||
|
||||
func (r *NetworkConnectDisConnect) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *NetworkConnectDisConnect) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"network": "required|string",
|
||||
"container": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *NetworkConnectDisConnect) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *NetworkConnectDisConnect) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *NetworkConnectDisConnect) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
42
app/http/requests/container/network_create.go
Normal file
42
app/http/requests/container/network_create.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type NetworkCreate struct {
|
||||
Name string `form:"name" json:"name"`
|
||||
Driver string `form:"driver" json:"driver"`
|
||||
Ipv4 Network `form:"ipv4" json:"ipv4"`
|
||||
Ipv6 Network `form:"ipv6" json:"ipv6"`
|
||||
Labels []string `form:"labels" json:"labels"`
|
||||
Options []string `form:"options" json:"options"`
|
||||
}
|
||||
|
||||
func (r *NetworkCreate) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *NetworkCreate) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|string",
|
||||
"driver": "required|string|in:bridge,overlay,macvlan,ipvlan",
|
||||
"ipv4": "required",
|
||||
"ipv6": "required",
|
||||
"labels": "slice",
|
||||
"options": "slice",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *NetworkCreate) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *NetworkCreate) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *NetworkCreate) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
@@ -1,16 +1,23 @@
|
||||
package requests
|
||||
|
||||
type ContainerPort struct {
|
||||
ContainerStart int `json:"start"`
|
||||
ContainerEnd int `json:"end"`
|
||||
Host string `json:"host"`
|
||||
HostStart int `json:"hostStart"`
|
||||
HostEnd int `json:"hostEnd"`
|
||||
Protocol string `json:"protocol"`
|
||||
ContainerStart int `form:"start" json:"start"`
|
||||
ContainerEnd int `form:"end" json:"end"`
|
||||
Host string `form:"host" json:"host"`
|
||||
HostStart int `form:"host_start" json:"host_start"`
|
||||
HostEnd int `form:"host_end" json:"host_end"`
|
||||
Protocol string `form:"protocol" json:"protocol"`
|
||||
}
|
||||
|
||||
type ContainerVolume struct {
|
||||
Host string `json:"host"`
|
||||
Container string `json:"container"`
|
||||
Mode string `json:"mode"`
|
||||
Host string `form:"start" json:"host"`
|
||||
Container string `form:"start" json:"container"`
|
||||
Mode string `form:"start" json:"mode"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
Enabled bool `form:"enabled" json:"enabled"`
|
||||
Gateway string `form:"gateway" json:"gateway"`
|
||||
IPRange string `form:"ip_range" json:"ip_range"`
|
||||
Subnet string `form:"subnet" json:"subnet"`
|
||||
}
|
||||
|
||||
38
app/http/requests/container/volume_create.go
Normal file
38
app/http/requests/container/volume_create.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type VolumeCreate struct {
|
||||
Name string `form:"name" json:"name"`
|
||||
Driver string `form:"driver" json:"driver"`
|
||||
Labels []string `form:"labels" json:"labels"`
|
||||
Options []string `form:"options" json:"options"`
|
||||
}
|
||||
|
||||
func (r *VolumeCreate) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *VolumeCreate) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|string",
|
||||
"driver": "required|string|in:local",
|
||||
"labels": "slice",
|
||||
"options": "slice",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *VolumeCreate) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *VolumeCreate) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *VolumeCreate) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
1426
docs/docs.go
1426
docs/docs.go
File diff suppressed because it is too large
Load Diff
1426
docs/swagger.json
1426
docs/swagger.json
File diff suppressed because it is too large
Load Diff
@@ -180,6 +180,11 @@ definitions:
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
panel_app_http_requests_container.ID:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
type: object
|
||||
panel_app_http_requests_plugins_rsync.Update:
|
||||
properties:
|
||||
auth_user:
|
||||
@@ -288,6 +293,88 @@ definitions:
|
||||
website_id:
|
||||
type: integer
|
||||
type: object
|
||||
requests.ContainerCreate:
|
||||
properties:
|
||||
auto_remove:
|
||||
type: boolean
|
||||
command:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
cpu_shares:
|
||||
type: integer
|
||||
cpus:
|
||||
type: integer
|
||||
entrypoint:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
env:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
image:
|
||||
type: string
|
||||
labels:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
memory:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
network:
|
||||
type: string
|
||||
open_stdin:
|
||||
type: boolean
|
||||
ports:
|
||||
items:
|
||||
$ref: '#/definitions/requests.ContainerPort'
|
||||
type: array
|
||||
privileged:
|
||||
type: boolean
|
||||
publish_all_ports:
|
||||
type: boolean
|
||||
restart_policy:
|
||||
type: string
|
||||
tty:
|
||||
type: boolean
|
||||
volumes:
|
||||
items:
|
||||
$ref: '#/definitions/requests.ContainerVolume'
|
||||
type: array
|
||||
type: object
|
||||
requests.ContainerPort:
|
||||
properties:
|
||||
end:
|
||||
type: integer
|
||||
host:
|
||||
type: string
|
||||
host_end:
|
||||
type: integer
|
||||
host_start:
|
||||
type: integer
|
||||
protocol:
|
||||
type: string
|
||||
start:
|
||||
type: integer
|
||||
type: object
|
||||
requests.ContainerRename:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
requests.ContainerVolume:
|
||||
properties:
|
||||
container:
|
||||
type: string
|
||||
host:
|
||||
type: string
|
||||
mode:
|
||||
type: string
|
||||
type: object
|
||||
requests.Copy:
|
||||
properties:
|
||||
new:
|
||||
@@ -340,6 +427,17 @@ definitions:
|
||||
path:
|
||||
type: string
|
||||
type: object
|
||||
requests.ImagePull:
|
||||
properties:
|
||||
auth:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
requests.Login:
|
||||
properties:
|
||||
password:
|
||||
@@ -354,6 +452,43 @@ definitions:
|
||||
old:
|
||||
type: string
|
||||
type: object
|
||||
requests.Network:
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
gateway:
|
||||
type: string
|
||||
ip_range:
|
||||
type: string
|
||||
subnet:
|
||||
type: string
|
||||
type: object
|
||||
requests.NetworkConnectDisConnect:
|
||||
properties:
|
||||
container:
|
||||
type: string
|
||||
network:
|
||||
type: string
|
||||
type: object
|
||||
requests.NetworkCreate:
|
||||
properties:
|
||||
driver:
|
||||
type: string
|
||||
ipv4:
|
||||
$ref: '#/definitions/requests.Network'
|
||||
ipv6:
|
||||
$ref: '#/definitions/requests.Network'
|
||||
labels:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
options:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
requests.NotExist:
|
||||
properties:
|
||||
path:
|
||||
@@ -479,6 +614,21 @@ definitions:
|
||||
kid:
|
||||
type: string
|
||||
type: object
|
||||
requests.VolumeCreate:
|
||||
properties:
|
||||
driver:
|
||||
type: string
|
||||
labels:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
options:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
info:
|
||||
contact:
|
||||
email: i@haozi.net
|
||||
@@ -976,6 +1126,729 @@ paths:
|
||||
summary: 更新 ACME 用户
|
||||
tags:
|
||||
- 证书管理
|
||||
/panel/container/create:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 创建一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.ContainerCreate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 创建容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/exist:
|
||||
get:
|
||||
description: 检查一个容器是否存在
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 检查容器是否存在
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/exist:
|
||||
get:
|
||||
description: 检查一个镜像是否存在
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 检查镜像是否存在
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/inspect:
|
||||
get:
|
||||
description: 查看一个镜像的详细信息
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看镜像
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/list:
|
||||
get:
|
||||
description: 获取所有镜像列表
|
||||
parameters:
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 获取镜像列表
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/prune:
|
||||
post:
|
||||
description: 清理无用的镜像
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 清理镜像
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/pull:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 拉取一个镜像
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.ImagePull'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 拉取镜像
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/image/remove:
|
||||
post:
|
||||
description: 删除一个镜像
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 删除镜像
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/inspect:
|
||||
get:
|
||||
description: 查看一个容器的详细信息
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/kill:
|
||||
post:
|
||||
description: 杀死一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 杀死容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/list:
|
||||
get:
|
||||
description: 获取所有容器列表
|
||||
parameters:
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 获取容器列表
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/logs:
|
||||
get:
|
||||
description: 查看一个容器的日志
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看容器日志
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/connect:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 连接一个容器到一个网络
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.NetworkConnectDisConnect'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 连接容器到网络
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/create:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 创建一个网络
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.NetworkCreate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 创建网络
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/disconnect:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 从一个网络断开一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.NetworkConnectDisConnect'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 从网络断开容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/exist:
|
||||
get:
|
||||
description: 检查一个网络是否存在
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 检查网络是否存在
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/inspect:
|
||||
get:
|
||||
description: 查看一个网络的详细信息
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看网络
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/list:
|
||||
get:
|
||||
description: 获取所有网络列表
|
||||
parameters:
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 获取网络列表
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/prune:
|
||||
post:
|
||||
description: 清理无用的网络
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 清理网络
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/network/remove:
|
||||
post:
|
||||
description: 删除一个网络
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 删除网络
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/prune:
|
||||
post:
|
||||
description: 清理无用的容器
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 清理容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/remove:
|
||||
post:
|
||||
description: 删除一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 删除容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/rename:
|
||||
post:
|
||||
description: 重命名一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.ContainerRename'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 重命名容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/restart:
|
||||
post:
|
||||
description: 重启一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 重启容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/search:
|
||||
get:
|
||||
description: 根据容器名称搜索容器
|
||||
parameters:
|
||||
- description: 容器名称
|
||||
in: query
|
||||
name: name
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 搜索容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/start:
|
||||
post:
|
||||
description: 启动一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 启动容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/stats:
|
||||
get:
|
||||
description: 查看一个容器的状态信息
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看容器状态
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/stop:
|
||||
post:
|
||||
description: 停止一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 停止容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/unpause:
|
||||
post:
|
||||
description: 取消暂停一个容器
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 取消暂停容器
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/create:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 创建一个卷
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/requests.VolumeCreate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 创建卷
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/exist:
|
||||
get:
|
||||
description: 检查一个卷是否存在
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 检查卷是否存在
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/inspect:
|
||||
get:
|
||||
description: 查看一个卷的详细信息
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 查看卷
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/list:
|
||||
get:
|
||||
description: 获取所有卷列表
|
||||
parameters:
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 获取卷列表
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/prune:
|
||||
post:
|
||||
description: 清理无用的卷
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 清理卷
|
||||
tags:
|
||||
- 容器
|
||||
/panel/container/volume/remove:
|
||||
post:
|
||||
description: 删除一个卷
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/panel_app_http_requests_container.ID'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.SuccessResponse'
|
||||
security:
|
||||
- BearerToken: []
|
||||
summary: 删除卷
|
||||
tags:
|
||||
- 容器
|
||||
/panel/file/archive:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
|
||||
requests "panel/app/http/requests/container"
|
||||
)
|
||||
|
||||
type Container interface {
|
||||
@@ -27,7 +29,7 @@ type Container interface {
|
||||
ContainerLogs(id string) (string, error)
|
||||
ContainerPrune() error
|
||||
NetworkList() ([]types.NetworkResource, error)
|
||||
NetworkCreate(name string) error
|
||||
NetworkCreate(config requests.NetworkCreate) (string, error)
|
||||
NetworkRemove(id string) error
|
||||
NetworkExist(name string) (bool, error)
|
||||
NetworkInspect(id string) (types.NetworkResource, error)
|
||||
@@ -35,16 +37,16 @@ type Container interface {
|
||||
NetworkDisconnect(networkID string, containerID string) error
|
||||
NetworkPrune() error
|
||||
ImageList() ([]image.Summary, error)
|
||||
ImageExist(reference string) (bool, error)
|
||||
ImagePull(reference string) error
|
||||
ImageRemove(imageID string) error
|
||||
ImageExist(id string) (bool, error)
|
||||
ImagePull(config requests.ImagePull) error
|
||||
ImageRemove(id string) error
|
||||
ImagePrune() error
|
||||
ImageInspect(imageID string) (types.ImageInspect, error)
|
||||
ImageInspect(id string) (types.ImageInspect, error)
|
||||
VolumeList() ([]*volume.Volume, error)
|
||||
VolumeCreate(name string, options, labels map[string]string) (volume.Volume, error)
|
||||
VolumeCreate(config requests.VolumeCreate) (volume.Volume, error)
|
||||
VolumeExist(name string) (bool, error)
|
||||
VolumeInspect(volumeID string) (volume.Volume, error)
|
||||
VolumeRemove(volumeID string) error
|
||||
VolumeInspect(id string) (volume.Volume, error)
|
||||
VolumeRemove(id string) error
|
||||
VolumePrune() error
|
||||
SliceToMap(slice []string) map[string]string
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
@@ -10,8 +11,12 @@ import (
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/goravel/framework/support/json"
|
||||
|
||||
requests "panel/app/http/requests/container"
|
||||
)
|
||||
|
||||
type Container struct {
|
||||
@@ -167,12 +172,37 @@ func (r *Container) NetworkList() ([]types.NetworkResource, error) {
|
||||
}
|
||||
|
||||
// NetworkCreate 创建网络
|
||||
func (r *Container) NetworkCreate(name string) error {
|
||||
_, err := r.client.NetworkCreate(context.Background(), name, types.NetworkCreate{
|
||||
Driver: "bridge",
|
||||
})
|
||||
func (r *Container) NetworkCreate(config requests.NetworkCreate) (string, error) {
|
||||
var ipamConfigs []network.IPAMConfig
|
||||
if config.Ipv4.Enabled {
|
||||
ipamConfigs = append(ipamConfigs, network.IPAMConfig{
|
||||
Subnet: config.Ipv4.Subnet,
|
||||
Gateway: config.Ipv4.Gateway,
|
||||
IPRange: config.Ipv4.IPRange,
|
||||
})
|
||||
}
|
||||
if config.Ipv6.Enabled {
|
||||
ipamConfigs = append(ipamConfigs, network.IPAMConfig{
|
||||
Subnet: config.Ipv6.Subnet,
|
||||
Gateway: config.Ipv6.Gateway,
|
||||
IPRange: config.Ipv6.IPRange,
|
||||
})
|
||||
}
|
||||
|
||||
return err
|
||||
options := types.NetworkCreate{
|
||||
EnableIPv6: config.Ipv6.Enabled,
|
||||
Driver: config.Driver,
|
||||
Options: r.SliceToMap(config.Options),
|
||||
Labels: r.SliceToMap(config.Labels),
|
||||
}
|
||||
if len(ipamConfigs) > 0 {
|
||||
options.IPAM = &network.IPAM{
|
||||
Config: ipamConfigs,
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := r.client.NetworkCreate(context.Background(), config.Name, options)
|
||||
return resp.ID, err
|
||||
}
|
||||
|
||||
// NetworkRemove 删除网络
|
||||
@@ -198,13 +228,13 @@ func (r *Container) NetworkInspect(id string) (types.NetworkResource, error) {
|
||||
}
|
||||
|
||||
// NetworkConnect 连接网络
|
||||
func (r *Container) NetworkConnect(id string, containerID string) error {
|
||||
return r.client.NetworkConnect(context.Background(), id, containerID, nil)
|
||||
func (r *Container) NetworkConnect(networkID string, containerID string) error {
|
||||
return r.client.NetworkConnect(context.Background(), networkID, containerID, nil)
|
||||
}
|
||||
|
||||
// NetworkDisconnect 断开网络
|
||||
func (r *Container) NetworkDisconnect(id string, containerID string) error {
|
||||
return r.client.NetworkDisconnect(context.Background(), id, containerID, true)
|
||||
func (r *Container) NetworkDisconnect(networkID string, containerID string) error {
|
||||
return r.client.NetworkDisconnect(context.Background(), networkID, containerID, true)
|
||||
}
|
||||
|
||||
// NetworkPrune 清理未使用的网络
|
||||
@@ -221,9 +251,9 @@ func (r *Container) ImageList() ([]image.Summary, error) {
|
||||
}
|
||||
|
||||
// ImageExist 判断镜像是否存在
|
||||
func (r *Container) ImageExist(str string) (bool, error) {
|
||||
func (r *Container) ImageExist(id string) (bool, error) {
|
||||
var options types.ImageListOptions
|
||||
options.Filters = filters.NewArgs(filters.Arg("reference", str))
|
||||
options.Filters = filters.NewArgs(filters.Arg("reference", id))
|
||||
images, err := r.client.ImageList(context.Background(), options)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -233,8 +263,22 @@ func (r *Container) ImageExist(str string) (bool, error) {
|
||||
}
|
||||
|
||||
// ImagePull 拉取镜像
|
||||
func (r *Container) ImagePull(str string) error {
|
||||
_, err := r.client.ImagePull(context.Background(), str, types.ImagePullOptions{})
|
||||
func (r *Container) ImagePull(config requests.ImagePull) error {
|
||||
options := types.ImagePullOptions{}
|
||||
if config.Auth {
|
||||
authConfig := registry.AuthConfig{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
}
|
||||
encodedJSON, err := json.Marshal(authConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authStr := base64.URLEncoding.EncodeToString(encodedJSON)
|
||||
options.RegistryAuth = authStr
|
||||
}
|
||||
|
||||
_, err := r.client.ImagePull(context.Background(), config.Name, options)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -266,19 +310,19 @@ func (r *Container) VolumeList() ([]*volume.Volume, error) {
|
||||
}
|
||||
|
||||
// VolumeCreate 创建存储卷
|
||||
func (r *Container) VolumeCreate(name string, options, labels map[string]string) (volume.Volume, error) {
|
||||
func (r *Container) VolumeCreate(config requests.VolumeCreate) (volume.Volume, error) {
|
||||
return r.client.VolumeCreate(context.Background(), volume.CreateOptions{
|
||||
Name: name,
|
||||
Driver: "local",
|
||||
DriverOpts: options,
|
||||
Labels: labels,
|
||||
Name: config.Name,
|
||||
Driver: config.Driver,
|
||||
DriverOpts: r.SliceToMap(config.Options),
|
||||
Labels: r.SliceToMap(config.Labels),
|
||||
})
|
||||
}
|
||||
|
||||
// VolumeExist 判断存储卷是否存在
|
||||
func (r *Container) VolumeExist(name string) (bool, error) {
|
||||
func (r *Container) VolumeExist(id string) (bool, error) {
|
||||
var options volume.ListOptions
|
||||
options.Filters = filters.NewArgs(filters.Arg("name", name))
|
||||
options.Filters = filters.NewArgs(filters.Arg("name", id))
|
||||
volumes, err := r.client.VolumeList(context.Background(), options)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -312,5 +356,6 @@ func (r *Container) SliceToMap(slice []string) map[string]string {
|
||||
m[sps[0]] = sps[1]
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func Api() {
|
||||
r.Post("kill", containerController.ContainerKill)
|
||||
r.Post("rename", containerController.ContainerRename)
|
||||
r.Get("stats", containerController.ContainerStats)
|
||||
r.Post("exist", containerController.ContainerExist)
|
||||
r.Get("exist", containerController.ContainerExist)
|
||||
r.Get("logs", containerController.ContainerLogs)
|
||||
r.Post("prune", containerController.ContainerPrune)
|
||||
|
||||
@@ -136,7 +136,7 @@ func Api() {
|
||||
r.Get("list", containerController.NetworkList)
|
||||
r.Post("create", containerController.NetworkCreate)
|
||||
r.Post("remove", containerController.NetworkRemove)
|
||||
r.Post("exist", containerController.NetworkExist)
|
||||
r.Get("exist", containerController.NetworkExist)
|
||||
r.Get("inspect", containerController.NetworkInspect)
|
||||
r.Post("connect", containerController.NetworkConnect)
|
||||
r.Post("disconnect", containerController.NetworkDisconnect)
|
||||
@@ -145,7 +145,7 @@ func Api() {
|
||||
|
||||
r.Prefix("image").Group(func(r route.Router) {
|
||||
r.Get("list", containerController.ImageList)
|
||||
r.Post("exist", containerController.ImageExist)
|
||||
r.Get("exist", containerController.ImageExist)
|
||||
r.Post("pull", containerController.ImagePull)
|
||||
r.Post("remove", containerController.ImageRemove)
|
||||
r.Post("prune", containerController.ImagePrune)
|
||||
@@ -155,7 +155,7 @@ func Api() {
|
||||
r.Prefix("volume").Group(func(r route.Router) {
|
||||
r.Get("list", containerController.VolumeList)
|
||||
r.Post("create", containerController.VolumeCreate)
|
||||
r.Post("exist", containerController.VolumeExist)
|
||||
r.Get("exist", containerController.VolumeExist)
|
||||
r.Get("inspect", containerController.VolumeInspect)
|
||||
r.Post("remove", containerController.VolumeRemove)
|
||||
r.Post("prune", containerController.VolumePrune)
|
||||
|
||||
Reference in New Issue
Block a user