Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Static Private Attributes
Arc::TargetRetrieverARC0 Class Reference

#include <TargetRetrieverARC0.h>

Inheritance diagram for Arc::TargetRetrieverARC0:
Inheritance graph
[legend]
Collaboration diagram for Arc::TargetRetrieverARC0:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ~TargetRetrieverARC0 ()
void GetTargets (TargetGenerator &mom, int targetType, int detailLevel)
 Method for collecting targets.

Static Public Member Functions

static PluginInstance (PluginArgument *arg)

Protected Attributes

const std::string flavour
const UserConfigusercfg
const URL url
const ServiceType serviceType

Private Member Functions

 TargetRetrieverARC0 (const UserConfig &usercfg, const URL &url, ServiceType st)
ThreadArgCreateThreadArg (TargetGenerator &mom, int targetType, int detailLevel)

Static Private Member Functions

static void QueryIndex (void *arg)
static void InterrogateTarget (void *arg)

Static Private Attributes

static Logger logger

Detailed Description

Definition at line 14 of file TargetRetrieverARC0.h.


Constructor & Destructor Documentation

Arc::TargetRetrieverARC0::TargetRetrieverARC0 ( const UserConfig usercfg,
const URL url,
ServiceType  st 
) [private]

Definition at line 44 of file TargetRetrieverARC0.cpp.

    : TargetRetriever(usercfg, url, st, "ARC0") {}

Here is the caller graph for this function:

Definition at line 48 of file TargetRetrieverARC0.cpp.

{}

Member Function Documentation

ThreadArg * Arc::TargetRetrieverARC0::CreateThreadArg ( TargetGenerator mom,
int  targetType,
int  detailLevel 
) [private]

Definition at line 30 of file TargetRetrieverARC0.cpp.

                                                                   {
    ThreadArg *arg = new ThreadArg;
    arg->mom = &mom;
    arg->usercfg = &usercfg;
    arg->url = url;
    arg->targetType = targetType;
    arg->detailLevel = detailLevel;
    return arg;
  }

Here is the caller graph for this function:

void Arc::TargetRetrieverARC0::GetTargets ( TargetGenerator mom,
int  targetType,
int  detailLevel 
) [virtual]

Method for collecting targets.

Pure virtual method for collecting targets. Implementation depends on the Grid middleware in question and is thus left to the specialized class.

Parameters:
momis the reference to the TargetGenerator which has loaded the TargetRetriever
targetTypeis the identificaion of targets to find (0=ExecutionTargets, 1=Grid Jobs)
detailLevelis the required level of details (1 = All details, 2 = Limited details)

Implements Arc::TargetRetriever.

Definition at line 58 of file TargetRetrieverARC0.cpp.

                                                        {

    logger.msg(VERBOSE, "TargetRetriverARC0 initialized with %s service url: %s",
               tostring(serviceType), url.str());

    switch (serviceType) {
    case COMPUTING:
      if (mom.AddService(url)) {
        ThreadArg *arg = CreateThreadArg(mom, targetType, detailLevel);
        if (!CreateThreadFunction(&InterrogateTarget, arg)) {
          delete arg;
          mom.RetrieverDone();
        }
      }
      break;
    case INDEX:
      if (mom.AddIndexServer(url)) {
        ThreadArg *arg = CreateThreadArg(mom, targetType, detailLevel);
        if (!CreateThreadFunction(&QueryIndex, arg)) {
          delete arg;
          mom.RetrieverDone();
        }
      }
      break;
    }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 50 of file TargetRetrieverARC0.cpp.

                                                           {
    TargetRetrieverPluginArgument *trarg =
      dynamic_cast<TargetRetrieverPluginArgument*>(arg);
    if (!trarg)
      return NULL;
    return new TargetRetrieverARC0(*trarg, *trarg, *trarg);
  }

Here is the call graph for this function:

void Arc::TargetRetrieverARC0::InterrogateTarget ( void *  arg) [static, private]

Definition at line 171 of file TargetRetrieverARC0.cpp.

                                                       {
    ThreadArg *thrarg = (ThreadArg*)arg;
    TargetGenerator& mom = *thrarg->mom;
    const UserConfig& usercfg = *thrarg->usercfg;
    int targetType = thrarg->targetType;

    //Create credential object in order to get the user DN
    Credential credential(!usercfg.ProxyPath().empty() ? usercfg.ProxyPath() :
                                                         usercfg.CertificatePath(),
                          !usercfg.ProxyPath().empty() ? usercfg.ProxyPath() :
                                                         usercfg.KeyPath(),
                          usercfg.CACertificatesDirectory(), "");

    //Query GRIS for all relevant information
    URL url = thrarg->url;
    url.ChangeLDAPScope(URL::subtree);

    if (targetType == 0)
      url.ChangeLDAPFilter("(|(objectclass=nordugrid-cluster)"
                           "(objectclass=nordugrid-queue)"
                           "(nordugrid-authuser-sn=" +
                           credential.GetIdentityName() + "))");
    else if (targetType == 1)
      url.ChangeLDAPFilter("(|(nordugrid-job-globalowner=" +
                           credential.GetIdentityName() + "))");

    DataHandle handler(url, usercfg);
    DataBuffer buffer;

    if (!handler) {
      logger.msg(INFO, "Can't create information handle - "
                 "is the ARC ldap DMC plugin available?");
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    if (!handler->StartReading(buffer)) {
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    int handle;
    unsigned int length;
    unsigned long long int offset;
    std::string result;

    while (buffer.for_write() || !buffer.eof_read())
      if (buffer.for_write(handle, length, offset, true)) {
        result.append(buffer[handle], length);
        buffer.is_written(handle);
      }

    if (!handler->StopReading()) {
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    XMLNode xmlresult(result);

    if (targetType == 0) {

      XMLNodeList queues =
        xmlresult.XPathLookup("//nordugrid-queue-name"
                              "[objectClass='nordugrid-queue']", NS());

      for (XMLNodeList::iterator it = queues.begin();
           it != queues.end(); it++) {

        XMLNode queue = *it;
        XMLNode cluster = queue.Parent();
        XMLNode authuser =
          (*it)["nordugrid-info-group-name"]["nordugrid-authuser-name"];

        ExecutionTarget target;

        target.GridFlavour = "ARC0";
        target.Cluster = thrarg->url;

        // Location attributes
        if (cluster["nordugrid-cluster-location"])
          target.PostCode = (std::string)cluster["nordugrid-cluster-location"];

        // Admin Domain attributes
        if (cluster["nordugrid-cluster-aliasname"])
          target.DomainName =
            (std::string)cluster["nordugrid-cluster-aliasname"];
        if (cluster["nordugrid-cluster-owner"])
          target.Owner = (std::string)cluster["nordugrid-cluster-owner"];

        // Computing Service attributes
        if (cluster["nordugrid-cluster-name"])
          target.ServiceName = (std::string)cluster["nordugrid-cluster-name"];
        target.ServiceType = "org.nordugrid.arc-classic";

        // Computing Endpoint attributes
        if (cluster["nordugrid-cluster-contactstring"])
          target.url = (std::string)cluster["nordugrid-cluster-contactstring"];
        target.Capability.push_back("executionmanagement.jobexecution");
        target.Capability.push_back("executionmanagement.jobmanager");
        target.Technology = "gridftp";
        if (cluster["nordugrid-cluster-middleware"]) {
          std::string mw =
            (std::string)cluster["nordugrid-cluster-middleware"];
          std::string::size_type pos1 = mw.find('-');
          if (pos1 == std::string::npos)
            target.Implementor = mw;
          else {
            target.Implementor = mw.substr(0, pos1);
            target.Implementation = mw.substr(pos1 + 1);
          }
        }
        if (queue["nordugrid-queue-status"]) {
          target.HealthStateInfo =
            (std::string)queue["nordugrid-queue-status"];
          if (target.HealthStateInfo.substr(0, 6) == "active")
            target.HealthState = "ok";
          else if (target.HealthStateInfo.substr(0, 8) == "inactive")
            target.HealthState = "critical";
          else
            target.HealthState = "other";
        }
        if (cluster["nordugrid-cluster-issuerca"])
          target.IssuerCA = (std::string)cluster["nordugrid-cluster-issuerca"];
        if (cluster["nordugrid-cluster-trustedca"])
          for (XMLNode n = cluster["nordugrid-cluster-trustedca"]; n; ++n)
            target.TrustedCA.push_back((std::string)n);
        target.Staging = "staginginout";
        target.JobDescriptions.push_back("nordugrid:xrsl");
        target.JobDescriptions.push_back("ogf:jsdl");

        // Computing Share attributes
        if (queue["nordugrid-queue-name"])
          target.ComputingShareName = (std::string)queue["nordugrid-queue-name"];
        if (queue["nordugrid-queue-maxwalltime"])
          target.MaxWallTime =
            (std::string)queue["nordugrid-queue-maxwalltime"];
        if (queue["nordugrid-queue-minwalltime"])
          target.MinWallTime =
            (std::string)queue["nordugrid-queue-minwalltime"];
        if (queue["nordugrid-queue-defaultwalltime"])
          target.DefaultWallTime =
            (std::string)queue["nordugrid-queue-defaultwalltime"];
        if (queue["nordugrid-queue-maxcputime"])
          target.MaxCPUTime =
            (std::string)queue["nordugrid-queue-maxcputime"];
        if (queue["nordugrid-queue-mincputime"])
          target.MinCPUTime =
            (std::string)queue["nordugrid-queue-mincputime"];
        if (queue["nordugrid-queue-defaultcputime"])
          target.DefaultCPUTime =
            (std::string)queue["nordugrid-queue-defaultcputime"];
        if (queue["nordugrid-queue-maxrunning"])
          target.MaxRunningJobs =
            stringtoi((std::string)queue["nordugrid-queue-maxrunning"]);
        if (queue["nordugrid-queue-maxqueable"])
          target.MaxWaitingJobs =
            stringtoi((std::string)queue["nordugrid-queue-maxqueable"]);
        if (queue["nordugrid-queue-maxuserrun"])
          target.MaxUserRunningJobs =
            stringtoi((std::string)queue["nordugrid-queue-maxuserrun"]);
        if (queue["nordugrid-queue-schedulingpolicy"])
          target.SchedulingPolicy =
            (std::string)queue["nordugrid-queue-schedulingpolicy"];
        if (queue["nordugrid-queue-nodememory"])
          target.MaxMainMemory = target.MaxVirtualMemory =
            stringtoi((std::string)queue["nordugrid-queue-nodememory"]);
        else if (cluster["nordugrid-cluster-nodememory"])
          target.MaxMainMemory = target.MaxVirtualMemory =
            stringtoi((std::string)cluster["nordugrid-cluster-nodememory"]);
        if (authuser["nordugrid-authuser-diskspace"])
          target.MaxDiskSpace =
            stringtoi((std::string)authuser["nordugrid-authuser-diskspace"]) / 1000;
        if (cluster["nordugrid-cluster-localse"])
          target.DefaultStorageService =
            (std::string)cluster["nordugrid-cluster-localse"];
        if (queue["nordugrid-queue-running"])
          target.RunningJobs =
            stringtoi((std::string)queue["nordugrid-queue-running"]);
        if (queue["nordugrid-queue-running"] &&
            queue["nordugrid-queue-gridrunning"])
          target.LocalRunningJobs =
            stringtoi((std::string)queue["nordugrid-queue-running"]) -
            stringtoi((std::string)queue["nordugrid-queue-gridrunning"]);
        if (queue["nordugrid-queue-gridqueued"] &&
            queue["nordugrid-queue-localqueued"])
          target.WaitingJobs =
            stringtoi((std::string)queue["nordugrid-queue-gridqueued"]) +
            stringtoi((std::string)queue["nordugrid-queue-localqueued"]);
        if (queue["nordugrid-queue-localqueued"])
          target.LocalWaitingJobs =
            stringtoi((std::string)queue["nordugrid-queue-localqueued"]);
        if (queue["nordugrid-queue-prelrmsqueued"])
          target.PreLRMSWaitingJobs =
            stringtoi((std::string)queue["nordugrid-queue-prelrmsqueued"]);
        target.TotalJobs =
          (target.RunningJobs > 0) ? target.RunningJobs : 0 +
          (target.WaitingJobs > 0) ? target.WaitingJobs : 0 +
          (target.PreLRMSWaitingJobs > 0) ? target.PreLRMSWaitingJobs : 0;
        if (authuser["nordugrid-authuser-freecpus"]) {
          std::string value =
            (std::string)authuser["nordugrid-authuser-freecpus"];
          std::string::size_type pos = 0;
          do {
            std::string::size_type spacepos = value.find(' ', pos);
            std::string entry;
            if (spacepos == std::string::npos)
              entry = value.substr(pos);
            else
              entry = value.substr(pos, spacepos - pos);
            int num_cpus;
            Period time;
            std::string::size_type colonpos = entry.find(':');
            if (colonpos == std::string::npos) {
              num_cpus = stringtoi(entry);
              time = LONG_MAX;
            }
            else {
              num_cpus = stringtoi(entry.substr(0, colonpos));
              time = stringtoi(entry.substr(colonpos + 1)) * 60;
            }
            target.FreeSlotsWithDuration[time] = num_cpus;
            pos = spacepos;
            if (pos != std::string::npos)
              pos++;
          } while (pos != std::string::npos);
          target.FreeSlots = target.FreeSlotsWithDuration.begin()->second;
        }
        if (cluster["nordugrid-queue-usedcpus"])
          target.UsedSlots =
            stringtoi((std::string)cluster["nordugrid-queue-usedcpus"]);
        if (cluster["nordugrid-queue-schedulingpolicy"])
          target.ReservationPolicy =
            (std::string)cluster["nordugrid-queue-schedulingpolicy"];

        // Computing Manager attributes
        if (cluster["nordugrid-cluster-lrms-type"])
          target.ManagerProductName =
            (std::string)cluster["nordugrid-cluster-lrms-type"];
        if (cluster["nordugrid-cluster-lrms-version"])
          target.ManagerProductVersion =
            (std::string)cluster["nordugrid-cluster-lrms-version"];
        if (queue["nordugrid-queue-totalcpus"])
          target.TotalPhysicalCPUs =
          target.TotalLogicalCPUs =
          target.TotalSlots =
            stringtoi((std::string)queue["nordugrid-queue-totalcpus"]);
        else if (cluster["nordugrid-cluster-totalcpus"])
          target.TotalPhysicalCPUs =
          target.TotalLogicalCPUs =
          target.TotalSlots =
            stringtoi((std::string)cluster["nordugrid-cluster-totalcpus"]);
        if (queue["nordugrid-queue-homogeneity"]) {
          if ((std::string)queue["nordugrid-queue-homogeneity"] == "false")
            target.Homogeneous = false;
        }
        else if (cluster["nordugrid-cluster-homogeneity"])
          if ((std::string)cluster["nordugrid-cluster-homogeneity"] == "false")
            target.Homogeneous = false;
        if (cluster["nordugrid-cluster-sessiondir-total"])
          target.WorkingAreaTotal =
            stringtoi((std::string)
                      cluster["nordugrid-cluster-sessiondir-total"]) / 1000;
        if (cluster["nordugrid-cluster-sessiondir-free"])
          target.WorkingAreaFree =
            stringtoi((std::string)
                      cluster["nordugrid-cluster-sessiondir-free"]) / 1000;
        if (cluster["nordugrid-cluster-sessiondir-lifetime"])
          target.WorkingAreaLifeTime =
            (std::string)cluster["nordugrid-cluster-sessiondir-lifetime"];
        if (cluster["nordugrid-cluster-cache-total"])
          target.CacheTotal =
            stringtoi((std::string)cluster["nordugrid-cluster-cache-total"]) / 1000;
        if (cluster["nordugrid-cluster-cache-free"])
          target.CacheFree =
            stringtoi((std::string)cluster["nordugrid-cluster-cache-free"]) / 1000;

        // Benchmarks
        if (queue["nordugrid-queue-benchmark"])
          for (XMLNode n = queue["nordugrid-queue-benchmark"]; n; ++n) {
            std::string benchmark = (std::string)n;
            std::string::size_type alpha = benchmark.find_first_of("@");
            std::string benchmarkname = benchmark.substr(0, alpha);
            double performance = stringtod(benchmark.substr(alpha + 1));
            target.Benchmarks[benchmarkname] = performance;
          }
        else if (cluster["nordugrid-cluster-benchmark"])
          for (XMLNode n = cluster["nordugrid-cluster-benchmark"]; n; ++n) {
            std::string benchmark = (std::string)n;
            std::string::size_type alpha = benchmark.find_first_of("@");
            std::string benchmarkname = benchmark.substr(0, alpha);
            double performance = stringtod(benchmark.substr(alpha + 1));
            target.Benchmarks[benchmarkname] = performance;
          }

        // Execution Environment attributes
        if (queue["nordugrid-queue-architecture"])
          target.Platform =
            (std::string)queue["nordugrid-queue-architecture"];
        else if (cluster["nordugrid-cluster-architecture"])
          target.Platform =
            (std::string)cluster["nordugrid-cluster-architecture"];
        if (queue["nordugrid-queue-nodecpu"]) {
          target.CPUVendor =
            (std::string)queue["nordugrid-queue-nodecpu"];
          target.CPUModel =
            (std::string)queue["nordugrid-queue-nodecpu"];
          target.CPUVersion =
            (std::string)queue["nordugrid-queue-nodecpu"];
          // target.CPUClockSpeed =
          //   (std::string)queue["nordugrid-queue-nodecpu"];
        }
        else if (cluster["nordugrid-cluster-nodecpu"]) {
          target.CPUVendor =
            (std::string)cluster["nordugrid-cluster-nodecpu"];
          target.CPUModel =
            (std::string)cluster["nordugrid-cluster-nodecpu"];
          target.CPUVersion =
            (std::string)cluster["nordugrid-cluster-nodecpu"];
          // target.CPUClockSpeed =
          //   (std::string)queue["nordugrid-cluster-nodecpu"];
        }
        if (queue["nordugrid-queue-nodememory"])
          target.MainMemorySize =
            stringtoi((std::string)queue["nordugrid-queue-nodememory"]);
        else if (cluster["nordugrid-cluster-nodememory"])
          target.MainMemorySize =
            stringtoi((std::string)cluster["nordugrid-cluster-nodememory"]);
        if (queue["nordugrid-queue-opsys"])
          target.OperatingSystem = Software((std::string)queue["nordugrid-queue-opsys"][0],
                                            (std::string)queue["nordugrid-queue-opsys"][1]);
        else if (cluster["nordugrid-cluster-opsys"])
          target.OperatingSystem = Software((std::string)cluster["nordugrid-cluster-opsys"][0],
                                            (std::string)cluster["nordugrid-cluster-opsys"][1]);
        if (cluster["nordugrid-cluster-nodeaccess"])
          for (XMLNode n = cluster["nordugrid-cluster-nodeaccess"]; n; ++n)
            if ((std::string)n == "inbound")
              target.ConnectivityIn = true;
            else if ((std::string)n == "outbound")
              target.ConnectivityOut = true;

        // Application Environments
        for (XMLNode n = cluster["nordugrid-cluster-runtimeenvironment"];
             n; ++n) {
          ApplicationEnvironment rte((std::string)n);
          rte.State = "UNDEFINEDVALUE";
          rte.FreeSlots = -1;
          rte.FreeUserSeats = -1;
          rte.FreeJobs = -1;
          target.ApplicationEnvironments.push_back(rte);
        }

        // Register target in TargetGenerator list
        mom.AddTarget(target);
      }
    }
    else if (targetType == 1) {

      XMLNodeList jobs =
        xmlresult.XPathLookup("//nordugrid-job-globalid"
                              "[objectClass='nordugrid-job']", NS());

      for (XMLNodeList::iterator it = jobs.begin(); it != jobs.end(); it++) {

        NS ns;
        XMLNode info(ns, "Job");

        if ((*it)["nordugrid-job-globalid"])
          info.NewChild("JobID") =
            (std::string)(*it)["nordugrid-job-globalid"];
        if ((*it)["nordugrid-job-jobname"])
          info.NewChild("Name") = (std::string)(*it)["nordugrid-job-jobname"];
        if ((*it)["nordugrid-job-submissiontime"])
          info.NewChild("LocalSubmissionTime") =
            (std::string)(*it)["nordugrid-job-submissiontime"];

        info.NewChild("Flavour") = "ARC0";
        info.NewChild("Cluster") = url.str();

        URL infoEndpoint(url);
        infoEndpoint.ChangeLDAPFilter("(nordugrid-job-globalid=" +
                                      (std::string)
                                      (*it)["nordugrid-job-globalid"] + ")");
        infoEndpoint.ChangeLDAPScope(URL::subtree);

        info.NewChild("InfoEndpoint") = infoEndpoint.str();

        mom.AddJob(info);
      }
    }

    delete thrarg;
    mom.RetrieverDone();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void Arc::TargetRetrieverARC0::QueryIndex ( void *  arg) [static, private]

Definition at line 86 of file TargetRetrieverARC0.cpp.

                                                {
    ThreadArg *thrarg = (ThreadArg*)arg;
    TargetGenerator& mom = *thrarg->mom;
    const UserConfig& usercfg = *thrarg->usercfg;

    URL url = thrarg->url;
    url.ChangeLDAPScope(URL::base);
    url.AddLDAPAttribute("giisregistrationstatus");
    DataHandle handler(url, usercfg);
    DataBuffer buffer;

    if (!handler) {
      logger.msg(INFO, "Can't create information handle - "
                 "is the ARC ldap DMC plugin available?");
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    if (!handler->StartReading(buffer)) {
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    int handle;
    unsigned int length;
    unsigned long long int offset;
    std::string result;

    while (buffer.for_write() || !buffer.eof_read())
      if (buffer.for_write(handle, length, offset, true)) {
        result.append(buffer[handle], length);
        buffer.is_written(handle);
      }

    if (!handler->StopReading()) {
      delete thrarg;
      mom.RetrieverDone();
      return;
    }

    XMLNode xmlresult(result);

    // GIISes
    XMLNodeList GIISes =
      xmlresult.XPathLookup("//Mds-Vo-name[Mds-Service-type]", NS());

    for (XMLNodeList::iterator it = GIISes.begin(); it != GIISes.end(); it++) {

      if ((std::string)(*it)["Mds-Reg-status"] == "PURGED")
        continue;

      TargetRetrieverARC0 retriever(usercfg,
                                    URL((std::string)(*it)["Mds-Service-type"] + "://" +
                                        (std::string)(*it)["Mds-Service-hn"] + ":" +
                                        (std::string)(*it)["Mds-Service-port"] + "/" +
                                        (std::string)(*it)["Mds-Service-Ldap-suffix"]),
                                    INDEX);
      retriever.GetTargets(mom, thrarg->targetType, thrarg->detailLevel);
    }

    // GRISes
    XMLNodeList GRISes =
      xmlresult.XPathLookup("//nordugrid-cluster-name"
                            "[objectClass='MdsService']", NS());

    for (XMLNodeList::iterator it = GRISes.begin(); it != GRISes.end(); it++) {

      if ((std::string)(*it)["Mds-Reg-status"] == "PURGED")
        continue;

      TargetRetrieverARC0 retriever(usercfg,
                                    URL((std::string)(*it)["Mds-Service-type"] + "://" +
                                        (std::string)(*it)["Mds-Service-hn"] + ":" +
                                        (std::string)(*it)["Mds-Service-port"] + "/" +
                                        (std::string)(*it)["Mds-Service-Ldap-suffix"]),
                                    COMPUTING);
      retriever.GetTargets(mom, thrarg->targetType, thrarg->detailLevel);
    }

    delete thrarg;
    mom.RetrieverDone();
  }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

const std::string Arc::TargetRetriever::flavour [protected, inherited]

Definition at line 64 of file TargetRetriever.h.

Reimplemented from Arc::TargetRetriever.

Definition at line 31 of file TargetRetrieverARC0.h.

const ServiceType Arc::TargetRetriever::serviceType [protected, inherited]

Definition at line 67 of file TargetRetriever.h.

const URL Arc::TargetRetriever::url [protected, inherited]

Definition at line 66 of file TargetRetriever.h.

const UserConfig& Arc::TargetRetriever::usercfg [protected, inherited]

Definition at line 65 of file TargetRetriever.h.


The documentation for this class was generated from the following files: