diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/flores.iml b/.idea/flores.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/flores.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..e71d854
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/const.go b/config/const.go
new file mode 100644
index 0000000..01df6bb
--- /dev/null
+++ b/config/const.go
@@ -0,0 +1,3 @@
+package config
+
+const Entrypoint = "http://127.0.0.1:8888"
diff --git a/go.mod b/go.mod
index 3d496a4..36fdcd1 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,10 @@ go 1.22.8
toolchain go1.23.4
-require github.com/gin-gonic/gin v1.10.0
+require (
+ github.com/gin-gonic/gin v1.10.0
+ github.com/golang-jwt/jwt/v5 v5.2.2
+)
require (
github.com/bytedance/sonic v1.11.6 // indirect
@@ -26,6 +29,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/samber/lo v1.49.1 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
@@ -33,7 +37,7 @@ require (
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.29.0 // indirect
- golang.org/x/text v0.15.0 // indirect
+ golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..683440c
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,98 @@
+github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
+github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
+github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
+github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
+github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
+github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
+github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
+github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
+github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
+github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
+github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/lib/http/containers/create.go b/lib/http/containers/create.go
new file mode 100644
index 0000000..42e55ff
--- /dev/null
+++ b/lib/http/containers/create.go
@@ -0,0 +1,68 @@
+package containers
+
+import (
+ "bytes"
+ "encoding/json"
+ "floares/config"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+type Create struct {
+ Image string `json:"image,required"`
+ Name string `json:"name,omitempty"`
+}
+type CreateJson struct {
+ Cause string `json:"cause"`
+ Message string `json:"message"`
+ Response int `json:"response"`
+ Id string `json:"Id,omitempty"`
+ Warning []string `json:"Warnings,omitempty"`
+}
+
+type create struct {
+ Image string `json:"image"`
+}
+
+func (c *Create) Create() (string, error) {
+ var container create
+ container.Image = c.Image
+
+ str, err := json.Marshal(container)
+ if err != nil {
+ log.Println(err)
+ return "", err
+ }
+ log.Println(string(str))
+ req, _ := http.NewRequest(http.MethodPost, config.Entrypoint+"/v2.1.2/libpod/containers/create", bytes.NewBuffer(str))
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ log.Println(err)
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ b, err := io.ReadAll(resp.Body)
+ log.Println(string(b))
+ var createJson CreateJson
+ err = json.NewDecoder(resp.Body).Decode(&createJson)
+ if err != nil {
+ log.Println(createJson)
+ log.Println(err)
+ return "", err
+ }
+ log.Println(createJson)
+ startContainer(createJson.Id)
+ return createJson.Id, nil
+}
+func startContainer(id string) error {
+ post, err := http.Post(fmt.Sprintf("/%s/libpod/containers/%s/start", config.Entrypoint, id), "application/json", nil)
+ if err != nil {
+ return err
+ }
+ bytes, err := io.ReadAll(post.Body)
+ log.Println(string(bytes))
+ return err
+}
diff --git a/lib/http/containers/list.go b/lib/http/containers/list.go
new file mode 100644
index 0000000..a6dfb5a
--- /dev/null
+++ b/lib/http/containers/list.go
@@ -0,0 +1,59 @@
+package containers
+
+import (
+ "encoding/json"
+ "floares/config"
+ "log"
+ "net/http"
+ "strings"
+ "time"
+)
+
+type ListContainers struct {
+ Id string `json:"id"`
+ Name string `json:"name"`
+ Image string `json:"image"`
+ Created string `json:"created"`
+ Ports []interface{} `json:"ports"`
+ State string `json:"state"`
+}
+type Containers struct {
+ Id string `json:"Id"`
+ Names []string `json:"Names"`
+ Image string `json:"Image"`
+ ImageID string `json:"ImageID"`
+ Command string `json:"Command"`
+ Created int `json:"Created"`
+ //Ports []interface{} `json:"Ports"`
+ State string `json:"State"`
+ Status string `json:"Status"`
+}
+
+func List() []ListContainers {
+ var containers []Containers
+ req, err := http.NewRequest(http.MethodGet, config.Entrypoint+"/containers/json?all=true", nil)
+ if err != nil {
+ log.Println("request for containers list error:", err)
+ return []ListContainers{}
+ }
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ log.Println("request for containers list error:", err)
+ return []ListContainers{}
+ }
+ err = json.NewDecoder(res.Body).Decode(&containers)
+ if err != nil {
+ log.Println("json decode container list error:", err)
+ }
+ var list []ListContainers
+ for _, container := range containers {
+ list = append(list, ListContainers{
+ Id: container.Id,
+ Name: strings.TrimPrefix(container.Names[0], "/"),
+ Image: container.Image,
+ Created: time.Unix(int64(container.Created), 0).Format(time.DateTime),
+ State: container.State,
+ })
+ }
+ return list
+}
diff --git a/lib/http/images/delete.go b/lib/http/images/delete.go
new file mode 100644
index 0000000..a30be04
--- /dev/null
+++ b/lib/http/images/delete.go
@@ -0,0 +1,41 @@
+package images
+
+import (
+ "context"
+ "encoding/json"
+ "floares/config"
+ "fmt"
+ "log"
+ "net/http"
+)
+
+type DeleteRsp struct {
+ Cause string `json:"cause"` //cause image is in use by a container
+ Message string `json:"message"`
+ Response int `json:"response"`
+}
+type DeleteRsult struct {
+ Code int `json:"code"`
+ Error string `json:"err,omitempty"`
+}
+
+func Delete(id string) DeleteRsult {
+ req, _ := http.NewRequestWithContext(context.Background(), http.MethodDelete, config.Entrypoint+fmt.Sprintf("/images/%s", id), nil)
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return DeleteRsult{
+ Error: err.Error(),
+ }
+ }
+ var deleteRsult DeleteRsp
+ var response DeleteRsult
+ response.Code = resp.StatusCode
+ _ = json.NewDecoder(resp.Body).Decode(&deleteRsult)
+ log.Println(deleteRsult)
+ if deleteRsult.Cause != "" {
+ return DeleteRsult{
+ Error: deleteRsult.Cause,
+ }
+ }
+ return response
+}
diff --git a/lib/http/images/list.go b/lib/http/images/list.go
index a8d61a3..9d057b0 100644
--- a/lib/http/images/list.go
+++ b/lib/http/images/list.go
@@ -1 +1,40 @@
package images
+
+import (
+ "encoding/json"
+ "floares/config"
+ "floares/lib/model"
+ "net/http"
+ "strconv"
+ "time"
+)
+
+type Image struct {
+ Id string `json:"id"`
+ Name string `json:"name"`
+ Tag string `json:"tag"`
+ Digest string `json:"digest"`
+ CreatedAt string `json:"created_at"`
+ Size string `json:"size"`
+}
+
+func List() []Image {
+ var images []model.Image
+
+ req, _ := http.NewRequest(http.MethodGet, config.Entrypoint+"/images/json", nil)
+ resp, _ := http.DefaultClient.Do(req)
+ defer resp.Body.Close()
+ json.NewDecoder(resp.Body).Decode(&images)
+ var imagesList []Image
+ for _, v := range images {
+ imagesList = append(imagesList, Image{
+ Id: v.Id[7:],
+ Name: v.Names[0],
+ Tag: v.RepoTags[0],
+ Digest: v.Digest,
+ CreatedAt: time.Unix(int64(v.Created), 0).Format(time.DateTime),
+ Size: strconv.Itoa(v.Size/1024/1024) + " MB",
+ })
+ }
+ return imagesList
+}
diff --git a/lib/http/images/pull.go b/lib/http/images/pull.go
new file mode 100644
index 0000000..f2837d2
--- /dev/null
+++ b/lib/http/images/pull.go
@@ -0,0 +1,44 @@
+package images
+
+import (
+ "context"
+ "encoding/json"
+ "floares/config"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+)
+
+type PullRsp struct {
+ Images []string `json:"images"`
+ Id string `json:"id"`
+ Error string `json:"errr,omitempty"`
+ Info string `json:"info,omitempty"`
+}
+
+func Pull(ref string) PullRsp {
+ var pull PullRsp
+ req, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, config.Entrypoint+fmt.Sprintf("/v2.2.2/libpod/images/pull?reference=%s&quiet=true", ref), nil)
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return PullRsp{
+ Error: err.Error(),
+ }
+ }
+ defer func(Body io.ReadCloser) {
+ err = Body.Close()
+ if err != nil {
+ log.Printf("Failed to close response body: %v", err)
+ }
+ }(resp.Body)
+ if resp.StatusCode != http.StatusOK {
+ return PullRsp{
+ Error: "status code " + resp.Status,
+ }
+ }
+ _ = json.NewDecoder(resp.Body).Decode(&pull)
+
+ return pull
+
+}
diff --git a/lib/http/network/list.go b/lib/http/network/list.go
index 27a4ccd..2905fdb 100644
--- a/lib/http/network/list.go
+++ b/lib/http/network/list.go
@@ -2,13 +2,15 @@ package network
import (
"encoding/json"
+ "floares/config"
"floares/lib/model"
"log"
"net/http"
+ "time"
)
func ListJsons() []model.NetWorkJson {
- req, _ := http.NewRequest("GET", "http://127.0.0.1:8888/networks", nil)
+ req, _ := http.NewRequest("GET", config.Entrypoint+"/networks", nil)
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Println("request for network list error:", err)
@@ -18,3 +20,23 @@ func ListJsons() []model.NetWorkJson {
err = json.NewDecoder(res.Body).Decode(&result)
return result
}
+func ListNetwork() []model.NetWork {
+ var result []model.NetWork
+ for _, v := range ListJsons() {
+ conf := v.IPAM.Config
+ var ipam []model.Config
+ for _, val := range conf {
+ ipam = append(ipam, model.Config{
+ Subnet: val.Subnet, Gateway: val.Gateway,
+ })
+ }
+ result = append(result, model.NetWork{
+ Name: v.Name,
+ Id: v.Id,
+ Created: v.Created.Format(time.DateTime),
+ Driver: v.Driver,
+ IPAM: ipam,
+ })
+ }
+ return result
+}
diff --git a/lib/http/system/basic.go b/lib/http/system/basic.go
index 08e8b44..facb2cf 100644
--- a/lib/http/system/basic.go
+++ b/lib/http/system/basic.go
@@ -2,13 +2,14 @@ package system
import (
"encoding/json"
+ "floares/config"
"floares/lib/model"
"log"
"net/http"
)
func Version() model.Version {
- req, _ := http.NewRequest("GET", "http://127.0.0.1:8888/version", nil)
+ req, _ := http.NewRequest("GET", config.Entrypoint+"/version", nil)
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Println("request for version list error:", err)
diff --git a/lib/http/volume/list.go b/lib/http/volume/list.go
index 29c3516..b3325b4 100644
--- a/lib/http/volume/list.go
+++ b/lib/http/volume/list.go
@@ -2,13 +2,14 @@ package volume
import (
"encoding/json"
+ "floares/config"
"floares/lib/model"
"log"
"net/http"
)
func ListJsons() model.VolumesJson {
- req, _ := http.NewRequest("GET", "http://127.0.0.1:8888/volumes", nil)
+ req, _ := http.NewRequest("GET", config.Entrypoint+"/volumes", nil)
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Println("request for volume list error:", err)
diff --git a/lib/model/images.go b/lib/model/images.go
new file mode 100644
index 0000000..ff8d6ed
--- /dev/null
+++ b/lib/model/images.go
@@ -0,0 +1,15 @@
+package model
+
+type Image struct {
+ Id string `json:"Id"`
+ RepoTags []string `json:"RepoTags"`
+ Created int `json:"Created"`
+ Size int `json:"Size"`
+ SharedSize int `json:"SharedSize"`
+ VirtualSize int `json:"VirtualSize"`
+ Labels *struct {
+ Maintainer string `json:"maintainer,omitempty"`
+ } `json:"Labels"`
+ Digest string `json:"Digest"`
+ Names []string `json:"Names"`
+}
diff --git a/lib/model/network.go b/lib/model/network.go
index b4d0801..2770765 100644
--- a/lib/model/network.go
+++ b/lib/model/network.go
@@ -33,3 +33,15 @@ type NetWorkJson struct {
Labels struct {
} `json:"Labels"`
}
+
+type NetWork struct {
+ Name string `json:"name"`
+ Id string `json:"id"`
+ Created string `json:"created"`
+ Driver string `json:"driver"`
+ IPAM []Config `json:"ipam"`
+}
+type Config struct {
+ Subnet string `json:"subnet"`
+ Gateway string `json:"gateway"`
+}
diff --git a/lib/model/volume.go b/lib/model/volume.go
index 71ba5ca..82ab307 100644
--- a/lib/model/volume.go
+++ b/lib/model/volume.go
@@ -1,18 +1,13 @@
package model
-import "time"
-
type VolumesJson struct {
- Volumes []struct {
- CreatedAt time.Time `json:"CreatedAt"`
- Driver string `json:"Driver"`
- Labels struct {
- } `json:"Labels"`
- Mountpoint string `json:"Mountpoint"`
- Name string `json:"Name"`
- Options struct {
- } `json:"Options"`
- Scope string `json:"Scope"`
- } `json:"Volumes"`
- Warnings []interface{} `json:"Warnings"`
+ Volumes []Volume `json:"volumes"`
+}
+type Volume struct {
+ Driver string `json:"driver"`
+ Labels struct {
+ } `json:"labels"`
+ Mountpoint string `json:"mountpoint"`
+ Name string `json:"name"`
+ Scope string `json:"scope"`
}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..260710a
--- /dev/null
+++ b/main.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "floares/service/auth"
+ "floares/service/containers"
+ "floares/service/images"
+ "floares/service/network"
+ "floares/service/system"
+ "floares/service/volume"
+ "github.com/gin-gonic/gin"
+ "net/http"
+)
+
+func main() {
+ r := gin.Default()
+ r.Use(func(c *gin.Context) {
+ c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
+ c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH")
+ c.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Content-Type,Authorization")
+ c.Header("Access-Control-Expose-Headers", "Content-Length")
+ c.Header("Access-Control-Allow-Credentials", "true")
+ if c.Request.Method == "OPTIONS" {
+ c.Status(http.StatusNoContent)
+ c.Abort()
+ }
+ return
+
+ })
+ a := r.Group("/api/auth")
+ a.POST("/sign-in", auth.Sign)
+ a.GET("/me", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{})
+ })
+ a.POST("/sign-up", auth.Sign)
+ system.RegisterRouter(r.Group("/system"))
+ containers.RegisterRouter(r.Group("/containers"))
+ images.RegisterRouter(r.Group("/images"))
+ network.RegisterRouter(r.Group("/network"))
+ volume.RegisterRouter(r.Group("/volumes"))
+ r.Run()
+}
diff --git a/service/auth/sigin.go b/service/auth/sigin.go
index fb45fb6..6fa5d92 100644
--- a/service/auth/sigin.go
+++ b/service/auth/sigin.go
@@ -1,24 +1,70 @@
package auth
import (
+ "crypto/sha1"
+ "encoding/base64"
"github.com/gin-gonic/gin"
- "log"
+ "github.com/golang-jwt/jwt/v5"
"net/http"
+ "time"
)
type SignReq struct {
Email string `json:"email"`
Password string `json:"password"`
}
+type User struct {
+ Id string `json:"id"`
+ DisplayName string `json:"displayName"`
+ PhotoURL string `json:"photoURL"`
+ PhoneNumber string `json:"phoneNumber"`
+ Country string `json:"country"`
+ Address string `json:"address"`
+ State string `json:"state"`
+ City string `json:"city"`
+ ZipCode string `json:"zipCode"`
+ About string `json:"about"`
+ Role string `json:"role"`
+ IsPublic bool `json:"isPublic"`
+ Email string `json:"email"`
+ Password string `json:"password"`
+}
func Sign(c *gin.Context) {
var req SignReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
- jwt.
- c.JSON(http.StatusOK, gin.H{
- "data": "hello world",
+ token, _ := GenToken(req.Email)
+ c.JSON(http.StatusOK, gin.H{
+ "accessToken": token,
+ "user": User{},
})
- log.Println(req)
+}
+
+type Token struct {
+ Token string `json:"token"`
+ AccessToken string `json:"access_token"`
+ ExpiresIn int `json:"expires_in"`
+ IssuedAt string `json:"issued_at"`
+}
+
+func DefaultToken(ip string) Token {
+ acc := sha1.Sum([]byte(ip))
+ access := base64.StdEncoding.EncodeToString(acc[:])
+ return Token{
+ Token: access,
+ AccessToken: access,
+ ExpiresIn: 300,
+ IssuedAt: time.Now().Format("2006-01-02T15:04:05.999999999Z"),
+ }
+}
+func GenToken(u string) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
+ "user": u,
+ "nbf": time.Now().Unix(),
+ "exp": time.Now().Add(time.Minute * 300).Unix(),
+ })
+
+ return token.SignedString([]byte("fasthub-center"))
}
diff --git a/service/containers/pods.go b/service/containers/pods.go
new file mode 100644
index 0000000..4c73bb3
--- /dev/null
+++ b/service/containers/pods.go
@@ -0,0 +1,35 @@
+package containers
+
+import (
+ "floares/lib/http/containers"
+ "github.com/gin-gonic/gin"
+)
+
+func ListContainers(c *gin.Context) {
+ container := containers.List()
+ c.JSON(200, gin.H{
+ "data": container,
+ })
+}
+
+func CreateContainer(c *gin.Context) {
+ var create containers.Create
+ if err := c.BindJSON(&create); err != nil {
+ c.JSON(200, gin.H{
+ "data": nil,
+ "error": err.Error(),
+ })
+ return
+ }
+ id, err := create.Create()
+ if err != nil {
+ c.JSON(200, gin.H{
+ "data": nil,
+ "error": err.Error(),
+ })
+ return
+ }
+ c.JSON(200, gin.H{
+ "data": id,
+ })
+}
diff --git a/service/containers/router.go b/service/containers/router.go
new file mode 100644
index 0000000..909b0dc
--- /dev/null
+++ b/service/containers/router.go
@@ -0,0 +1,9 @@
+package containers
+
+import "github.com/gin-gonic/gin"
+
+func RegisterRouter(r *gin.RouterGroup) {
+ r.GET("/all", ListContainers)
+ r.POST("/create", CreateContainer)
+
+}
diff --git a/service/images/base.go b/service/images/base.go
new file mode 100644
index 0000000..5ae6235
--- /dev/null
+++ b/service/images/base.go
@@ -0,0 +1,43 @@
+package images
+
+import (
+ "floares/lib/http/images"
+ "github.com/gin-gonic/gin"
+ "net/http"
+)
+
+func ListImages(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{
+ "data": images.List(),
+ "code": http.StatusOK,
+ })
+}
+func PullImage(c *gin.Context) {
+ type Ref struct {
+ Ref string `json:"ref"`
+ }
+ var ref Ref
+ if err := c.ShouldBind(&ref); err != nil {
+ c.JSON(http.StatusOK, gin.H{
+ "code": http.StatusBadRequest,
+ "data": gin.H{
+ "err": err.Error(),
+ },
+ })
+ return
+ }
+ c.JSON(http.StatusOK, gin.H{
+ "data": images.Pull(ref.Ref),
+ "code": http.StatusOK,
+ })
+}
+
+func Delete(c *gin.Context) {
+ result := images.Delete(c.Param("id"))
+
+ c.JSON(http.StatusOK, gin.H{
+ "code": http.StatusOK,
+ "err": result.Error,
+ })
+
+}
diff --git a/service/images/router.go b/service/images/router.go
new file mode 100644
index 0000000..16e8742
--- /dev/null
+++ b/service/images/router.go
@@ -0,0 +1,10 @@
+package images
+
+import "github.com/gin-gonic/gin"
+
+func RegisterRouter(c *gin.RouterGroup) {
+ c.GET("/", ListImages)
+ c.POST("/pull", PullImage)
+ c.DELETE("/:id", Delete)
+
+}
diff --git a/service/network/list.go b/service/network/list.go
new file mode 100644
index 0000000..7bbf4f6
--- /dev/null
+++ b/service/network/list.go
@@ -0,0 +1,14 @@
+package network
+
+import (
+ "floares/lib/http/network"
+ "github.com/gin-gonic/gin"
+)
+
+func ListNetwork(c *gin.Context) {
+ net := network.ListNetwork()
+ c.JSON(200, gin.H{
+ "data": net,
+ "code": 200,
+ })
+}
diff --git a/service/network/router.go b/service/network/router.go
new file mode 100644
index 0000000..85e64ba
--- /dev/null
+++ b/service/network/router.go
@@ -0,0 +1,7 @@
+package network
+
+import "github.com/gin-gonic/gin"
+
+func RegisterRouter(r *gin.RouterGroup) {
+ r.GET("/", ListNetwork)
+}
diff --git a/service/system/basic.go b/service/system/basic.go
new file mode 100644
index 0000000..9b80796
--- /dev/null
+++ b/service/system/basic.go
@@ -0,0 +1,26 @@
+package system
+
+import (
+ "floares/lib/http/network"
+ "floares/lib/http/system"
+ "floares/lib/http/volume"
+ "floares/lib/model"
+ "github.com/gin-gonic/gin"
+)
+
+func BasicInfo(c *gin.Context) {
+ bas := system.Info()
+ version := system.Version()
+ c.JSON(200, model.BasicInfo{
+ Uptime: bas.Uptime,
+ DefaultRuntime: bas.DefaultRuntime,
+ NCPU: bas.NCPU,
+ MemTotal: bas.MemTotal,
+ OperatingSystem: bas.OperatingSystem,
+ Images: bas.Images,
+ Containers: bas.Containers,
+ Platform: version.Platform,
+ Volumes: len(volume.ListJsons().Volumes),
+ Networks: len(network.ListJsons()),
+ })
+}
diff --git a/service/system/router.go b/service/system/router.go
new file mode 100644
index 0000000..bb6a120
--- /dev/null
+++ b/service/system/router.go
@@ -0,0 +1,9 @@
+package system
+
+import "github.com/gin-gonic/gin"
+
+func RegisterRouter(r *gin.RouterGroup) {
+ r.GET("/ping", BasicInfo)
+ r.GET("/basic", BasicInfo)
+
+}
diff --git a/service/volume/list.go b/service/volume/list.go
new file mode 100644
index 0000000..cc04a5d
--- /dev/null
+++ b/service/volume/list.go
@@ -0,0 +1,14 @@
+package volume
+
+import (
+ "floares/lib/http/volume"
+ "github.com/gin-gonic/gin"
+ "net/http"
+)
+
+func List(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{
+ "data": volume.ListJsons(),
+ "code": http.StatusOK,
+ })
+}
diff --git a/service/volume/router.go b/service/volume/router.go
new file mode 100644
index 0000000..c7753ea
--- /dev/null
+++ b/service/volume/router.go
@@ -0,0 +1,7 @@
+package volume
+
+import "github.com/gin-gonic/gin"
+
+func RegisterRouter(c *gin.RouterGroup) {
+ c.GET("/", List)
+}
diff --git a/tmp/runner-build b/tmp/runner-build
new file mode 100755
index 0000000..72c147e
Binary files /dev/null and b/tmp/runner-build differ