mirror of
https://github.com/amir20/dozzle.git
synced 2026-06-23 04:10:12 +00:00
6a014d1e76
Deploy VitePress site to Pages / build (push) Has been cancelled
Deploy VitePress site to Pages / Deploy (push) Has been cancelled
Push container / Push branches and PRs (push) Has been cancelled
Test / Typecheck (push) Has been cancelled
Test / JavaScript Tests (push) Has been cancelled
Test / Go Tests (push) Has been cancelled
Test / Go Staticcheck (push) Has been cancelled
Test / Integration Tests (push) Has been cancelled
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
131 lines
3.3 KiB
Go
131 lines
3.3 KiB
Go
package cloud
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/amir20/dozzle/internal/container"
|
|
pb "github.com/amir20/dozzle/proto/cloud"
|
|
)
|
|
|
|
type containerActionArgs struct {
|
|
ContainerID string `json:"container_id"`
|
|
Host string `json:"host_id"`
|
|
}
|
|
|
|
func executeContainerAction(ctx context.Context, name string, argsJSON string, deps ToolDeps) (*pb.CallToolResponse, error) {
|
|
var args containerActionArgs
|
|
if err := json.Unmarshal([]byte(argsJSON), &args); err != nil {
|
|
return nil, fmt.Errorf("failed to parse arguments: %w", err)
|
|
}
|
|
|
|
action, err := resolveAction(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
hostID, containerID, err := resolveContainerRef(args.ContainerID, args.Host, deps)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cs, err := deps.HostService.FindContainer(hostID, containerID, deps.Labels)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("container not found: %w", err)
|
|
}
|
|
|
|
if err := cs.Action(ctx, action); err != nil {
|
|
return nil, fmt.Errorf("action failed: %w", err)
|
|
}
|
|
|
|
message := fmt.Sprintf("Successfully %s container %s.", pastTense(action), cs.Container.Name)
|
|
|
|
return &pb.CallToolResponse{
|
|
Success: true,
|
|
Result: &pb.CallToolResponse_Action{Action: &pb.ActionResult{
|
|
Success: true,
|
|
ContainerId: cs.Container.ID,
|
|
Action: string(action),
|
|
Message: message,
|
|
}},
|
|
}, nil
|
|
}
|
|
|
|
func executeUpdateContainer(ctx context.Context, argsJSON string, deps ToolDeps) (*pb.CallToolResponse, error) {
|
|
var args containerActionArgs
|
|
if err := json.Unmarshal([]byte(argsJSON), &args); err != nil {
|
|
return nil, fmt.Errorf("failed to parse arguments: %w", err)
|
|
}
|
|
|
|
hostID, containerID, err := resolveContainerRef(args.ContainerID, args.Host, deps)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cs, err := deps.HostService.FindContainer(hostID, containerID, deps.Labels)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("container not found: %w", err)
|
|
}
|
|
|
|
progressCh := make(chan container.UpdateProgress)
|
|
var updated bool
|
|
var updateErr error
|
|
done := make(chan struct{})
|
|
go func() {
|
|
updated, updateErr = cs.Update(ctx, progressCh)
|
|
close(done)
|
|
}()
|
|
for range progressCh {
|
|
}
|
|
<-done
|
|
if updateErr != nil {
|
|
return nil, fmt.Errorf("update failed: %w", updateErr)
|
|
}
|
|
|
|
message := fmt.Sprintf("Successfully updated container %s by pulling the latest image and recreating it.", cs.Container.Name)
|
|
if !updated {
|
|
message = fmt.Sprintf("Container %s is already running the latest image. No update was needed.", cs.Container.Name)
|
|
}
|
|
|
|
return &pb.CallToolResponse{
|
|
Success: true,
|
|
Result: &pb.CallToolResponse_Action{Action: &pb.ActionResult{
|
|
Success: true,
|
|
ContainerId: cs.Container.ID,
|
|
Action: "update",
|
|
Message: message,
|
|
}},
|
|
}, nil
|
|
}
|
|
|
|
func pastTense(action container.ContainerAction) string {
|
|
switch action {
|
|
case container.Start:
|
|
return "started"
|
|
case container.Stop:
|
|
return "stopped"
|
|
case container.Restart:
|
|
return "restarted"
|
|
case container.Remove:
|
|
return "removed"
|
|
default:
|
|
return string(action) + "ed"
|
|
}
|
|
}
|
|
|
|
func resolveAction(name string) (container.ContainerAction, error) {
|
|
switch name {
|
|
case "start_container":
|
|
return container.Start, nil
|
|
case "stop_container":
|
|
return container.Stop, nil
|
|
case "restart_container":
|
|
return container.Restart, nil
|
|
case "remove_container":
|
|
return container.Remove, nil
|
|
default:
|
|
return "", fmt.Errorf("unknown action: %s", name)
|
|
}
|
|
}
|