GPT-backend/main.go
2024-05-29 13:29:32 +02:00

162 lines
3.5 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
type Hosts struct {
Hosts []Host `json:"hosts"`
}
type Host struct {
Name string `json:"name"`
IP string `json:"ip"`
Port string `json:"port"`
Containers []Container `json:"containers"`
}
type Container struct {
Name string `json:"names"`
Port int `json:"port"`
IP string `json:"ip"`
Image string `json:"image"`
ID string `json:"id"`
}
type Details struct {
Parent_model string `json:"parent_model"`
Format string `json:"format"`
Family string `json:"family"`
Families []string `json:"families"`
Parameter_size string `json:"parameter_size"`
Quantization_level string `json:"quantization_level"`
}
type Model struct {
Name string `json:"name"`
Model string `json:"model"`
Modified_at string `json:"modified_at"`
Size int `json:"size"`
Details Details `json:"details"`
Ip string `json:"ip"`
Port int `json:"port"`
}
type Models struct {
Models []Model `json:"models"`
}
func get_ollama_tags(ctr []Container) (Models, error) {
retval := []Model{}
for _, ollama := range ctr {
url := fmt.Sprintf("http://%s:%d/api/tags", ollama.IP, ollama.Port)
resp, err := http.Get(url)
if err != nil {
return Models{}, fmt.Errorf("failed to get %s: %v", url, err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return Models{}, fmt.Errorf("failed to read body: %v", err)
}
mods := Models{}
err = json.Unmarshal(body, &mods)
if err != nil {
return Models{}, fmt.Errorf("failed to unmarshal JSON: %v", err)
}
fmt.Printf("%+v\n", mods)
for n := range mods.Models {
mods.Models[n].Ip = ollama.IP
mods.Models[n].Port = ollama.Port
}
fmt.Printf("mod: %+v\n", mods)
retval = append(retval, mods.Models...)
}
return Models{Models: retval}, nil
}
func get_ollama_containers(host Host) []Container {
ctr_list := []Container{}
fmt.Printf("%s -> %s\n", host.Name, host.IP)
cli, err := client.NewClientWithOpts(client.WithHost(fmt.Sprintf("tcp://%s:%s", host.IP, host.Port)))
if err != nil {
panic(err)
}
defer cli.Close()
containers, err := cli.ContainerList(context.Background(), container.ListOptions{All: false})
if err != nil {
panic(err)
}
for _, ctr := range containers {
if strings.Contains(ctr.Names[0], "ollama") && ctr.Image == "ollama/ollama" {
c := Container{ID: ctr.ID, Name: ctr.Names[0], Image: ctr.Image}
fmt.Println(ctr.Ports[0])
c.IP = host.IP
c.Port = int(ctr.Ports[0].PublicPort)
ctr_list = append(ctr_list, c)
}
}
return ctr_list
}
func (h *Hosts) Add(name string, ip string, port string) {
h.Hosts = append(h.Hosts, Host{Name: name, IP: ip, Port: port})
}
func main() {
hosts := Hosts{}
hosts.Add("thor", "192.168.55.13", "2375")
hosts.Add("ironman", "192.168.55.10", "2375")
ctr := []Container{}
// get_ollama_tags()
for _, host := range hosts.Hosts {
fmt.Printf("%s -> %s\n", host.Name, host.IP)
ctr = append(ctr, get_ollama_containers(host)...)
fmt.Println(ctr)
}
models, err := get_ollama_tags(ctr)
if err != nil {
panic(err)
}
fmt.Print(models)
r := gin.Default()
r.GET("/api/tags", func(c *gin.Context) {
models, err := get_ollama_tags(ctr)
if err != nil {
panic(err)
}
c.JSON(200, models)
})
r.Run(":4000")
fmt.Print("END")
}