Files
hexis/internal/provider/systemd.go
T
kami cca63269e1 Initial commit: Hexis capability registry + execution service baseline
Go daemon (hexisd/hexisctl) implementing capability registry, guarded
execution (confirmations, blessed-entity checks), systemd/workspace-mcp
providers per ECOSYSTEM-SPEC.md. Snapshotting existing working state
before further development.
2026-07-20 00:50:37 +04:00

69 lines
1.9 KiB
Go

package provider
import (
"fmt"
"os/exec"
"strings"
"github.com/kami/hexis/internal/domain"
)
type SystemdProvider struct{}
func NewSystemdProvider() *SystemdProvider {
return &SystemdProvider{}
}
func (p *SystemdProvider) Name() string { return "systemd" }
func (p *SystemdProvider) Execute(capability *domain.Capability, req *domain.ExecuteRequest) (map[string]any, error) {
unitName := req.TargetEntityID
if unitName == "" {
unitName = capability.TargetEntityID
}
if !isValidUnitName(unitName) {
return nil, fmt.Errorf("invalid unit name: %q", unitName)
}
var cmd *exec.Cmd
switch capability.Operation {
case "restart":
cmd = exec.Command("systemctl", "restart", unitName)
case "start":
cmd = exec.Command("systemctl", "start", unitName)
case "stop":
cmd = exec.Command("systemctl", "stop", unitName)
case "status":
cmd = exec.Command("systemctl", "status", unitName)
case "reload":
cmd = exec.Command("systemctl", "reload", unitName)
case "enable":
cmd = exec.Command("systemctl", "enable", unitName)
case "disable":
cmd = exec.Command("systemctl", "disable", unitName)
default:
return nil, fmt.Errorf("unsupported systemd operation: %s", capability.Operation)
}
output, err := cmd.CombinedOutput()
if err != nil {
return map[string]any{
"stdout": string(output),
"exit_code": cmd.ProcessState.ExitCode(),
}, fmt.Errorf("systemctl %s failed: %w\n%s", capability.Operation, err, string(output))
}
return map[string]any{
"stdout": string(output),
"exit_code": 0,
}, nil
}
func isValidUnitName(name string) bool {
if name == "" || strings.Contains(name, "..") || strings.Contains(name, "/") || strings.Contains(name, ";") || strings.Contains(name, "|") || strings.Contains(name, "$") || strings.Contains(name, "`") || strings.Contains(name, "'") || strings.Contains(name, `"`) || strings.Contains(name, "\\") {
return false
}
return true
}