MCPcopy Create free account
hub / github.com/keploy/keploy / Agent

Function Agent

cli/agent.go:19–102  ·  view source on GitHub ↗
(ctx context.Context, logger *zap.Logger, conf *config.Config, serviceFactory ServiceFactory, cmdConfigurator CmdConfigurator)

Source from the content-addressed store, hash-verified

17}
18
19func Agent(ctx context.Context, logger *zap.Logger, conf *config.Config, serviceFactory ServiceFactory, cmdConfigurator CmdConfigurator) *cobra.Command {
20 var cmd = &cobra.Command{
21 Use: "agent",
22 Short: "starts keploy agent for hooking and starting proxy",
23 // Hidden: true,
24 PreRunE: func(cmd *cobra.Command, _ []string) error {
25 return cmdConfigurator.Validate(ctx, cmd)
26 },
27 RunE: func(cmd *cobra.Command, _ []string) error {
28 svc, err := serviceFactory.GetService(ctx, cmd.Name())
29 if err != nil {
30 utils.LogError(logger, err, "failed to get service")
31 return nil
32 }
33
34 var a agent.Service
35 var ok bool
36 if a, ok = svc.(agent.Service); !ok {
37 utils.LogError(logger, nil, "service doesn't satisfy agent service interface")
38 return nil
39 }
40
41 // Self-terminate (gracefully) if the parent keploy client dies
42 // abnormally, so the agent never orphans and keeps eBPF hooks /
43 // DNS / proxy+ingress ports alive that would hang the next run.
44 // Read the flags directly so this never depends on config wiring.
45 //
46 // Skip it in docker mode: there the agent runs in its OWN
47 // `docker run --rm` container (separate PID namespace), so
48 // --client-pid is the *host* keploy PID and is not visible here —
49 // kill(pid, 0) would return ESRCH and we'd self-terminate
50 // immediately, breaking record/replay. The container's --rm
51 // lifecycle bounds the agent in that mode instead.
52 clientPID, cpErr := cmd.Flags().GetUint32("client-pid")
53 isDocker, dockErr := cmd.Flags().GetBool("is-docker")
54 switch {
55 case cpErr != nil || dockErr != nil:
56 // A flag was renamed/removed or the command was built without
57 // AddFlags. Don't guess — leave the watchdog off and say so,
58 // rather than silently watching a zero PID.
59 logger.Debug("could not read client-pid/is-docker flags; parent-death watchdog left disabled",
60 zap.NamedError("clientPidErr", cpErr), zap.NamedError("isDockerErr", dockErr))
61 case isDocker:
62 logger.Debug("parent-death watchdog disabled in docker mode (separate PID namespace; --rm bounds the container)")
63 default:
64 watchParentProcess(ctx, logger, int(clientPID))
65 }
66
67 startAgentCh := make(chan int)
68 router := chi.NewRouter()
69
70 routes.ActiveHooks.New(router, a, logger)
71 go func() {
72 select {
73 case <-ctx.Done():
74 logger.Info("context cancelled before agent http server could start")
75 return
76 case p := <-startAgentCh:

Callers

nothing calls this directly

Calls 11

SetupMethod · 0.95
LogErrorFunction · 0.92
StartAgentServerFunction · 0.92
NameMethod · 0.80
watchParentProcessFunction · 0.70
ValidateMethod · 0.65
GetServiceMethod · 0.65
DebugMethod · 0.65
NewMethod · 0.65
AfterSetupMethod · 0.65
AddFlagsMethod · 0.65

Tested by

no test coverage detected