remote.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package nginx
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/astaxie/beego/logs"
  6. "github.com/pkg/sftp"
  7. "golang.org/x/crypto/ssh"
  8. "io"
  9. "net"
  10. "nginx-ui/server/models"
  11. "os"
  12. "time"
  13. )
  14. // RemoteInstance 远程
  15. type RemoteInstance struct {
  16. nginx *models.Nginx
  17. client *ssh.Client
  18. LastResult string
  19. }
  20. func (n *RemoteInstance) Connect() error {
  21. if n.client != nil {
  22. return nil
  23. }
  24. config := ssh.ClientConfig{}
  25. config.SetDefaults()
  26. config.User = n.nginx.User
  27. config.Auth = []ssh.AuthMethod{
  28. ssh.Password(n.nginx.Password),
  29. }
  30. config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  31. return nil
  32. }
  33. config.Timeout = time.Second * 60
  34. addr := fmt.Sprintf("%s:%d", n.nginx.IpAddr, n.nginx.Port)
  35. client, err := ssh.Dial("tcp", addr, &config)
  36. if err != nil {
  37. logs.Warn("connect error", err)
  38. return err
  39. }
  40. n.client = client
  41. go n.onDisConnect()
  42. return nil
  43. }
  44. // Run RemoteInstance 这里应该要处理session断开的流程吧
  45. func (n *RemoteInstance) Run(cmd string) (string, error) {
  46. logs.Info("Run: ", cmd)
  47. if n.client == nil {
  48. err := n.Connect()
  49. if err != nil {
  50. return "", err
  51. }
  52. }
  53. session, err := n.client.NewSession()
  54. if err != nil {
  55. logs.Warn("NewSession fail", err)
  56. return "", err
  57. }
  58. defer session.Close()
  59. buf, err := session.CombinedOutput(cmd)
  60. n.LastResult = string(buf)
  61. logger.Printf("out: %v", n.LastResult)
  62. if err != nil {
  63. err = errors.New(fmt.Sprintf("%s;\n%s", err.Error(), n.LastResult))
  64. }
  65. return n.LastResult, err
  66. }
  67. func (n *RemoteInstance) Close(onlySession bool) {
  68. if onlySession {
  69. return
  70. }
  71. if n.client != nil {
  72. n.client.Close()
  73. n.client = nil
  74. }
  75. }
  76. func (n *RemoteInstance) onDisConnect() {
  77. if n.client != nil {
  78. err := n.client.Wait()
  79. logger.Printf("disconnect", err)
  80. }
  81. n.client = nil
  82. }
  83. func (n *RemoteInstance) SetNginx(nginx *models.Nginx) {
  84. n.nginx = nginx
  85. }
  86. func (n *RemoteInstance) getSSHConfig() ssh.ClientConfig {
  87. config := ssh.ClientConfig{}
  88. config.SetDefaults()
  89. config.User = n.nginx.User
  90. config.Auth = []ssh.AuthMethod{
  91. ssh.Password(n.nginx.Password),
  92. }
  93. config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  94. return nil
  95. }
  96. config.Timeout = time.Second * 60
  97. return config
  98. }
  99. // SendFile RemoteInstance 这里应该要处理session断开的流程吧
  100. func (n *RemoteInstance) SendFile(src string, remote string) error {
  101. session, err := sftp.NewClient(n.client)
  102. if err != nil {
  103. return err
  104. }
  105. defer session.Close()
  106. srcFile, err := os.Open(src)
  107. if err != nil {
  108. return err
  109. }
  110. defer srcFile.Close()
  111. dstFile, err := session.Create(remote)
  112. if err != nil {
  113. return err
  114. }
  115. defer dstFile.Close()
  116. l, err := io.Copy(dstFile, srcFile)
  117. logs.Info("sendFile ok with size: ", l)
  118. return err
  119. }