feat: compatible with openrc and sysvinit (#10723)

This commit is contained in:
ssongliu
2025-10-22 18:32:42 +08:00
committed by GitHub
parent f462591e9c
commit c06ba18023
50 changed files with 1310 additions and 687 deletions
+25
View File
@@ -0,0 +1,25 @@
package manager
import (
"errors"
"strings"
"time"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/cmd"
)
func handlerErr(out string, err error) error {
if err != nil {
if out != "" {
return errors.New(out)
}
return err
}
return nil
}
func run(name string, args ...string) (string, error) {
global.LOG.Debugf("handle with controller `%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, " "))
}
+61
View File
@@ -0,0 +1,61 @@
package manager
import (
"fmt"
"os"
"path/filepath"
"github.com/1Panel-dev/1Panel/core/utils/cmd"
)
type Openrc struct{ toolCmd string }
func NewOpenrc() *Openrc {
return &Openrc{toolCmd: "rc-service"}
}
func (s *Openrc) Name() string {
return "openrc"
}
func (s *Openrc) IsActive(serviceName string) (bool, error) {
out, err := cmd.RunDefaultWithStdoutBashCf("if service %s status >/dev/null 2>&1; then echo 'active'; else echo 'inactive'; fi", serviceName)
if err != nil {
return false, err
}
return out == "active\n", nil
}
func (s *Openrc) IsEnable(serviceName string) (bool, error) {
out, err := cmd.RunDefaultWithStdoutBashCf("if ls /etc/rc*.d/S*%s >/dev/null 2>&1; then echo 'enabled'; else echo 'disabled'; fi", serviceName)
if err != nil {
return false, err
}
return out == "enabled\n", nil
}
func (s *Openrc) IsExist(serviceName string) (bool, error) {
_, err := os.Stat(filepath.Join("/etc/init.d", serviceName))
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, fmt.Errorf("stat /etc/init.d/%s failed: %w", serviceName, err)
}
return true, nil
}
func (s *Openrc) Status(serviceName string) (string, error) {
return run(s.toolCmd, serviceName, "status")
}
func (s *Openrc) Operate(operate, serviceName string) error {
switch operate {
case "enable":
return handlerErr(run("rc-update", "add", serviceName, "default"))
case "disable":
return handlerErr(run("rc-update", "del", serviceName, "default"))
default:
return handlerErr(run(s.toolCmd, serviceName, operate))
}
}
func (s *Openrc) Reload() error {
return nil
}
+54
View File
@@ -0,0 +1,54 @@
package manager
import (
"strings"
)
type Snap struct{ toolCmd string }
func NewSnap() *Snap {
return &Snap{toolCmd: "snap"}
}
func (s *Snap) IsExist(serviceName string) bool {
out, err := run(s.toolCmd, "services")
if err != nil {
return false
}
return strings.Contains(out, serviceName)
}
func (s *Snap) IsActive(serviceName string) bool {
out, err := run(s.toolCmd, "services")
if err != nil {
return false
}
lines := strings.Split(out, "\n")
for _, line := range lines {
if strings.Contains(line, serviceName) && strings.Contains(line, "active") {
return true
}
}
return false
}
func (s *Snap) IsEnable(serviceName string) bool {
out, err := run(s.toolCmd, "services")
if err != nil {
return false
}
lines := strings.Split(out, "\n")
for _, line := range lines {
if strings.Contains(line, serviceName) && strings.Contains(line, "enabled") {
return true
}
}
return false
}
func (s *Snap) Operate(operate, serviceName string) error {
if s.IsExist(serviceName) {
return handlerErr(run(s.toolCmd, operate, serviceName))
}
return nil
}
+75
View File
@@ -0,0 +1,75 @@
package manager
import (
"strings"
)
type Systemd struct{ toolCmd string }
func NewSystemd() *Systemd {
return &Systemd{toolCmd: "systemctl"}
}
func (s *Systemd) Name() string {
return "systemd"
}
func (s *Systemd) IsActive(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-active", serviceName)
if err != nil && out != "inactive\n" {
if NewSnap().IsActive(serviceName) {
return true, nil
}
return false, err
}
return out == "active\n", nil
}
func (s *Systemd) IsEnable(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-enabled", serviceName)
if err != nil && out != "disabled\n" {
if serviceName == "sshd" && out == "alias\n" {
return s.IsEnable("ssh")
}
if NewSnap().IsEnable(serviceName) {
return true, nil
}
return false, err
}
return out == "enabled\n", nil
}
func (s *Systemd) IsExist(serviceName string) (bool, error) {
out, err := run(s.toolCmd, "is-enabled", serviceName)
if err != nil && out != "enabled\n" {
if strings.Contains(out, "disabled") {
return true, err
}
if NewSnap().IsExist(serviceName) {
return true, nil
}
return false, err
}
return true, err
}
func (s *Systemd) Status(serviceName string) (string, error) {
return run(s.toolCmd, "status", serviceName)
}
func (s *Systemd) Operate(operate, serviceName string) error {
out, err := run(s.toolCmd, operate, serviceName)
if err != nil {
if serviceName == "sshd" && strings.Contains(out, "alias name or linked unit file") {
return s.Operate(operate, "ssh")
}
if err := NewSnap().Operate(operate, serviceName); err == nil {
return nil
}
return handlerErr(run(s.toolCmd, operate, serviceName))
}
return nil
}
func (s *Systemd) Reload() error {
out, err := run(s.toolCmd, "daemon-reload")
return handlerErr(out, err)
}
+54
View File
@@ -0,0 +1,54 @@
package manager
import (
"fmt"
"os"
"path/filepath"
"github.com/1Panel-dev/1Panel/core/utils/cmd"
)
type Sysvinit struct{ toolCmd string }
func NewSysvinit() *Sysvinit {
return &Sysvinit{toolCmd: "service"}
}
func (s *Sysvinit) Name() string {
return "sysvinit"
}
func (s *Sysvinit) IsActive(serviceName string) (bool, error) {
out, err := cmd.RunDefaultWithStdoutBashCf("if service %s status >/dev/null 2>&1; then echo 'active'; else echo 'inactive'; fi", serviceName)
if err != nil {
return false, err
}
return out == "active\n", nil
}
func (s *Sysvinit) IsEnable(serviceName string) (bool, error) {
out, err := cmd.RunDefaultWithStdoutBashCf("if ls /etc/rc*.d/S*%s >/dev/null 2>&1; then echo 'enabled'; else echo 'disabled'; fi", serviceName)
if err != nil {
return false, err
}
return out == "enabled\n", nil
}
func (s *Sysvinit) IsExist(serviceName string) (bool, error) {
_, err := os.Stat(filepath.Join("/etc/init.d", serviceName))
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, fmt.Errorf("stat /etc/init.d/%s failed: %w", serviceName, err)
}
return true, nil
}
func (s *Sysvinit) Status(serviceName string) (string, error) {
return run(s.toolCmd, serviceName, "status")
}
func (s *Sysvinit) Operate(operate, serviceName string) error {
return handlerErr(run(s.toolCmd, serviceName, operate))
}
func (s *Sysvinit) Reload() error {
return nil
}