This commit is contained in:
2025-04-23 04:18:28 +02:00
parent 10a7d9bb6b
commit a16ac8f627
276 changed files with 85166 additions and 1 deletions

View File

@@ -0,0 +1,94 @@
package executor
import (
"fmt"
"os/exec"
"sync"
"time"
)
// Job represents a command execution job
type Job struct {
ID string
Command string
Args []string
StartTime time.Time
EndTime time.Time
Status string
Output string
Error string
}
// Executor handles command execution
type Executor struct {
jobs map[string]*Job
jobsLock sync.RWMutex
}
// NewExecutor creates a new executor instance
func NewExecutor() *Executor {
return &Executor{
jobs: make(map[string]*Job),
}
}
// ExecuteCommand runs a command and returns a job ID
func (e *Executor) ExecuteCommand(command string, args []string) (string, error) {
job := &Job{
ID: fmt.Sprintf("job-%d", time.Now().UnixNano()),
Command: command,
Args: args,
StartTime: time.Now(),
Status: "running",
}
e.jobsLock.Lock()
e.jobs[job.ID] = job
e.jobsLock.Unlock()
go func() {
cmd := exec.Command(command, args...)
output, err := cmd.CombinedOutput()
e.jobsLock.Lock()
defer e.jobsLock.Unlock()
job.EndTime = time.Now()
job.Output = string(output)
if err != nil {
job.Status = "failed"
job.Error = err.Error()
} else {
job.Status = "completed"
}
}()
return job.ID, nil
}
// GetJob returns information about a specific job
func (e *Executor) GetJob(jobID string) (*Job, error) {
e.jobsLock.RLock()
defer e.jobsLock.RUnlock()
job, exists := e.jobs[jobID]
if !exists {
return nil, fmt.Errorf("job not found: %s", jobID)
}
return job, nil
}
// ListJobs returns all jobs
func (e *Executor) ListJobs() []*Job {
e.jobsLock.RLock()
defer e.jobsLock.RUnlock()
jobs := make([]*Job, 0, len(e.jobs))
for _, job := range e.jobs {
jobs = append(jobs, job)
}
return jobs
}

View File

@@ -0,0 +1,125 @@
package packagemanager
import (
"fmt"
"os/exec"
"runtime"
"strings"
)
// PackageManager handles package installation across different platforms
type PackageManager struct {
platform string
}
// NewPackageManager creates a new package manager instance
func NewPackageManager() *PackageManager {
return &PackageManager{
platform: runtime.GOOS,
}
}
// InstallPackage installs a package using the appropriate package manager
func (pm *PackageManager) InstallPackage(packageName string) (string, error) {
var cmd *exec.Cmd
switch pm.platform {
case "darwin":
// macOS - use Homebrew
cmd = exec.Command("brew", "install", packageName)
case "linux":
// Linux - use apt
cmd = exec.Command("apt", "install", "-y", packageName)
case "windows":
// Windows - use scoop
cmd = exec.Command("scoop", "install", packageName)
default:
return "", fmt.Errorf("unsupported platform: %s", pm.platform)
}
output, err := cmd.CombinedOutput()
return string(output), err
}
// UninstallPackage removes a package
func (pm *PackageManager) UninstallPackage(packageName string) (string, error) {
var cmd *exec.Cmd
switch pm.platform {
case "darwin":
cmd = exec.Command("brew", "uninstall", packageName)
case "linux":
cmd = exec.Command("apt", "remove", "-y", packageName)
case "windows":
cmd = exec.Command("scoop", "uninstall", packageName)
default:
return "", fmt.Errorf("unsupported platform: %s", pm.platform)
}
output, err := cmd.CombinedOutput()
return string(output), err
}
// ListInstalledPackages returns a list of installed packages
func (pm *PackageManager) ListInstalledPackages() ([]string, error) {
var cmd *exec.Cmd
switch pm.platform {
case "darwin":
cmd = exec.Command("brew", "list")
case "linux":
cmd = exec.Command("apt", "list", "--installed")
case "windows":
cmd = exec.Command("scoop", "list")
default:
return nil, fmt.Errorf("unsupported platform: %s", pm.platform)
}
output, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
// Parse output into a list of packages
packages := strings.Split(string(output), "\n")
var result []string
for _, pkg := range packages {
if pkg = strings.TrimSpace(pkg); pkg != "" {
result = append(result, pkg)
}
}
return result, nil
}
// SearchPackage searches for a package
func (pm *PackageManager) SearchPackage(query string) ([]string, error) {
var cmd *exec.Cmd
switch pm.platform {
case "darwin":
cmd = exec.Command("brew", "search", query)
case "linux":
cmd = exec.Command("apt", "search", query)
case "windows":
cmd = exec.Command("scoop", "search", query)
default:
return nil, fmt.Errorf("unsupported platform: %s", pm.platform)
}
output, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
// Parse output into a list of packages
packages := strings.Split(string(output), "\n")
var result []string
for _, pkg := range packages {
if pkg = strings.TrimSpace(pkg); pkg != "" {
result = append(result, pkg)
}
}
return result, nil
}

281
pkg/sal/vm/manager.go Normal file
View File

@@ -0,0 +1,281 @@
package vm
import (
"fmt"
"log"
)
// Manager handles VM operations
type Manager struct {
vms map[string]*VM
}
// VM represents a virtual machine
type VM struct {
Name string
CPU int
Memory string
Disks []Disk
Description string
Running bool
}
// Disk represents a VM disk
type Disk struct {
Name string
Size string
Type string
}
// NewManager creates a new VM manager
func NewManager() *Manager {
return &Manager{
vms: make(map[string]*VM),
}
}
// Define creates a new VM definition
func (m *Manager) Define(params Params) string {
log.Printf("VM Manager: Define called with params: %v", params)
name := params.Get("name")
if name == "" {
return "Error: VM name is required"
}
// Check if VM already exists
if _, exists := m.vms[name]; exists {
return fmt.Sprintf("Error: VM '%s' already exists", name)
}
// Create new VM
cpu := params.GetInt("cpu")
if cpu <= 0 {
cpu = 1
}
memory := params.Get("memory")
if memory == "" {
memory = "1GB"
}
description := params.Get("description")
vm := &VM{
Name: name,
CPU: cpu,
Memory: memory,
Description: description,
Disks: []Disk{},
Running: false,
}
// Add VM to map
m.vms[name] = vm
return fmt.Sprintf("VM '%s' defined successfully with %d CPU(s) and %s memory",
name, cpu, memory)
}
// Start starts a VM
func (m *Manager) Start(params Params) string {
log.Printf("VM Manager: Start called with params: %v", params)
name := params.Get("name")
if name == "" {
return "Error: VM name is required"
}
// Find VM
vm, exists := m.vms[name]
if !exists {
return fmt.Sprintf("Error: VM '%s' not found", name)
}
// Check if already running
if vm.Running {
return fmt.Sprintf("VM '%s' is already running", name)
}
// Start VM
vm.Running = true
return fmt.Sprintf("VM '%s' started successfully", name)
}
// Stop stops a VM
func (m *Manager) Stop(params Params) string {
log.Printf("VM Manager: Stop called with params: %v", params)
name := params.Get("name")
if name == "" {
return "Error: VM name is required"
}
// Find VM
vm, exists := m.vms[name]
if !exists {
return fmt.Sprintf("Error: VM '%s' not found", name)
}
// Check if already stopped
if !vm.Running {
return fmt.Sprintf("VM '%s' is already stopped", name)
}
// Stop VM
vm.Running = false
return fmt.Sprintf("VM '%s' stopped successfully", name)
}
// DiskAdd adds a disk to a VM
func (m *Manager) DiskAdd(params Params) string {
log.Printf("VM Manager: DiskAdd called with params: %v", params)
vmName := params.Get("name")
if vmName == "" {
return "Error: VM name is required"
}
// Find VM
vm, exists := m.vms[vmName]
if !exists {
return fmt.Sprintf("Error: VM '%s' not found", vmName)
}
// Get disk parameters
diskName := params.Get("disk_name")
if diskName == "" {
return "Error: Disk name is required"
}
// Check if disk already exists
for _, disk := range vm.Disks {
if disk.Name == diskName {
return fmt.Sprintf("Error: Disk '%s' already exists on VM '%s'", diskName, vmName)
}
}
// Create new disk
size := params.Get("size")
if size == "" {
size = "10GB"
}
diskType := params.Get("type")
if diskType == "" {
diskType = "ssd"
}
disk := Disk{
Name: diskName,
Size: size,
Type: diskType,
}
// Add disk to VM
vm.Disks = append(vm.Disks, disk)
return fmt.Sprintf("Disk '%s' added to VM '%s' with size %s and type %s",
diskName, vmName, size, diskType)
}
// Delete deletes a VM
func (m *Manager) Delete(params Params) string {
log.Printf("VM Manager: Delete called with params: %v", params)
name := params.Get("name")
if name == "" {
return "Error: VM name is required"
}
// Find VM
vm, exists := m.vms[name]
if !exists {
return fmt.Sprintf("Error: VM '%s' not found", name)
}
// Check if VM is running and force flag is not set
if vm.Running && !params.GetBool("force") {
return fmt.Sprintf("Error: VM '%s' is running. Use force:true to delete anyway", name)
}
// Delete VM
delete(m.vms, name)
return fmt.Sprintf("VM '%s' deleted successfully", name)
}
// List returns a list of all VMs
func (m *Manager) List() string {
log.Printf("VM Manager: List called")
if len(m.vms) == 0 {
return "No VMs defined"
}
var result string
result = "Defined VMs:\n"
for _, vm := range m.vms {
status := "stopped"
if vm.Running {
status = "running"
}
result += fmt.Sprintf("- %s (%s): %d CPU, %s memory\n",
vm.Name, status, vm.CPU, vm.Memory)
if vm.Description != "" {
result += fmt.Sprintf(" Description: %s\n", vm.Description)
}
if len(vm.Disks) > 0 {
result += " Disks:\n"
for _, disk := range vm.Disks {
result += fmt.Sprintf(" - %s: %s %s\n",
disk.Name, disk.Size, disk.Type)
}
}
}
return result
}
// Status returns the status of a VM
func (m *Manager) Status(params Params) string {
log.Printf("VM Manager: Status called with params: %v", params)
name := params.Get("name")
if name == "" {
return "Error: VM name is required"
}
// Find VM
vm, exists := m.vms[name]
if !exists {
return fmt.Sprintf("Error: VM '%s' not found", name)
}
// Get VM status
status := "stopped"
if vm.Running {
status = "running"
}
result := fmt.Sprintf("VM '%s' status: %s\n", vm.Name, status)
result += fmt.Sprintf("CPU: %d\n", vm.CPU)
result += fmt.Sprintf("Memory: %s\n", vm.Memory)
if vm.Description != "" {
result += fmt.Sprintf("Description: %s\n", vm.Description)
}
if len(vm.Disks) > 0 {
result += "Disks:\n"
for _, disk := range vm.Disks {
result += fmt.Sprintf("- %s: %s %s\n",
disk.Name, disk.Size, disk.Type)
}
}
return result
}

38
pkg/sal/vm/params.go Normal file
View File

@@ -0,0 +1,38 @@
package vm
import (
"strconv"
"strings"
)
// Params is a simple helper for working with parameter maps
type Params map[string]string
// Get returns the value for a key
func (p Params) Get(key string) string {
if val, ok := p[key]; ok {
return val
}
return ""
}
// GetInt returns the value for a key as an integer
func (p Params) GetInt(key string) int {
val := p.Get(key)
if val == "" {
return 0
}
i, err := strconv.Atoi(val)
if err != nil {
return 0
}
return i
}
// GetBool returns the value for a key as a boolean
func (p Params) GetBool(key string) bool {
val := strings.ToLower(p.Get(key))
return val == "true" || val == "1" || val == "yes" || val == "y"
}