mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
Introduces proxy_install_only (default: false) which, when enabled, skips the proxy for package manager commands that do not download packages (e.g. npm ls, pip list), avoiding unnecessary MITM overhead. - Add ProxyInstallOnly to Config and config template - Add IsKnownDownloadCommand / MayDownloadPackages to ParsedCommand - Add DownloadCommands to npm and pypi PM configs covering update, ci, audit, dlx, exec, x, download, run and equivalents per PM - Extract shared runner.Execute used by both proxy flow and guard - Proxy flow short-circuits to runner.Execute for non-download commands when proxy_install_only=true
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package runner
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
|
|
"github.com/safedep/dry/log"
|
|
"github.com/safedep/pmg/packagemanager"
|
|
"github.com/safedep/pmg/sandbox/executor"
|
|
"github.com/safedep/pmg/usefulerror"
|
|
)
|
|
|
|
// 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 {
|
|
humanError := "Failed to execute package manager command"
|
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
humanError = fmt.Sprintf("Package manager command exited with code: %d", exitErr.ExitCode())
|
|
}
|
|
|
|
return usefulerror.Useful().
|
|
WithCode(usefulerror.ErrCodePackageManagerExecutionFailed).
|
|
WithHumanError(humanError).
|
|
WithHelp("Check the package manager command and its arguments").
|
|
Wrap(err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|