2024-04-24 11:18:03 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-05-29 13:29:32 +02:00
|
|
|
"context"
|
2024-04-24 12:25:55 +00:00
|
|
|
"encoding/json"
|
2024-04-24 11:18:03 +00:00
|
|
|
"fmt"
|
2024-04-24 12:25:55 +00:00
|
|
|
"io"
|
|
|
|
"net/http"
|
2024-05-29 13:29:32 +02:00
|
|
|
"strings"
|
2024-04-24 11:18:03 +00:00
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2024-05-29 13:29:32 +02:00
|
|
|
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/client"
|
2024-04-24 11:18:03 +00:00
|
|
|
)
|
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
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"`
|
|
|
|
}
|
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
type Containers struct {
|
|
|
|
Containers []Container `json:"containers"`
|
|
|
|
}
|
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
type Container struct {
|
2024-06-05 11:32:46 +02:00
|
|
|
Name string `json:"names"`
|
|
|
|
Port int `json:"port"`
|
|
|
|
IP string `json:"ip"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
ID string `json:"id"`
|
|
|
|
Status string `json:"status"`
|
|
|
|
State string `json:"state"`
|
2024-05-29 13:29:32 +02:00
|
|
|
}
|
|
|
|
|
2024-04-24 12:25:55 +00:00
|
|
|
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 {
|
2024-06-13 12:35:57 +02:00
|
|
|
Container string `json:"container"`
|
2024-04-24 12:25:55 +00:00
|
|
|
Name string `json:"name"`
|
|
|
|
Model string `json:"model"`
|
|
|
|
Modified_at string `json:"modified_at"`
|
2024-04-24 12:37:02 +00:00
|
|
|
Size int `json:"size"`
|
2024-04-24 12:25:55 +00:00
|
|
|
Details Details `json:"details"`
|
2024-04-24 12:37:02 +00:00
|
|
|
Ip string `json:"ip"`
|
2024-05-29 13:29:32 +02:00
|
|
|
Port int `json:"port"`
|
2024-06-05 11:32:46 +02:00
|
|
|
State string `json:"state"`
|
2024-04-24 12:25:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Models struct {
|
|
|
|
Models []Model `json:"models"`
|
|
|
|
}
|
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
func get_ollama_tags(hosts Hosts) (Models, error) {
|
|
|
|
|
|
|
|
var ctr Containers
|
|
|
|
|
|
|
|
for _, host := range hosts.Hosts {
|
2024-06-06 10:29:32 +02:00
|
|
|
fmt.Printf("HOST: %s -> %s\n", host.Name, host.IP)
|
2024-06-05 11:32:46 +02:00
|
|
|
ctr.Adds(get_ollama_containers(host, false))
|
2024-06-04 15:12:00 +02:00
|
|
|
// ctr = append(ctr, get_ollama_containers(host)...)
|
2024-06-06 10:29:32 +02:00
|
|
|
// fmt.Println(ctr)
|
2024-06-04 15:12:00 +02:00
|
|
|
}
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
retval := []Model{}
|
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
for _, ollama := range ctr.Containers {
|
2024-06-06 10:29:32 +02:00
|
|
|
// fmt.Println(ollama)
|
2024-06-05 11:32:46 +02:00
|
|
|
if ollama.State != "running" {
|
|
|
|
retval = append(retval, Model{Ip: ollama.IP, Port: ollama.Port, State: "stopped"})
|
|
|
|
} else {
|
|
|
|
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)
|
|
|
|
}
|
2024-06-13 12:35:57 +02:00
|
|
|
fmt.Printf("%+v\n", mods)
|
2024-06-05 11:32:46 +02:00
|
|
|
|
|
|
|
for n := range mods.Models {
|
|
|
|
mods.Models[n].Ip = ollama.IP
|
|
|
|
mods.Models[n].Port = ollama.Port
|
|
|
|
mods.Models[n].State = "running"
|
2024-06-13 12:35:57 +02:00
|
|
|
mods.Models[n].Container = ollama.Name
|
2024-06-06 10:29:32 +02:00
|
|
|
fmt.Printf("mod: %s - %s:%d\n", mods.Models[n].Name, mods.Models[n].Ip, mods.Models[n].Port)
|
2024-06-05 11:32:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
retval = append(retval, mods.Models...)
|
2024-05-29 13:29:32 +02:00
|
|
|
}
|
2024-04-24 11:18:03 +00:00
|
|
|
}
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
return Models{Models: retval}, nil
|
|
|
|
}
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-06-05 11:32:46 +02:00
|
|
|
func get_ollama_containers(host Host, all bool) Containers {
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
ctr_list := Containers{}
|
2024-04-24 12:37:02 +00:00
|
|
|
|
2024-06-06 10:29:32 +02:00
|
|
|
// fmt.Printf("%s -> %s\n", host.Name, host.IP)
|
2024-05-29 13:29:32 +02:00
|
|
|
cli, err := client.NewClientWithOpts(client.WithHost(fmt.Sprintf("tcp://%s:%s", host.IP, host.Port)))
|
2024-04-24 12:25:55 +00:00
|
|
|
if err != nil {
|
2024-06-05 13:24:34 +02:00
|
|
|
fmt.Println(err)
|
|
|
|
return ctr_list
|
2024-04-24 12:25:55 +00:00
|
|
|
}
|
2024-05-29 13:29:32 +02:00
|
|
|
defer cli.Close()
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-06-05 11:32:46 +02:00
|
|
|
containers, err := cli.ContainerList(context.Background(), container.ListOptions{All: all})
|
2024-05-29 13:29:32 +02:00
|
|
|
if err != nil {
|
2024-06-05 13:24:34 +02:00
|
|
|
fmt.Println(err)
|
|
|
|
return ctr_list
|
2024-05-29 13:29:32 +02:00
|
|
|
}
|
2024-04-24 12:25:55 +00:00
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
for _, ctr := range containers {
|
2024-06-06 10:29:32 +02:00
|
|
|
if strings.Contains(ctr.Names[0], "ollama") { //&& ctr.Image == "ollama/ollama" {
|
2024-06-05 11:32:46 +02:00
|
|
|
c := Container{ID: ctr.ID, Name: ctr.Names[0], Image: ctr.Image, State: ctr.State, Status: ctr.Status}
|
|
|
|
if ctr.State == "running" {
|
2024-06-06 10:29:32 +02:00
|
|
|
// fmt.Println(ctr.Ports[0])
|
2024-06-05 11:32:46 +02:00
|
|
|
c.Port = int(ctr.Ports[0].PublicPort)
|
|
|
|
}
|
2024-05-29 13:29:32 +02:00
|
|
|
c.IP = host.IP
|
2024-06-04 15:12:00 +02:00
|
|
|
ctr_list.Add(c)
|
|
|
|
// ctr_list = append(ctr_list, c)
|
2024-05-29 13:29:32 +02:00
|
|
|
}
|
2024-04-24 12:47:00 +00:00
|
|
|
}
|
|
|
|
|
2024-06-06 10:29:32 +02:00
|
|
|
// fmt.Println(ctr_list)
|
2024-06-05 11:32:46 +02:00
|
|
|
|
2024-05-29 13:29:32 +02:00
|
|
|
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})
|
2024-04-24 12:25:55 +00:00
|
|
|
}
|
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
func (c *Containers) Add(ctr Container) {
|
|
|
|
c.Containers = append(c.Containers, ctr)
|
|
|
|
}
|
2024-05-29 13:29:32 +02:00
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
func (c *Containers) Adds(ctrs Containers) {
|
|
|
|
c.Containers = append(c.Containers, ctrs.Containers...)
|
|
|
|
}
|
2024-05-29 13:29:32 +02:00
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
func (h *Hosts) Init() {
|
|
|
|
h.Add("thor", "192.168.55.13", "2375")
|
|
|
|
h.Add("ironman", "192.168.55.10", "2375")
|
2024-08-29 16:02:46 +02:00
|
|
|
h.Add("hela", "192.168.55.15", "2375")
|
2024-06-04 15:12:00 +02:00
|
|
|
}
|
2024-05-29 13:29:32 +02:00
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
func main() {
|
2024-05-29 13:29:32 +02:00
|
|
|
|
2024-06-04 15:12:00 +02:00
|
|
|
port := "4000"
|
|
|
|
|
|
|
|
hosts := Hosts{}
|
|
|
|
hosts.Init()
|
2024-04-24 11:18:03 +00:00
|
|
|
|
|
|
|
r := gin.Default()
|
2024-04-24 12:25:55 +00:00
|
|
|
r.GET("/api/tags", func(c *gin.Context) {
|
2024-06-04 15:12:00 +02:00
|
|
|
models, err := get_ollama_tags(hosts)
|
2024-05-29 13:29:32 +02:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2024-04-24 12:25:55 +00:00
|
|
|
c.JSON(200, models)
|
2024-04-24 11:18:03 +00:00
|
|
|
})
|
|
|
|
|
2024-06-05 11:32:46 +02:00
|
|
|
sapp := r.Group("/_app")
|
|
|
|
sapp.Static("/", "./static/_app")
|
|
|
|
|
|
|
|
static := r.Group("/static")
|
|
|
|
static.Static("/", "./static/static")
|
|
|
|
|
|
|
|
r.StaticFile("/", "./static/index.html")
|
|
|
|
r.StaticFile("/favicon.png", "./static/favicon.png")
|
|
|
|
|
|
|
|
r.ForwardedByClientIP = true
|
|
|
|
|
2024-06-06 10:29:32 +02:00
|
|
|
fmt.Println("Starting server on port " + port)
|
2024-06-04 15:12:00 +02:00
|
|
|
r.Run(":" + port)
|
2024-05-10 11:52:42 +02:00
|
|
|
|
|
|
|
fmt.Print("END")
|
2024-04-24 11:18:03 +00:00
|
|
|
}
|