fix: SSH client execution compatible with controller (#10854)

This commit is contained in:
ssongliu 2025-11-04 15:36:18 +08:00 committed by GitHub
parent 6982396572
commit 7ea179c2da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 80 additions and 39 deletions

View file

@ -23,17 +23,17 @@ type Controller interface {
} }
func New() (Controller, error) { func New() (Controller, error) {
managerOptions := []string{"systemd", "openrc", "sysvinit"} managerOptions := []string{"systemctl", "rc-service", "service"}
for _, item := range managerOptions { for _, item := range managerOptions {
if _, err := exec.LookPath(item); err != nil { if _, err := exec.LookPath(item); err != nil {
continue continue
} }
switch item { switch item {
case "systemd": case "systemctl":
return manager.NewSystemd(), nil return manager.NewSystemd(), nil
case "openrc": case "rc-service":
return manager.NewOpenrc(), nil return manager.NewOpenrc(), nil
case "sysvinit": case "service":
return manager.NewSysvinit(), nil return manager.NewSysvinit(), nil
} }
} }
@ -182,8 +182,8 @@ func loadFromPredefined(mgr Controller, keyword string) string {
"fail2ban": {"fail2ban.service", "fail2ban"}, "fail2ban": {"fail2ban.service", "fail2ban"},
"supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"}, "supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"},
"ssh": {"sshd.service", "ssh.service", "sshd", "ssh"}, "ssh": {"sshd.service", "ssh.service", "sshd", "ssh"},
"1panel-core": {"1panel-core.service", "1panel-cored"}, "1panel-core": {"1panel-core.service"},
"1panel-agent": {"1panel-agent.service", "1panel-agentd"}, "1panel-agent": {"1panel-agent.service"},
"docker": {"docker.service", "dockerd"}, "docker": {"docker.service", "dockerd"},
} }
if val, ok := predefinedMap[keyword]; ok { if val, ok := predefinedMap[keyword]; ok {

View file

@ -8,6 +8,7 @@ import (
"github.com/1Panel-dev/1Panel/core/global" "github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/controller/manager" "github.com/1Panel-dev/1Panel/core/utils/controller/manager"
"github.com/1Panel-dev/1Panel/core/utils/ssh"
) )
type Controller interface { type Controller interface {
@ -23,23 +24,48 @@ type Controller interface {
} }
func New() (Controller, error) { func New() (Controller, error) {
managerOptions := []string{"systemd", "openrc", "sysvinit"} managerOptions := []string{"systemctl", "rc-service", "service"}
for _, item := range managerOptions { for _, item := range managerOptions {
if _, err := exec.LookPath(item); err != nil { if _, err := exec.LookPath(item); err != nil {
continue continue
} }
switch item { switch item {
case "systemd": case "systemctl":
return manager.NewSystemd(), nil return manager.NewSystemd(), nil
case "openrc": case "rc-service":
return manager.NewOpenrc(), nil return manager.NewOpenrc(), nil
case "sysvinit": case "service":
return manager.NewSysvinit(), nil return manager.NewSysvinit(), nil
} }
} }
return nil, errors.New("not support such manager initializatio") return nil, errors.New("not support such manager initializatio")
} }
func NewWithClient(client *ssh.SSHClient) (Controller, error) {
managerOptions := []string{"systemctl", "rc-service", "service"}
for _, item := range managerOptions {
stdout, err := client.Runf("which %s", item)
if err != nil || (len(strings.ReplaceAll(stdout, "\n", "")) == 0) {
continue
}
switch item {
case "systemctl":
mgr := manager.NewSystemd()
mgr.Client = client
return mgr, nil
case "rc-service":
mgr := manager.NewOpenrc()
mgr.Client = client
return mgr, nil
case "service":
mgr := manager.NewSysvinit()
mgr.Client = client
return mgr, nil
}
}
return nil, errors.New("not support such manager initializatio")
}
func Handle(operate, serviceName string) error { func Handle(operate, serviceName string) error {
service, err := LoadServiceName(serviceName) service, err := LoadServiceName(serviceName)
if err != nil { if err != nil {
@ -149,7 +175,7 @@ func LoadServiceName(keyword string) (string, error) {
} }
processedName := loadProcessedName(client.Name(), keyword) processedName := loadProcessedName(client.Name(), keyword)
exist, err := client.IsExist(processedName) exist, _ := client.IsExist(processedName)
if exist { if exist {
return processedName, nil return processedName, nil
} }
@ -182,8 +208,8 @@ func loadFromPredefined(mgr Controller, keyword string) string {
"fail2ban": {"fail2ban.service", "fail2ban"}, "fail2ban": {"fail2ban.service", "fail2ban"},
"supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"}, "supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"},
"ssh": {"sshd.service", "ssh.service", "sshd", "ssh"}, "ssh": {"sshd.service", "ssh.service", "sshd", "ssh"},
"1panel-core": {"1panel-core.service", "1panel-cored"}, "1panel-core": {"1panel-core.service"},
"1panel-agent": {"1panel-agent.service", "1panel-agentd"}, "1panel-agent": {"1panel-agent.service"},
"docker": {"docker.service", "dockerd"}, "docker": {"docker.service", "dockerd"},
} }
if val, ok := predefinedMap[keyword]; ok { if val, ok := predefinedMap[keyword]; ok {

View file

@ -7,6 +7,7 @@ import (
"github.com/1Panel-dev/1Panel/core/global" "github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/cmd" "github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/ssh"
) )
func handlerErr(out string, err error) error { func handlerErr(out string, err error) error {
@ -19,7 +20,10 @@ func handlerErr(out string, err error) error {
return nil return nil
} }
func run(name string, args ...string) (string, error) { func run(client *ssh.SSHClient, name string, args ...string) (string, error) {
global.LOG.Debugf("handle with controller `%s %s`", name, strings.Join(args, " ")) global.LOG.Debugf("handle with controller `%s %s`", name, strings.Join(args, " "))
if client == nil {
return cmd.NewCommandMgr(cmd.WithTimeout(10*time.Second)).RunWithStdoutBashCf("LANGUAGE=en_US:en %s %s", name, strings.Join(args, " ")) return cmd.NewCommandMgr(cmd.WithTimeout(10*time.Second)).RunWithStdoutBashCf("LANGUAGE=en_US:en %s %s", name, strings.Join(args, " "))
}
return client.Runf("LANGUAGE=en_US:en %s %s", name, strings.Join(args, " "))
} }

View file

@ -6,9 +6,13 @@ import (
"path/filepath" "path/filepath"
"github.com/1Panel-dev/1Panel/core/utils/cmd" "github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/ssh"
) )
type Openrc struct{ toolCmd string } type Openrc struct {
toolCmd string
Client *ssh.SSHClient
}
func NewOpenrc() *Openrc { func NewOpenrc() *Openrc {
return &Openrc{toolCmd: "rc-service"} return &Openrc{toolCmd: "rc-service"}
@ -32,8 +36,7 @@ func (s *Openrc) IsEnable(serviceName string) (bool, error) {
return out == "enabled\n", nil return out == "enabled\n", nil
} }
func (s *Openrc) IsExist(serviceName string) (bool, error) { func (s *Openrc) IsExist(serviceName string) (bool, error) {
_, err := os.Stat(filepath.Join("/etc/init.d", serviceName)) if _, err := os.Stat(filepath.Join("/etc/init.d", serviceName)); err != nil {
if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil return false, nil
} }
@ -42,17 +45,17 @@ func (s *Openrc) IsExist(serviceName string) (bool, error) {
return true, nil return true, nil
} }
func (s *Openrc) Status(serviceName string) (string, error) { func (s *Openrc) Status(serviceName string) (string, error) {
return run(s.toolCmd, serviceName, "status") return run(s.Client, s.toolCmd, serviceName, "status")
} }
func (s *Openrc) Operate(operate, serviceName string) error { func (s *Openrc) Operate(operate, serviceName string) error {
switch operate { switch operate {
case "enable": case "enable":
return handlerErr(run("rc-update", "add", serviceName, "default")) return handlerErr(run(s.Client, "rc-update", "add", serviceName, "default"))
case "disable": case "disable":
return handlerErr(run("rc-update", "del", serviceName, "default")) return handlerErr(run(s.Client, "rc-update", "del", serviceName, "default"))
default: default:
return handlerErr(run(s.toolCmd, serviceName, operate)) return handlerErr(run(s.Client, s.toolCmd, serviceName, operate))
} }
} }

View file

@ -11,7 +11,7 @@ func NewSnap() *Snap {
} }
func (s *Snap) IsExist(serviceName string) bool { func (s *Snap) IsExist(serviceName string) bool {
out, err := run(s.toolCmd, "services") out, err := run(nil, s.toolCmd, "services")
if err != nil { if err != nil {
return false return false
} }
@ -19,7 +19,7 @@ func (s *Snap) IsExist(serviceName string) bool {
} }
func (s *Snap) IsActive(serviceName string) bool { func (s *Snap) IsActive(serviceName string) bool {
out, err := run(s.toolCmd, "services") out, err := run(nil, s.toolCmd, "services")
if err != nil { if err != nil {
return false return false
} }
@ -33,7 +33,7 @@ func (s *Snap) IsActive(serviceName string) bool {
} }
func (s *Snap) IsEnable(serviceName string) bool { func (s *Snap) IsEnable(serviceName string) bool {
out, err := run(s.toolCmd, "services") out, err := run(nil, s.toolCmd, "services")
if err != nil { if err != nil {
return false return false
} }
@ -48,7 +48,7 @@ func (s *Snap) IsEnable(serviceName string) bool {
func (s *Snap) Operate(operate, serviceName string) error { func (s *Snap) Operate(operate, serviceName string) error {
if s.IsExist(serviceName) { if s.IsExist(serviceName) {
return handlerErr(run(s.toolCmd, operate, serviceName)) return handlerErr(run(nil, s.toolCmd, operate, serviceName))
} }
return nil return nil
} }

View file

@ -2,9 +2,14 @@ package manager
import ( import (
"strings" "strings"
"github.com/1Panel-dev/1Panel/core/utils/ssh"
) )
type Systemd struct{ toolCmd string } type Systemd struct {
toolCmd string
Client *ssh.SSHClient
}
func NewSystemd() *Systemd { func NewSystemd() *Systemd {
return &Systemd{toolCmd: "systemctl"} return &Systemd{toolCmd: "systemctl"}
@ -14,7 +19,7 @@ func (s *Systemd) Name() string {
return "systemd" return "systemd"
} }
func (s *Systemd) IsActive(serviceName string) (bool, error) { func (s *Systemd) IsActive(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-active", serviceName) out, err := run(s.Client, s.toolCmd, "is-active", serviceName)
if err != nil && out != "inactive\n" { if err != nil && out != "inactive\n" {
if NewSnap().IsActive(serviceName) { if NewSnap().IsActive(serviceName) {
return true, nil return true, nil
@ -25,7 +30,7 @@ func (s *Systemd) IsActive(serviceName string) (bool, error) {
} }
func (s *Systemd) IsEnable(serviceName string) (bool, error) { func (s *Systemd) IsEnable(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-enabled", serviceName) out, err := run(s.Client, s.toolCmd, "is-enabled", serviceName)
if err != nil && out != "disabled\n" { if err != nil && out != "disabled\n" {
if serviceName == "sshd" && out == "alias\n" { if serviceName == "sshd" && out == "alias\n" {
return s.IsEnable("ssh") return s.IsEnable("ssh")
@ -39,7 +44,7 @@ func (s *Systemd) IsEnable(serviceName string) (bool, error) {
} }
func (s *Systemd) IsExist(serviceName string) (bool, error) { func (s *Systemd) IsExist(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-enabled", serviceName) out, err := run(s.Client, s.toolCmd, "is-enabled", serviceName)
if err != nil && out != "enabled\n" { if err != nil && out != "enabled\n" {
if strings.Contains(out, "disabled") { if strings.Contains(out, "disabled") {
return true, err return true, err
@ -53,10 +58,10 @@ func (s *Systemd) IsExist(serviceName string) (bool, error) {
} }
func (s *Systemd) Status(serviceName string) (string, error) { func (s *Systemd) Status(serviceName string) (string, error) {
return run(s.toolCmd, "status", serviceName) return run(s.Client, s.toolCmd, "status", serviceName)
} }
func (s *Systemd) Operate(operate, serviceName string) error { func (s *Systemd) Operate(operate, serviceName string) error {
out, err := run(s.toolCmd, operate, serviceName) out, err := run(s.Client, s.toolCmd, operate, serviceName)
if err != nil { if err != nil {
if serviceName == "sshd" && strings.Contains(out, "alias name or linked unit file") { if serviceName == "sshd" && strings.Contains(out, "alias name or linked unit file") {
return s.Operate(operate, "ssh") return s.Operate(operate, "ssh")
@ -64,12 +69,12 @@ func (s *Systemd) Operate(operate, serviceName string) error {
if err := NewSnap().Operate(operate, serviceName); err == nil { if err := NewSnap().Operate(operate, serviceName); err == nil {
return nil return nil
} }
return handlerErr(run(s.toolCmd, operate, serviceName)) return handlerErr(run(s.Client, s.toolCmd, operate, serviceName))
} }
return nil return nil
} }
func (s *Systemd) Reload() error { func (s *Systemd) Reload() error {
out, err := run(s.toolCmd, "daemon-reload") out, err := run(s.Client, s.toolCmd, "daemon-reload")
return handlerErr(out, err) return handlerErr(out, err)
} }

View file

@ -6,9 +6,13 @@ import (
"path/filepath" "path/filepath"
"github.com/1Panel-dev/1Panel/core/utils/cmd" "github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/ssh"
) )
type Sysvinit struct{ toolCmd string } type Sysvinit struct {
toolCmd string
Client *ssh.SSHClient
}
func NewSysvinit() *Sysvinit { func NewSysvinit() *Sysvinit {
return &Sysvinit{toolCmd: "service"} return &Sysvinit{toolCmd: "service"}
@ -32,8 +36,7 @@ func (s *Sysvinit) IsEnable(serviceName string) (bool, error) {
return out == "enabled\n", nil return out == "enabled\n", nil
} }
func (s *Sysvinit) IsExist(serviceName string) (bool, error) { func (s *Sysvinit) IsExist(serviceName string) (bool, error) {
_, err := os.Stat(filepath.Join("/etc/init.d", serviceName)) if _, err := os.Stat(filepath.Join("/etc/init.d", serviceName)); err != nil {
if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil return false, nil
} }
@ -42,11 +45,11 @@ func (s *Sysvinit) IsExist(serviceName string) (bool, error) {
return true, nil return true, nil
} }
func (s *Sysvinit) Status(serviceName string) (string, error) { func (s *Sysvinit) Status(serviceName string) (string, error) {
return run(s.toolCmd, serviceName, "status") return run(s.Client, s.toolCmd, serviceName, "status")
} }
func (s *Sysvinit) Operate(operate, serviceName string) error { func (s *Sysvinit) Operate(operate, serviceName string) error {
return handlerErr(run(s.toolCmd, serviceName, operate)) return handlerErr(run(s.Client, s.toolCmd, serviceName, operate))
} }
func (s *Sysvinit) Reload() error { func (s *Sysvinit) Reload() error {