Skip to content

Commit 1d80813

Browse files
committed
添加server操作
1 parent cc653f1 commit 1d80813

File tree

7 files changed

+435
-13
lines changed

7 files changed

+435
-13
lines changed

cmd/mysqlNew.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,5 @@ func toFile(name string) {
144144

145145
func isExists(name string) bool {
146146
_, err := os.Stat(name)
147-
if os.IsNotExist(err) {
148-
return false
149-
}
150-
return true
147+
return !os.IsNotExist(err)
151148
}

cmd/server.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright © 2023 hxoreyer
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in
12+
all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.
21+
*/
22+
package cmd
23+
24+
import (
25+
"fmt"
26+
27+
"github.com/hxoreyer/ktool/ctl"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
// serverCmd represents the server command
32+
var serverCmd = &cobra.Command{
33+
Use: "server",
34+
Short: "操作server",
35+
Long: `可以向server发起上传下载等命令`,
36+
Run: func(cmd *cobra.Command, args []string) {
37+
path, err := cmd.Flags().GetString("path")
38+
if err != nil {
39+
fmt.Println(err)
40+
return
41+
}
42+
if !isExists(path) {
43+
fmt.Println(path, "is not exist.")
44+
return
45+
}
46+
c := ctl.NewYaml(path)
47+
c.Run()
48+
},
49+
}
50+
51+
func init() {
52+
rootCmd.AddCommand(serverCmd)
53+
54+
serverCmd.Flags().StringP("path", "p", "./server.yaml", "服务器配置")
55+
}

ctl/bar.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package ctl
2+
3+
import "fmt"
4+
5+
type KBar struct {
6+
percent int64 //百分比
7+
cur int64 //当前进度位置
8+
total int64 //总进度
9+
rate string //进度条
10+
graph string //显示符号
11+
text string //后缀内容
12+
}
13+
14+
func (bar *KBar) New(start, total int64, text string) {
15+
bar.cur = start
16+
bar.total = total
17+
bar.text = text
18+
if bar.graph == "" {
19+
bar.graph = "█"
20+
}
21+
bar.percent = bar.getPercent()
22+
for i := 0; i < int(bar.percent); i += 2 {
23+
bar.rate += bar.graph //初始化进度条位置
24+
}
25+
}
26+
27+
func (bar *KBar) Play(cur int64) {
28+
bar.cur = cur
29+
last := bar.percent
30+
bar.percent = bar.getPercent()
31+
if bar.percent != last && bar.percent%2 == 0 {
32+
for i := 0; i < int(bar.percent-last)/2; i++ {
33+
bar.rate += bar.graph
34+
}
35+
} else {
36+
bar.percent = last
37+
}
38+
fmt.Printf("\r [%-51s]%3d%% %8d/%-10d[%-s]", bar.rate, bar.percent, bar.cur, bar.total, bar.text)
39+
}
40+
41+
func (bar *KBar) getPercent() int64 {
42+
pc := int64(float32(bar.cur) / float32(bar.total) * 100)
43+
return pc
44+
}
45+
46+
func (bar *KBar) NewWithGraph(start, total int64, graph string, text string) {
47+
bar.graph = graph
48+
bar.New(start, total, text)
49+
}
50+
51+
func (bar *KBar) Finish() {
52+
fmt.Println()
53+
}

ctl/clientConfig.go

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package ctl
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io/ioutil"
7+
"log"
8+
"net"
9+
"os"
10+
"os/exec"
11+
"os/signal"
12+
"path"
13+
"sync"
14+
"time"
15+
16+
"github.com/pkg/sftp"
17+
"golang.org/x/crypto/ssh"
18+
)
19+
20+
const (
21+
Windows = "windows"
22+
Linux = "linux"
23+
Macos = "darwin"
24+
)
25+
26+
type ClientConfig struct {
27+
Host string
28+
Port string
29+
Username string
30+
Password string
31+
sshClient *ssh.Client
32+
sftpClient *sftp.Client
33+
LastResult string
34+
}
35+
36+
func CreateClient(host string, port string, username, password string) *ClientConfig {
37+
cf := &ClientConfig{}
38+
var (
39+
sshClient *ssh.Client
40+
sftpClient *sftp.Client
41+
err error
42+
)
43+
44+
cf.Host = host
45+
cf.Port = port
46+
cf.Username = username
47+
cf.Password = password
48+
49+
config := ssh.ClientConfig{
50+
User: cf.Username,
51+
Auth: []ssh.AuthMethod{ssh.Password(cf.Password)},
52+
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
53+
return nil
54+
},
55+
Timeout: 10 * time.Second,
56+
}
57+
58+
addr := fmt.Sprintf("%s:%s", cf.Host, cf.Port)
59+
60+
if sshClient, err = ssh.Dial("tcp", addr, &config); err != nil {
61+
log.Fatalf("connect ssh error: %s", err.Error())
62+
return nil
63+
}
64+
65+
cf.sshClient = sshClient
66+
67+
if sftpClient, err = sftp.NewClient(sshClient); err != nil {
68+
log.Fatalf("connect sftp error: %s", err.Error())
69+
return nil
70+
}
71+
72+
cf.sftpClient = sftpClient
73+
return cf
74+
}
75+
76+
func (cf *ClientConfig) RunShell(shell string) string {
77+
var (
78+
session *ssh.Session
79+
err error
80+
)
81+
82+
if session, err = cf.sshClient.NewSession(); err != nil {
83+
log.Fatalf("new session error: %s", err.Error())
84+
}
85+
defer session.Close()
86+
87+
var output bytes.Buffer
88+
session.Stdout = &output
89+
go func() {
90+
var tmp string
91+
for {
92+
tmp = output.String()
93+
if cf.LastResult != tmp {
94+
cmd := exec.Command("cmd", "/C", "cls")
95+
cmd.Stdout = os.Stdout
96+
cmd.Run()
97+
fmt.Println(tmp)
98+
cf.LastResult = tmp
99+
}
100+
}
101+
}()
102+
if err := session.Run(shell); err != nil {
103+
fmt.Println(shell)
104+
log.Fatalf("run shell error: %s", err.Error())
105+
} else {
106+
cf.LastResult = output.String()
107+
}
108+
return cf.LastResult
109+
}
110+
111+
func (cf *ClientConfig) Upload(srcPath, dstPath string) {
112+
fmt.Println("searching...")
113+
s, err := os.Stat(srcPath)
114+
if err != nil {
115+
panic(err)
116+
}
117+
if s.IsDir() {
118+
cf.uploadDirectory(srcPath, dstPath)
119+
} else {
120+
cf.uploadFile(srcPath, dstPath)
121+
}
122+
}
123+
124+
func (cf *ClientConfig) uploadDirectory(srcPath, dstPath string) {
125+
126+
localFiles, err := ioutil.ReadDir(srcPath)
127+
if err != nil {
128+
panic(err)
129+
}
130+
cf.sftpClient.Mkdir(dstPath)
131+
132+
for _, backupDir := range localFiles {
133+
localFilePath := path.Join(srcPath, backupDir.Name())
134+
remoteFilePath := path.Join(dstPath, backupDir.Name())
135+
136+
if backupDir.IsDir() {
137+
cf.sftpClient.Mkdir(remoteFilePath)
138+
cf.uploadDirectory(localFilePath, remoteFilePath)
139+
} else {
140+
cf.uploadFile(localFilePath, remoteFilePath)
141+
}
142+
}
143+
}
144+
145+
func (cf *ClientConfig) uploadFile(srcPath, dstPath string) {
146+
srcFile, err := os.Open(srcPath)
147+
if err != nil {
148+
panic("os.Open error : " + err.Error() + srcPath)
149+
}
150+
151+
defer srcFile.Close()
152+
153+
dstFile, err := cf.sftpClient.Create(dstPath)
154+
if err != nil {
155+
panic("sftpClient.Create error : " + err.Error())
156+
157+
}
158+
159+
defer dstFile.Close()
160+
ff, err := ioutil.ReadAll(srcFile)
161+
if err != nil {
162+
panic("ReadAll error : " + err.Error())
163+
}
164+
wg := sync.WaitGroup{}
165+
wg.Add(1)
166+
go func() {
167+
stat, _ := dstFile.Stat()
168+
state2, _ := srcFile.Stat()
169+
bar := KBar{}
170+
bar.New(stat.Size(), state2.Size(), dstFile.Name())
171+
for {
172+
stat, _ := dstFile.Stat()
173+
if stat.Size() < state2.Size() {
174+
bar.Play(stat.Size())
175+
time.Sleep(time.Duration(100 * time.Millisecond))
176+
} else {
177+
bar.Play(stat.Size())
178+
bar.Finish()
179+
break
180+
}
181+
}
182+
wg.Done()
183+
}()
184+
dstFile.Write(ff)
185+
dstFile.Chmod(0777)
186+
wg.Wait()
187+
188+
}
189+
190+
func (cf *ClientConfig) Download(srcPath, dstPath string) {
191+
srcFile, _ := cf.sftpClient.Open(srcPath)
192+
dstFile, _ := os.Create(dstPath)
193+
194+
defer func() {
195+
_ = srcFile.Close()
196+
_ = dstFile.Close()
197+
}()
198+
199+
if _, err := srcFile.WriteTo(dstFile); err != nil {
200+
log.Fatalf("download erroe: %s", err.Error())
201+
}
202+
203+
fmt.Println("download success")
204+
}
205+
206+
func (cf *ClientConfig) waitForQuit() {
207+
c := make(chan os.Signal)
208+
signal.Notify(c, os.Interrupt, os.Kill)
209+
<-c
210+
}
211+
212+
func BuildExec(path, system, name string) {
213+
var cmdStr string
214+
if system == Windows {
215+
cmdStr = fmt.Sprintf("cd %s&SET CGO_ENABLED=0&SET GOOS=%s&SET GOARCH=amd64&go build %s", path, system, name)
216+
} else {
217+
cmdStr = fmt.Sprintf("cd %s&CGO_ENABLED=0&GOOS=%s&GOARCH=amd64&go build %s", path, system, name)
218+
}
219+
cmd := exec.Command("cmd", "/C", cmdStr)
220+
_ = cmd.Run()
221+
}
222+
223+
func (cf *ClientConfig) Run(procName string) {
224+
defer func() {
225+
pid := cf.RunShell(fmt.Sprintf("pgrep %s", path.Base(procName)))
226+
cf.RunShell(fmt.Sprintf("kill %s", pid))
227+
}()
228+
go cf.RunShell(procName)
229+
cf.waitForQuit()
230+
}

0 commit comments

Comments
 (0)