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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 1310 additions and 687 deletions

View file

@ -134,9 +134,8 @@ func (u *AIToolService) Close(name string) error {
if err != nil {
return err
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec %s ollama stop %s", containerName, name)
if err != nil {
return fmt.Errorf("handle ollama stop %s failed, stdout: %s, err: %v", name, stdout, err)
if err := cmd.RunDefaultBashCf("docker exec %s ollama stop %s", containerName, name); err != nil {
return fmt.Errorf("handle ollama stop %s failed, %v", name, err)
}
return nil
}
@ -193,9 +192,8 @@ func (u *AIToolService) Delete(req dto.ForceDelete) error {
}
for _, item := range ollamaList {
if item.Status != constant.StatusDeleted {
stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec %s ollama rm %s", containerName, item.Name)
if err != nil && !req.ForceDelete {
return fmt.Errorf("handle ollama rm %s failed, stdout: %s, err: %v", item.Name, stdout, err)
if err := cmd.RunDefaultBashCf("docker exec %s ollama rm %s", containerName, item.Name); err != nil && !req.ForceDelete {
return fmt.Errorf("handle ollama rm %s failed, %v", item.Name, err)
}
}
_ = aiRepo.Delete(repo.WithByID(item.ID))

View file

@ -1082,11 +1082,7 @@ func runScript(task *task.Task, appInstall *model.AppInstall, operate string) er
task.LogStart(logStr)
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute), cmd.WithWorkDir(workDir))
out, err := cmdMgr.RunWithStdoutBashC(scriptPath)
if err != nil {
if out != "" {
err = errors.New(out)
}
if err := cmdMgr.RunBashC(scriptPath); err != nil {
task.LogFailedWithErr(logStr, err)
return err
}

View file

@ -19,7 +19,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/compose"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/pkg/errors"
)
func (u *BackupService) RedisBackup(req dto.CommonBackup) error {
@ -98,9 +97,8 @@ func handleRedisBackup(redisInfo *repo.RootInfo, parentTask *task.Task, recordID
}
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec %s redis-cli -a %s --no-auth-warning save", redisInfo.ContainerName, redisInfo.Password)
if err != nil {
return errors.New(string(stdout))
if err := cmd.RunDefaultBashCf("docker exec %s redis-cli -a %s --no-auth-warning save", redisInfo.ContainerName, redisInfo.Password); err != nil {
return err
}
if strings.HasSuffix(fileName, ".tar.gz") {
@ -111,16 +109,14 @@ func handleRedisBackup(redisInfo *repo.RootInfo, parentTask *task.Task, recordID
return nil
}
if strings.HasSuffix(fileName, ".aof") {
stdout1, err := cmd.RunDefaultWithStdoutBashCf("docker cp %s:/data/appendonly.aof %s/%s", redisInfo.ContainerName, backupDir, fileName)
if err != nil {
return errors.New(stdout1)
if err := cmd.RunDefaultBashCf("docker cp %s:/data/appendonly.aof %s/%s", redisInfo.ContainerName, backupDir, fileName); err != nil {
return err
}
return nil
}
stdout1, err1 := cmd.RunDefaultWithStdoutBashCf("docker cp %s:/data/dump.rdb %s/%s", redisInfo.ContainerName, backupDir, fileName)
if err1 != nil {
return errors.New(stdout1)
if err := cmd.RunDefaultBashCf("docker cp %s:/data/dump.rdb %s/%s", redisInfo.ContainerName, backupDir, fileName); err != nil {
return err
}
return nil
}

View file

@ -16,7 +16,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/compose"
"github.com/pkg/errors"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/model"
@ -179,9 +178,8 @@ func handleWebsiteRecover(website *model.Website, parentTask *task.Task, recover
if err = fileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), GetOpenrestyDir(SitesRootDir), ""); err != nil {
return err
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
if err != nil {
return errors.New(stdout)
if err := cmd.RunDefaultBashCf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName); err != nil {
return err
}
oldWebsite.ID = website.ID
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {

View file

@ -21,14 +21,15 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/clam"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
"github.com/jinzhu/copier"
"github.com/robfig/cron/v3"
)
type ClamService struct {
serviceName string
serviceName string
freshClamService string
}
type IClamService interface {
@ -56,23 +57,31 @@ func (c *ClamService) LoadBaseInfo() (dto.ClamBaseInfo, error) {
var baseInfo dto.ClamBaseInfo
baseInfo.Version = "-"
baseInfo.FreshVersion = "-"
exist1, _ := systemctl.IsExist(constant.ClamServiceNameCentOs)
if exist1 {
c.serviceName = constant.ClamServiceNameCentOs
baseInfo.IsExist = true
baseInfo.IsActive, _ = systemctl.IsActive(constant.ClamServiceNameCentOs)
clamSvc, err := controller.LoadServiceName("clam")
if err != nil {
baseInfo.IsExist = false
return baseInfo, nil
}
exist2, _ := systemctl.IsExist(constant.ClamServiceNameUbuntu)
if exist2 {
c.serviceName = constant.ClamServiceNameUbuntu
c.serviceName = clamSvc
exist, _ := controller.CheckExist(clamSvc)
if exist {
baseInfo.IsExist = true
baseInfo.IsActive, _ = systemctl.IsActive(constant.ClamServiceNameUbuntu)
baseInfo.IsActive, _ = controller.CheckActive(clamSvc)
}
freshExist, _ := systemctl.IsExist(constant.FreshClamService)
freshSvc, err := controller.LoadServiceName("freshclam")
if err != nil {
baseInfo.FreshIsExist = false
return baseInfo, nil
}
c.freshClamService = freshSvc
freshExist, _ := controller.CheckExist(freshSvc)
if freshExist {
baseInfo.FreshIsExist = true
baseInfo.FreshIsActive, _ = systemctl.IsActive(constant.FreshClamService)
baseInfo.FreshIsActive, _ = controller.CheckActive(freshSvc)
}
if !cmd.Which("clamdscan") {
baseInfo.IsActive = false
}
@ -87,7 +96,7 @@ func (c *ClamService) LoadBaseInfo() (dto.ClamBaseInfo, error) {
}
}
} else {
_ = clam.CheckClamIsActive(false, clamRepo)
_ = clam.StopAllClamJob(false, clamRepo)
}
if baseInfo.FreshIsActive {
version, err := cmd.RunDefaultWithStdoutBashC("freshclam --version")
@ -105,15 +114,13 @@ func (c *ClamService) LoadBaseInfo() (dto.ClamBaseInfo, error) {
func (c *ClamService) Operate(operate string) error {
switch operate {
case "start", "restart", "stop":
stdout, err := cmd.RunDefaultWithStdoutBashCf("systemctl %s %s", operate, c.serviceName)
if err != nil {
return fmt.Errorf("%s the %s failed, err: %s", operate, c.serviceName, stdout)
if err := controller.Handle(operate, c.serviceName); err != nil {
return fmt.Errorf("%s the %s failed, err: %s", operate, c.serviceName, err)
}
return nil
case "fresh-start", "fresh-restart", "fresh-stop":
stdout, err := cmd.RunDefaultWithStdoutBashCf("systemctl %s %s", strings.TrimPrefix(operate, "fresh-"), constant.FreshClamService)
if err != nil {
return fmt.Errorf("%s the %s failed, err: %s", operate, c.serviceName, stdout)
if err := controller.Handle(strings.TrimPrefix(operate, "fresh-"), c.freshClamService); err != nil {
return fmt.Errorf("%s the %s failed, err: %s", operate, c.serviceName, err)
}
return nil
default:
@ -306,7 +313,7 @@ func (c *ClamService) Delete(req dto.ClamDelete) error {
}
func (c *ClamService) HandleOnce(id uint) error {
if active := clam.CheckClamIsActive(true, clamRepo); !active {
if active := clam.StopAllClamJob(true, clamRepo); !active {
return buserr.New("ErrClamdscanNotFound")
}
clamItem, _ := clamRepo.Get(repo.WithByID(id))
@ -379,37 +386,13 @@ func (c *ClamService) LoadFile(req dto.ClamFileReq) (string, error) {
filePath := ""
switch req.Name {
case "clamd":
if c.serviceName == constant.ClamServiceNameUbuntu {
filePath = "/etc/clamav/clamd.conf"
} else {
filePath = "/etc/clamd.d/scan.conf"
}
filePath = c.loadConfigPath("clamd")
case "clamd-log":
filePath = c.loadLogPath("clamd-log")
if len(filePath) != 0 {
break
}
if c.serviceName == constant.ClamServiceNameUbuntu {
filePath = "/var/log/clamav/clamav.log"
} else {
filePath = "/var/log/clamd.scan"
}
case "freshclam":
if c.serviceName == constant.ClamServiceNameUbuntu {
filePath = "/etc/clamav/freshclam.conf"
} else {
filePath = "/etc/freshclam.conf"
}
filePath = c.loadConfigPath("freshclam")
case "freshclam-log":
filePath = c.loadLogPath("freshclam-log")
if len(filePath) != 0 {
break
}
if c.serviceName == constant.ClamServiceNameUbuntu {
filePath = "/var/log/clamav/freshclam.log"
} else {
filePath = "/var/log/freshclam.log"
}
default:
return "", fmt.Errorf("not support such type")
}
@ -432,23 +415,11 @@ func (c *ClamService) LoadFile(req dto.ClamFileReq) (string, error) {
func (c *ClamService) UpdateFile(req dto.UpdateByNameAndFile) error {
filePath := ""
service := ""
switch req.Name {
case "clamd":
if c.serviceName == constant.ClamServiceNameUbuntu {
service = constant.ClamServiceNameUbuntu
filePath = "/etc/clamav/clamd.conf"
} else {
service = constant.ClamServiceNameCentOs
filePath = "/etc/clamd.d/scan.conf"
}
filePath = c.loadConfigPath("clamd")
case "freshclam":
if c.serviceName == constant.ClamServiceNameUbuntu {
filePath = "/etc/clamav/freshclam.conf"
} else {
filePath = "/etc/freshclam.conf"
}
service = "clamav-freshclam.service"
filePath = c.loadConfigPath("freshclam")
default:
return fmt.Errorf("not support such type")
}
@ -461,50 +432,65 @@ func (c *ClamService) UpdateFile(req dto.UpdateByNameAndFile) error {
_, _ = write.WriteString(req.File)
write.Flush()
_ = systemctl.Restart(service)
_ = controller.HandleRestart(c.serviceName)
return nil
}
func (c *ClamService) loadLogPath(name string) string {
confPath := ""
if name == "clamd-log" {
if c.serviceName == constant.ClamServiceNameUbuntu {
confPath = "/etc/clamav/clamd.conf"
} else {
confPath = "/etc/clamd.d/scan.conf"
}
} else {
if c.serviceName == constant.ClamServiceNameUbuntu {
confPath = "/etc/clamav/freshclam.conf"
} else {
confPath = "/etc/freshclam.conf"
}
}
if _, err := os.Stat(confPath); err != nil {
return ""
configKey := "clamd"
searchPrefix := "LogFile "
if name != "clamd-log" {
configKey = "freshclam"
searchPrefix = "UpdateLogFile "
}
confPath := c.loadConfigPath(configKey)
content, err := os.ReadFile(confPath)
if err != nil {
global.LOG.Debugf("read config of %s failed, err: %v", configKey, err)
return ""
}
lines := strings.Split(string(content), "\n")
if name == "clamd-log" {
for _, line := range lines {
if strings.HasPrefix(line, "LogFile ") {
return strings.Trim(strings.ReplaceAll(line, "LogFile ", ""), " ")
}
}
} else {
for _, line := range lines {
if strings.HasPrefix(line, "UpdateLogFile ") {
return strings.Trim(strings.ReplaceAll(line, "UpdateLogFile ", ""), " ")
}
for _, line := range lines {
if strings.HasPrefix(line, searchPrefix) {
return strings.Trim(strings.ReplaceAll(line, searchPrefix, ""), " ")
}
}
if configKey == "clamd" {
if _, err := os.Stat("/var/log/clamav/clamav.log"); err == nil {
return "/var/log/clamav/clamav.log"
}
if _, err := os.Stat("/var/log/clamd.scan"); err == nil {
return "/var/log/clamd.scan"
}
}
if configKey == "freshclam" {
if _, err := os.Stat("/var/log/clamav/freshclam.log"); err == nil {
return "/var/log/clamav/freshclam.log"
}
if _, err := os.Stat("/var/log/freshclam.log"); err == nil {
return "/var/log/freshclam.log"
}
}
return ""
}
func (c *ClamService) loadConfigPath(confType string) string {
switch confType {
case "clamd":
if _, err := os.Stat("/etc/clamav/clamd.conf"); err == nil {
return "/etc/clamav/clamd.conf"
}
return "/etc/clamd.d/scan.conf"
case "freshclam":
if _, err := os.Stat("/etc/clamav/freshclam.conf"); err == nil {
return "/etc/clamav/freshclam.conf"
}
return "/etc/freshclam.conf"
default:
return ""
}
}
func handleAlert(infectedFiles, clamName string, clamId uint) {
itemInfected, _ := strconv.Atoi(strings.TrimSpace(infectedFiles))
if itemInfected < 0 {

View file

@ -21,6 +21,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/xpu"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/copier"
"github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v4/cpu"
@ -53,23 +54,25 @@ func NewIDashboardService() IDashboardService {
}
func (u *DashboardService) Restart(operation string) error {
if operation != "1panel" && operation != "system" && operation != "1panel-agent" {
switch operation {
case "system":
{
go func() {
if err := cmd.RunDefaultBashCf("%s reboot", cmd.SudoHandleCmd()); err != nil {
global.LOG.Errorf("handle reboot failed, %v", err)
}
}()
return nil
}
case "1panel-agent":
controller.RestartPanel(false, true, false)
return nil
case "1panel":
controller.RestartPanel(true, true, false)
return nil
default:
return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation)
}
itemCmd := fmt.Sprintf("%s systemctl restart 1panel-agent.service && %s systemctl restart 1panel-core.service", cmd.SudoHandleCmd(), cmd.SudoHandleCmd())
if operation == "system" {
itemCmd = fmt.Sprintf("%s reboot", cmd.SudoHandleCmd())
}
if operation == "1panel-agent" {
itemCmd = fmt.Sprintf("%s systemctl restart 1panel-agent.service", cmd.SudoHandleCmd())
}
go func() {
stdout, err := cmd.RunDefaultWithStdoutBashC(itemCmd)
if err != nil {
global.LOG.Errorf("handle %s failed, err: %v", itemCmd, stdout)
}
}()
return nil
}
func (u *DashboardService) LoadOsInfo() (*dto.OsInfo, error) {

View file

@ -2,7 +2,6 @@ package service
import (
"bufio"
"errors"
"fmt"
"net"
"os"
@ -19,6 +18,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/ntp"
"github.com/shirou/gopsutil/v4/mem"
)
@ -122,7 +122,7 @@ func (u *DeviceService) Update(key, value string) error {
if err := ntp.UpdateSystemTimeZone(value); err != nil {
return err
}
go common.RestartService(global.IsMaster, true, false)
go controller.RestartPanel(global.IsMaster, true, false)
case "DNS":
if err := updateDNS(strings.Split(value, ",")); err != nil {
return err
@ -131,9 +131,8 @@ func (u *DeviceService) Update(key, value string) error {
if cmd.CheckIllegal(value) {
return buserr.New("ErrCmdIllegal")
}
std, err := cmd.RunDefaultWithStdoutBashCf("%s hostnamectl set-hostname %s", cmd.SudoHandleCmd(), value)
if err != nil {
return errors.New(std)
if err := cmd.RunDefaultBashCf("%s hostnamectl set-hostname %s", cmd.SudoHandleCmd(), value); err != nil {
return err
}
case "Ntp", "LocalTime":
if cmd.CheckIllegal(value) {
@ -222,12 +221,11 @@ func (u *DeviceService) UpdatePasswd(req dto.ChangePasswd) error {
if cmd.CheckIllegal(req.User, req.Passwd) {
return buserr.New("ErrCmdIllegal")
}
std, err := cmd.RunDefaultWithStdoutBashCf("%s echo '%s:%s' | %s chpasswd", cmd.SudoHandleCmd(), req.User, req.Passwd, cmd.SudoHandleCmd())
if err != nil {
if err := cmd.RunDefaultBashCf("%s echo '%s:%s' | %s chpasswd", cmd.SudoHandleCmd(), req.User, req.Passwd, cmd.SudoHandleCmd()); err != nil {
if strings.Contains(err.Error(), "does not exist") {
return buserr.New("ErrNotExistUser")
}
return errors.New(std)
return err
}
return nil
}
@ -245,9 +243,8 @@ func (u *DeviceService) UpdateSwap(req dto.SwapHelper) error {
}
cmdMgr := cmd.NewCommandMgr(cmd.WithTask(*taskItem))
if !req.IsNew {
std, err := cmdMgr.RunWithStdoutBashCf("%s swapoff %s", cmd.SudoHandleCmd(), req.Path)
if err != nil {
return fmt.Errorf("handle swapoff %s failed, err: %s", req.Path, std)
if err := cmdMgr.RunBashCf("%s swapoff %s", cmd.SudoHandleCmd(), req.Path); err != nil {
return fmt.Errorf("handle swapoff %s failed, %v", req.Path)
}
}
if req.Size == 0 {
@ -257,27 +254,23 @@ func (u *DeviceService) UpdateSwap(req dto.SwapHelper) error {
return operateSwapWithFile(true, req)
}
taskItem.LogStart(i18n.GetMsgByKey("CreateSwap"))
stdDD, err := cmdMgr.RunWithStdoutBashCf("%s dd if=/dev/zero of=%s bs=1024 count=%d", cmd.SudoHandleCmd(), req.Path, req.Size)
if err != nil {
return fmt.Errorf("handle dd %s failed, std: %s, err: %s", req.Path, stdDD, err)
if err := cmdMgr.RunBashCf("%s dd if=/dev/zero of=%s bs=1024 count=%d", cmd.SudoHandleCmd(), req.Path, req.Size); err != nil {
return fmt.Errorf("handle dd %s failed, %v", req.Path, err)
}
taskItem.Log("chmod 0600 " + req.Path)
stdChmod, err := cmdMgr.RunWithStdoutBashCf("%s chmod 0600 %s", cmd.SudoHandleCmd(), req.Path)
if err != nil {
return fmt.Errorf("handle chmod 0600 %s failed,std: %s, err: %s", req.Path, stdChmod, err)
if err := cmdMgr.RunBashCf("%s chmod 0600 %s", cmd.SudoHandleCmd(), req.Path); err != nil {
return fmt.Errorf("handle chmod 0600 %s failed, %v", req.Path, err)
}
taskItem.LogStart(i18n.GetMsgByKey("FormatSwap"))
stdMkswap, err := cmdMgr.RunWithStdoutBashCf("%s mkswap -f %s", cmd.SudoHandleCmd(), req.Path)
if err != nil {
return fmt.Errorf("handle mkswap -f %s failed, std: %s, err: %s", req.Path, stdMkswap, err)
if err := cmdMgr.RunBashCf("%s mkswap -f %s", cmd.SudoHandleCmd(), req.Path); err != nil {
return fmt.Errorf("handle mkswap -f %s failed, %v", req.Path, err)
}
taskItem.LogStart(i18n.GetMsgByKey("EnableSwap"))
stdSwapon, err := cmdMgr.RunWithStdoutBashCf("%s swapon %s", cmd.SudoHandleCmd(), req.Path)
if err != nil {
_, _ = cmdMgr.RunWithStdoutBashCf("%s swapoff %s", cmd.SudoHandleCmd(), req.Path)
return fmt.Errorf("handle swapoff %s failed,std: %s, err: %s", req.Path, stdSwapon, err)
if err := cmdMgr.RunBashCf("%s swapon %s", cmd.SudoHandleCmd(), req.Path); err != nil {
_ = cmdMgr.RunBashCf("%s swapoff %s", cmd.SudoHandleCmd(), req.Path)
return fmt.Errorf("handle swapoff %s failed, %v", req.Path, err)
}
return operateSwapWithFile(false, req)
}, nil)

View file

@ -13,6 +13,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/build"
@ -260,7 +261,7 @@ func (u *DeviceService) Clean(req []dto.Clean) {
_ = settingRepo.Update("LastCleanData", fmt.Sprintf("%v", len(req)))
if restart {
go common.RestartService(false, true, false)
go controller.RestartPanel(false, true, false)
}
}

View file

@ -8,15 +8,13 @@ import (
"os"
"path"
"strings"
"time"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/pkg/errors"
)
type DockerService struct{}
@ -236,7 +234,9 @@ func (u *DockerService) UpdateConf(req dto.SettingUpdate, withRestart bool) erro
}
if withRestart {
return restartDocker()
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
}
return nil
}
@ -280,8 +280,8 @@ func (u *DockerService) UpdateLogOption(req dto.LogOption) error {
return err
}
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
return nil
}
@ -319,8 +319,8 @@ func (u *DockerService) UpdateIpv6Option(req dto.Ipv6Option) error {
return err
}
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
return nil
}
@ -343,25 +343,19 @@ func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
return err
}
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
return nil
}
func (u *DockerService) OperateDocker(req dto.DockerOperation) error {
service := "docker"
sudo := cmd.SudoHandleCmd()
dockerCmd, err := getDockerRestartCommand()
if err != nil {
return err
}
if req.Operation == "stop" {
isSocketActive, _ := systemctl.IsActive("docker.socket")
isSocketActive, _ := controller.CheckExist("docker.socket")
if isSocketActive {
std, err := cmd.RunDefaultWithStdoutBashCf("%s systemctl stop docker.socket", sudo)
if err != nil {
global.LOG.Errorf("handle systemctl stop docker.socket failed, err: %v", std)
if err := controller.HandleStop("docker.socket"); err != nil {
global.LOG.Errorf("handle stop docker.socket failed, err: %v", err)
}
}
}
@ -370,9 +364,8 @@ func (u *DockerService) OperateDocker(req dto.DockerOperation) error {
return err
}
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s %s %s ", dockerCmd, req.Operation, service)
if err != nil {
return errors.New(string(stdout))
if err := controller.Handle(req.Operation, service); err != nil {
return err
}
return nil
}
@ -435,32 +428,7 @@ func validateDockerConfig() error {
return nil
}
if err != nil || (stdout != "" && strings.TrimSpace(stdout) != "configuration OK") {
return fmt.Errorf("Docker configuration validation failed, err: %v", stdout)
}
return nil
}
func getDockerRestartCommand() (string, error) {
stdout, err := cmd.RunDefaultWithStdoutBashC("which docker")
if err != nil {
return "", fmt.Errorf("failed to find docker: %v", err)
}
dockerPath := stdout
if strings.Contains(dockerPath, "snap") {
return "snap", nil
}
return "systemctl", nil
}
func restartDocker() error {
global.LOG.Info("restart docker")
restartCmd, err := getDockerRestartCommand()
if err != nil {
return err
}
stdout, err := cmd.NewCommandMgr(cmd.WithTimeout(3*time.Minute)).RunWithStdoutBashCf("%s restart docker", restartCmd)
if err != nil {
return fmt.Errorf("failed to restart Docker: %s", stdout)
return fmt.Errorf("Docker configuration validation failed, %v", err)
}
return nil
}

View file

@ -16,6 +16,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/firewall"
fireClient "github.com/1Panel-dev/1Panel/agent/utils/firewall/client"
"github.com/jinzhu/copier"
@ -211,8 +212,8 @@ func (u *FirewallService) OperateFirewall(req dto.FirewallOperation) error {
return fmt.Errorf("not supported operation: %s", req.Operation)
}
if needRestartDocker && req.WithDockerRestart {
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
}
return nil
@ -624,9 +625,8 @@ func (u *FirewallService) updatePingStatus(enable string) error {
return err
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s sysctl -p", cmd.SudoHandleCmd())
if err != nil {
return fmt.Errorf("update ping status failed, err: %v", stdout)
if err := cmd.RunDefaultBashCf("%s sysctl -p", cmd.SudoHandleCmd()); err != nil {
return fmt.Errorf("update ping status failed, %v", err)
}
return nil

View file

@ -17,9 +17,9 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/ini_conf"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/pkg/errors"
"gopkg.in/ini.v1"
)
@ -52,9 +52,9 @@ func (h *HostToolService) GetToolStatus(req request.HostToolReq) (*response.Host
return res, nil
}
supervisorConfig.IsExist = true
serviceExist, _ := systemctl.IsExist(constant.Supervisord)
serviceExist, _ := controller.CheckExist(constant.Supervisord)
if !serviceExist {
serviceExist, _ = systemctl.IsExist(constant.Supervisor)
serviceExist, _ = controller.CheckExist(constant.Supervisor)
if !serviceExist {
supervisorConfig.IsExist = false
res.Config = supervisorConfig
@ -76,7 +76,7 @@ func (h *HostToolService) GetToolStatus(req request.HostToolReq) (*response.Host
_, ctlRrr := exec.LookPath("supervisorctl")
supervisorConfig.CtlExist = ctlRrr == nil
active, _ := systemctl.IsActive(supervisorConfig.ServiceName)
active, _ := controller.CheckActive(supervisorConfig.ServiceName)
if active {
supervisorConfig.Status = "running"
} else {
@ -193,7 +193,7 @@ func (h *HostToolService) CreateToolConfig(req request.HostToolCreate) error {
return err
}
}
if err = systemctl.Restart(req.ServiceName); err != nil {
if err = controller.HandleRestart(req.ServiceName); err != nil {
global.LOG.Errorf("[init] restart %s failed err %s", req.ServiceName, err.Error())
return err
}
@ -209,7 +209,7 @@ func (h *HostToolService) OperateTool(req request.HostToolReq) error {
serviceName = serviceNameSet.Value
}
}
return systemctl.Operate(req.Operate, serviceName)
return controller.Handle(req.Operate, serviceName)
}
func (h *HostToolService) OperateToolConfig(req request.HostToolConfig) (*response.HostToolConfig, error) {
@ -251,7 +251,7 @@ func (h *HostToolService) OperateToolConfig(req request.HostToolConfig) (*respon
if err = fileOp.WriteFile(configPath, strings.NewReader(req.Content), fileInfo.Mode()); err != nil {
return nil, err
}
if err = systemctl.Restart(serviceName); err != nil {
if err = controller.HandleRestart(serviceName); err != nil {
_ = fileOp.WriteFile(configPath, bytes.NewReader(oldContent), fileInfo.Mode())
return nil, err
}

View file

@ -16,6 +16,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
)
@ -134,7 +135,7 @@ func (u *ImageRepoService) Delete(req dto.OperateByID) error {
return err
}
go func() {
_ = restartDocker()
_ = controller.HandleRestart("docker")
}()
return nil
}
@ -262,8 +263,8 @@ func stopBeforeUpdateRepo() error {
if err := validateDockerConfig(); err != nil {
return err
}
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
@ -275,8 +276,8 @@ func stopBeforeUpdateRepo() error {
cancel()
return errors.New("the docker service cannot be restarted")
default:
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl is-active docker")
if string(stdout) == "active\n" && err == nil {
active, err := controller.CheckActive("docker")
if active && err != nil {
global.LOG.Info("docker restart with new conf successful!")
return nil
}

View file

@ -1,7 +1,6 @@
package service
import (
"errors"
"fmt"
"os"
"path"
@ -238,10 +237,6 @@ func getNginxParamsFromStaticFile(scope dto.NginxKey, newParams []dto.NginxParam
}
func opNginx(containerName, operate string) error {
var (
out string
err error
)
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(20 * time.Second))
cmdStr := fmt.Sprintf("docker exec -i %s nginx ", containerName)
if operate == constant.NginxCheck {
@ -249,11 +244,7 @@ func opNginx(containerName, operate string) error {
} else {
cmdStr = cmdStr + "-s reload"
}
out, err = cmdMgr.RunWithStdoutBashC(cmdStr)
if err != nil {
if out != "" {
return errors.New(out)
}
if err := cmdMgr.RunBashC(cmdStr); err != nil {
return err
}
return nil

View file

@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
fcgiclient "github.com/tomasen/fcgi_client"
"maps"
"os"
"os/exec"
@ -17,6 +16,8 @@ import (
"strings"
"time"
fcgiclient "github.com/tomasen/fcgi_client"
"github.com/1Panel-dev/1Panel/agent/app/task"
"github.com/1Panel-dev/1Panel/agent/cmd/server/nginx_conf"
"gopkg.in/ini.v1"
@ -679,9 +680,6 @@ func (r *RuntimeService) GetPHPExtensions(runtimeID uint) (response.PHPExtension
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(20 * time.Second))
out, err := cmdMgr.RunWithStdoutBashCf("docker exec -i %s php -m", runtime.ContainerName)
if err != nil {
if out != "" {
return res, errors.New(out)
}
return res, err
}
extensions := strings.Split(out, "\n")

View file

@ -23,7 +23,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/copier"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/pkg/errors"
"gorm.io/gorm"
)
@ -381,10 +380,9 @@ func snapAppImage(snap snapHelper, req dto.SnapshotCreate, targetDir string) err
if len(imageList) != 0 {
snap.Task.Log(strings.Join(imageList, " "))
snap.Task.Logf("docker save %s | gzip -c > %s", strings.Join(imageList, " "), path.Join(targetDir, "images.tar.gz"))
std, err := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute)).RunWithStdoutBashCf("docker save %s | gzip -c > %s", strings.Join(imageList, " "), path.Join(targetDir, "images.tar.gz"))
if err != nil {
snap.Task.LogFailedWithErr(i18n.GetMsgByKey("SnapDockerSave"), errors.New(std))
return errors.New(std)
if err := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute)).RunBashCf("docker save %s | gzip -c > %s", strings.Join(imageList, " "), path.Join(targetDir, "images.tar.gz")); err != nil {
snap.Task.LogFailedWithErr(i18n.GetMsgByKey("SnapDockerSave"), err)
return err
}
snap.Task.LogSuccess(i18n.GetMsgByKey("SnapDockerSave"))
} else {

View file

@ -17,7 +17,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/pkg/errors"
)
@ -226,7 +226,7 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
return
}
_ = os.RemoveAll(rootDir)
common.RestartService(true, true, true)
controller.RestartPanel(true, true, true)
}()
return nil
}
@ -352,10 +352,9 @@ func recoverAppData(src string, itemHelper *snapRecoverHelper) error {
itemHelper.Task.Log(i18n.GetMsgByKey("RecoverAppEmpty"))
return nil
}
std, err := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute)).RunWithStdoutBashCf("docker load < %s", path.Join(src, "images.tar.gz"))
if err != nil {
itemHelper.Task.LogFailedWithErr(i18n.GetMsgByKey("RecoverAppImage"), errors.New(std))
return fmt.Errorf("docker load images failed, err: %v", err)
if err := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute)).RunBashCf("docker load < %s", path.Join(src, "images.tar.gz")); err != nil {
itemHelper.Task.LogFailedWithErr(i18n.GetMsgByKey("RecoverAppImage"), err)
return fmt.Errorf("docker load images failed, %v", err)
}
itemHelper.Task.LogSuccess(i18n.GetMsgByKey("RecoverAppImage"))
return nil
@ -404,8 +403,8 @@ func recoverBaseData(src string, itemHelper *snapRecoverHelper) error {
}
}
if err := restartDocker(); err != nil {
return err
if err := controller.HandleRestart("docker"); err != nil {
return fmt.Errorf("failed to restart Docker: %v", err)
}
return nil
}
@ -435,9 +434,8 @@ func restartCompose(composePath string, itemHelper *snapRecoverHelper) error {
continue
}
upCmd := fmt.Sprintf("docker compose -f %s up -d", pathItem)
stdout, err := cmd.RunDefaultWithStdoutBashC(upCmd)
if err != nil {
itemHelper.Task.LogFailedWithErr(i18n.GetMsgByKey("RecoverCompose"), errors.New(stdout))
if err := cmd.RunDefaultBashC(upCmd); err != nil {
itemHelper.Task.LogFailedWithErr(i18n.GetMsgByKey("RecoverCompose"), err)
continue
}
itemHelper.Task.LogSuccess(i18n.GetWithName("RecoverComposeItem", pathItem))

View file

@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"net"
"os"
"os/user"
"path"
@ -13,6 +14,7 @@ import (
"strings"
"time"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/copier"
csvexport "github.com/1Panel-dev/1Panel/agent/utils/csv_export"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
@ -27,7 +29,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/pkg/errors"
)
@ -74,22 +75,18 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
data.IsExist = false
data.Message = err.Error()
} else {
active, err := systemctl.IsActive(serviceName)
active, err := controller.CheckActive(serviceName)
data.IsActive = active
if !active && err != nil {
data.Message = err.Error()
}
}
out, err := systemctl.RunSystemCtl("is-enabled", serviceName)
enable, err := controller.CheckEnable(serviceName)
if err != nil {
data.AutoStart = false
} else {
if out == "alias\n" {
data.AutoStart, _ = systemctl.IsEnable("ssh")
} else {
data.AutoStart = out == "enabled\n"
}
data.AutoStart = enable
}
sshConf, err := os.ReadFile(sshPath)
@ -139,29 +136,20 @@ func (u *SSHService) OperateSSH(operation string) error {
if err != nil {
return err
}
sudo := cmd.SudoHandleCmd()
if operation == "enable" || operation == "disable" {
serviceName += ".service"
}
if operation == "stop" {
isSocketActive, _ := systemctl.IsActive(serviceName + ".socket")
isSocketActive, _ := controller.CheckActive(serviceName + ".socket")
if isSocketActive {
std, err := cmd.RunDefaultWithStdoutBashCf("%s systemctl stop %s", sudo, serviceName+".socket")
if err != nil {
global.LOG.Errorf("handle systemctl stop %s.socket failed, err: %v", serviceName, std)
if err := controller.HandleStop(serviceName + ".socket"); err != nil {
global.LOG.Errorf("handle stop %s.socket failed, err: %v", serviceName, err)
}
}
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s systemctl %s %s", sudo, operation, serviceName)
if err != nil {
if strings.Contains(stdout, "alias name or linked unit file") {
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s systemctl %s ssh", sudo, operation)
if err != nil {
return fmt.Errorf("%s ssh(alias name or linked unit file) failed, stdout: %s, err: %v", operation, stdout, err)
}
}
return fmt.Errorf("%s %s failed, stdout: %s, err: %v", operation, serviceName, stdout, err)
if err := controller.Handle(operation, serviceName); err != nil {
return fmt.Errorf("%s %s failed, err: %v", operation, serviceName, err)
}
return nil
}
@ -190,7 +178,7 @@ func (u *SSHService) Update(req dto.SSHUpdate) error {
if req.Key == "Port" {
stdout, _ := cmd.RunDefaultWithStdoutBashCf("%s getenforce", sudo)
if stdout == "Enforcing\n" {
_, _ = cmd.RunDefaultWithStdoutBashCf("%s semanage port -a -t ssh_port_t -p tcp %s", sudo, req.NewValue)
_ = cmd.RunDefaultBashCf("%s semanage port -a -t ssh_port_t -p tcp %s", sudo, req.NewValue)
}
ruleItem := dto.PortRuleUpdate{
@ -220,7 +208,7 @@ func (u *SSHService) Update(req dto.SSHUpdate) error {
}
}
_, _ = cmd.RunDefaultWithStdoutBashCf("%s systemctl restart %s", sudo, serviceName)
_ = controller.HandleRestart(serviceName)
return nil
}
@ -306,15 +294,13 @@ func (u *SSHService) CreateRootCert(req dto.RootCertOperate) error {
if len(req.PassPhrase) != 0 {
command = fmt.Sprintf("ssh-keygen -t %s -P %s -f %s/.ssh/%s | echo y", req.EncryptionMode, req.PassPhrase, currentUser.HomeDir, req.Name)
}
stdout, err := cmd.RunDefaultWithStdoutBashC(command)
if err != nil {
return fmt.Errorf("generate failed, err: %v, message: %s", err, stdout)
if err := cmd.RunDefaultBashC(command); err != nil {
return fmt.Errorf("generate failed, %v", err)
}
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("cat %s >> %s", publicPath, authFilePath)
if err != nil {
return fmt.Errorf("generate failed, err: %v, message: %s", err, stdout)
if err := cmd.RunDefaultBashCf("cat %s >> %s", publicPath, authFilePath); err != nil {
return fmt.Errorf("generate failed, %v", err)
}
cert.PrivateKeyPath = privatePath
@ -599,8 +585,7 @@ func (u *SSHService) UpdateByFile(req dto.SettingUpdate) error {
if err != nil {
return err
}
sudo := cmd.SudoHandleCmd()
_, _ = cmd.RunDefaultWithStdoutBashCf("%s systemctl restart %s", sudo, serviceName)
_ = controller.HandleRestart(serviceName)
return nil
}
@ -772,24 +757,24 @@ func loadFailedSecureDatas(line string) dto.SSHHistory {
}
func checkIsStandard(item dto.SSHHistory) bool {
if len(item.Address) == 0 {
if len(item.Address) == 0 || net.ParseIP(item.Address) == nil {
return false
}
portItem, _ := strconv.Atoi(item.Port)
return portItem != 0
return portItem > 0 && portItem < 65536
}
func handleGunzip(path string) error {
if _, err := cmd.RunDefaultWithStdoutBashCf("gunzip %s", path); err != nil {
if err := cmd.RunDefaultBashCf("gunzip %s", path); err != nil {
return err
}
return nil
}
func loadServiceName() (string, error) {
if exist, _ := systemctl.IsExist("sshd"); exist {
if exist, _ := controller.CheckExist("sshd"); exist {
return "sshd", nil
} else if exist, _ := systemctl.IsExist("ssh"); exist {
} else if exist, _ := controller.CheckExist("ssh"); exist {
return "ssh", nil
}
return "", errors.New("The ssh or sshd service is unavailable")
@ -867,7 +852,7 @@ func updateLocalConn(newPort uint) error {
}
func updateSSHSocketFile(newPort string) error {
active, _ := systemctl.IsActive("ssh.socket")
active, _ := controller.CheckActive("ssh.socket")
if !active {
return nil
}
@ -898,6 +883,7 @@ func updateSSHSocketFile(newPort string) error {
if _, err = fileItem.WriteString(strings.Join(lines, "\n")); err != nil {
return err
}
_ = cmd.RunDefaultBashC("systemctl daemon-reload && systemctl restart ssh.socket")
_ = controller.Reload()
_ = controller.HandleRestart("ssh.socket")
return nil
}

View file

@ -1632,10 +1632,7 @@ func (w WebsiteService) UpdateSitePermission(req request.WebsiteUpdateDirPermiss
}
absoluteIndexPath := GetSitePath(website, SiteIndexDir)
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
if out, err := cmdMgr.RunWithStdoutBashCf("%s chown -R %s:%s %s", cmd.SudoHandleCmd(), req.User, req.Group, absoluteIndexPath); err != nil {
if out != "" {
return errors.New(out)
}
if err := cmdMgr.RunBashCf("%s chown -R %s:%s %s", cmd.SudoHandleCmd(), req.User, req.Group, absoluteIndexPath); err != nil {
return err
}
website.User = req.User

View file

@ -1032,8 +1032,7 @@ func checkIsLinkApp(website model.Website) bool {
func chownRootDir(path string) error {
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(1 * time.Second))
_, err := cmdMgr.RunWithStdoutBashCf(`chown -R 1000:1000 "%s"`, path)
if err != nil {
if err := cmdMgr.RunBashCf(`chown -R 1000:1000 "%s"`, path); err != nil {
return err
}
return nil

View file

@ -5,8 +5,4 @@ const (
Supervisor = "supervisor"
SupervisorConfigPath = "SupervisorConfigPath"
SupervisorServiceName = "SupervisorServiceName"
ClamServiceNameCentOs = "clamd@scan.service"
ClamServiceNameUbuntu = "clamav-daemon.service"
FreshClamService = "clamav-freshclam.service"
)

View file

@ -62,9 +62,8 @@ func initLang() {
downloadLangFromRemote(fileOp)
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("cp -r %s %s", path.Join(tmpPath, "lang"), "/usr/local/bin/")
if err != nil {
global.LOG.Errorf("load lang from package failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("cp -r %s %s", path.Join(tmpPath, "lang"), "/usr/local/bin/"); err != nil {
global.LOG.Errorf("load lang from package failed, %v", err)
return
}
global.LOG.Info("init lang successful")
@ -74,9 +73,8 @@ func initLang() {
downloadGeoFromRemote(fileOp, geoPath)
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("mkdir %s && cp %s %s/", path.Dir(geoPath), path.Join(tmpPath, "GeoIP.mmdb"), path.Dir(geoPath))
if err != nil {
global.LOG.Errorf("load geo ip from package failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("mkdir %s && cp %s %s/", path.Dir(geoPath), path.Join(tmpPath, "GeoIP.mmdb"), path.Dir(geoPath)); err != nil {
global.LOG.Errorf("load geo ip from package failed, %v", err)
return
}
global.LOG.Info("init geo ip successful")
@ -116,9 +114,8 @@ func downloadLangFromRemote(fileOp files.FileOp) {
global.LOG.Error("download lang.tar.gz failed, no such file")
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("tar zxvfC %s %s", "/usr/local/bin/lang.tar.gz", "/usr/local/bin/")
if err != nil {
fmt.Printf("decompress lang.tar.gz failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("tar zxvfC %s %s", "/usr/local/bin/lang.tar.gz", "/usr/local/bin/"); err != nil {
global.LOG.Errorf("decompress lang.tar.gz failed, %v", err)
return
}
_ = os.Remove("/usr/local/bin/lang.tar.gz")

View file

@ -26,7 +26,7 @@ func (n NvidiaSMI) LoadGpuInfo() (*common.GpuInfo, error) {
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(5 * time.Second))
itemData, err := cmdMgr.RunWithStdoutBashC("nvidia-smi -q -x")
if err != nil {
return nil, fmt.Errorf("calling nvidia-smi failed, err: %w", err)
return nil, fmt.Errorf("calling nvidia-smi failed, %v", err)
}
data := []byte(itemData)
version := "v11"

View file

@ -8,7 +8,7 @@ import (
"sync"
"time"
baseGlobal "github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
)
@ -45,31 +45,31 @@ func (x XpuSMI) loadDeviceData(device Device, wg *sync.WaitGroup, res *[]XPUSimp
wgCmd.Wait()
if xpuErr != nil {
baseGlobal.LOG.Errorf("calling xpu-smi discovery failed for device %d, err: %v\n", device.DeviceID, xpuErr)
global.LOG.Errorf("calling xpu-smi discovery failed for device %d, %v", device.DeviceID, xpuErr)
return
}
var info Device
if err := json.Unmarshal([]byte(xpuData), &info); err != nil {
baseGlobal.LOG.Errorf("xpuData json unmarshal failed for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("xpuData json unmarshal failed for device %d, err: %v", device.DeviceID, err)
return
}
bytes, err := strconv.ParseInt(info.MemoryPhysicalSizeByte, 10, 64)
if err != nil {
baseGlobal.LOG.Errorf("Error parsing memory size for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("Error parsing memory size for device %d, err: %v", device.DeviceID, err)
return
}
xpu.Memory = fmt.Sprintf("%.1f MB", float64(bytes)/(1024*1024))
if statsErr != nil {
baseGlobal.LOG.Errorf("calling xpu-smi stats failed for device %d, err: %v\n", device.DeviceID, statsErr)
global.LOG.Errorf("calling xpu-smi stats failed for device %d, err: %v", device.DeviceID, statsErr)
return
}
var stats DeviceStats
if err := json.Unmarshal([]byte(statsData), &stats); err != nil {
baseGlobal.LOG.Errorf("statsData json unmarshal failed for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("statsData json unmarshal failed for device %d, err: %v", device.DeviceID, err)
return
}
@ -95,7 +95,7 @@ func (x XpuSMI) LoadDashData() ([]XPUSimpleInfo, error) {
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(5 * time.Second))
data, err := cmdMgr.RunWithStdoutBashC("xpu-smi discovery -j")
if err != nil {
return nil, fmt.Errorf("calling xpu-smi failed, err: %w", err)
return nil, fmt.Errorf("calling xpu-smi failed, %v", err)
}
var deviceInfo DeviceInfo
@ -124,7 +124,7 @@ func (x XpuSMI) LoadGpuInfo() (*XpuInfo, error) {
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(5 * time.Second))
data, err := cmdMgr.RunWithStdoutBashC("xpu-smi discovery -j")
if err != nil {
return nil, fmt.Errorf("calling xpu-smi failed, err: %w", err)
return nil, fmt.Errorf("calling xpu-smi failed, %v", err)
}
var deviceInfo DeviceInfo
if err := json.Unmarshal([]byte(data), &deviceInfo); err != nil {
@ -146,7 +146,7 @@ func (x XpuSMI) LoadGpuInfo() (*XpuInfo, error) {
processData, err := cmdMgr.RunWithStdoutBashC("xpu-smi ps -j")
if err != nil {
return nil, fmt.Errorf("calling xpu-smi ps failed, err: %w", err)
return nil, fmt.Errorf("calling xpu-smi ps failed, %s", err)
}
var psList DeviceUtilByProcList
if err := json.Unmarshal([]byte(processData), &psList); err != nil {
@ -205,13 +205,13 @@ func (x XpuSMI) loadDeviceInfo(device Device, wg *sync.WaitGroup, res *XpuInfo,
wgCmd.Wait()
if xpuErr != nil {
baseGlobal.LOG.Errorf("calling xpu-smi discovery failed for device %d, err: %v\n", device.DeviceID, xpuErr)
global.LOG.Errorf("calling xpu-smi discovery failed for device %d, %v", device.DeviceID, xpuErr)
return
}
var info Device
if err := json.Unmarshal([]byte(xpuData), &info); err != nil {
baseGlobal.LOG.Errorf("xpuData json unmarshal failed for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("xpuData json unmarshal failed for device %d, err: %v", device.DeviceID, err)
return
}
@ -220,20 +220,20 @@ func (x XpuSMI) loadDeviceInfo(device Device, wg *sync.WaitGroup, res *XpuInfo,
bytes, err := strconv.ParseInt(info.MemoryPhysicalSizeByte, 10, 64)
if err != nil {
baseGlobal.LOG.Errorf("Error parsing memory size for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("Error parsing memory size for device %d, err: %v", device.DeviceID, err)
return
}
xpu.Basic.Memory = fmt.Sprintf("%.1f MB", float64(bytes)/(1024*1024))
xpu.Basic.FreeMemory = info.MemoryFreeSizeByte
if statsErr != nil {
baseGlobal.LOG.Errorf("calling xpu-smi stats failed for device %d, err: %v\n", device.DeviceID, statsErr)
global.LOG.Errorf("calling xpu-smi stats failed for device %d, err: %v", device.DeviceID, statsErr)
return
}
var stats DeviceStats
if err := json.Unmarshal([]byte(statsData), &stats); err != nil {
baseGlobal.LOG.Errorf("statsData json unmarshal failed for device %d, err: %v\n", device.DeviceID, err)
global.LOG.Errorf("statsData json unmarshal failed for device %d, err: %v", device.DeviceID, err)
return
}

View file

@ -14,7 +14,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/robfig/cron/v3"
)
@ -34,37 +34,13 @@ func AddScanTask(taskItem *task.Task, clam model.Clam, timeNow string) {
}
taskItem.Logf("clamdscan --fdpass %s %s", strategy, clam.Path)
mgr := cmd.NewCommandMgr(cmd.WithIgnoreExist1(), cmd.WithTimeout(time.Duration(clam.Timeout)*time.Second), cmd.WithTask(*taskItem))
stdout, err := mgr.RunWithStdoutBashCf("clamdscan --fdpass %s %s", strategy, clam.Path)
if err != nil {
return fmt.Errorf("clamdscan failed, stdout: %v, err: %v", stdout, err)
if err := mgr.RunBashCf("clamdscan --fdpass %s %s", strategy, clam.Path); err != nil {
return fmt.Errorf("clamdscan failed, %v", err)
}
return nil
}, nil)
}
func CheckClamIsActive(withCheck bool, clamRepo repo.IClamRepo) bool {
if withCheck {
isActive := false
exist1, _ := systemctl.IsExist(constant.ClamServiceNameCentOs)
if exist1 {
isActive, _ = systemctl.IsActive(constant.ClamServiceNameCentOs)
}
exist2, _ := systemctl.IsExist(constant.ClamServiceNameUbuntu)
if exist2 {
isActive, _ = systemctl.IsActive(constant.ClamServiceNameUbuntu)
}
if isActive {
return true
}
}
clams, _ := clamRepo.List(repo.WithByStatus(constant.StatusEnable))
for i := 0; i < len(clams); i++ {
global.Cron.Remove(cron.EntryID(clams[i].EntryID))
_ = clamRepo.Update(clams[i].ID, map[string]interface{}{"status": constant.StatusDisable, "entry_id": 0})
}
return false
}
func AnalysisFromLog(pathItem string, record *model.ClamRecord) {
file, err := os.ReadFile(pathItem)
if err != nil {
@ -86,3 +62,22 @@ func AnalysisFromLog(pathItem string, record *model.ClamRecord) {
}
}
}
func StopAllClamJob(withCheck bool, clamRepo repo.IClamRepo) bool {
if withCheck {
isActive := false
isexist, _ := controller.CheckExist("clam")
if isexist {
isActive, _ = controller.CheckActive("clam")
}
if isActive {
return false
}
}
clams, _ := clamRepo.List(repo.WithByStatus(constant.StatusEnable))
for i := 0; i < len(clams); i++ {
global.Cron.Remove(cron.EntryID(clams[i].EntryID))
_ = clamRepo.Update(clams[i].ID, map[string]interface{}{"status": constant.StatusDisable, "entry_id": 0})
}
return true
}

View file

@ -70,16 +70,14 @@ func (c *CommandHelper) RunBashCWithArgs(arg ...string) error {
}
func (c *CommandHelper) RunBashC(command string) error {
std, err := c.run("bash", "-c", command)
if err != nil {
return fmt.Errorf("handle failed, std: %s, err: %v", std, err)
if _, err := c.run("bash", "-c", command); err != nil {
return err
}
return nil
}
func (c *CommandHelper) RunBashCf(command string, arg ...interface{}) error {
std, err := c.run("bash", "-c", fmt.Sprintf(command, arg...))
if err != nil {
return fmt.Errorf("handle failed, std: %s, err: %v", std, err)
if _, err := c.run("bash", "-c", fmt.Sprintf(command, arg...)); err != nil {
return err
}
return nil
}
@ -237,16 +235,16 @@ func handleErr(stdout, stderr bytes.Buffer, ignoreExist1 bool, err error) (strin
}
}
}
errMsg := ""
if len(stderr.String()) != 0 {
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
outItem := stdout.String()
errItem := stderr.String()
if len(errItem) != 0 && len(outItem) != 0 {
return outItem, fmt.Errorf("stdout: %s; stderr: %s, err: %v", outItem, errItem, err)
}
if len(stdout.String()) != 0 {
if len(errMsg) != 0 {
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
} else {
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
}
if len(errItem) != 0 {
return outItem, fmt.Errorf("stderr: %s, err: %v", errItem, err)
}
return errMsg, err
if len(outItem) != 0 {
return outItem, fmt.Errorf("stdout: %s, err: %v", outItem, err)
}
return "", err
}

View file

@ -18,7 +18,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"golang.org/x/net/idna"
)
@ -398,28 +397,6 @@ func HandleIPList(content string) ([]string, error) {
return res, nil
}
func RestartService(core, agent, reload bool) {
command := ""
if reload {
command = "systemctl daemon-reload && "
}
switch {
case core && agent:
command += "systemctl restart 1panel-core.service && systemctl restart 1panel-agent.service"
case core:
command += "systemctl restart 1panel-core.service"
case agent:
command += "systemctl restart 1panel-agent.service"
default:
return
}
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(1 * time.Second))
std, err := cmdMgr.RunWithStdoutBashC(command)
if err != nil {
global.LOG.Errorf("restart 1panel service failed, err: %v, std: %s", err, std)
}
}
func GetSystemVersion(versionString string) string {
re := regexp.MustCompile(`v(\d+\.\d+\.\d+)`)
match := re.FindStringSubmatch(versionString)

View file

@ -0,0 +1,197 @@
package controller
import (
"errors"
"fmt"
"os/exec"
"strings"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/controller/manager"
)
type Controller interface {
Name() string
IsActive(serviceName string) (bool, error)
IsEnable(serviceName string) (bool, error)
IsExist(serviceName string) (bool, error)
Status(serviceName string) (string, error)
Operate(operate, serviceName string) error
Reload() error
}
func New() (Controller, error) {
managerOptions := []string{"systemd", "openrc", "sysvinit"}
for _, item := range managerOptions {
if _, err := exec.LookPath(item); err != nil {
continue
}
switch item {
case "systemd":
return manager.NewSystemd(), nil
case "openrc":
return manager.NewOpenrc(), nil
case "sysvinit":
return manager.NewSysvinit(), nil
}
}
return nil, errors.New("not support such manager initializatio")
}
func Handle(operate, serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
client, err := New()
if err != nil {
return err
}
return client.Operate(operate, service)
}
func HandleStart(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("start", service)
}
func HandleStop(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("stop", service)
}
func HandleRestart(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("restart", service)
}
func CheckExist(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
b, er := client.IsExist(service)
return b, er
}
func CheckActive(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
return client.IsActive(service)
}
func CheckEnable(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
return client.IsEnable(service)
}
func Reload() error {
client, err := New()
if err != nil {
return err
}
return client.Reload()
}
func RestartPanel(core, agent, reload bool) {
client, err := New()
if err != nil {
global.LOG.Errorf("load client for controller failed, err: %v", err)
return
}
if reload {
if err := client.Reload(); err != nil {
global.LOG.Errorf("restart 1panel service failed, err: %v", err)
return
}
}
if agent {
if err := client.Operate("restart", "1panel-agent"); err != nil {
global.LOG.Errorf("restart 1panel agent service failed, err: %v", err)
return
}
}
if core {
if err := client.Operate("restart", "1panel-core"); err != nil {
global.LOG.Errorf("restart 1panel core service failed, err: %v", err)
return
}
}
}
func LoadServiceName(keyword string) (string, error) {
client, err := New()
if err != nil {
return "", err
}
processedName := loadProcessedName(client.Name(), keyword)
exist, err := client.IsExist(processedName)
if exist {
return processedName, nil
}
alistName := loadFromPredefined(client, keyword)
if len(alistName) != 0 {
return alistName, nil
}
return "", fmt.Errorf("find such service for %s failed", keyword)
}
func loadProcessedName(mgr, keyword string) string {
keyword = strings.ToLower(keyword)
if strings.HasSuffix(keyword, ".service.socket") {
keyword = strings.TrimSuffix(keyword, ".service.socket") + ".socket"
}
if mgr != "systemd" {
keyword = strings.TrimSuffix(keyword, ".service")
return keyword
}
if !strings.HasSuffix(keyword, ".service") && !strings.HasSuffix(keyword, ".socket") {
keyword += ".service"
}
return keyword
}
func loadFromPredefined(mgr Controller, keyword string) string {
predefinedMap := map[string][]string{
"clam": {"clamav-daemon.service", "clamd@scan.service", "clamd"},
"freshclam": {"clamav-freshclam.service", "freshclam.service"},
"fail2ban": {"fail2ban.service", "fail2ban"},
"supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"},
"ssh": {"sshd.service", "ssh.service", "sshd", "ssh"},
"1panel-core": {"1panel-core.service", "1panel-cored"},
"1panel-agent": {"1panel-agent.service", "1panel-agentd"},
"docker": {"docker.service", "dockerd"},
}
if val, ok := predefinedMap[keyword]; ok {
for _, item := range val {
if exist, _ := mgr.IsExist(item); exist {
return item
}
}
}
return ""
}

View file

@ -0,0 +1,25 @@
package manager
import (
"errors"
"strings"
"time"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/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, " "))
}

View file

@ -0,0 +1,61 @@
package manager
import (
"fmt"
"os"
"path/filepath"
"github.com/1Panel-dev/1Panel/agent/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
}

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
}

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)
}

View file

@ -0,0 +1,54 @@
package manager
import (
"fmt"
"os"
"path/filepath"
"github.com/1Panel-dev/1Panel/agent/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
}

View file

@ -30,7 +30,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/mholt/archiver/v4"
"github.com/pkg/errors"
"github.com/spf13/afero"
)
@ -178,10 +177,7 @@ func (f FileOp) ChownR(dst string, uid string, gid string, sub bool) error {
cmdStr = fmt.Sprintf(`chown -R %s:%s "%s"`, uid, gid, dst)
}
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
if msg, err := cmdMgr.RunWithStdoutBashC(cmdStr); err != nil {
if msg != "" {
return errors.New(msg)
}
if err := cmdMgr.RunBashC(cmdStr); err != nil {
return err
}
return nil
@ -193,10 +189,7 @@ func (f FileOp) ChmodR(dst string, mode int64, sub bool) error {
cmdStr = fmt.Sprintf(`%s chmod -R %v "%s"`, cmd.SudoHandleCmd(), fmt.Sprintf("%04o", mode), dst)
}
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
if msg, err := cmdMgr.RunWithStdoutBashC(cmdStr); err != nil {
if msg != "" {
return errors.New(msg)
}
if err := cmdMgr.RunBashC(cmdStr); err != nil {
return err
}
return nil
@ -208,10 +201,7 @@ func (f FileOp) ChmodRWithMode(dst string, mode fs.FileMode, sub bool) error {
cmdStr = fmt.Sprintf(`%s chmod -R %v "%s"`, cmd.SudoHandleCmd(), fmt.Sprintf("%o", mode.Perm()), dst)
}
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
if msg, err := cmdMgr.RunWithStdoutBashC(cmdStr); err != nil {
if msg != "" {
return errors.New(msg)
}
if err := cmdMgr.RunBashC(cmdStr); err != nil {
return err
}
return nil

View file

@ -9,6 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
)
var ForwardListRegex = regexp.MustCompile(`^port=(\d{1,5}):proto=(.+?):toport=(\d{1,5}):toaddr=(.*)$`)
@ -31,39 +32,35 @@ func (f *Firewall) Status() (bool, error) {
func (f *Firewall) Version() (string, error) {
stdout, err := cmd.RunDefaultWithStdoutBashC("LANGUAGE=en_US:en firewall-cmd --version")
if err != nil {
return "", fmt.Errorf("load the firewall version failed, err: %s", stdout)
return "", fmt.Errorf("load the firewall version failed, %v", err)
}
return strings.ReplaceAll(stdout, "\n ", ""), nil
}
func (f *Firewall) Start() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl start firewalld")
if err != nil {
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
if err := controller.HandleStart("firewalld"); err != nil {
return fmt.Errorf("enable the firewall failed, err: %v", err)
}
return nil
}
func (f *Firewall) Stop() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl stop firewalld")
if err != nil {
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
if err := controller.HandleStop("firewalld"); err != nil {
return fmt.Errorf("stop the firewall failed, err: %v", err)
}
return nil
}
func (f *Firewall) Restart() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl restart firewalld")
if err != nil {
return fmt.Errorf("restart the firewall failed, err: %s", stdout)
if err := controller.HandleRestart("firewalld"); err != nil {
return fmt.Errorf("restart the firewall failed, err: %v", err)
}
return nil
}
func (f *Firewall) Reload() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("firewall-cmd --reload")
if err != nil {
return fmt.Errorf("reload firewall failed, err: %s", stdout)
if err := cmd.RunDefaultBashC("firewall-cmd --reload"); err != nil {
return fmt.Errorf("reload firewall failed, err: %v", err)
}
return nil
}
@ -170,9 +167,8 @@ func (f *Firewall) Port(port FireInfo, operation string) error {
return buserr.New("ErrCmdIllegal")
}
stdout, err := cmd.RunDefaultWithStdoutBashCf("firewall-cmd --zone=public --%s-port=%s/%s --permanent", operation, port.Port, port.Protocol)
if err != nil {
return fmt.Errorf("%s (port: %s/%s strategy: %s) failed, err: %s", operation, port.Port, port.Protocol, port.Strategy, stdout)
if err := cmd.RunDefaultBashCf("firewall-cmd --zone=public --%s-port=%s/%s --permanent", operation, port.Port, port.Protocol); err != nil {
return fmt.Errorf("%s (port: %s/%s strategy: %s) failed, %v", operation, port.Port, port.Protocol, port.Strategy, err)
}
return nil
}
@ -195,14 +191,12 @@ func (f *Firewall) RichRules(rule FireInfo, operation string) error {
ruleStr += fmt.Sprintf("protocol=%s ", rule.Protocol)
}
ruleStr += rule.Strategy
stdout, err := cmd.RunDefaultWithStdoutBashCf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleStr)
if err != nil {
return fmt.Errorf("%s rich rules (%s) failed, err: %s", operation, ruleStr, stdout)
if err := cmd.RunDefaultBashCf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleStr); err != nil {
return fmt.Errorf("%s rich rules (%s) failed, %v", operation, ruleStr, err)
}
if len(rule.Address) == 0 {
stdout1, err := cmd.RunDefaultWithStdoutBashCf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, strings.ReplaceAll(ruleStr, "family=ipv4 ", "family=ipv6 "))
if err != nil {
return fmt.Errorf("%s rich rules (%s) failed, err: %s", operation, strings.ReplaceAll(ruleStr, "family=ipv4 ", "family=ipv6 "), stdout1)
if err := cmd.RunDefaultBashCf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, strings.ReplaceAll(ruleStr, "family=ipv4 ", "family=ipv6 ")); err != nil {
return fmt.Errorf("%s rich rules (%s) failed, %v", operation, strings.ReplaceAll(ruleStr, "family=ipv4 ", "family=ipv6 "), err)
}
}
return nil
@ -214,11 +208,10 @@ func (f *Firewall) PortForward(info Forward, operation string) error {
ruleStr = fmt.Sprintf("firewall-cmd --zone=public --%s-forward-port=port=%s:proto=%s:toaddr=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.TargetIP, info.TargetPort)
}
stdout, err := cmd.RunDefaultWithStdoutBashC(ruleStr)
if err != nil {
return fmt.Errorf("%s port forward failed, err: %s", operation, stdout)
if err := cmd.RunDefaultBashC(ruleStr); err != nil {
return fmt.Errorf("%s port forward failed, %s", operation, err)
}
if err = f.Reload(); err != nil {
if err := f.Reload(); err != nil {
return err
}
return nil
@ -250,13 +243,12 @@ func (f *Firewall) EnableForward() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("firewall-cmd --zone=public --query-masquerade")
if err != nil {
if strings.HasSuffix(strings.TrimSpace(stdout), "no") {
stdout, err = cmd.RunDefaultWithStdoutBashC("firewall-cmd --zone=public --add-masquerade --permanent")
if err != nil {
return fmt.Errorf("%s: %s", err, stdout)
if err := cmd.RunDefaultBashC("firewall-cmd --zone=public --add-masquerade --permanent"); err != nil {
return err
}
return f.Reload()
}
return fmt.Errorf("%s: %s", err, stdout)
return err
}
return nil

View file

@ -39,37 +39,32 @@ func NewIptables() (*Iptables, error) {
return iptables, nil
}
func (iptables *Iptables) outf(tab, rule string, a ...any) (stdout string, err error) {
func (iptables *Iptables) out(tab, rule string) (string, error) {
cmdMgr := cmd.NewCommandMgr(cmd.WithIgnoreExist1(), cmd.WithTimeout(20*time.Second))
stdout, err = cmdMgr.RunWithStdoutBashCf("%s iptables -t %s %s", iptables.CmdStr, tab, fmt.Sprintf(rule, a...))
if err != nil && stdout != "" {
global.LOG.Errorf("iptables failed, err: %s", stdout)
stdout, err := cmdMgr.RunWithStdoutBashCf("%s iptables -t %s %s", iptables.CmdStr, tab, rule)
if err != nil {
global.LOG.Errorf("iptables failed, %v", err)
}
return
return stdout, nil
}
func (iptables *Iptables) runf(tab, rule string, a ...any) error {
stdout, err := iptables.outf(tab, rule, a...)
if err != nil {
return fmt.Errorf("%s, %s", err, stdout)
func (iptables *Iptables) run(tab, rule string) error {
if _, err := iptables.out(tab, rule); err != nil {
return err
}
if stdout != "" {
return fmt.Errorf("iptables error: %s", stdout)
}
return nil
}
func (iptables *Iptables) Check() error {
stdout, err := cmd.RunDefaultWithStdoutBashC("cat /proc/sys/net/ipv4/ip_forward")
if err != nil {
return fmt.Errorf("check ip_forward error: %w, output: %s", err, stdout)
return fmt.Errorf("check ip_forward failed, %v", err)
}
if strings.TrimSpace(stdout) == "0" {
return fmt.Errorf("ipv4 forward disabled")
}
chain, err := iptables.outf(NatTab, "-L -n | grep 'Chain %s'", PreRoutingChain)
chain, err := iptables.out(NatTab, fmt.Sprintf("-L -n | grep 'Chain %s'", PreRoutingChain))
if err != nil {
return fmt.Errorf("failed to check chain: %w", err)
}
@ -81,18 +76,18 @@ func (iptables *Iptables) Check() error {
}
func (iptables *Iptables) NewChain(tab, chain string) error {
return iptables.runf(tab, "-N %s", chain)
return iptables.run(tab, "-N "+chain)
}
func (iptables *Iptables) AppendChain(tab string, chain, chain1 string) error {
return iptables.runf(tab, "-A %s -j %s", chain, chain1)
return iptables.run(tab, fmt.Sprintf("-A %s -j %s", chain, chain1))
}
func (iptables *Iptables) NatList(chain ...string) ([]IptablesNatInfo, error) {
if len(chain) == 0 {
chain = append(chain, PreRoutingChain)
}
stdout, err := iptables.outf(NatTab, "-nvL %s --line-numbers", chain[0])
stdout, err := iptables.out(NatTab, fmt.Sprintf("-nvL %s --line-numbers", chain[0]))
if err != nil {
return nil, err
}
@ -132,11 +127,11 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string
iptablesArg += fmt.Sprintf(" -i %s", iface)
}
iptablesArg += fmt.Sprintf(" -p %s --dport %s -j DNAT --to-destination %s:%s", protocol, srcPort, dest, destPort)
if err := iptables.runf(NatTab, iptablesArg); err != nil {
if err := iptables.run(NatTab, iptablesArg); err != nil {
return err
}
if err := iptables.runf(NatTab, fmt.Sprintf(
if err := iptables.run(NatTab, fmt.Sprintf(
"-A %s -d %s -p %s --dport %s -j MASQUERADE",
PostRoutingChain,
dest,
@ -146,7 +141,7 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string
return err
}
if err := iptables.runf(FilterTab, fmt.Sprintf(
if err := iptables.run(FilterTab, fmt.Sprintf(
"-A %s -d %s -p %s --dport %s -j ACCEPT",
ForwardChain,
dest,
@ -156,7 +151,7 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string
return err
}
if err := iptables.runf(FilterTab, fmt.Sprintf(
if err := iptables.run(FilterTab, fmt.Sprintf(
"-A %s -s %s -p %s --sport %s -j ACCEPT",
ForwardChain,
dest,
@ -171,7 +166,7 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string
iptablesArg += fmt.Sprintf(" -i %s", iface)
}
iptablesArg += fmt.Sprintf(" -p %s --dport %s -j REDIRECT --to-port %s", protocol, srcPort, destPort)
if err := iptables.runf(NatTab, iptablesArg); err != nil {
if err := iptables.run(NatTab, iptablesArg); err != nil {
return err
}
}
@ -189,12 +184,12 @@ func (iptables *Iptables) NatAdd(protocol, srcPort, dest, destPort, iface string
}
func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPort, iface string) error {
if err := iptables.runf(NatTab, "-D %s %s", PreRoutingChain, num); err != nil {
if err := iptables.run(NatTab, fmt.Sprintf("-D %s %s", PreRoutingChain, num)); err != nil {
return err
}
if dest != "" && dest != "127.0.0.1" && dest != "localhost" {
if err := iptables.runf(NatTab, fmt.Sprintf(
if err := iptables.run(NatTab, fmt.Sprintf(
"-D %s -d %s -p %s --dport %s -j MASQUERADE",
PostRoutingChain,
dest,
@ -204,7 +199,7 @@ func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPor
return err
}
if err := iptables.runf(FilterTab, fmt.Sprintf(
if err := iptables.run(FilterTab, fmt.Sprintf(
"-D %s -d %s -p %s --dport %s -j ACCEPT",
ForwardChain,
dest,
@ -214,7 +209,7 @@ func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPor
return err
}
if err := iptables.runf(FilterTab, fmt.Sprintf(
if err := iptables.run(FilterTab, fmt.Sprintf(
"-D %s -s %s -p %s --sport %s -j ACCEPT",
ForwardChain,
dest,
@ -238,13 +233,13 @@ func (iptables *Iptables) NatRemove(num string, protocol, srcPort, dest, destPor
}
func (iptables *Iptables) Reload() error {
if err := iptables.runf(NatTab, "-F %s", PreRoutingChain); err != nil {
if err := iptables.run(NatTab, "-F "+PreRoutingChain); err != nil {
return err
}
if err := iptables.runf(NatTab, "-F %s", PostRoutingChain); err != nil {
if err := iptables.run(NatTab, "-F "+PostRoutingChain); err != nil {
return err
}
if err := iptables.runf(FilterTab, "-F %s", ForwardChain); err != nil {
if err := iptables.run(FilterTab, "-F "+ForwardChain); err != nil {
return err
}

View file

@ -38,24 +38,22 @@ func (f *Ufw) Status() (bool, error) {
func (f *Ufw) Version() (string, error) {
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s version | grep ufw", f.CmdStr)
if err != nil {
return "", fmt.Errorf("load the firewall status failed, err: %s", stdout)
return "", fmt.Errorf("load the firewall status failed, %v", err)
}
info := strings.ReplaceAll(stdout, "\n", "")
return strings.ReplaceAll(info, "ufw ", ""), nil
}
func (f *Ufw) Start() error {
stdout, err := cmd.RunDefaultWithStdoutBashCf("echo y | %s enable", f.CmdStr)
if err != nil {
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
if err := cmd.RunDefaultBashCf("echo y | %s enable", f.CmdStr); err != nil {
return fmt.Errorf("enable the firewall failed, %v", err)
}
return nil
}
func (f *Ufw) Stop() error {
stdout, err := cmd.RunDefaultWithStdoutBashCf("%s disable", f.CmdStr)
if err != nil {
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
if err := cmd.RunDefaultBashCf("%s disable", f.CmdStr); err != nil {
return fmt.Errorf("stop the firewall failed, %v", err)
}
return nil
}
@ -184,9 +182,8 @@ func (f *Ufw) Port(port FireInfo, operation string) error {
if len(port.Protocol) != 0 {
command += fmt.Sprintf("/%s", port.Protocol)
}
stdout, err := cmd.RunDefaultWithStdoutBashC(command)
if err != nil {
return fmt.Errorf("%s (%s) failed, err: %s", operation, command, stdout)
if err := cmd.RunDefaultBashC(command); err != nil {
return fmt.Errorf("%s (%s) failed, %v", operation, command, err)
}
return nil
}
@ -224,13 +221,12 @@ func (f *Ufw) RichRules(rule FireInfo, operation string) error {
stdout, err := cmd.RunDefaultWithStdoutBashC(ruleStr)
if err != nil {
if strings.Contains(stdout, "ERROR: Invalid position") || strings.Contains(stdout, "ERROR: 无效位置") {
stdout, err := cmd.RunDefaultWithStdoutBashC(strings.ReplaceAll(ruleStr, "insert 1 ", ""))
if err != nil {
return fmt.Errorf("%s rich rules (%s), failed, err: %s", operation, ruleStr, stdout)
if err := cmd.RunDefaultBashC(strings.ReplaceAll(ruleStr, "insert 1 ", "")); err != nil {
return fmt.Errorf("%s rich rules (%s), failed, %v", operation, ruleStr, err)
}
return nil
}
return fmt.Errorf("%s rich rules (%s), failed, err: %s", operation, ruleStr, stdout)
return fmt.Errorf("%s rich rules (%s), failed, %v", operation, ruleStr, err)
}
return nil
}

View file

@ -62,9 +62,8 @@ func GetRemoteTime(site string) (time.Time, error) {
func UpdateSystemTime(dateTime string) error {
system := runtime.GOOS
if system == "linux" {
stdout2, err := cmd.RunDefaultWithStdoutBashCf(`%s date -s "%s"`, cmd.SudoHandleCmd(), dateTime)
if err != nil {
return fmt.Errorf("update system time failed,stdout: %s, err: %v", stdout2, err)
if err := cmd.RunDefaultBashCf(`%s date -s "%s"`, cmd.SudoHandleCmd(), dateTime); err != nil {
return fmt.Errorf("update system time failed, %v", err)
}
return nil
}
@ -74,9 +73,8 @@ func UpdateSystemTime(dateTime string) error {
func UpdateSystemTimeZone(timezone string) error {
system := runtime.GOOS
if system == "linux" {
stdout, err := cmd.RunDefaultWithStdoutBashCf(`%s timedatectl set-timezone "%s"`, cmd.SudoHandleCmd(), timezone)
if err != nil {
return fmt.Errorf("update system time zone failed, stdout: %s, err: %v", stdout, err)
if err := cmd.RunDefaultBashCf(`%s timedatectl set-timezone "%s"`, cmd.SudoHandleCmd(), timezone); err != nil {
return fmt.Errorf("update system time zone failed, %v", err)
}
return nil
}

View file

@ -1,116 +0,0 @@
package systemctl
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"os/exec"
"strings"
)
func RunSystemCtl(args ...string) (string, error) {
cmd := exec.Command("systemctl", args...)
output, err := cmd.CombinedOutput()
if err != nil {
return string(output), fmt.Errorf("failed to run command: %w", err)
}
return string(output), nil
}
func isSnapService(serviceName string) bool {
cmd := exec.Command("snap", "services")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return false
}
return strings.Contains(out.String(), serviceName)
}
func isSnapServiceActive(serviceName string) bool {
cmd := exec.Command("snap", "services")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return false
}
lines := strings.Split(out.String(), "\n")
for _, line := range lines {
if strings.Contains(line, serviceName) && strings.Contains(line, "active") {
return true
}
}
return false
}
func IsActive(serviceName string) (bool, error) {
out, err := RunSystemCtl("is-active", serviceName)
if err == nil {
return strings.TrimSpace(out) == "active", nil
}
if isSnapServiceActive(serviceName) {
return true, nil
}
return false, fmt.Errorf("service %s is not active: %v", serviceName, err)
}
func IsEnable(serviceName string) (bool, error) {
out, err := RunSystemCtl("is-enabled", serviceName)
if err == nil {
return strings.TrimSpace(out) == "enabled", nil
}
if isSnapServiceActive(serviceName) {
return true, nil
}
return false, fmt.Errorf("failed to determine if service %s is enabled: %v", serviceName, err)
}
func IsExist(serviceName string) (bool, error) {
out, err := RunSystemCtl("is-enabled", serviceName)
if err == nil || strings.Contains(out, "disabled") {
return true, nil
}
if isSnapService(serviceName) {
return true, nil
}
return false, nil
}
func handlerErr(out string, err error) error {
if err != nil {
if out != "" {
return errors.New(out)
}
return err
}
return nil
}
func Restart(serviceName string) error {
out, err := RunSystemCtl("restart", serviceName)
if err == nil {
return nil
}
if isSnapService(serviceName) {
cmd := exec.Command("snap", "restart", serviceName)
output, snapErr := cmd.CombinedOutput()
return handlerErr(string(output), snapErr)
}
return handlerErr(out, err)
}
func Operate(operate, serviceName string) error {
out, err := RunSystemCtl(operate, serviceName)
if err == nil {
return nil
}
if isSnapService(serviceName) && (operate == "start" || operate == "stop" || operate == "restart") {
cmd := exec.Command("snap", operate, serviceName)
output, snapErr := cmd.CombinedOutput()
return handlerErr(string(output), snapErr)
}
return handlerErr(out, err)
}

View file

@ -8,7 +8,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
)
type Fail2ban struct{}
@ -23,15 +23,14 @@ type FirewallClient interface {
}
func NewFail2Ban() (*Fail2ban, error) {
isExist, _ := systemctl.IsExist("fail2ban.service")
isExist, _ := controller.CheckExist("fail2ban.service")
if isExist {
if _, err := os.Stat(defaultPath); err != nil {
if err := initLocalFile(); err != nil {
return nil, err
}
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl restart fail2ban.service")
if err != nil {
global.LOG.Errorf("restart fail2ban failed, err: %s", stdout)
if err := controller.HandleRestart("fail2ban.service"); err != nil {
global.LOG.Errorf("restart fail2ban failed, err: %v", err)
return nil, err
}
}
@ -40,9 +39,9 @@ func NewFail2Ban() (*Fail2ban, error) {
}
func (f *Fail2ban) Status() (bool, bool, bool) {
isEnable, _ := systemctl.IsEnable("fail2ban.service")
isActive, _ := systemctl.IsActive("fail2ban.service")
isExist, _ := systemctl.IsExist("fail2ban.service")
isEnable, _ := controller.CheckEnable("fail2ban.service")
isActive, _ := controller.CheckActive("fail2ban.service")
isExist, _ := controller.CheckExist("fail2ban.service")
return isEnable, isActive, isExist
}
@ -50,7 +49,7 @@ func (f *Fail2ban) Status() (bool, bool, bool) {
func (f *Fail2ban) Version() string {
stdout, err := cmd.RunDefaultWithStdoutBashC("fail2ban-client version")
if err != nil {
global.LOG.Errorf("load the fail2ban version failed, err: %s", stdout)
global.LOG.Errorf("load the fail2ban version failed, %v", err)
return "-"
}
return strings.ReplaceAll(stdout, "\n", "")
@ -59,15 +58,13 @@ func (f *Fail2ban) Version() string {
func (f *Fail2ban) Operate(operate string) error {
switch operate {
case "start", "restart", "stop", "enable", "disable":
stdout, err := cmd.RunDefaultWithStdoutBashCf("systemctl %s fail2ban.service", operate)
if err != nil {
return fmt.Errorf("%s the fail2ban.service failed, err: %s", operate, stdout)
if err := controller.Handle(operate, "fail2ban.service"); err != nil {
return fmt.Errorf("%s the fail2ban.service failed, err: %v", operate, err)
}
return nil
case "reload":
stdout, err := cmd.RunDefaultWithStdoutBashC("fail2ban-client reload")
if err != nil {
return fmt.Errorf("fail2ban-client reload, err: %s", stdout)
if err := cmd.RunDefaultBashC("fail2ban-client reload"); err != nil {
return fmt.Errorf("fail2ban-client reload, %v", err)
}
return nil
default:
@ -159,9 +156,9 @@ action = %(action_mwl)s
logpath = $logpath`
banaction := ""
if active, _ := systemctl.IsActive("firewalld"); active {
if active, _ := controller.CheckActive("firewalld"); active {
banaction = "firewallcmd-ipset"
} else if active, _ := systemctl.IsActive("ufw"); active {
} else if active, _ := controller.CheckActive("ufw"); active {
banaction = "ufw"
} else {
banaction = "iptables-allports"

View file

@ -2,7 +2,6 @@ package toolbox
import (
"bufio"
"errors"
"fmt"
"os"
"os/user"
@ -13,7 +12,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/systemctl"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/toolbox/helper"
)
@ -63,29 +62,26 @@ func NewFtpClient() (*Ftp, error) {
groupItem, err := user.LookupGroupId("1000")
if err == nil {
stdout2, err := cmd.RunDefaultWithStdoutBashCf("useradd -u 1000 -g %s %s", groupItem.Name, "1panel")
if err != nil {
return nil, errors.New(stdout2)
if err := cmd.RunDefaultBashCf("useradd -u 1000 -g %s %s", groupItem.Name, "1panel"); err != nil {
return nil, err
}
return &Ftp{DefaultUser: "1panel", DefaultGroup: groupItem.Name}, nil
}
if err.Error() != user.UnknownGroupIdError("1000").Error() {
return nil, err
}
stdout, err := cmd.RunDefaultWithStdoutBashC("groupadd -g 1000 1panel")
if err != nil {
return nil, errors.New(string(stdout))
if err := cmd.RunDefaultBashC("groupadd -g 1000 1panel"); err != nil {
return nil, err
}
stdout2, err := cmd.RunDefaultWithStdoutBashC("useradd -u 1000 -g 1panel 1panel")
if err != nil {
return nil, errors.New(stdout2)
if err := cmd.RunDefaultBashC("useradd -u 1000 -g 1panel 1panel"); err != nil {
return nil, err
}
return &Ftp{DefaultUser: "1panel", DefaultGroup: "1panel"}, nil
}
func (f *Ftp) Status() (bool, bool) {
isActive, _ := systemctl.IsActive("pure-ftpd.service")
isExist, _ := systemctl.IsExist("pure-ftpd.service")
isActive, _ := controller.CheckActive("pure-ftpd.service")
isExist, _ := controller.CheckExist("pure-ftpd.service")
return isActive, isExist
}
@ -93,9 +89,8 @@ func (f *Ftp) Status() (bool, bool) {
func (f *Ftp) Operate(operate string) error {
switch operate {
case "start", "restart", "stop":
stdout, err := cmd.RunDefaultWithStdoutBashCf("systemctl %s pure-ftpd.service", operate)
if err != nil {
return fmt.Errorf("%s the pure-ftpd.service failed, err: %s", operate, stdout)
if err := controller.Handle(operate, "pure-ftpd.service"); err != nil {
return fmt.Errorf("%s the pure-ftpd.service failed, err: %v", operate, err)
}
return nil
default:
@ -119,17 +114,15 @@ func (f *Ftp) UserAdd(username, passwd, path string) error {
return err
}
_ = f.Reload()
std2, err := cmd.RunDefaultWithStdoutBashCf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path)
if err != nil {
return errors.New(std2)
if err := cmd.RunDefaultBashCf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path); err != nil {
return err
}
return nil
}
func (f *Ftp) UserDel(username string) error {
std, err := cmd.RunDefaultWithStdoutBashCf("pure-pw userdel %s", username)
if err != nil {
return errors.New(std)
if err := cmd.RunDefaultBashCf("pure-pw userdel %s", username); err != nil {
return err
}
_ = f.Reload()
return nil
@ -186,13 +179,11 @@ func (f *Ftp) SetPasswd(username, passwd string) error {
}
func (f *Ftp) SetPath(username, path string) error {
std, err := cmd.RunDefaultWithStdoutBashCf("pure-pw usermod %s -d %s", username, path)
if err != nil {
return errors.New(std)
if err := cmd.RunDefaultBashCf("pure-pw usermod %s -d %s", username, path); err != nil {
return err
}
std2, err := cmd.RunDefaultWithStdoutBashCf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path)
if err != nil {
return errors.New(std2)
if err := cmd.RunDefaultBashCf("chown -R %s:%s %s", f.DefaultUser, f.DefaultGroup, path); err != nil {
return err
}
return nil
}
@ -202,9 +193,8 @@ func (f *Ftp) SetStatus(username, status string) error {
if status == constant.StatusDisable {
statusItem = "1"
}
std, err := cmd.RunDefaultWithStdoutBashCf("pure-pw usermod %s -r %s", username, statusItem)
if err != nil {
return errors.New(std)
if err := cmd.RunDefaultBashCf("pure-pw usermod %s -r %s", username, statusItem); err != nil {
return err
}
return nil
}
@ -212,7 +202,7 @@ func (f *Ftp) SetStatus(username, status string) error {
func (f *Ftp) LoadList() ([]FtpList, error) {
std, err := cmd.RunDefaultWithStdoutBashC("pure-pw list")
if err != nil {
return nil, errors.New(std)
return nil, err
}
var lists []FtpList
lines := strings.Split(std, "\n")
@ -223,7 +213,7 @@ func (f *Ftp) LoadList() ([]FtpList, error) {
}
std2, err := cmd.RunDefaultWithStdoutBashCf("pure-pw show %s | grep 'Allowed client IPs :'", parts[0])
if err != nil {
global.LOG.Errorf("handle pure-pw show %s failed, err: %v", parts[0], std2)
global.LOG.Errorf("handle pure-pw show %s failed, %v", parts[0], err)
continue
}
status := constant.StatusDisable
@ -237,9 +227,8 @@ func (f *Ftp) LoadList() ([]FtpList, error) {
}
func (f *Ftp) Reload() error {
std, err := cmd.RunDefaultWithStdoutBashC("pure-pw mkdb")
if err != nil {
return errors.New(std)
if err := cmd.RunDefaultBashC("pure-pw mkdb"); err != nil {
return err
}
return nil
}
@ -296,7 +285,7 @@ func (f *Ftp) LoadLogs(user, operation string) ([]FtpLog, error) {
}
func handleGunzip(path string) error {
if _, err := cmd.RunDefaultWithStdoutBashCf("gunzip %s", path); err != nil {
if err := cmd.RunDefaultBashCf("gunzip %s", path); err != nil {
return err
}
return nil

View file

@ -26,8 +26,8 @@ import (
"github.com/1Panel-dev/1Panel/core/buserr"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/common"
"github.com/1Panel-dev/1Panel/core/utils/controller"
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
"github.com/1Panel-dev/1Panel/core/utils/firewall"
"github.com/1Panel-dev/1Panel/core/utils/req_helper/proxy_local"
@ -192,10 +192,7 @@ func (u *SettingService) UpdateBindInfo(req dto.BindInfo) error {
}
go func() {
time.Sleep(1 * time.Second)
_, err := cmd.RunDefaultWithStdoutBashC("systemctl restart 1panel-core.service")
if err != nil {
global.LOG.Errorf("restart system with new bind info failed, err: %v", err)
}
controller.RestartPanel(true, false, false)
}()
return nil
}
@ -261,9 +258,7 @@ func (u *SettingService) UpdatePort(port uint) error {
}
go func() {
time.Sleep(1 * time.Second)
if _, err := cmd.RunDefaultWithStdoutBashC("systemctl restart 1panel-core.service"); err != nil {
global.LOG.Errorf("restart system port failed, err: %v", err)
}
controller.RestartPanel(true, false, false)
}()
return nil
}
@ -282,10 +277,7 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
_ = os.Remove(path.Join(secretDir, "server.key"))
go func() {
time.Sleep(1 * time.Second)
_, err := cmd.RunDefaultWithStdoutBashC("systemctl restart 1panel-core.service")
if err != nil {
global.LOG.Errorf("restart system failed, err: %v", err)
}
controller.RestartPanel(true, false, false)
}()
return nil
}
@ -380,10 +372,7 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
if req.SSL != status {
go func() {
time.Sleep(1 * time.Second)
_, err := cmd.RunDefaultWithStdoutBashC("systemctl restart 1panel-core.service")
if err != nil {
global.LOG.Errorf("restart system failed, err: %v", err)
}
controller.RestartPanel(true, false, false)
}()
}
if err := settingRepo.Update("SSL", req.SSL); err != nil {

View file

@ -10,7 +10,6 @@ import (
"sort"
"strconv"
"strings"
"time"
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/app/model"
@ -20,6 +19,7 @@ import (
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/common"
"github.com/1Panel-dev/1Panel/core/utils/controller"
"github.com/1Panel-dev/1Panel/core/utils/files"
"github.com/1Panel-dev/1Panel/core/utils/req_helper"
)
@ -207,10 +207,7 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
global.CONF.Base.Version = req.Version
_ = settingRepo.Update("SystemStatus", "Free")
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(10 * time.Second))
_, _ = cmdMgr.RunWithStdoutBashC("systemctl daemon-reload")
_, _ = cmdMgr.RunWithStdoutBashC("systemctl restart 1panel-agent.service")
_, _ = cmdMgr.RunWithStdoutBashC("systemctl restart 1panel-core.service")
controller.RestartPanel(true, true, true)
}()
return nil
}

View file

@ -11,6 +11,7 @@ import (
"github.com/1Panel-dev/1Panel/core/i18n"
cmdUtils "github.com/1Panel-dev/1Panel/core/utils/cmd"
"github.com/1Panel-dev/1Panel/core/utils/common"
"github.com/1Panel-dev/1Panel/core/utils/controller"
"github.com/1Panel-dev/1Panel/core/utils/files"
"github.com/spf13/cobra"
@ -88,11 +89,7 @@ var restoreCmd = &cobra.Command{
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep5"))
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreSuccessful"))
_, _ = cmdUtils.RunDefaultWithStdoutBashC("systemctl daemon-reload")
std, err := cmdUtils.RunDefaultWithStdoutBashC("1pctl restart all")
if err != nil {
fmt.Println(std)
}
controller.RestartPanel(true, true, true)
return nil
},
}

View file

@ -61,9 +61,8 @@ func initLang() {
downloadLangFromRemote()
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("cp -r %s %s", path.Join(tmpPath, "lang"), "/usr/local/bin/")
if err != nil {
global.LOG.Errorf("load lang from package failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("cp -r %s %s", path.Join(tmpPath, "lang"), "/usr/local/bin/"); err != nil {
global.LOG.Errorf("load lang from package failed, %v", err)
return
}
global.LOG.Info("init lang successful")
@ -73,9 +72,8 @@ func initLang() {
downloadGeoFromRemote(geoPath)
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("mkdir %s && cp %s %s/", path.Dir(geoPath), path.Join(tmpPath, "GeoIP.mmdb"), path.Dir(geoPath))
if err != nil {
global.LOG.Errorf("load geo ip from package failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("mkdir %s && cp %s %s/", path.Dir(geoPath), path.Join(tmpPath, "GeoIP.mmdb"), path.Dir(geoPath)); err != nil {
global.LOG.Errorf("load geo ip from package failed, %v", err)
return
}
global.LOG.Info("init geo ip successful")
@ -115,9 +113,8 @@ func downloadLangFromRemote() {
global.LOG.Error("download lang.tar.gz failed, no such file")
return
}
std, err := cmd.RunDefaultWithStdoutBashCf("tar zxvfC %s %s", "/usr/local/bin/lang.tar.gz", "/usr/local/bin/")
if err != nil {
fmt.Printf("decompress lang.tar.gz failed, std: %s, err: %v", std, err)
if err := cmd.RunDefaultBashCf("tar zxvfC %s %s", "/usr/local/bin/lang.tar.gz", "/usr/local/bin/"); err != nil {
global.LOG.Errorf("decompress lang.tar.gz failed, %v", err)
return
}
_ = os.Remove("/usr/local/bin/lang.tar.gz")

View file

@ -0,0 +1,197 @@
package controller
import (
"errors"
"fmt"
"os/exec"
"strings"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/controller/manager"
)
type Controller interface {
Name() string
IsActive(serviceName string) (bool, error)
IsEnable(serviceName string) (bool, error)
IsExist(serviceName string) (bool, error)
Status(serviceName string) (string, error)
Operate(operate, serviceName string) error
Reload() error
}
func New() (Controller, error) {
managerOptions := []string{"systemd", "openrc", "sysvinit"}
for _, item := range managerOptions {
if _, err := exec.LookPath(item); err != nil {
continue
}
switch item {
case "systemd":
return manager.NewSystemd(), nil
case "openrc":
return manager.NewOpenrc(), nil
case "sysvinit":
return manager.NewSysvinit(), nil
}
}
return nil, errors.New("not support such manager initializatio")
}
func Handle(operate, serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
client, err := New()
if err != nil {
return err
}
return client.Operate(operate, service)
}
func HandleStart(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("start", service)
}
func HandleStop(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("stop", service)
}
func HandleRestart(serviceName string) error {
service, err := LoadServiceName(serviceName)
if err != nil {
return err
}
return Handle("restart", service)
}
func CheckExist(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
b, er := client.IsExist(service)
return b, er
}
func CheckActive(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
return client.IsActive(service)
}
func CheckEnable(serviceName string) (bool, error) {
service, err := LoadServiceName(serviceName)
if err != nil {
return false, err
}
client, err := New()
if err != nil {
return false, err
}
return client.IsEnable(service)
}
func Reload() error {
client, err := New()
if err != nil {
return err
}
return client.Reload()
}
func RestartPanel(core, agent, reload bool) {
client, err := New()
if err != nil {
global.LOG.Errorf("load client for controller failed, err: %v", err)
return
}
if reload {
if err := client.Reload(); err != nil {
global.LOG.Errorf("restart 1panel service failed, err: %v", err)
return
}
}
if agent {
if err := client.Operate("restart", "1panel-agent"); err != nil {
global.LOG.Errorf("restart 1panel agent service failed, err: %v", err)
return
}
}
if core {
if err := client.Operate("restart", "1panel-core"); err != nil {
global.LOG.Errorf("restart 1panel core service failed, err: %v", err)
return
}
}
}
func LoadServiceName(keyword string) (string, error) {
client, err := New()
if err != nil {
return "", err
}
processedName := loadProcessedName(client.Name(), keyword)
exist, err := client.IsExist(processedName)
if exist {
return processedName, nil
}
alistName := loadFromPredefined(client, keyword)
if len(alistName) != 0 {
return alistName, nil
}
return "", fmt.Errorf("find such service for %s failed", keyword)
}
func loadProcessedName(mgr, keyword string) string {
keyword = strings.ToLower(keyword)
if strings.HasSuffix(keyword, ".service.socket") {
keyword = strings.TrimSuffix(keyword, ".service.socket") + ".socket"
}
if mgr != "systemd" {
keyword = strings.TrimSuffix(keyword, ".service")
return keyword
}
if !strings.HasSuffix(keyword, ".service") && !strings.HasSuffix(keyword, ".socket") {
keyword += ".service"
}
return keyword
}
func loadFromPredefined(mgr Controller, keyword string) string {
predefinedMap := map[string][]string{
"clam": {"clamav-daemon.service", "clamd@scan.service", "clamd"},
"freshclam": {"clamav-freshclam.service", "freshclam.service"},
"fail2ban": {"fail2ban.service", "fail2ban"},
"supervisor": {"supervisord.service", "supervisor.service", "supervisord", "supervisor"},
"ssh": {"sshd.service", "ssh.service", "sshd", "ssh"},
"1panel-core": {"1panel-core.service", "1panel-cored"},
"1panel-agent": {"1panel-agent.service", "1panel-agentd"},
"docker": {"docker.service", "dockerd"},
}
if val, ok := predefinedMap[keyword]; ok {
for _, item := range val {
if exist, _ := mgr.IsExist(item); exist {
return item
}
}
}
return ""
}

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, " "))
}

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
}

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
}

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)
}

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
}