otsdaq  3.06.00
GatewaySupervisor.h
1 #ifndef _ots_GatewaySupervisor_h
2 #define _ots_GatewaySupervisor_h
3 
4 #include "otsdaq/CoreSupervisors/ConfigurationSupervisorBase.h"
5 #include "otsdaq/CoreSupervisors/CorePropertySupervisorBase.h"
6 #include "otsdaq/FiniteStateMachine/RunControlStateMachine.h"
7 #include "otsdaq/GatewaySupervisor/Iterator.h"
8 #include "otsdaq/SOAPUtilities/SOAPMessenger.h"
9 #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h"
10 #include "otsdaq/WebUsersUtilities/WebUsers.h"
11 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
12 
13 #include "otsdaq/CodeEditor/CodeEditor.h"
14 #include "otsdaq/TablePlugins/DesktopIconTable.h"
15 
16 #include "otsdaq/NetworkUtilities/TransceiverSocket.h" // for UDP state changer
17 
18 #pragma GCC diagnostic push
19 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
20 #include <xdaq/Application.h>
21 #pragma GCC diagnostic pop
22 #include "otsdaq/Macros/XDAQApplicationMacros.h"
23 
24 #include <toolbox/task/WorkLoop.h>
25 #include <xdata/String.h>
26 #include <xgi/Method.h>
27 #include "otsdaq/GatewaySupervisor/PixelHistoPicGen.h"
28 
29 #include <set>
30 #include <sstream>
31 #include <string>
32 
33 // clang-format off
34 
36 // #define FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE std::string("FSMLastConfiguredGroupAlias.hist")
37 // #define FSM_LAST_STARTED_GROUP_ALIAS_FILE std::string("FSMLastStartedGroupAlias.hist")
38 
39 // #define FSM_CONFIGURED_GROUP_ALIASES_FILE std::string("FSMConfiguredGroupAliases.hist")
40 // #define FSM_STARTED_GROUP_ALIASES_FILE std::string("FSMStartedGroupAlias.hist")
41 
42 // #define FSM_CONFIGURED_OR_STARTED_GROUP_ALIASES_FILE std::string("FSMConfiguredOrStartedGroupAlias.hist")
43 
44 // #define FSM_CONFIGURED_CONTEXTS_FILE std::string("FSMConfiguredContexts.hist")
45 // #define FSM_STARTED_CONTEXTS_FILE std::string("FSMStartedContexts.hist")
46 // #define FSM_CONFIGURED_OR_STARTED_CONTEXTS_FILE std::string("FSMConfiguredOrStartedContexts.hist")
47 
48 // #define FSM_CONFIGURED_BACKBONES_FILE std::string("FSMConfiguredBackbones.hist")
49 // #define FSM_STARTED_BACKBONES_FILE std::string("FSMStartedBackbones.hist")
50 // #define FSM_CONFIGURED_OR_STARTED_BACKBONES_FILE std::string("FSMConfiguredOrStartedBackbones.hist")
51 
52 // #define FSM_CONFIGURED_ITERATORS_FILE std::string("FSMConfiguredIterators.hist")
53 // #define FSM_STARTED_ITERATORS_FILE std::string("FSMStartedIterators.hist")
54 // #define FSM_CONFIGURED_OR_STARTED_ITERATORS_FILE std::string("FSMConfiguredOrStartedIterators.hist")
55 
56 
57 namespace ots
58 {
59 class ConfigurationManager;
60 class TableGroupKey;
61 class WorkLoopManager;
62 
63 
68  class GatewaySupervisor : public xdaq::Application,
69  public SOAPMessenger,
73  {
74  friend class WizardSupervisor;
75  friend class Iterator;
76 
77  static const std::string COMMAND_PARAM_LOG_ENTRY_PREAMBLE;
78  static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_PREAMBLE;
79  static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_OVERRIDE_PREAMBLE;
80 
81  public:
82  XDAQ_INSTANTIATOR();
83 
84  GatewaySupervisor (xdaq::ApplicationStub* s);
85  virtual ~GatewaySupervisor (void);
86 
87  void init (void);
88 
89  void Default (xgi::Input* in, xgi::Output* out);
90 
91  void loginRequest (xgi::Input* in, xgi::Output* out);
92  void request (xgi::Input* in, xgi::Output* out);
93  void tooltipRequest (xgi::Input* in, xgi::Output* out);
94  void XGI_Turtle (xgi::Input* in, xgi::Output* out);
95 
96  void addStateMachineStatusToXML (HttpXmlDocument& xmlOut, const std::string& fsmName, bool getRunNumber = true);
97  void addFilteredConfigAliasesToXML (HttpXmlDocument& xmlOut, const std::string& fsmName);
98  void addRequiredFsmLogInputToXML (HttpXmlDocument& xmlOut, const std::string& fsmName);
99 
100  // State Machine requests handlers
101  void stateMachineXgiHandler(xgi::Input* in, xgi::Output* out);
102  void stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out);
103 
104  static std::string getIconHeaderString(void);
105  static bool handleAddDesktopIconRequest(const std::string& author, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut, std::vector<DesktopIconTable::DesktopIcon>* newIcons = nullptr);
106  static void handleGetApplicationIdRequest(AllSupervisorInfo* applicationInfo, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>* portTranslationMap = nullptr);
107 
108  xoap::MessageReference stateMachineXoapHandler(xoap::MessageReference msg);
109 
110  bool stateMachineThread(toolbox::task::WorkLoop* workLoop);
111 
112  // Status requests handlers
113  void statusRequest(xgi::Input* in, xgi::Output* out);
114  void infoRequestResultHandler(xgi::Input* in, xgi::Output* out);
115  bool infoRequestThread(toolbox::task::WorkLoop* workLoop);
116 
117  // External GatewaySupervisor XOAP handlers
118  xoap::MessageReference supervisorCookieCheck(xoap::MessageReference msg);
119  xoap::MessageReference supervisorGetActiveUsers(xoap::MessageReference msg);
120  xoap::MessageReference supervisorSystemMessage(xoap::MessageReference msg);
121  xoap::MessageReference supervisorGetUserInfo(xoap::MessageReference msg);
122  xoap::MessageReference supervisorSystemLogbookEntry(xoap::MessageReference msg);
123  xoap::MessageReference supervisorLastTableGroupRequest(xoap::MessageReference msg);
124 
125  // Finite State Machine States
126  void stateInitial(toolbox::fsm::FiniteStateMachine& fsm) override;
127  void statePaused(toolbox::fsm::FiniteStateMachine& fsm) override;
128  void stateRunning(toolbox::fsm::FiniteStateMachine& fsm) override;
129  void stateHalted(toolbox::fsm::FiniteStateMachine& fsm) override;
130  void stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) override;
131  void inError(toolbox::fsm::FiniteStateMachine& fsm) override;
132 
133  void transitionConfiguring(toolbox::Event::Reference e) override;
134  void transitionHalting(toolbox::Event::Reference e) override;
135  void transitionInitializing(toolbox::Event::Reference e) override;
136  void transitionPausing(toolbox::Event::Reference e) override;
137  void transitionResuming(toolbox::Event::Reference e) override;
138  void transitionStarting(toolbox::Event::Reference e) override;
139  void transitionStopping(toolbox::Event::Reference e) override;
140  void transitionShuttingDown(toolbox::Event::Reference e) override;
141  void transitionStartingUp(toolbox::Event::Reference e) override;
142  void enteringError(toolbox::Event::Reference e) override;
143 
144  void makeSystemLogEntry(const std::string& entryText, const std::string& subjectText = "");
145  static void addSystemMessage(std::string toUserCSV, std::string message);
146 
147  void checkForAsyncError(void);
148 
149  // CorePropertySupervisorBase override functions
150  virtual void setSupervisorPropertyDefaults (void) override;
151  virtual void forceSupervisorPropertyValues (void) override;
152 
153 
154  private:
155  unsigned int getNextRunNumber (const std::string& fsmName = "");
156  void setNextRunNumber (unsigned int runNumber, const std::string& fsmName = "");
157  std::string getLastLogEntry (const std::string& logType, const std::string& fsmName = "");
158  void setLastLogEntry (const std::string& logType, const std::string& logEntry, const std::string& fsmName = "");
159 
160 
161  static xoap::MessageReference lastTableGroupRequestHandler (const SOAPParameters& parameters);
162  static void launchStartOTSCommand (const std::string& command, ConfigurationManager* cfgMgr);
163  static void launchStartOneServerCommand (const std::string& command, ConfigurationManager* cfgMgr, const std::string& contextName);
164 
165  static void indicateOtsAlive (const CorePropertySupervisorBase* properties = 0);
166  xoap::MessageReference TRACESupervisorRequest (xoap::MessageReference message);
167 
168  static void StateChangerWorkLoop (GatewaySupervisor* supervisorPtr);
169  static void AppStatusWorkLoop (GatewaySupervisor* supervisorPtr, const bool doDisconnected = false);
170 
171  std::string attemptStateMachineTransition (HttpXmlDocument* xmldoc,
172  std::ostringstream* out,
173  const std::string& command,
174  const std::string& fsmName,
175  const std::string& fsmWindowName,
176  const std::string& username,
177  const std::vector<std::string>& parameters,
178  std::string logEntry = "");
179  void broadcastMessage (xoap::MessageReference msg);
180  void broadcastMessageToRemoteGateways (const xoap::MessageReference msg);
181  bool broadcastMessageToRemoteGatewaysComplete (const xoap::MessageReference msg);
182  void signalAndWaitForBroadcastThreads (unsigned int numberOfThreads);
183 
184  struct BroadcastMessageIterationsDoneStruct
185  {
186  // Creating std::vector<std::vector<bool>>
187  // because of problems with the standard library
188  // not allowing passing by reference of bool types.
189  // Broadcast thread implementation requires passing by reference.
190  ~BroadcastMessageIterationsDoneStruct()
191  {
192  for (auto& arr : iterationsDone_)
193  delete[] arr;
194  iterationsDone_.clear();
195  arraySizes_.clear();
196  } // end destructor
197 
198  void push(const unsigned int& size)
199  {
200  iterationsDone_.push_back(new bool[size]);
201  arraySizes_.push_back(size);
202 
203  // initialize to false
204  for (unsigned int i = 0; i < size; ++i)
205  iterationsDone_[iterationsDone_.size() - 1][i] = false;
206  } // end push()
207 
208  bool* operator[](unsigned int i) { return iterationsDone_[i]; }
209  const bool* operator[](unsigned int i) const { return iterationsDone_[i]; }
210  unsigned int size(unsigned int i = -1)
211  {
212  if (i == (unsigned int)-1)
213  return iterationsDone_.size();
214  return arraySizes_[i];
215  }
216 
217  private:
218  std::vector<bool*> iterationsDone_;
219  std::vector<unsigned int> arraySizes_;
220  }; // end BroadcastMessageIterationsDoneStruct definition
221 
222  struct BroadcastThreadStruct
223  {
224  //===================
225  BroadcastThreadStruct()
226  : threadIndex_(-1)
227  , exitThread_(false)
228  , working_(true)
229  , workToDo_(false)
230  , error_(false)
231  {
232  } // end BroadcastThreadStruct constructor()
233 
234  //===================
235  BroadcastThreadStruct(BroadcastThreadStruct &&b)
236  : threadIndex_(b.threadIndex_)
237  , exitThread_(b.exitThread_)
238  , working_(b.working_)
239  , workToDo_(b.workToDo_)
240  , error_(b.error_)
241  {
242  } // end BroadcastThreadStruct move constructor()
243 
244 
246  {
247  //===================
248  BroadcastMessageStruct(const SupervisorInfo& appInfo,
249  xoap::MessageReference message,
250  const std::string& command,
251  const unsigned int& iteration,
252  bool& iterationsDone,
253  std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner)
254  : appInfo_(appInfo)
255  , message_(message)
256  , command_(command)
257  , iteration_(iteration)
258  , iterationsDone_(iterationsDone)
259  , iterationsDoneOwner_(iterationsDoneOwner)
260  {
261  }
262 
263  const SupervisorInfo& appInfo_;
264  xoap::MessageReference message_;
265  const std::string command_;
266  const unsigned int iteration_;
267  bool& iterationsDone_;
268  // Keep the BroadcastMessageIterationsDoneStruct alive while this message
269  // is in use by a thread, preventing UAF even if broadcastMessage() returns
270  // early (e.g. on timeout or exception) before the thread finishes.
271  std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner_;
272 
273  std::string reply_;
274  }; // end BroadcastMessageStruct definition
275 
276  //===================
277  void setMessage(const SupervisorInfo& appInfo,
278  xoap::MessageReference message,
279  const std::string& command,
280  const unsigned int& iteration,
281  bool& iterationsDone,
282  std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner)
283  {
284  messages_.clear();
286  appInfo, message, command, iteration, iterationsDone, iterationsDoneOwner));
287  workToDo_ = true;
288  } // end setMessage()
289 
290  const SupervisorInfo& getAppInfo() { return messages_[0].appInfo_; }
291  xoap::MessageReference getMessage() { return messages_[0].message_; }
292  const std::string& getCommand() { return messages_[0].command_; }
293  const unsigned int& getIteration() { return messages_[0].iteration_; }
294  std::string& getReply() { return messages_[0].reply_; }
295  bool& getIterationsDone() { return messages_[0].iterationsDone_; }
296 
297  // each thread accesses these members
298  std::mutex threadMutex_;
299  unsigned int threadIndex_;
300  volatile bool exitThread_, working_, workToDo_, error_;
301  // always just 1 message (for now)
302  std::vector<BroadcastThreadStruct::BroadcastMessageStruct> messages_;
303 
304  }; // end BroadcastThreadStruct declaration
305  static void broadcastMessageThread(
306  GatewaySupervisor* supervisorPtr,
307  std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct> threadStruct);
308  bool handleBroadcastMessageTarget(const SupervisorInfo& appInfo,
309  xoap::MessageReference message,
310  const std::string& command,
311  const unsigned int& iteration,
312  std::string& reply,
313  unsigned int threadIndex = 0);
314 
315 
316  // Member Variables -----------------------
317 
318  bool supervisorGuiHasBeenLoaded_;
319  static WebUsers theWebUsers_;
320  std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */,
321  std::string /* translatedHostPort */>>
322  portTranslationMap_;
323 
324  WorkLoopManager stateMachineWorkLoopManager_;
325  toolbox::BSem stateMachineSemaphore_;
326 
327  std::string activeStateMachineName_;
328  std::string activeStateMachineWindowName_;
329  std::string activeStateMachineDumpFormatOnRun_, activeStateMachineDumpFormatOnConfigure_;
330  std::string activeStateMachineSystemDumpOnRun_, activeStateMachineSystemDumpOnConfigure_;
331  bool activeStateMachineSystemDumpOnRunEnable_, activeStateMachineSystemDumpOnConfigureEnable_;
332  std::string activeStateMachineSystemDumpOnRunFilename_, activeStateMachineSystemDumpOnConfigureFilename_;
333  bool activeStateMachineRequireUserLogOnRun_, activeStateMachineRequireUserLogOnConfigure_;
334  std::string activeStateMachineRunInfoPluginType_;
335  std::map<std::string /* fsmName */, std::string /* logEntry */>
336  stateMachineConfigureLogEntry_, stateMachineStartLogEntry_, stateMachineStopLogEntry_;
337  std::string activeStateMachineRunNumber_, activeStateMachineRunAlias_, activeStateMachineConfigurationAlias_;
338  bool activeStateMachineRollOverLogOnConfigure_, activeStateMachineRollOverLogOnStart_;
339  std::chrono::steady_clock::time_point
340  activeStateMachineRunStartTime;
341  int activeStateMachineRunDuration_ms;
342  unsigned int activeStateMachineConfigureConditionID_, activeStateMachineRunConditionID_;
343  std::string activeStateMachineSubsystemCommonList_, activeStateMachineSubsystemCommonOverrideList_;
344 
345  std::mutex systemStatusMutex_;
346  std::string lastLogbookEntry_;
347  time_t lastLogbookEntryTime_ = 0;
348 
349  std::string lastConsoleErr_, lastConsoleWarn_, lastConsoleInfo_, lastConsoleErrTime_, lastConsoleWarnTime_, lastConsoleInfoTime_;
350  std::string firstConsoleErr_, firstConsoleWarn_, firstConsoleInfo_, firstConsoleErrTime_, firstConsoleWarnTime_, firstConsoleInfoTime_;
351  size_t systemConsoleErrCount_ = 0, systemConsoleWarnCount_ = 0, systemConsoleInfoCount_ = 0;
352 
353  std::pair<std::string /*group name*/, TableGroupKey>
354  theConfigurationTableGroup_;
355  std::string stateMachineTransitionUsername_;
356 
357  Iterator theIterator_;
358  std::mutex stateMachineAccessMutex_;
360  std::string stateMachineLastCommandInput_;
361  enum
362  {
363  VERBOSE_MUTEX = 0
364  };
365 
366  CodeEditor codeEditor_;
367 
368  std::mutex broadcastCommandMessageIndexMutex_, broadcastIterationsDoneMutex_;
369  unsigned int broadcastCommandMessageIndex_;
370  bool broadcastIterationsDone_;
371  std::mutex broadcastIterationBreakpointMutex_;
372  unsigned int broadcastIterationBreakpoint_;
374  std::mutex broadcastCommandStatusUpdateMutex_;
375  std::string broadcastCommandStatus_;
376  static std::vector<std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct>> broadcastThreadStructs_;
377 
378  std::string securityType_;
379  PixelHistoPicGen picGen_;
380 
381  //Variable used by the RunInfo plugin
382  unsigned int conditionID_;
383 
384 public: //used by remote subsystem control and status
385 
388 
389  enum class ConfigDumpTypes
390  {
391  Text,
392  JSON_all,
393  Unknown
394  };
395 
396  std::string command, fsmName;
397  private: //make error private to connect to set timestamp
398  std::string error;
399  time_t errorTimestamp = 0;
400  public:
401  void setError(const std::string& err) { error = err; errorTimestamp = time(0); }
402  void clearError() { error = ""; errorTimestamp = 0; }
403  void copyError(const RemoteGatewayInfo& r) { error = r.error; errorTimestamp = r.errorTimestamp; }
404  const std::string& getError() const { return error; }
405  const std::string getErrorTimestamp() const { return StringMacros::getTimestampString(errorTimestamp); }
406 
407  std::string config_dump;
408  ConfigDumpTypes config_dump_type = ConfigDumpTypes::Unknown;
409 
410  size_t ignoreStatusCount = 0;
411 
412  size_t consoleErrCount = 0, consoleWarnCount = 0;
413 
414  std::string fullName;
415  std::string user_data_path_record;
416  std::string setupType, instancePath, instanceHost, instanceUser;
417 
418  std::string selected_config_alias;
419  std::set<std::string> config_aliases;
420  std::string iconString, parentIconFolderPath, landingPage, permissionThresholdString;
421 
422  std::string usernameWithLock;
423 
424  enum class FSM_ModeTypes
425  {
426  Follow_FSM,
427  DoNotHalt,
428  OnlyConfigure,
429  };
430  FSM_ModeTypes fsm_mode = FSM_ModeTypes::Follow_FSM;
431  bool fsm_included = true;
432 
433  std::string getFsmMode() const {
434  switch(fsm_mode)
435  {
436  case FSM_ModeTypes::Follow_FSM: return "Follow FSM";
437  case FSM_ModeTypes::DoNotHalt: return "Do Not Halt";
438  case FSM_ModeTypes::OnlyConfigure: return "Only Configure";
439  default: return "Impossible";
440  }
441  } //end getFsmMode()
442 
443  std::string getConfigDumpType() const {
444  switch(config_dump_type)
445  {
446  case ConfigDumpTypes::Text: return "Text";
447  case ConfigDumpTypes::JSON_all: return "JSON all";
448  default: return "Unknown";
449  }
450  } //end getFsmMode()
451 
452  std::map<std::string, SupervisorInfo::SubappInfo> subapps;
453  }; //end GatewaySupervisor::RemoteGatewayInfo struct
454 
455  std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps_;
456  std::mutex remoteGatewayAppsMutex_;
457  std::map<std::string /* appName */,
458  bool /* lastStatusGood */> appLastStatusGood_;
459  std::mutex dualStatusThreadMutex_;
460 
461  std::map<unsigned int /* lid */, SupervisorInfo> localAllSupervisorInfo_;
462 
463 
464  std::mutex latestGatewayIconsMutex_;
465  std::vector<DesktopIconTable::DesktopIcon> latestGatewayIcons_;
466  std::pair<std::string /* latestIconContext group */, TableGroupKey>
468 
470  std::pair<std::string /* latestIconContext group */, TableGroupKey>
472 
473  static void CheckRemoteGatewayStatus (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket, const std::string& ipForReverseLoginOverUDP, int portForReverseLoginOverUDP);
474  static void SendRemoteGatewayCommand (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket);
475  static void GetRemoteGatewayIcons (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket);
476  void loadRemoteGatewaySettings (std::vector<GatewaySupervisor::RemoteGatewayInfo>& remoteGateways, bool onlyNotFound = false) const;
477  void saveRemoteGatewaySettings (void) const;
478  static std::string translateURLForRequestOrigin (const std::string& url, const std::string& requestOrigin, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
479  static std::string translateRemoteIconStringForRequestOrigin (const std::string& iconString, const std::string& requestOrigin, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
480 
481  };
482 // clang-format on
483 
484 } // namespace ots
485 
486 #endif
friend class GatewaySupervisor
for access to indicateOtsAlive()
std::string latestGatewayRemoteIconsString_
cached string of remote gateway icons for quick access
virtual void setSupervisorPropertyDefaults(void) override
override to control supervisor specific defaults
void stateHalted(toolbox::fsm::FiniteStateMachine &fsm) override
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
std::vector< DesktopIconTable::DesktopIcon > latestGatewayIcons_
used to track the latest desktop icons (which are defined by the active context but allowed to change...
void statePaused(toolbox::fsm::FiniteStateMachine &fsm) override
void stateRunning(toolbox::fsm::FiniteStateMachine &fsm) override
std::map< unsigned int, SupervisorInfo > localAllSupervisorInfo_
only use in main thread, stable copy of app status
std::pair< std::string, TableGroupKey > latestGatewayIconsContextGroup_
used to track the table group key for the latest desktop icons
void stateConfigured(toolbox::fsm::FiniteStateMachine &fsm) override
void stateInitial(toolbox::fsm::FiniteStateMachine &fsm) override
std::pair< std::string, TableGroupKey > latestGatewayRemoteIconsContextGroup_
used to track the table group key for the latest remote desktop icons
defines used also by OtsConfigurationWizardSupervisor
ConfigDumpTypes
<FSM Modes: 'Follow FSM,' 'Do not Halt' (artdaq), or 'Only Configure' (DCS/DQM)
FSM_ModeTypes
<FSM Modes: 'Follow FSM,' 'Do not Halt' (artdaq), or 'Only Configure' (DCS/DQM)
std::string permissionThresholdString
used for desktop icons
std::set< std::string > config_aliases
used for remote gateway subapp control
std::string selected_config_alias
used for remote gateway subapp control
FSM_ModeTypes fsm_mode
used for remote gateway subapp control
std::string fsmName
when not "", need to send
std::map< std::string, SupervisorInfo::SubappInfo > subapps
remote gateways can have subapps
size_t ignoreStatusCount
if non-zero, do not ask for status
std::string instanceUser
used for remote ots instance ssh launch
std::string user_data_path_record
used for remote gateway subapp control
static std::string getTimestampString(const std::string &linuxTimeInSeconds)