Skip to content

Commit 24db9a8

Browse files
committed
Add: One-click functionality to check the availability of the current cache
1 parent ff4fb6d commit 24db9a8

File tree

5 files changed

+160
-2
lines changed

5 files changed

+160
-2
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Rankings do not differentiate priority levels.
3737
2. Completing unit test code
3838
3. Security-related features, such as encrypting configuration files, hiding sensitive information from plain text display, and switching to interactive password input
3939
4. Support for key-based authentication
40-
5. One-click functionality to check the availability of the current cache
4140

4241
## Quick Start
4342

README_zh.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
2. 完成单元测试代码
3838
3. 安全相关功能,配置文件加密、隐藏明文显示的敏感信息、密码输入应改为交互式等
3939
4. 支持秘钥登陆
40-
5. 一键检查当前缓存是否可用功能
4140

4241
## 快速开始
4342

cmd/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/Driver-C/tryssh/cmd/create"
66
"github.com/Driver-C/tryssh/cmd/delete"
77
"github.com/Driver-C/tryssh/cmd/get"
8+
"github.com/Driver-C/tryssh/cmd/prune"
89
"github.com/Driver-C/tryssh/cmd/scp"
910
"github.com/Driver-C/tryssh/cmd/ssh"
1011
"github.com/Driver-C/tryssh/cmd/version"
@@ -24,6 +25,7 @@ func NewTrysshCommand() *cobra.Command {
2425
rootCmd.AddCommand(create.NewCreateCommand())
2526
rootCmd.AddCommand(delete.NewDeleteCommand())
2627
rootCmd.AddCommand(get.NewGetCommand())
28+
rootCmd.AddCommand(prune.NewPruneCommand())
2729
rootCmd.CompletionOptions.DisableDefaultCmd = true
2830
return rootCmd
2931
}

cmd/prune/prune.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package prune
2+
3+
import (
4+
"github.com/Driver-C/tryssh/config"
5+
"github.com/Driver-C/tryssh/control/prune"
6+
"github.com/spf13/cobra"
7+
"time"
8+
)
9+
10+
const (
11+
concurrency = 8
12+
sshTimeout = 2 * time.Second
13+
)
14+
15+
func NewPruneCommand() *cobra.Command {
16+
pruneCmd := &cobra.Command{
17+
Use: "prune",
18+
Short: "Check if all current caches are available and clear the ones that are not available",
19+
Long: "Check if all current caches are available and clear the ones that are not available",
20+
Run: func(cmd *cobra.Command, args []string) {
21+
auto, _ := cmd.Flags().GetBool("auto")
22+
concurrencyOpt, _ := cmd.Flags().GetInt("concurrency")
23+
timeout, _ := cmd.Flags().GetDuration("timeout")
24+
configuration := config.LoadConfig()
25+
pruneControl := prune.NewPruneController(configuration, auto, timeout, concurrencyOpt)
26+
pruneControl.PruneCaches()
27+
},
28+
}
29+
pruneCmd.Flags().BoolP(
30+
"auto", "a", false, "Automatically perform concurrent cache optimization without"+
31+
" asking for confirmation to delete")
32+
pruneCmd.Flags().IntP(
33+
"concurrency", "c", concurrency, "Number of multiple requests to perform at a time")
34+
pruneCmd.Flags().DurationP("timeout", "t", sshTimeout,
35+
"SSH timeout when attempting to log in. It can be \"1s\" or \"1m\" or other duration")
36+
return pruneCmd
37+
}

control/prune/prune.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package prune
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"github.com/Driver-C/tryssh/config"
7+
"github.com/Driver-C/tryssh/launcher"
8+
"github.com/Driver-C/tryssh/launcher/ssh"
9+
"github.com/Driver-C/tryssh/utils"
10+
"os"
11+
"strings"
12+
"sync"
13+
"time"
14+
)
15+
16+
type Controller struct {
17+
configuration *config.MainConfig
18+
auto bool
19+
sshTimeout time.Duration
20+
concurrency int
21+
}
22+
23+
func (pc *Controller) PruneCaches() {
24+
newServerList := make([]config.ServerListConfig, 0)
25+
if pc.auto {
26+
newServerList = pc.concurrencyDeleteCache()
27+
} else {
28+
for _, server := range pc.configuration.ServerLists {
29+
lan := &ssh.Launcher{SshConnector: *launcher.GetSshConnectorFromConfig(&server)}
30+
// Set timeout
31+
lan.SshTimeout = pc.sshTimeout
32+
// Determine if connection is possible
33+
if err := lan.TryToConnect(); err != nil {
34+
if !pc.interactiveDeleteCache(server) {
35+
newServerList = append(newServerList, server)
36+
}
37+
} else {
38+
utils.Logger.Infof("Cache %v is still available.", server)
39+
newServerList = append(newServerList, server)
40+
}
41+
}
42+
}
43+
pc.configuration.ServerLists = newServerList
44+
if config.UpdateConfig(pc.configuration) {
45+
utils.Logger.Infoln("Update config successful.")
46+
} else {
47+
utils.Logger.Errorln("Update config failed.")
48+
}
49+
}
50+
51+
func (pc *Controller) interactiveDeleteCache(server config.ServerListConfig) bool {
52+
reader := bufio.NewReader(os.Stdin)
53+
for {
54+
fmt.Printf("Are you sure you want to delete this cache? "+
55+
"Please enter \"yes\" to confirm deletion, or \"no\" to cancel. %s\n"+
56+
"(yes/no): ", server)
57+
stdin, _ := reader.ReadString('\n')
58+
// Delete space
59+
stdin = strings.TrimSpace(stdin)
60+
switch stdin {
61+
case "yes":
62+
utils.Logger.Infof("The cache %v has been marked for deletion.", server)
63+
return true
64+
case "no":
65+
utils.Logger.Infof("Cache %v skipped.", server)
66+
return false
67+
default:
68+
utils.Logger.Errorln("Input error:", stdin)
69+
}
70+
}
71+
}
72+
73+
func (pc *Controller) concurrencyDeleteCache() []config.ServerListConfig {
74+
newServerList := make([]config.ServerListConfig, 0)
75+
launchersChan := make(chan *ssh.Launcher)
76+
var mutex sync.Mutex
77+
var wg sync.WaitGroup
78+
79+
go func(launchersChan chan<- *ssh.Launcher) {
80+
for _, server := range pc.configuration.ServerLists {
81+
lan := &ssh.Launcher{SshConnector: *launcher.GetSshConnectorFromConfig(&server)}
82+
launchersChan <- lan
83+
}
84+
close(launchersChan)
85+
}(launchersChan)
86+
87+
for i := 0; i < pc.concurrency; i++ {
88+
wg.Add(1)
89+
go func(launchersChan <-chan *ssh.Launcher, wg *sync.WaitGroup) {
90+
defer wg.Done()
91+
for {
92+
launcherP, ok := <-launchersChan
93+
if !ok {
94+
break
95+
}
96+
server := launcher.GetConfigFromSshConnector(&launcherP.SshConnector)
97+
launcherP.SshTimeout = pc.sshTimeout
98+
if err := launcherP.TryToConnect(); err == nil {
99+
utils.Logger.Infof("Cache %v is still available.", server)
100+
mutex.Lock()
101+
newServerList = append(newServerList, *server)
102+
mutex.Unlock()
103+
} else {
104+
utils.Logger.Infof("The cache %v has been marked for deletion.", server)
105+
}
106+
}
107+
}(launchersChan, &wg)
108+
}
109+
wg.Wait()
110+
return newServerList
111+
}
112+
113+
func NewPruneController(configuration *config.MainConfig, auto bool, timeout time.Duration,
114+
concurrency int) *Controller {
115+
return &Controller{
116+
configuration: configuration,
117+
auto: auto,
118+
sshTimeout: timeout,
119+
concurrency: concurrency,
120+
}
121+
}

0 commit comments

Comments
 (0)