Repository navigation
Expand file tree
/
Copy pathinternal.go
More file actions
85 lines (72 loc) · 2.37 KB
/
Copy pathinternal.go
File metadata and controls
85 lines (72 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package server
import (
"context"
"fmt"
"log/slog"
"os/exec"
"slices"
"strings"
"github.com/roadrunner-server/errors"
"github.com/roadrunner-server/pool/v2/ipc/pipe"
"github.com/roadrunner-server/pool/v2/ipc/socket"
"github.com/roadrunner-server/pool/v2/pool"
"github.com/roadrunner-server/pool/v2/process"
"github.com/roadrunner-server/tcplisten"
)
// prepareCmd normalises a command slice: a single-element slice whose value is
// a space-separated string is split into individual arguments; a multi-element
// slice is used as-is.
func prepareCmd(command []string) []string {
if len(command) == 1 {
return strings.Fields(command[0])
}
return command
}
// customCmd creates worker commands and uses the server command by default.
func (p *Plugin) customCmd(env map[string]string) pool.Command {
return func(command []string) *exec.Cmd {
// if no command provided, use the server's one
if len(command) == 0 {
command = p.cfg.Command
}
preparedCmd := prepareCmd(command)
cmd := exec.CommandContext(context.Background(), preparedCmd[0], preparedCmd[1:]...)
// copy prepared envs
cmd.Env = slices.Clone(p.preparedEnvs)
// append external envs
for k, v := range env {
cmd.Env = append(cmd.Env, strings.ToUpper(k)+"="+v)
}
process.IsolateProcess(cmd)
// if a user is not empty, and the OS is linux or macOS,
// execute php worker from that particular user
if p.cfg.User != "" {
err := process.ExecuteFromUser(cmd, p.cfg.User)
if err != nil {
panic(fmt.Errorf("RoadRunner can't execute process from the specified user: %s, error: %w", p.cfg.User, err))
}
}
return cmd
}
}
// creates relay and worker factory.
func initFactory(log *slog.Logger, relay string, relaySocket *tcplisten.UnixSocketOptions) (pool.Factory, error) {
const op = errors.Op("server_plugin_init_factory")
if relay == "" || relay == pipes {
return pipe.NewPipeFactory(log), nil
}
network, _, ok := strings.Cut(relay, delim)
if !ok {
return nil, errors.E(op, errors.Network, errors.Str("invalid DSN (tcp://:6001, unix://file.sock)"))
}
lsn, err := tcplisten.CreateListenerWithOptions(relay, relaySocket)
if err != nil {
return nil, errors.E(op, errors.Network, err)
}
switch network {
case unix, tcp:
return socket.NewSocketServer(lsn, log), nil
default:
return nil, errors.E(op, errors.Network, errors.Str("invalid DSN (tcp://:6001, unix://file.sock)"))
}
}