cca63269e1
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.
69 lines
1.9 KiB
Go
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
|
|
}
|