mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 16:10:59 +08:00
feat: 容器部分
This commit is contained in:
@@ -1,19 +1,384 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
requests "panel/app/http/requests/container"
|
||||
"panel/internal/services"
|
||||
)
|
||||
|
||||
type ContainerController struct {
|
||||
// Dependent services
|
||||
container services.Container
|
||||
}
|
||||
|
||||
func NewContainerController() *ContainerController {
|
||||
return &ContainerController{
|
||||
// Inject services
|
||||
container: services.NewContainer(),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ContainerController) Index(ctx http.Context) http.Response {
|
||||
return nil
|
||||
func (r *ContainerController) ContainerList(ctx http.Context) http.Response {
|
||||
containers, err := r.container.ContainerListAll()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, containers)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerSearch(ctx http.Context) http.Response {
|
||||
fields := strings.Fields(ctx.Request().Query("names"))
|
||||
containers, err := r.container.ContainerListByNames(fields)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, containers)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
|
||||
var request requests.ContainerCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
var hostConf container.HostConfig
|
||||
var networkConf network.NetworkingConfig
|
||||
|
||||
portMap := make(nat.PortMap)
|
||||
for _, port := range request.Ports {
|
||||
if port.ContainerStart-port.ContainerEnd != port.HostStart-port.HostEnd {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, fmt.Sprintf("容器端口和主机端口数量不匹配(容器: %d 主机: %d)", port.ContainerStart-port.ContainerEnd, port.HostStart-port.HostEnd))
|
||||
}
|
||||
if port.ContainerStart > port.ContainerEnd || port.HostStart > port.HostEnd || port.ContainerStart < 1 || port.HostStart < 1 {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "端口范围不正确")
|
||||
}
|
||||
|
||||
count := 0
|
||||
for host := port.HostStart; host <= port.HostEnd; host++ {
|
||||
bindItem := nat.PortBinding{HostPort: strconv.Itoa(host), HostIP: port.Host}
|
||||
portMap[nat.Port(fmt.Sprintf("%d/%s", port.ContainerStart+count, port.Protocol))] = []nat.PortBinding{bindItem}
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
exposed := make(nat.PortSet)
|
||||
for port := range portMap {
|
||||
exposed[port] = struct{}{}
|
||||
}
|
||||
|
||||
if request.Network != "" {
|
||||
switch request.Network {
|
||||
case "host", "none", "bridge":
|
||||
hostConf.NetworkMode = container.NetworkMode(request.Network)
|
||||
}
|
||||
networkConf.EndpointsConfig = map[string]*network.EndpointSettings{request.Network: {}}
|
||||
} else {
|
||||
networkConf = network.NetworkingConfig{}
|
||||
}
|
||||
|
||||
hostConf.Privileged = request.Privileged
|
||||
hostConf.AutoRemove = request.AutoRemove
|
||||
hostConf.CPUShares = request.CPUShares
|
||||
hostConf.PublishAllPorts = request.PublishAllPorts
|
||||
hostConf.RestartPolicy = container.RestartPolicy{Name: container.RestartPolicyMode(request.RestartPolicy)}
|
||||
if request.RestartPolicy == "on-failure" {
|
||||
hostConf.RestartPolicy.MaximumRetryCount = 5
|
||||
}
|
||||
hostConf.NanoCPUs = request.CPUs * 1000000000
|
||||
hostConf.Memory = request.Memory * 1024 * 1024
|
||||
hostConf.MemorySwap = 0
|
||||
hostConf.PortBindings = portMap
|
||||
hostConf.Binds = []string{}
|
||||
|
||||
volumes := make(map[string]struct{})
|
||||
for _, volume := range request.Volumes {
|
||||
volumes[volume.Container] = struct{}{}
|
||||
hostConf.Binds = append(hostConf.Binds, fmt.Sprintf("%s:%s:%s", volume.Host, volume.Container, volume.Mode))
|
||||
}
|
||||
|
||||
id, err := r.container.ContainerCreate(request.Name,
|
||||
container.Config{
|
||||
Image: request.Image,
|
||||
Env: request.Env,
|
||||
Entrypoint: request.Entrypoint,
|
||||
Cmd: request.Command,
|
||||
Labels: r.container.SliceToMap(request.Labels),
|
||||
ExposedPorts: exposed,
|
||||
OpenStdin: request.OpenStdin,
|
||||
Tty: request.Tty,
|
||||
Volumes: volumes,
|
||||
},
|
||||
hostConf,
|
||||
networkConf,
|
||||
)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, id)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerRemove(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerStart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerStart(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerStop(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerStop(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerRestart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerRestart(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerPause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerPause(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerUnpause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerUnpause(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.ContainerInspect(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerKill(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerKill(request.ID); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerRename(ctx http.Context) http.Response {
|
||||
var request requests.ContainerRename
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := r.container.ContainerRename(request.ID, request.Name); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerStats(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.ContainerStats(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
exist, err := r.container.ContainerExist(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, exist)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerLogs(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
data, err := r.container.ContainerLogs(request.ID)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ContainerPrune(ctx http.Context) http.Response {
|
||||
if err := r.container.ContainerPrune(); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkList(ctx http.Context) http.Response {
|
||||
networks, err := r.container.NetworkList()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, networks)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkCreate(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkRemove(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkConnect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkDisconnect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) NetworkPrune(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImageList(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImageExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImagePull(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImageRemove(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImagePrune(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) ImageInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumeList(ctx http.Context) http.Response {
|
||||
volumes, err := r.container.VolumeList()
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, volumes)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumeCreate(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumeExist(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumeInspect(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumeRemove(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *ContainerController) VolumePrune(ctx http.Context) http.Response {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
66
app/http/requests/container/container_create.go
Normal file
66
app/http/requests/container/container_create.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type ContainerCreate struct {
|
||||
Name string `form:"name" json:"name"`
|
||||
Image string `form:"image" json:"image"`
|
||||
Ports []ContainerPort `form:"ports" json:"ports"`
|
||||
Network string `form:"network" json:"network"`
|
||||
Volumes []ContainerVolume `form:"volumes" json:"volumes"`
|
||||
Labels []string `form:"labels" json:"labels"`
|
||||
Env []string `form:"env" json:"env"`
|
||||
Entrypoint []string `form:"entrypoint" json:"entrypoint"`
|
||||
Command []string `form:"command" json:"command"`
|
||||
RestartPolicy string `form:"restart_policy" json:"restart_policy"`
|
||||
AutoRemove bool `form:"auto_remove" json:"auto_remove"`
|
||||
Privileged bool `form:"privileged" json:"privileged"`
|
||||
OpenStdin bool `form:"openStdin" json:"open_stdin"`
|
||||
PublishAllPorts bool `form:"publish_all_ports" json:"publish_all_ports"`
|
||||
Tty bool `form:"tty" json:"tty"`
|
||||
CPUShares int64 `form:"cpu_shares" json:"cpu_shares"`
|
||||
CPUs int64 `form:"cpus" json:"cpus"`
|
||||
Memory int64 `form:"memory" json:"memory"`
|
||||
}
|
||||
|
||||
func (r *ContainerCreate) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ContainerCreate) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|string",
|
||||
"image": "required|string",
|
||||
"ports": "slice",
|
||||
"network": "string",
|
||||
"volumes": "slice",
|
||||
"labels": "slice",
|
||||
"env": "slice",
|
||||
"entrypoint": "slice",
|
||||
"command": "slice",
|
||||
"restart_policy": "string|in:always,on-failure,unless-stopped,no",
|
||||
"auto_remove": "bool",
|
||||
"privileged": "bool",
|
||||
"open_stdin": "bool",
|
||||
"publish_all_ports": "bool",
|
||||
"tty": "bool",
|
||||
"cpu_shares": "int",
|
||||
"cpus": "int",
|
||||
"memory": "int",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ContainerCreate) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerCreate) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerCreate) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
34
app/http/requests/container/container_rename.go
Normal file
34
app/http/requests/container/container_rename.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type ContainerRename struct {
|
||||
ID string `form:"id" json:"id"`
|
||||
Name string `form:"name" json:"name"`
|
||||
}
|
||||
|
||||
func (r *ContainerRename) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ContainerRename) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"id": "required|string",
|
||||
"name": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ContainerRename) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerRename) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerRename) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
68
app/http/requests/container/container_update.go
Normal file
68
app/http/requests/container/container_update.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type ContainerUpdate struct {
|
||||
ID string `form:"id" json:"id"`
|
||||
Name string `form:"name" json:"name"`
|
||||
Image string `form:"image" json:"image"`
|
||||
Ports []ContainerPort `form:"ports" json:"ports"`
|
||||
Network string `form:"network" json:"network"`
|
||||
Volumes []ContainerVolume `form:"volumes" json:"volumes"`
|
||||
Labels []string `form:"labels" json:"labels"`
|
||||
Env []string `form:"env" json:"env"`
|
||||
Entrypoint []string `form:"entrypoint" json:"entrypoint"`
|
||||
Command []string `form:"command" json:"command"`
|
||||
RestartPolicy string `form:"restart_policy" json:"restart_policy"`
|
||||
AutoRemove bool `form:"auto_remove" json:"auto_remove"`
|
||||
Privileged bool `form:"privileged" json:"privileged"`
|
||||
OpenStdin bool `form:"openStdin" json:"open_stdin"`
|
||||
PublishAllPorts bool `form:"publish_all_ports" json:"publish_all_ports"`
|
||||
Tty bool `form:"tty" json:"tty"`
|
||||
CPUShares int64 `form:"cpu_shares" json:"cpu_shares"`
|
||||
CPUs int64 `form:"cpus" json:"cpus"`
|
||||
Memory int64 `form:"memory" json:"memory"`
|
||||
}
|
||||
|
||||
func (r *ContainerUpdate) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ContainerUpdate) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"id": "required|string",
|
||||
"name": "required|string",
|
||||
"image": "required|string",
|
||||
"ports": "slice",
|
||||
"network": "string",
|
||||
"volumes": "slice",
|
||||
"labels": "slice",
|
||||
"env": "slice",
|
||||
"entrypoint": "slice",
|
||||
"command": "slice",
|
||||
"restart_policy": "string|in:always,on-failure,unless-stopped,no",
|
||||
"auto_remove": "bool",
|
||||
"privileged": "bool",
|
||||
"open_stdin": "bool",
|
||||
"publish_all_ports": "bool",
|
||||
"tty": "bool",
|
||||
"cpu_shares": "int",
|
||||
"cpus": "int",
|
||||
"memory": "int",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ContainerUpdate) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerUpdate) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ContainerUpdate) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
32
app/http/requests/container/id.go
Normal file
32
app/http/requests/container/id.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
)
|
||||
|
||||
type ID struct {
|
||||
ID string `form:"id" json:"id"`
|
||||
}
|
||||
|
||||
func (r *ID) Authorize(ctx http.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ID) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"id": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ID) Messages(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ID) Attributes(ctx http.Context) map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (r *ID) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
return nil
|
||||
}
|
||||
16
app/http/requests/container/types.go
Normal file
16
app/http/requests/container/types.go
Normal file
@@ -0,0 +1,16 @@
|
||||
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"`
|
||||
}
|
||||
|
||||
type ContainerVolume struct {
|
||||
Host string `json:"host"`
|
||||
Container string `json:"container"`
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
@@ -1 +1,50 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"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"
|
||||
)
|
||||
|
||||
type Container interface {
|
||||
ContainerListAll() ([]types.Container, error)
|
||||
ContainerListByNames(names []string) ([]types.Container, error)
|
||||
ContainerCreate(name string, config container.Config, host container.HostConfig, networkConfig network.NetworkingConfig) (string, error)
|
||||
ContainerRemove(id string) error
|
||||
ContainerStart(id string) error
|
||||
ContainerStop(id string) error
|
||||
ContainerRestart(id string) error
|
||||
ContainerPause(id string) error
|
||||
ContainerUnpause(id string) error
|
||||
ContainerInspect(id string) (types.ContainerJSON, error)
|
||||
ContainerKill(id string) error
|
||||
ContainerRename(id string, newName string) error
|
||||
ContainerStats(id string) (types.ContainerStats, error)
|
||||
ContainerExist(name string) (bool, error)
|
||||
ContainerUpdate(id string, config container.UpdateConfig) error
|
||||
ContainerLogs(id string) (string, error)
|
||||
ContainerPrune() error
|
||||
NetworkList() ([]types.NetworkResource, error)
|
||||
NetworkCreate(name string) error
|
||||
NetworkRemove(id string) error
|
||||
NetworkExist(name string) (bool, error)
|
||||
NetworkInspect(id string) (types.NetworkResource, error)
|
||||
NetworkConnect(networkID string, containerID string) error
|
||||
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
|
||||
ImagePrune() error
|
||||
ImageInspect(imageID string) (types.ImageInspect, error)
|
||||
VolumeList() ([]*volume.Volume, error)
|
||||
VolumeCreate(name string, options, labels map[string]string) (volume.Volume, error)
|
||||
VolumeExist(name string) (bool, error)
|
||||
VolumeInspect(volumeID string) (volume.Volume, error)
|
||||
VolumeRemove(volumeID string) error
|
||||
VolumePrune() error
|
||||
SliceToMap(slice []string) map[string]string
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
@@ -17,12 +18,12 @@ type Container struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func NewContainer(sock ...string) *Container {
|
||||
func NewContainer(sock ...string) Container {
|
||||
if len(sock) == 0 {
|
||||
sock[0] = "/run/podman/podman.sock"
|
||||
}
|
||||
cli, _ := client.NewClientWithOpts(client.WithHost("unix://"+sock[0]), client.WithAPIVersionNegotiation())
|
||||
return &Container{
|
||||
return Container{
|
||||
client: cli,
|
||||
}
|
||||
}
|
||||
@@ -81,6 +82,11 @@ func (r *Container) ContainerStop(id string) error {
|
||||
return r.client.ContainerStop(context.Background(), id, container.StopOptions{})
|
||||
}
|
||||
|
||||
// ContainerRestart 重启容器
|
||||
func (r *Container) ContainerRestart(id string) error {
|
||||
return r.client.ContainerRestart(context.Background(), id, container.StopOptions{})
|
||||
}
|
||||
|
||||
// ContainerPause 暂停容器
|
||||
func (r *Container) ContainerPause(id string) error {
|
||||
return r.client.ContainerPause(context.Background(), id)
|
||||
@@ -111,8 +117,8 @@ func (r *Container) ContainerStats(id string) (types.ContainerStats, error) {
|
||||
return r.client.ContainerStats(context.Background(), id, false)
|
||||
}
|
||||
|
||||
// ContainerExists 判断容器是否存在
|
||||
func (r *Container) ContainerExists(name string) (bool, error) {
|
||||
// ContainerExist 判断容器是否存在
|
||||
func (r *Container) ContainerExist(name string) (bool, error) {
|
||||
var options container.ListOptions
|
||||
options.Filters = filters.NewArgs(filters.Arg("name", name))
|
||||
containers, err := r.client.ContainerList(context.Background(), options)
|
||||
@@ -155,11 +161,6 @@ func (r *Container) ContainerPrune() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ContainerRestart 重启容器
|
||||
func (r *Container) ContainerRestart(id string) error {
|
||||
return r.client.ContainerRestart(context.Background(), id, container.StopOptions{})
|
||||
}
|
||||
|
||||
// NetworkList 列出网络
|
||||
func (r *Container) NetworkList() ([]types.NetworkResource, error) {
|
||||
return r.client.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
@@ -174,6 +175,11 @@ func (r *Container) NetworkCreate(name string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// NetworkRemove 删除网络
|
||||
func (r *Container) NetworkRemove(id string) error {
|
||||
return r.client.NetworkRemove(context.Background(), id)
|
||||
}
|
||||
|
||||
// NetworkExist 判断网络是否存在
|
||||
func (r *Container) NetworkExist(name string) (bool, error) {
|
||||
var options types.NetworkListOptions
|
||||
@@ -207,11 +213,6 @@ func (r *Container) NetworkPrune() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// NetworkRemove 删除网络
|
||||
func (r *Container) NetworkRemove(id string) error {
|
||||
return r.client.NetworkRemove(context.Background(), id)
|
||||
}
|
||||
|
||||
// ImageList 列出镜像
|
||||
func (r *Container) ImageList() ([]image.Summary, error) {
|
||||
return r.client.ImageList(context.Background(), types.ImageListOptions{
|
||||
@@ -258,6 +259,12 @@ func (r *Container) ImageInspect(id string) (types.ImageInspect, error) {
|
||||
return img, err
|
||||
}
|
||||
|
||||
// VolumeList 列出存储卷
|
||||
func (r *Container) VolumeList() ([]*volume.Volume, error) {
|
||||
volumes, err := r.client.VolumeList(context.Background(), volume.ListOptions{})
|
||||
return volumes.Volumes, err
|
||||
}
|
||||
|
||||
// VolumeCreate 创建存储卷
|
||||
func (r *Container) VolumeCreate(name string, options, labels map[string]string) (volume.Volume, error) {
|
||||
return r.client.VolumeCreate(context.Background(), volume.CreateOptions{
|
||||
@@ -268,12 +275,6 @@ func (r *Container) VolumeCreate(name string, options, labels map[string]string)
|
||||
})
|
||||
}
|
||||
|
||||
// VolumeList 列出存储卷
|
||||
func (r *Container) VolumeList() ([]*volume.Volume, error) {
|
||||
volumes, err := r.client.VolumeList(context.Background(), volume.ListOptions{})
|
||||
return volumes.Volumes, err
|
||||
}
|
||||
|
||||
// VolumeExist 判断存储卷是否存在
|
||||
func (r *Container) VolumeExist(name string) (bool, error) {
|
||||
var options volume.ListOptions
|
||||
@@ -301,3 +302,15 @@ func (r *Container) VolumePrune() error {
|
||||
_, err := r.client.VolumesPrune(context.Background(), filters.NewArgs())
|
||||
return err
|
||||
}
|
||||
|
||||
// SliceToMap 将切片转换为 map
|
||||
func (r *Container) SliceToMap(slice []string) map[string]string {
|
||||
m := make(map[string]string)
|
||||
for _, s := range slice {
|
||||
if strings.Contains(s, "=") {
|
||||
sps := strings.SplitN(s, "=", 2)
|
||||
m[sps[0]] = sps[1]
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -113,6 +113,54 @@ func Api() {
|
||||
r.Get("pingStatus", safeController.GetPingStatus)
|
||||
r.Post("pingStatus", safeController.SetPingStatus)
|
||||
})
|
||||
r.Prefix("container").Middleware(middleware.Jwt()).Group(func(r route.Router) {
|
||||
containerController := controllers.NewContainerController()
|
||||
r.Get("list", containerController.ContainerList)
|
||||
r.Get("search", containerController.ContainerSearch)
|
||||
r.Post("create", containerController.ContainerCreate)
|
||||
r.Post("remove", containerController.ContainerRemove)
|
||||
r.Post("start", containerController.ContainerStart)
|
||||
r.Post("stop", containerController.ContainerStop)
|
||||
r.Post("restart", containerController.ContainerRestart)
|
||||
r.Post("pause", containerController.ContainerPause)
|
||||
r.Post("unpause", containerController.ContainerUnpause)
|
||||
r.Get("inspect", containerController.ContainerInspect)
|
||||
r.Post("kill", containerController.ContainerKill)
|
||||
r.Post("rename", containerController.ContainerRename)
|
||||
r.Get("stats", containerController.ContainerStats)
|
||||
r.Post("exist", containerController.ContainerExist)
|
||||
r.Get("logs", containerController.ContainerLogs)
|
||||
r.Post("prune", containerController.ContainerPrune)
|
||||
|
||||
r.Prefix("network").Group(func(r route.Router) {
|
||||
r.Get("list", containerController.NetworkList)
|
||||
r.Post("create", containerController.NetworkCreate)
|
||||
r.Post("remove", containerController.NetworkRemove)
|
||||
r.Post("exist", containerController.NetworkExist)
|
||||
r.Get("inspect", containerController.NetworkInspect)
|
||||
r.Post("connect", containerController.NetworkConnect)
|
||||
r.Post("disconnect", containerController.NetworkDisconnect)
|
||||
r.Post("prune", containerController.NetworkPrune)
|
||||
})
|
||||
|
||||
r.Prefix("image").Group(func(r route.Router) {
|
||||
r.Get("list", containerController.ImageList)
|
||||
r.Post("exist", containerController.ImageExist)
|
||||
r.Post("pull", containerController.ImagePull)
|
||||
r.Post("remove", containerController.ImageRemove)
|
||||
r.Post("prune", containerController.ImagePrune)
|
||||
r.Get("inspect", containerController.ImageInspect)
|
||||
})
|
||||
|
||||
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("inspect", containerController.VolumeInspect)
|
||||
r.Post("remove", containerController.VolumeRemove)
|
||||
r.Post("prune", containerController.VolumePrune)
|
||||
})
|
||||
})
|
||||
r.Prefix("file").Middleware(middleware.Jwt()).Group(func(r route.Router) {
|
||||
fileController := controllers.NewFileController()
|
||||
r.Post("create", fileController.Create)
|
||||
|
||||
Reference in New Issue
Block a user