package handlers import ( "errors" "fmt" "net/http" "os/exec" "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/grpcsrv/commander" "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/models" "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/service" "github.com/gin-gonic/gin" ) type JobsHandlers struct { cmder *commander.Commander svc *service.ScriptService } func NewJobsHandlers(cmder *commander.Commander, svc *service.ScriptService) JobsHandlers { return JobsHandlers{cmder: cmder, svc: svc} } type AddJobIn struct { Command string `json:"command" binding:"required"` InterpreterID int64 `json:"interpreter_id"` Stdin *string `json:"stdin"` AgentID string `json:"agent_id" binding:"required"` } type AddJobOut struct { ID int64 `json:"id"` Command []string `json:"command"` Stdin *string `json:"stdin"` Stdout string `json:"stdout"` Stderr string `json:"stderr"` Status int32 `json:"status"` } // AddJob creates and executes a job on a target agent. // @Summary Create and run a job on an agent // @Description Sends a command to the specified agent, waits for execution, and returns the result // @Tags jobs // @Accept json // @Produce json // @Param body body AddJobIn true "Job request" // @Success 201 {object} AddJobOut // @Security Bearer // @Router /jobs [post] func (self *JobsHandlers) AddJob(c *gin.Context) { err := func() error { var in AddJobIn if err := c.Bind(&in); err != nil { return err } agent, ok := self.cmder.GetAgent(in.AgentID) if !ok { c.Status(http.StatusNotFound) return fmt.Errorf("agent not found") } var command []string if in.InterpreterID == 0 { command = []string{"sh", "-c", in.Command} } else { var err error command, err = self.svc.ResolveCommand( c.Request.Context(), in.InterpreterID, in.Command, ) if err != nil { return err } } jid, err := agent.AddJob(models.JobForInsert{ Command: command, Stdin: in.Stdin, }) if err != nil { return err } job, err := agent.WaitJob(jid) if err != nil && !errors.As(err, &exec.ExitError{}) { return err } c.JSON(http.StatusCreated, AddJobOut{ ID: job.ID, Command: job.Command, Stdin: job.Stdin, Stdout: job.Stdout, Stderr: job.Stderr, Status: job.Status, }) return nil }() if err != nil { c.Error(err) } }