in cmd/ops_agent_uap_plugin/service_windows.go [80:160]
func (ps *OpsAgentPluginServer) Start(ctx context.Context, msg *pb.StartRequest) (*pb.StartResponse, error) {
ps.mu.Lock()
if ps.cancel != nil {
log.Printf("The Ops Agent plugin is started already, skipping the current request")
ps.mu.Unlock()
return &pb.StartResponse{}, nil
}
log.Printf("Received a Start request: %s. Starting the Ops Agent", msg)
pContext, cancel := context.WithCancel(context.Background())
ps.cancel = cancel
ps.mu.Unlock()
// Detect conflicting installations.
preInstalledAgents, err := findPreExistentAgents(&windowsServiceManager{}, AgentWindowsServiceName)
if len(preInstalledAgents) != 0 || err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
log.Printf("Start() failed: %s", err)
return nil, status.Error(9, err.Error()) // FailedPrecondition
}
// Calculate plugin install and state dirs.
pluginInstallDir, err := osext.ExecutableFolder()
if err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
log.Printf("Start() failed, because it cannot determine the plugin install location: %s", err)
return nil, status.Error(13, err.Error()) // Internal
}
pluginStateDir := msg.GetConfig().GetStateDirectoryPath()
if pluginStateDir == "" {
pluginStateDir = DefaultPluginStateDirectory
}
log.Printf("Determined pluginInstallDir: %v, and pluginStateDir: %v", pluginInstallDir, pluginStateDir)
// Create a windows Event logger. This is used to log generated subagent configs, and health check results.
windowsEventLogger, err := createWindowsEventLogger()
if err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
log.Printf("Start() failed, because it failed to create Windows event logger: %s", err)
return nil, status.Error(13, err.Error()) // Internal
}
// Receive config from the Start request and write it to the Ops Agent config file.
if err := writeCustomConfigToFile(msg, OpsAgentConfigLocationWindows); err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
windowsEventLogger.Close()
log.Printf("Start() failed, because it failed to write the custom Ops Agent config to file: %s", err)
return nil, status.Errorf(13, "failed to write the custom Ops Agent config to file: %s", err) // Internal
}
// Subagents config validation and generation.
if err := generateSubAgentConfigs(ctx, OpsAgentConfigLocationWindows, pluginStateDir, windowsEventLogger); err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
windowsEventLogger.Close()
log.Printf("Start() failed at the subagent config validation and generation step: %s", err)
return nil, status.Error(9, err.Error()) // FailedPrecondition
}
// Trigger Healthchecks.
healthCheckFileLogger := healthchecks.CreateHealthChecksLogger(filepath.Join(pluginStateDir, LogsDirectory))
runHealthChecks(healthCheckFileLogger, windowsEventLogger)
// Create a Windows Job object and stores its handle, to ensure that all child processes are killed when the parent process exits.
_, err = createWindowsJobHandle()
if err != nil {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
windowsEventLogger.Close()
log.Printf("Start() failed, because it failed to create a Windows Job object: %s", err)
return nil, status.Error(13, err.Error()) // Internal
}
cancelFunc := func() {
ps.Stop(ctx, &pb.StopRequest{Cleanup: false})
windowsEventLogger.Close()
}
go runSubagents(pContext, cancelFunc, pluginInstallDir, pluginStateDir, runSubAgentCommand, ps.runCommand)
return &pb.StartResponse{}, nil
}