refactor: mover apps TUI de fn_operations/ a apps/
Separa aplicaciones ejecutables (docker_tui, pipeline_launcher) de la librería fn_operations. La carpeta apps/ contiene módulos Go independientes, fn_operations/ queda como librería pura de models/store/operations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lucasdataproyects/devfactory/shell"
|
||||
)
|
||||
|
||||
const dockerTimeout = 15 * time.Second
|
||||
|
||||
// --- Containers ---
|
||||
|
||||
func ListContainers() ([]DockerContainer, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "ps", "-a", "--format", "{{json .}}")
|
||||
stdout, err := result.Both()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseJSONLines[DockerContainer](stdout.Stdout)
|
||||
}
|
||||
|
||||
func StartContainer(id string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "start", id).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
func StopContainer(id string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "stop", id).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
func RestartContainer(id string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "restart", id).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
func ContainerLogs(id string, lines int) (string, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "logs", "--tail", itoa(lines), id)
|
||||
out, err := result.Both()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// docker logs writes to both stdout and stderr
|
||||
output := out.Stdout
|
||||
if out.Stderr != "" {
|
||||
if output != "" {
|
||||
output += "\n"
|
||||
}
|
||||
output += out.Stderr
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// --- Images ---
|
||||
|
||||
func ListImages() ([]DockerImage, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "image", "ls", "--format", "{{json .}}")
|
||||
stdout, err := result.Both()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseJSONLines[DockerImage](stdout.Stdout)
|
||||
}
|
||||
|
||||
func PullImage(name string) (string, error) {
|
||||
result := shell.RunWithTimeout("docker", 120*time.Second, "pull", name)
|
||||
out, err := result.Both()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.Stdout, nil
|
||||
}
|
||||
|
||||
func RemoveImage(id string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "rmi", id).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
// --- Volumes ---
|
||||
|
||||
func ListVolumes() ([]DockerVolume, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "volume", "ls", "--format", "{{json .}}")
|
||||
stdout, err := result.Both()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseJSONLines[DockerVolume](stdout.Stdout)
|
||||
}
|
||||
|
||||
func CreateVolume(name string) error {
|
||||
args := []string{"volume", "create"}
|
||||
if name != "" {
|
||||
args = append(args, name)
|
||||
}
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, args...).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
func RemoveVolume(name string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "volume", "rm", name).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
// --- Networks ---
|
||||
|
||||
func ListNetworks() ([]DockerNetwork, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "network", "ls", "--format", "{{json .}}")
|
||||
stdout, err := result.Both()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseJSONLines[DockerNetwork](stdout.Stdout)
|
||||
}
|
||||
|
||||
func CreateNetwork(name string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "network", "create", name).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
func RemoveNetwork(name string) error {
|
||||
_, err := shell.RunWithTimeout("docker", dockerTimeout, "network", "rm", name).Both()
|
||||
return err
|
||||
}
|
||||
|
||||
// --- Compose ---
|
||||
|
||||
func ComposePS() ([]ComposeService, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "compose", "ps", "--format", "json")
|
||||
stdout, err := result.Both()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// docker compose ps --format json returns a JSON array
|
||||
var services []ComposeService
|
||||
if err := json.Unmarshal([]byte(stdout.Stdout), &services); err != nil {
|
||||
// Try line-by-line as fallback
|
||||
return parseJSONLines[ComposeService](stdout.Stdout)
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func ComposeUp() (string, error) {
|
||||
result := shell.RunWithTimeout("docker", 120*time.Second, "compose", "up", "-d")
|
||||
out, err := result.Both()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.Stdout + out.Stderr, nil
|
||||
}
|
||||
|
||||
func ComposeDown() (string, error) {
|
||||
result := shell.RunWithTimeout("docker", 60*time.Second, "compose", "down")
|
||||
out, err := result.Both()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.Stdout + out.Stderr, nil
|
||||
}
|
||||
|
||||
func ComposeLogs(lines int) (string, error) {
|
||||
result := shell.RunWithTimeout("docker", dockerTimeout, "compose", "logs", "--tail", itoa(lines))
|
||||
out, err := result.Both()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.Stdout + out.Stderr, nil
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
|
||||
func parseJSONLines[T any](s string) ([]T, error) {
|
||||
var result []T
|
||||
for _, line := range strings.Split(strings.TrimSpace(s), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
var item T
|
||||
if err := json.Unmarshal([]byte(line), &item); err != nil {
|
||||
continue
|
||||
}
|
||||
result = append(result, item)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func itoa(n int) string {
|
||||
return fmt.Sprintf("%d", n)
|
||||
}
|
||||
Reference in New Issue
Block a user