init
This commit is contained in:
12
go.mod
Normal file
12
go.mod
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module ollamaScan
|
||||||
|
|
||||||
|
go 1.22.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||||
|
github.com/panjf2000/ants v1.3.0 // indirect
|
||||||
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
|
github.com/schollz/progressbar/v3 v3.18.0 // indirect
|
||||||
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
|
golang.org/x/term v0.29.0 // indirect
|
||||||
|
)
|
12
go.sum
Normal file
12
go.sum
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||||
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||||
|
github.com/panjf2000/ants v1.3.0 h1:8pQ+8leaLc9lys2viEEr8md0U4RN6uOSUCE9bOYjQ9M=
|
||||||
|
github.com/panjf2000/ants v1.3.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY=
|
||||||
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
|
||||||
|
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
|
||||||
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||||
|
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
92
main.go
Normal file
92
main.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ollamaScan/models"
|
||||||
|
"ollamaScan/utils"
|
||||||
|
|
||||||
|
"github.com/schollz/progressbar/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ScanIP(ip string, port int) models.OllamaInfo {
|
||||||
|
c := &http.Client{
|
||||||
|
Timeout: time.Second * 2,
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("GET", "http://"+ip+":"+strconv.Itoa(port)+"/api/tags", nil)
|
||||||
|
if err != nil {
|
||||||
|
return models.OllamaInfo{}
|
||||||
|
}
|
||||||
|
r, err := c.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return models.OllamaInfo{}
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
d, _ := io.ReadAll(r.Body)
|
||||||
|
info := models.OllamaInfo{
|
||||||
|
Host: ip,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(d, &info)
|
||||||
|
if err != nil {
|
||||||
|
return models.OllamaInfo{}
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
ipList := flag.String("l", "./ips.txt", "IP List File (default=./ips.txt)")
|
||||||
|
threads := flag.Int("t", 50, "Thread Num (default=50)")
|
||||||
|
outPath := flag.String("o", "./out.txt", "Output Save File (default=./out.txt)")
|
||||||
|
useJson := flag.Bool("json", false, "Output JSON Format (default=false)")
|
||||||
|
d, err := utils.ReadFile(*ipList)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list := strings.Split(d, "\n")
|
||||||
|
pro := progressbar.Default(int64(len(list)), "Scanning...")
|
||||||
|
pool := utils.PoolInfo{}
|
||||||
|
pool.NewPool(*threads)
|
||||||
|
results := make([]models.OllamaInfo, 2000)
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
pool.AddTask(func() {
|
||||||
|
info := ScanIP(list[i], 11434)
|
||||||
|
if info.Port != 0 {
|
||||||
|
results = append(results, info)
|
||||||
|
}
|
||||||
|
pro.Add(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defer pool.Pool.Release()
|
||||||
|
pool.TaskWaitGroup.Wait()
|
||||||
|
if *useJson {
|
||||||
|
buff := strings.Builder{}
|
||||||
|
out, _ := json.Marshal(results)
|
||||||
|
buff.Write(out)
|
||||||
|
if err := utils.WriteFile(*outPath, buff.String()); err != nil {
|
||||||
|
fmt.Println("Save Error:", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buff := strings.Builder{}
|
||||||
|
for _, i := range results {
|
||||||
|
if i.Port == 0 && len(i.Models) == 0 { //skip invalid data
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buff.WriteString("http://" + i.Host + ":" + strconv.Itoa(i.Port) + "/\n")
|
||||||
|
for _, j := range i.Models {
|
||||||
|
buff.WriteString("\t" + j.Name + " ModelSize:" + utils.FormatBytes(j.Size) + " " + " ParamSize:" + j.Details.ParameterSize + " QuantLevel:" + j.Details.QuantizationLevel + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := utils.WriteFile(*outPath, buff.String()); err != nil {
|
||||||
|
fmt.Println("Save Error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("Done! Saved to", outPath)
|
||||||
|
}
|
15
models/models_info.go
Normal file
15
models/models_info.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type ModelInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Details struct {
|
||||||
|
ParameterSize string `json:"parameter_size"`
|
||||||
|
QuantizationLevel string `json:"quantization_level"`
|
||||||
|
} `json:"details"`
|
||||||
|
}
|
||||||
|
type OllamaInfo struct {
|
||||||
|
Host string `json:"host"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Models []ModelInfo `json:"models"`
|
||||||
|
}
|
31
readme.md
Normal file
31
readme.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
# Ollama Scanner (扫描器)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
一个多线程的Ollama扫描器工具
|
||||||
|
使用ants库实现的简单扫描器
|
||||||
|
|
||||||
|
## Build (构建)
|
||||||
|
|
||||||
|
```text
|
||||||
|
go build .
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to use?
|
||||||
|
|
||||||
|
```text
|
||||||
|
ollamaScan
|
||||||
|
-t Num Threads (Default:50)
|
||||||
|
-l IP List File(Single IP Line) (Default:ips.txt)
|
||||||
|
-o Output File (Default: out.txt)
|
||||||
|
-json Save as Json Format (Default: False)
|
||||||
|
```
|
||||||
|
```text
|
||||||
|
ollamaScan
|
||||||
|
-t 线程数 (默认:50)
|
||||||
|
-l IP列表文件(一行一个) (默认:ips.txt)
|
||||||
|
-o 输出文件 (默认: out.txt)
|
||||||
|
-json 保存为Json (默认: False)
|
||||||
|
```
|
40
utils/file.go
Normal file
40
utils/file.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReadFile(path string) (string, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
d, _ := io.ReadAll(file)
|
||||||
|
return string(d), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteFile(path string, content string) error {
|
||||||
|
file, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
file.WriteString(content)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatBytes(bytes uint64) string {
|
||||||
|
const unit = 1024
|
||||||
|
if bytes < unit {
|
||||||
|
return fmt.Sprintf("%d B", bytes)
|
||||||
|
}
|
||||||
|
div, exp := uint64(unit), 0
|
||||||
|
for n := bytes / unit; n >= unit; n /= unit {
|
||||||
|
div *= unit
|
||||||
|
exp++
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.1f %ciB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
||||||
|
}
|
27
utils/goroutine_pool.go
Normal file
27
utils/goroutine_pool.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/panjf2000/ants"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PoolInfo struct {
|
||||||
|
Pool *ants.Pool
|
||||||
|
MaxWorkers int
|
||||||
|
TaskWaitGroup sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pool *PoolInfo) NewPool(num int) {
|
||||||
|
p, err := ants.NewPool(num)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Create Pool Error:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pool.Pool = p
|
||||||
|
pool.MaxWorkers = num
|
||||||
|
}
|
||||||
|
func (pool *PoolInfo) AddTask(fun func()) {
|
||||||
|
pool.Pool.Submit(fun)
|
||||||
|
}
|
Reference in New Issue
Block a user