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.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user