Files
Charon/backend/internal/services/docker_service.go
GitHub Actions 63cebf07ab Refactor services and improve error handling
- Updated file permissions in certificate_service_test.go and log_service_test.go to use octal notation.
- Added a new doc.go file to document the services package.
- Enhanced error handling in docker_service.go, log_service.go, notification_service.go, proxyhost_service.go, remoteserver_service.go, update_service.go, and uptime_service.go by logging errors when closing resources.
- Improved log_service.go to simplify log file processing and deduplication.
- Introduced CRUD tests for notification templates in notification_service_template_test.go.
- Removed the obsolete python_compile_check.sh script.
- Updated notification_service.go to improve template management functions.
- Added tests for uptime service notifications in uptime_service_notification_test.go.
2025-12-08 05:55:17 +00:00

108 lines
2.6 KiB
Go

package services
import (
"context"
"fmt"
"strings"
"github.com/Wikid82/charon/backend/internal/logger"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
type DockerPort struct {
PrivatePort uint16 `json:"private_port"`
PublicPort uint16 `json:"public_port"`
Type string `json:"type"`
}
type DockerContainer struct {
ID string `json:"id"`
Names []string `json:"names"`
Image string `json:"image"`
State string `json:"state"`
Status string `json:"status"`
Network string `json:"network"`
IP string `json:"ip"`
Ports []DockerPort `json:"ports"`
}
type DockerService struct {
client *client.Client
}
func NewDockerService() (*DockerService, error) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, fmt.Errorf("failed to create docker client: %w", err)
}
return &DockerService{client: cli}, nil
}
func (s *DockerService) ListContainers(ctx context.Context, host string) ([]DockerContainer, error) {
var cli *client.Client
var err error
if host == "" || host == "local" {
cli = s.client
} else {
cli, err = client.NewClientWithOpts(client.WithHost(host), client.WithAPIVersionNegotiation())
if err != nil {
return nil, fmt.Errorf("failed to create remote client: %w", err)
}
defer func() {
if err := cli.Close(); err != nil {
logger.Log().WithError(err).Warn("failed to close docker client")
}
}()
}
containers, err := cli.ContainerList(ctx, container.ListOptions{All: false})
if err != nil {
return nil, fmt.Errorf("failed to list containers: %w", err)
}
var result []DockerContainer
for _, c := range containers {
// Get the first network's IP address if available
networkName := ""
ipAddress := ""
if c.NetworkSettings != nil && len(c.NetworkSettings.Networks) > 0 {
for name, net := range c.NetworkSettings.Networks {
networkName = name
ipAddress = net.IPAddress
break // Just take the first one for now
}
}
// Clean up names (remove leading slash)
names := make([]string, len(c.Names))
for i, name := range c.Names {
names[i] = strings.TrimPrefix(name, "/")
}
// Map ports
var ports []DockerPort
for _, p := range c.Ports {
ports = append(ports, DockerPort{
PrivatePort: p.PrivatePort,
PublicPort: p.PublicPort,
Type: p.Type,
})
}
result = append(result, DockerContainer{
ID: c.ID[:12], // Short ID
Names: names,
Image: c.Image,
State: c.State,
Status: c.Status,
Network: networkName,
IP: ipAddress,
Ports: ports,
})
}
return result, nil
}