2026-04-17 01:13:30 +05:30
|
|
|
package runner
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
|
|
|
|
|
"github.com/safedep/dry/log"
|
|
|
|
|
"github.com/safedep/pmg/packagemanager"
|
|
|
|
|
"github.com/safedep/pmg/sandbox/executor"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Execute runs a package manager command without proxy or guard analysis.
|
|
|
|
|
// It applies sandbox policy if configured, then executes the command directly.
|
|
|
|
|
func Execute(ctx context.Context, pc *packagemanager.ParsedCommand, pmName string, dryRun bool) error {
|
|
|
|
|
if len(pc.Command.Exe) == 0 {
|
|
|
|
|
return fmt.Errorf("no command to execute")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if dryRun {
|
|
|
|
|
log.Debugf("Dry run, skipping command execution")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd := exec.CommandContext(ctx, pc.Command.Exe, pc.Command.Args...)
|
|
|
|
|
cmd.Stdin = os.Stdin
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
|
|
|
|
|
result, err := executor.ApplySandbox(ctx, cmd, pmName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to apply sandbox: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
if err := result.Close(); err != nil {
|
|
|
|
|
log.Errorf("failed to close sandbox: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
if result.ShouldRun() {
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
2026-05-12 18:11:18 +05:30
|
|
|
exitCode := -1
|
2026-04-17 01:13:30 +05:30
|
|
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
2026-05-12 18:11:18 +05:30
|
|
|
exitCode = exitErr.ExitCode()
|
2026-04-17 01:13:30 +05:30
|
|
|
}
|
2026-05-12 18:11:18 +05:30
|
|
|
return executor.WrapCommandExecutionError(err, result, exitCode)
|
2026-04-17 01:13:30 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|