Skip to content

Commit 2a3e056

Browse files
committed
支持node宿主机的容器查看
1 parent 0877b55 commit 2a3e056

File tree

12 files changed

+294
-580
lines changed

12 files changed

+294
-580
lines changed

.DS_Store

4 KB
Binary file not shown.

go.mod

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ require (
88
github.com/gogo/protobuf v1.3.2
99
github.com/gorilla/websocket v1.4.2
1010
github.com/imroc/req v0.3.2
11+
github.com/json-iterator/go v1.1.12
12+
github.com/onsi/ginkgo v1.16.5 // indirect
13+
github.com/onsi/gomega v1.20.0 // indirect
14+
github.com/robfig/cron/v3 v3.0.1
1115
github.com/spf13/viper v1.12.0
1216
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
17+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
18+
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
1319
gopkg.in/go-playground/validator.v9 v9.31.0
1420
gorm.io/driver/mysql v1.3.3
1521
gorm.io/gorm v1.23.5
16-
k8s.io/apimachinery v0.24.1
1722
)
1823

1924
require (
20-
github.com/Microsoft/go-winio v0.5.2 // indirect
21-
github.com/docker/distribution v2.8.1+incompatible // indirect
22-
github.com/docker/docker v20.10.17+incompatible // indirect
23-
github.com/docker/go-connections v0.4.0 // indirect
24-
github.com/docker/go-units v0.4.0 // indirect
2525
github.com/fsnotify/fsnotify v1.5.4 // indirect
2626
github.com/gin-contrib/sse v0.1.0 // indirect
2727
github.com/go-playground/locales v0.13.0 // indirect
@@ -32,34 +32,26 @@ require (
3232
github.com/hashicorp/hcl v1.0.0 // indirect
3333
github.com/jinzhu/inflection v1.0.0 // indirect
3434
github.com/jinzhu/now v1.1.4 // indirect
35-
github.com/json-iterator/go v1.1.12 // indirect
3635
github.com/leodido/go-urn v1.2.0 // indirect
3736
github.com/magiconair/properties v1.8.6 // indirect
3837
github.com/mattn/go-isatty v0.0.14 // indirect
3938
github.com/mitchellh/mapstructure v1.5.0 // indirect
4039
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
4140
github.com/modern-go/reflect2 v1.0.2 // indirect
42-
github.com/opencontainers/go-digest v1.0.0 // indirect
43-
github.com/opencontainers/image-spec v1.0.2 // indirect
4441
github.com/pelletier/go-toml v1.9.5 // indirect
4542
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
46-
github.com/pkg/errors v0.9.1 // indirect
47-
github.com/robfig/cron/v3 v3.0.1 // indirect
48-
github.com/sirupsen/logrus v1.9.0 // indirect
4943
github.com/spf13/afero v1.8.2 // indirect
5044
github.com/spf13/cast v1.5.0 // indirect
5145
github.com/spf13/jwalterweatherman v1.1.0 // indirect
5246
github.com/spf13/pflag v1.0.5 // indirect
5347
github.com/subosito/gotenv v1.3.0 // indirect
5448
github.com/ugorji/go/codec v1.1.7 // indirect
55-
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
56-
golang.org/x/oauth2 v0.0.0-20220630143837-2104d58473e0 // indirect
57-
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
49+
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
50+
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
5851
golang.org/x/text v0.3.7 // indirect
5952
google.golang.org/appengine v1.6.7 // indirect
6053
google.golang.org/protobuf v1.28.0 // indirect
61-
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
6254
gopkg.in/ini.v1 v1.66.4 // indirect
6355
gopkg.in/yaml.v2 v2.4.0 // indirect
64-
gopkg.in/yaml.v3 v3.0.0 // indirect
56+
gopkg.in/yaml.v3 v3.0.1 // indirect
6557
)

go.sum

Lines changed: 13 additions & 439 deletions
Large diffs are not rendered by default.

library/sshtool/index.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,22 @@ import (
77
"time"
88
)
99

10-
func SSHConnect(username, password, rsaPrivate, host, port string) (session *ssh.Session, err error) {
10+
func SSHConnect(username, password, rsaPrivate, host, port string) (client *ssh.Client, session *ssh.Session, err error) {
1111
auth := []ssh.AuthMethod{}
1212
if rsaPrivate != "" {
1313
var signer ssh.Signer
1414
signer, err = ssh.ParsePrivateKey([]byte(rsaPrivate))
1515
if err != nil {
16-
return nil, err
16+
return
1717
}
1818
auth = append(auth, ssh.PublicKeys(signer))
1919
}
2020
if username != "" && password != "" {
2121
auth = append(auth, ssh.Password(password))
2222
}
2323
if len(auth) == 0 {
24-
return nil, errors.New("password & rsa is nil")
24+
err = errors.New("password & rsa is nil")
25+
return
2526
}
2627

2728
clientConfig := &ssh.ClientConfig{
@@ -31,7 +32,7 @@ func SSHConnect(username, password, rsaPrivate, host, port string) (session *ssh
3132
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
3233
}
3334
addr := fmt.Sprintf("%s:%s", host, port)
34-
client, err := ssh.Dial("tcp", addr, clientConfig)
35+
client, err = ssh.Dial("tcp", addr, clientConfig)
3536
if err != nil {
3637
return
3738
}

local/upgrade.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
<div style="line-height: 30px;">
2+
<div>
3+
<b>v1.2.4</b>
4+
<p>
5+
1. Node宿主机管理支持容器查看;
6+
</p>
7+
</div>
8+
<div>
9+
<b>v1.2.31</b>
10+
<p>
11+
1. bugfix: ops go ssh client造成node实例产生大量sshd进程;
12+
</p>
13+
</div>
214
<div>
315
<b>v1.2.3</b>
416
<p>

local/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.2.3
1+
v1.2.4

models/cronjob.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func InitCronjob() {
4949
func initSystemCronjob() {
5050
var systemCron = cron.New()
5151
systemCron.AddFunc("0 4 */1 * *", func() {
52-
NodeClean()
52+
NodeDockerPrune()
5353
})
5454
systemCron.Run()
5555
}

models/node.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func GetNodes() (res []Node) {
5858
return res
5959
}
6060

61-
func NodeClean() {
61+
func NodeDockerPrune() {
6262
for _, item := range GetNodes() {
6363
_, err := item.Exec("docker system prune -a -f")
6464
log.StdOut("nodeClean", item.IP, err)
@@ -208,12 +208,15 @@ func (t *Node) WorkspaceSshIdRsaPath() string {
208208

209209
//sync exec remote shell
210210
func (t *Node) Exec(cmd string) (res []byte, err error) {
211-
s, err := sshtool.SSHConnect(t.SshUsername, t.SshPassword, t.SshKey, t.IP, t.SshPort)
211+
client,session, err := sshtool.SSHConnect(t.SshUsername, t.SshPassword, t.SshKey, t.IP, t.SshPort)
212212
if err != nil {
213213
return
214214
}
215-
defer s.Close()
216-
res, err = s.CombinedOutput(cmd)
215+
defer func() {
216+
session.Close()
217+
client.Close()
218+
}()
219+
res, err = session.CombinedOutput(cmd)
217220
return
218221
}
219222

web/controller/node.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ func (t *NodeController) Init(group *gin.RouterGroup) {
1616
group.GET(".", t.index)
1717
group.GET("/create", t.create)
1818
group.POST("/save", t.save)
19-
group.POST("/docker/version", t.dockerVersion)
20-
group.POST("/docker/stats", t.dockerStats)
19+
2120
detailGroup := group.Group("/i/:nid", middleware.Node())
2221
detailGroup.GET(".", t.info)
2322
detailGroup.DELETE(".", t.del)
23+
detailDockerGroup := detailGroup.Group("/docker")
24+
detailDockerGroup.GET(".", t.dockerIndex)
25+
detailDockerGroup.POST("/restart", t.dockerRestart)
26+
detailDockerGroup.POST("/rm", t.dockerRm)
27+
detailDockerGroup.POST("/ps", t.dockerPs)
28+
detailDockerGroup.POST("/stats", t.dockerStats)
29+
30+
dockerGroup := group.Group("/docker")
31+
dockerGroup.POST("/version", t.dockerVersion)
2432
}
2533

2634
func (t *NodeController) index(c *gin.Context) {
@@ -29,19 +37,40 @@ func (t *NodeController) index(c *gin.Context) {
2937
}
3038

3139
func (t *NodeController) create(c *gin.Context) {
32-
g.HTML(c, "node/info.html", gin.H{
40+
g.HTML(c, "node/info.html", gin.H{})
41+
}
42+
43+
func (t *NodeController) dockerIndex(c *gin.Context) {
44+
g.HTML(c, "node/docker.html", gin.H{
45+
"node": models.GetNode(c),
3346
})
3447
}
3548

49+
//node docker ps
50+
func (t *NodeController) dockerPs(c *gin.Context) {
51+
res, err := node.DockerPs(c)
52+
ginutil.JsonAuto(c, "Success", err, res)
53+
}
54+
55+
//node docker restart
56+
func (t *NodeController) dockerRestart(c *gin.Context) {
57+
ginutil.JsonAuto(c, "Success", node.DockerRestart(c), nil)
58+
}
59+
60+
//node docker rm -f
61+
func (t *NodeController) dockerRm(c *gin.Context) {
62+
ginutil.JsonAuto(c, "Success", node.DockerRm(c), nil)
63+
}
64+
3665
//node docker version
3766
func (t *NodeController) dockerVersion(c *gin.Context) {
38-
res, err := node.GetDockerVersion(c)
67+
res, err := node.DockerVersion(c)
3968
ginutil.JsonAuto(c, "Success", err, res)
4069
}
4170

4271
//node docker stats
4372
func (t *NodeController) dockerStats(c *gin.Context) {
44-
res, err := node.GetDockerStats(c)
73+
res, err := node.DockerStats(c)
4574
ginutil.JsonAuto(c, "Success", err, res)
4675
}
4776

web/service/node/info.go

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"app/library/ginutil"
55
"app/library/types/convert"
66
"app/models"
7+
"errors"
78
"github.com/gin-gonic/gin"
89
jsoniter "github.com/json-iterator/go"
910
"strings"
@@ -14,7 +15,7 @@ type valInfos struct {
1415
Ids []uint32 `json:"ids" form:"ids" binding:"required"`
1516
}
1617

17-
func getNodeRemoteShellResult(c *gin.Context, shell string) (res gin.H, err error) {
18+
func DockerVersion(c *gin.Context) (res gin.H, err error) {
1819
res = gin.H{}
1920
var val valInfos
2021
if err = ginutil.ShouldBind(c, &val); err != nil {
@@ -24,14 +25,13 @@ func getNodeRemoteShellResult(c *gin.Context, shell string) (res gin.H, err erro
2425
if err = models.DB().Find(&list, "id IN (?)", val.Ids).Error; err != nil {
2526
return
2627
}
27-
//并发
2828
var maps sync.Map
2929
var wg sync.WaitGroup
3030
for _, v := range list {
3131
wg.Add(1)
3232
go func(i models.Node) {
3333
defer wg.Done()
34-
bytes, er := i.Exec(shell)
34+
bytes, er := i.Exec("docker version --format='{{json .}}'")
3535
var item = gin.H{"id": i.ID, "content": string(bytes), "error": ""}
3636
if er != nil {
3737
item["error"] = er.Error()
@@ -48,26 +48,54 @@ func getNodeRemoteShellResult(c *gin.Context, shell string) (res gin.H, err erro
4848
return
4949
}
5050

51-
func GetDockerVersion(c *gin.Context) (res gin.H, err error) {
52-
return getNodeRemoteShellResult(c, "docker version --format='{{json .}}'")
51+
func DockerPs(c *gin.Context) (res []interface{}, err error) {
52+
var node = models.GetNode(c)
53+
bytes, err := node.Exec("docker ps --format='{{json .}}'")
54+
if err != nil {
55+
return
56+
}
57+
res = make([]interface{}, 0)
58+
for _, strItem := range strings.Split(string(bytes), "\n") {
59+
var resItem gin.H
60+
if jsoniter.Unmarshal([]byte(strItem), &resItem) == nil {
61+
res = append(res, resItem)
62+
}
63+
}
64+
return
5365
}
5466

55-
func GetDockerStats(c *gin.Context) (res gin.H, err error) {
56-
res, err = getNodeRemoteShellResult(c, "docker stats --no-stream --format='{{json .}}'")
67+
func DockerRestart(c *gin.Context) (err error) {
68+
var name = ginutil.Input(c, "name")
69+
if name == "" {
70+
return errors.New("name is nil")
71+
}
72+
var node = models.GetNode(c)
73+
_, err = node.Exec("docker restart " + name)
74+
return
75+
}
76+
77+
func DockerRm(c *gin.Context) (err error) {
78+
var name = ginutil.Input(c, "name")
79+
if name == "" {
80+
return errors.New("name is nil")
81+
}
82+
var node = models.GetNode(c)
83+
_, err = node.Exec("docker rm -f " + name)
84+
return
85+
}
86+
87+
func DockerStats(c *gin.Context) (res []interface{}, err error) {
88+
var node = models.GetNode(c)
89+
bytes, err := node.Exec("docker stats --no-stream --format='{{json .}}'")
5790
if err != nil {
5891
return
5992
}
60-
for k, v := range res {
61-
var item = v.(gin.H)
62-
var content = convert.MustString(item["content"])
63-
var jsonItemList = []gin.H{}
64-
for _, i := range strings.Split(content, "\n") {
65-
var jsonItem gin.H
66-
if er := jsoniter.Unmarshal([]byte(i), &jsonItem); er == nil {
67-
jsonItemList = append(jsonItemList, jsonItem)
68-
}
93+
res = make([]interface{}, 0)
94+
for _, strItem := range strings.Split(string(bytes), "\n") {
95+
var resItem gin.H
96+
if jsoniter.Unmarshal([]byte(strItem), &resItem) == nil {
97+
res = append(res, resItem)
6998
}
70-
res[k] = jsonItemList
7199
}
72100
return
73101
}

0 commit comments

Comments
 (0)