Exemple #1
0
 /// <summary>
 /// ThreadStart method. Will clone all of the EPR's in the EPR list back tot he Host.
 /// This is a special case, set up by Loading a snapshot - - where the EPR List will
 /// contain what the EPR's *SHOULD BE*, rather than	what they actually are.
 /// </summary>
 private void clone()
 {
     try
     {
         eprHostChannel = RemOpWithTimedRetries(() => (new DeviceSimulatorChannel(HostName)), TimeSpan.FromSeconds(3), 3);
         try
         {
             foreach (EPRInstance _epr in EPRs)
             {
                 if (string.Compare(_epr.Profile, EPRInstance.NOPROFILE) != 0)
                 {
                     DeviceInstance _di = RemOpWithTimedRetries(() => eprHostChannel.CreateInstance(_epr.Profile, _epr.IPAddress, _epr.Protocols), TimeSpan.FromSeconds(3), 3);
                     _epr.ResetDevice(_di);
                 }
             }
             WorkStatus = HostVMStatus.Done;
         }
         catch (Exception _ex)
         {
             GenUtils.HangError("Encountered error while cloning EPR " + HostName + " :: " + _ex.Message);
             WorkStatus = HostVMStatus.Error;
         }
     }
     catch (Exception _ex)
     {
         GenUtils.HangError("Encountered error while connect (for cloning) to EPR " + HostName + " :: " + _ex.Message);
         WorkStatus = HostVMStatus.Error;
     }
 }
Exemple #2
0
 /// <summary>
 /// ThreadStart method.  manages starting one or more EPRs on this host. All needed parameters are
 /// passed through member variables (old school) - vis numToStart, startProfile and startProtocols.
 /// </summary>
 private void startEPRs()
 {
     try
     {
         int _started = numToStart;
         for (int _ndx = 0; (_ndx < EPRs.Count) && (_started > 0); _ndx++)
         {
             if (!EPRs[_ndx].InUse)
             {
                 DeviceInstance _di = RemOpWithTimedRetries(() => eprHostChannel.CreateInstance(startProfile, EPRs[_ndx].IPAddress, startProtocols), TimeSpan.FromSeconds(3), 3);
                 --_started;
                 EPRs[_ndx].ResetDevice(_di);
             }
             else
             {
                 GenUtils.HangError(EPRs[_ndx].HostName + " is already in use as " + EPRs[_ndx].Profile + ". Start command ignored for this EPR");
             }
         }
         WorkStatus = HostVMStatus.Done;
     }
     catch (Exception _ex)
     {
         GenUtils.HangError("Encountered error whie starting EPRs on " + HostName + " :: " + _ex.Message);
         WorkStatus = HostVMStatus.Error;
     }
 }
Exemple #3
0
 /// <summary>
 /// ThreadStart method.  Will manage the tearing down of one or more EPR instancs on this Host VM.
 /// This is executed in a thread - even though the operation itself is fairly quick.
 /// </summary>
 private void destroy()
 {
     //-------------------------------------------------------------------------------------------------------
     // Follows use rule - if no IP addresses have been specifically specified on the command line, then
     // operation will affect ALL EPR IP's on this host.
     try
     {
         if (specifiedIPs.Count == 0)
         {
             RemOpWithTimedRetries(() => eprHostChannel.DestroyAllInstances(), TimeSpan.FromSeconds(3), 3);
         }
         else
         {
             foreach (EPRInstance _epr in EPRs)
             {
                 RemOpWithTimedRetries(() => eprHostChannel.DestroyInstance(_epr.IPAddress), TimeSpan.FromSeconds(3), 3);
             }
         }
         //-----------------------------------------------------------------------------------------------------
         // If IP's have been specified, it is probably only a few (< 5) so running this loop twice is not
         // terrible.  If no IPs were specified, we would have to do this anyhow.
         foreach (EPRInstance _epr in EPRs)
         {
             _epr.ClearDevice();
         }
         WorkStatus = HostVMStatus.Done;
     }
     catch (Exception _ex)
     {
         GenUtils.HangError("Error when destroying EPRs : " + _ex.Message);
         WorkStatus = HostVMStatus.Error;
     }
 }
Exemple #4
0
 /// <summary>
 /// Will return a profile name based on either a matching string or a partial match,
 /// If the profile is supported by the Host.
 /// </summary>
 /// <param name="pTarget">Profile (fullname or fragment) to find</param>
 /// <returns>Actual profile name or null if not found</returns>
 public string FindProfile(string pTarget)
 {
     try
     {
         return(InstalledProfiles.FirstOrDefault(_prof => ((string.Compare(_prof.Name, pTarget, true) == 0) || (_prof.Name.Contains(pTarget)))).Name);
     }
     catch (Exception)
     {
         GenUtils.HangError(pTarget + " Cannot be resolved into an installed profile on " + HostName + "?");
         return(null);
     }
 }
Exemple #5
0
        /// <summary>
        /// Will read in a snapshot file and then exactly duplicate that snapshot on all specified VM's
        /// (if they are also in the snapshot file), or on all VM's that were in the snapshot file
        /// </summary>
        /// <param name="pHosts">List of VMs to load (specified or from the xml file)</param>
        /// <param name="pSnap"></param>
        static void LoadSnapShot(List <HostVM> pHosts, string pSnap)
        {
            //---------------------------------------------------------------------------------------------------------
            // We want the filename to always use .xml as an extension.  So - if the filename does not end in .xml -
            // append .xml to the filename.  Then, see if the file exists and carry on.
            string _extension = Path.GetExtension(pSnap);

            if (string.Compare(_extension, @".xml", true) != 0)
            {
                GenUtils.Exclaim("Snapshot file name must use .xml extension. Appending .xml to " + pSnap);
                pSnap += ".xml";
            }
            if (!File.Exists(pSnap))
            {
                GenUtils.HangError("Cannot find file : " + pSnap);
                GenUtils.Exclaim("Press Enter to exit...");
                Console.ReadLine();
                Environment.Exit(2);
            }
            GenUtils.Exclaim("Loading " + pSnap + "....");
            List <HostVM> Loaded   = new List <HostVM>();
            XmlDocument   _xReader = new XmlDocument();

            _xReader.Load(pSnap);

            //---------------------------------------------------------------------------------------------------------
            //Read the XML file and reconstruct the list of VM's and all the EPRs on each VM (EPR Host) from the file.
            //
            foreach (XmlNode _vmHost in _xReader.SelectSingleNode(@"EPRSnapShot"))
            {
                HostVM _tmpVM = new HostVM(_vmHost.Attributes.GetNamedItem(@"HostName").FirstChild.Value.Trim(), HostVM.HostOperations.Connect, true);
                foreach (XmlNode _eprInst in _vmHost.ChildNodes)
                {
                    string      _ip  = _eprInst.Attributes.GetNamedItem(@"EPR").FirstChild.Value;
                    EPRInstance _epr = new EPRInstance(IPAddress.Parse(_ip));
                    _tmpVM.EPRs.Add(_epr);
                    if (_eprInst.Attributes.GetNamedItem(@"Profile") != null)
                    {
                        string _prots = _eprInst.Attributes.GetNamedItem(@"Protocols").FirstChild.Value;
                        _epr.Profile = _eprInst.Attributes.GetNamedItem(@"Profile").FirstChild.Value;
                        _epr.SetProtocols(_prots);
                    }
                }
                Loaded.Add(_tmpVM);
            }

            //---------------------------------------------------------------------------------------------------------
            // To apply the snapshot, we have to follow this pattern:
            //	For every EPRHostVM that remains in the List of VMs (from the -VM option or the default hosts file)
            //					If there is not a match for it in the Snapshot file - remove it from the Hosts List
            //	For every EPRHostVM that remains in the list:
            //		Stop all EPR instances on the host
            //		Replicate, EPR Instance for EPR instance from the snapshot file to the host VM
            GenUtils.Exclaim("Applying snapshot....");
            bool _done;
            int  _hostNdx = 0;

            //-------------------------------------------------------------------------------------------------------
            // First - eliminate any Hosts that are in the main list and the not snapshot file...
            do
            {
                _done = true;
                for ( ; _hostNdx < pHosts.Count; _hostNdx++)
                {
                    if (Loaded.Find(_hst => string.Compare(_hst.HostName, pHosts[_hostNdx].HostName, true) == 0) == null)
                    {
                        _done = false;
                        break;
                    }
                }
                if (_hostNdx < pHosts.Count)
                {
                    GenUtils.Exclaim(pHosts[_hostNdx].HostName + " was not found in the Snapshot.  Removing Host from main list.");
                    pHosts.RemoveAt(_hostNdx);
                }
            }while (!_done);
            if (pHosts.Count == 0)
            {
                GenUtils.HangError("There are no EPR Host VMs left in the list of specified Hosts.");
                return;
            }

            //-------------------------------------------------------------------------------------------------------
            // Next, report on any hosts that were in the Snapshot file, but are NOT in the main Action List...
            _hostNdx = 0;
            do
            {
                _done = true;
                for ( ; _hostNdx < Loaded.Count; _hostNdx++)
                {
                    if (pHosts.Find(_hst => string.Compare(_hst.HostName, Loaded[_hostNdx].HostName, true) == 0) == null)
                    {
                        _done = false;
                        break;
                    }
                }
                if (_hostNdx < pHosts.Count)
                {
                    GenUtils.Exclaim(Loaded[_hostNdx].HostName + " was not found in the main List of EPR Host VMs.  Removing Host from snapshot list.");
                    Loaded.RemoveAt(_hostNdx);
                }
            }while (!_done);

            //---------------------------------------------------------------------------------------------------------
            // For the VMs that remain, they have been started because we could communciate with them and get their EPR
            // info) -- but now we must destroy any existing EPR instances.
            foreach (HostVM _host in pHosts)
            {
                _host.WorkQ.Add(HostVM.HostOperations.Stop);
                _host.WorkStatus = HostVM.HostVMStatus.Pending;
            }
            Dispatch(pHosts, true);

            //---------------------------------------------------------------------------------------------------------
            // Finally, we need to clone the snapshot Host EPR instances in the new HostVMs.
            foreach (HostVM _host in pHosts)
            {
                // Find the matching Host from the snapshot file...
                HostVM _clone = Loaded.Find(_hst => string.Compare(_hst.HostName, _host.HostName, true) == 0);
                if (_clone == null)
                {
                    throw new Exception("Could not find Expected EPR Host VM to clone (" + _host.HostName + ") ?!");
                }
                _host.EPRs = _clone.EPRs;
                _host.WorkQ.Add(HostVM.HostOperations.Clone);
                _host.WorkStatus = HostVM.HostVMStatus.Pending;
            }
            Dispatch(pHosts, true);
        }
Exemple #6
0
        /// <summary>
        /// MainLine.  Enter here.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            List <HostVM> Hosts = new List <HostVM>();
            Options       _opts = null;

            try
            {
                _opts = new Options(args);
            }
            catch (Exception _ex)
            {
                GenUtils.HangError(_ex.Message);
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.DarkCyan;
                Console.WriteLine("Usage:\nManageEPRs");
                Console.WriteLine("  -Start <Options>  -- Start EPR instances. Options are explained below");
                Console.WriteLine("    -VM \"list of vms to use\"  -- Optional. EPR_FQDN,EPR_FQDN....");
                Console.WriteLine("          Can also specify a specific VM and IP - EPR_FQDN/IPAddr");
                Console.WriteLine("    -Profile \"<Profile Name>\" -- Required. Name of profile to start");
                Console.WriteLine("    -Jedi | -Oz -- Required. Must know architecture to load balance EPRS.");
                Console.WriteLine("    -Num #EPRsTostart -- Optional. -Jedi will start 255, -Oz will start 765");
                Console.WriteLine("    -Protocols \"Comma Separated List of Protocols to support\"");
                Console.WriteLine("  -Stop <Options>  -- Stop EPR instances. Options are explained below");
                Console.WriteLine("    -VM \"list of vms to use\"  -- Optional. EPR_FQDN,EPR_FQDN....");
                Console.WriteLine("          Can also specify a specific VM and IP - EPR_FQDN/IPAddr");
                Console.WriteLine("  -Shutdown <Options>  -- Stops all EPR instances and halts the EPR service.");
                Console.WriteLine("    -VM \"list of vms to use\"  -- Optional. EPR_FQDN,EPR_FQDN....");
                Console.WriteLine("    NOTE: This functionality is not yet implemented...");
                Console.WriteLine("  -Snapshot <Options>  -- Create snapshot for recreating a configuration.");
                Console.WriteLine("    -Name \"SnapshotFileName\"  -- Required. Snapshot filename (for Replay)");
                Console.WriteLine("    -VM \"list of vms to use\"  -- Optional. EPR_FQDN,EPR_FQDN....");
                Console.WriteLine("  -Load <Options>  -- Load a snapshot to recreate it's environment.");
                Console.WriteLine("    -Name \"SnapshotFileName\"  -- Required. Snapshot filename (to load)");
                Console.WriteLine("    -VM \"list of vms to use\"  -- Optional. EPR_FQDN,EPR_FQDN....");
                Console.WriteLine("  -List -- Will list all EPRs (used and unused) on all VMs specified");
                Console.WriteLine("  -ListUsed -- Will list Used EPRs on all VMs specified");
                Console.WriteLine("  -ListUnused -- Will list Unused EPRs on all VMs specified\n");
                Console.WriteLine("  -Log \"LogFile\"  - Change the name of the default log file to 'LogFile'.");
                Console.WriteLine("        Default log file is named .\\ManageEPRs.Log.txt and is always created.");
                Console.WriteLine("  -Threads # -- Sets the maximum number of threads to use to #. # <= 10.");
                Console.WriteLine("NOTES:");
                Console.WriteLine("  -List, -ListUsed or -ListUnused can be used with -Start, -Stop or -Shutdown");
                Console.WriteLine("  If -VM is NOT specified, then ALL EPR Host VM's will be contacted");
                Console.WriteLine("    and operated on.  Be careful with -Stop and -Shutdown!!");
                Console.WriteLine("  If a -Start request cannot be satisfied with the VMs specified,");
                Console.WriteLine("    or with all VMs, then as many EPRS as can be started will be started.");
                Console.WriteLine("\n\nPress Enter to exit.");
                Console.ResetColor();
                Console.ReadLine();
                Environment.Exit(1);
            }

            //-------------------------------------------------------------------------------------------------------
            // Create the initial ist of Host VM's to use.  This will just create the initial objects - it does not
            // attempt to communicate with the VM's yet.  that will be done through the thread dispatcher bcause
            // the communication process can be cumebrsome and time consuming so we wat to multi-thread it.
            foreach (string _host in _opts.VMs)
            {
                Hosts.Add(new HostVM(_host, HostVM.HostOperations.Connect, _opts.ForceStart));
            }

            //---------------------------------------------------------------------------------------------------------
            // Now, we are ready to start communicating with the VM's and build the info from each viable VM.  If
            // -Skip was included on the command line, then we will not force the EPRService to start on the VM if
            // if it is not already running.  VM's that cannot be communicated with will be removed from the Hosts
            // list.  Also, VM's that had invalid IP addresses specified will also be removed from the Hosts list.
            // When the execution of this segment is complete, Hosts will contain all VM's to be used in this session.
            GenUtils.Exclaim("Contacting EPR Host Vm's.  This can take a few minutes....");
            try
            {
                Dispatch(Hosts);
            }
            catch (Exception _ex)
            {
                GenUtils.HangError("Error during initial communication - " + _ex.Message);
                Environment.Exit(5);
            }

            //---------------------------------------------------------------------------------------------------------
            // Some of the operations will require further processing of the Hosts list. For example, if we are
            // starting EPR's then we have to find the correct Hosts to use based on several things such as number,
            // profiles and specified ip addresses. Once we are done with that, we can dispatch all of the operations
            // together and let the thread dispatcher handle not over-taxing the system.
            switch (_opts.Action)
            {
            case Options.ToolActions.Start:
                FitEPRs(Hosts, _opts);
                break;

            case Options.ToolActions.Stop:
                foreach (HostVM _hst in Hosts)
                {
                    _hst.WorkQ.Add(HostVM.HostOperations.Stop);
                    _hst.WorkStatus = HostVM.HostVMStatus.Pending;
                }
                break;

            case Options.ToolActions.Shutdown:
                GenUtils.HangError("Sorry.  This feature has not yet been implemented.");
                break;

            case Options.ToolActions.Load:
                LoadSnapShot(Hosts, _opts.Snapshot);
                break;

            case Options.ToolActions.NoAction:
                break;
            }
            if (_opts.Action != Options.ToolActions.NoAction)
            {
                if (Hosts.Count > 0)
                {
                    Dispatch(Hosts);
                }
                else
                {
                    GenUtils.HangError("There are no VM's that can fulfill the request?");
                    Environment.Exit(7);
                }
            }

            //---------------------------------------------------------------------------------------------------------
            // These are "non-action" commands because they do not make any changes to the VM's ot EPR instances.
            if (_opts.TakeSnapshot)
            {
                CaptureSnapshot(Hosts, _opts.Snapshot);
            }
            if (_opts.ListAction != Options.ToolActions.NoAction)
            {
                Report(_opts.ListAction, Hosts);
            }
        }
Exemple #7
0
        /// <summary>
        /// Finds open VM's/IP addresses for EPRS.  Will follow these placement rules:
        /// (1) Use targeted VM's whenever possible (for Jedi and Oz - #of network connections)
        /// (2) Use small pools first to reduce fragmentation
        /// (3) Start as many EPRs as possible - notify if # cannot be fully satisfied
        /// </summary>
        /// <param name="pHosts">List of VM's to use</param>
        /// <param name="pOpts">Options form the command line</param>
        /// <returns>true if EPRs started, false if there was a problem</returns>
        static bool FitEPRs(List <HostVM> pHosts, Options pOpts)
        {
            List <int> _sorted = new List <int>();
            int        _hostNdx;
            int        _sortNdx;
            bool       _inserted;
            string     _targetVMIdentifier  = pOpts.IsJedi ? "255" : "765";
            string     _foreignVMIdentifier = pOpts.IsJedi ? "765" : "255";
            int        _numEPRs             = pOpts.StartNum > 0 ? pOpts.StartNum : pOpts.IsOz ? 765 : 255;

            //---------------------------------------------------------------------------------------------------------
            // First thing - remove all VM's from the list that either do not have any EPR instancs available, or
            // do not support the profile that was requested.
            _hostNdx = 0;
            bool _good2Use = false;

            do
            {
                for ( ; _hostNdx < pHosts.Count; _hostNdx++)
                {
                    //-----------------------------------------------------------------------------------------------------
                    // Because we allow the use of a Partial string for the Profile name, we need to resolve what was
                    // specified on the command line to a real profile (if it exists).  So - resolve the profile.
                    _good2Use = true;
                    string _tProf = pHosts[_hostNdx].FindProfile(pOpts.Profile);
                    if ((pHosts[_hostNdx].EPRInstancesAvailable == 0) || (string.IsNullOrEmpty(_tProf)))
                    {
                        _good2Use = false;
                        break;
                    }
                    if (!pOpts.AllowMix)
                    {
                        foreach (EPRInstance _locEpr in pHosts[_hostNdx].EPRs.Where(_inst => _inst.WasAlreadyExecuting))
                        {
//                            if ((_locEpr.WasAlreadyExecuting) && (string.Compare(_locEpr.Profile, _tProf, true) != 0))
                            if (string.Compare(_locEpr.Profile, _tProf, true) != 0)
                            {
                                _good2Use = false;
                                break;
                            }
                        }
                    }
                    if (!_good2Use)
                    {
                        break;
                    }
                    pHosts[_hostNdx].ProfileToStart = _tProf;
                }
                if (!_good2Use)
                {
                    GenUtils.Exclaim("Removing VM " + pHosts[_hostNdx].HostName + " because it does not match requirements.");
                    pHosts.RemoveAt(_hostNdx);
                }
            }while (_hostNdx < pHosts.Count);
            if (pHosts.Count == 0)
            {
                GenUtils.HangError("There are no VM's that match the requirements ?");
                return(false);
            }

            //---------------------------------------------------------------------------------------------------------
            // Sort the VM's that *could* be used according to the following rules:
            // 1 - The VM's that are "tailored" for the specified architecture, should be first in the list
            // 2 - The VM's with the fewest available EPR's should be before those with more available EPRS (to reduce
            //				fragmentation
            for (_hostNdx = 0; _hostNdx < pHosts.Count; _hostNdx++)
            {
                _inserted = false;
                for (_sortNdx = 0; _sortNdx < _sorted.Count; _sortNdx++)
                {
                    //-----------------------------------------------------------------------------------------------------
                    // Check for the case where what is on the front of the sorted list is NOT the targeted VM - and what
                    // is being placed now is a targeted VM - then put the targeted VM in the first spot  regardless of
                    // how many available EPRs it has.
                    if ((pHosts[_hostNdx].HostName.Contains(_targetVMIdentifier)) && (pHosts[_sorted[_sortNdx]].HostName.Contains(_foreignVMIdentifier)))
                    {
                        _inserted = true;
                        _sorted.Insert(_sortNdx, _hostNdx);
                        break;
                        //-----------------------------------------------------------------------------------------------------
                        // Ok - if the current Vm is the same tagretted platform as the one in the sorted list, then compare
                        // the numebr of available VM's - and sort them smallest to greatest.
                    }
                    else if (((pHosts[_hostNdx].HostName.Contains(_targetVMIdentifier)) && (pHosts[_sorted[_sortNdx]].HostName.Contains(_targetVMIdentifier))) ||
                             ((pHosts[_hostNdx].HostName.Contains(_foreignVMIdentifier)) && (pHosts[_sorted[_sortNdx]].HostName.Contains(_foreignVMIdentifier))))
                    {
                        if (pHosts[_hostNdx].EPRInstancesAvailable <= pHosts[_sorted[_sortNdx]].EPRInstancesAvailable)
                        {
                            _inserted = true;
                            _sorted.Insert(_sortNdx, _hostNdx);
                            break;
                        }
                    }
                }
                //-------------------------------------------------------------------------------------------------------
                // It may not be obvious, BUT if we reach here and have not yet inserted the current Host, then it has to
                // go at the end of the _sorted list.
                if (!_inserted)
                {
                    _sorted.Add(_hostNdx);
                }
            }

            // Now that we have the VM's sorted such that the VM's with the fewest available EPRs are first
            // in the list, we can start to use those VM's to bring up the EPRs requested. This is a cross between a first fit
            // and a best fit algorithm - and it should result in reducing "fragmentation" of EPR usage across Host VMs.
            _hostNdx = 0;
            int _cnt = _sorted.Count;

            do
            {
                //-------------------------------------------------------------------------------------------------------
                // The VM will not allow us to assign more EPR's to start than it has available - so, we can just assign
                // how many we need and then subtract what VM reorts is the number we can start.
                HostVM _vm = pHosts[_sorted[_hostNdx]];
                _vm.EPRsToStart      = _numEPRs;
                _vm.ProtocolsToStart = pOpts.EPRProtocols;
                _vm.WorkQ.Add(HostVM.HostOperations.Start);
                _vm.WorkStatus = HostVM.HostVMStatus.Pending;
                _numEPRs      -= _vm.EPRsToStart;
                ++_hostNdx;
            }while ((_numEPRs > 0) && (_hostNdx < _cnt));

            if (_numEPRs > 0)
            {
                GenUtils.Exclaim("There are not enough available EPR instances. Only " + (pOpts.StartNum - _numEPRs).ToString() +
                                 " will be started!\n\n");
            }
            return(true);
        }
Exemple #8
0
        /// <summary>
        /// ThreadStart method.  Executed in a worker thread to connect to the VM associated with this object,
        /// possibly start the EPR service and/or to pull information regarding the EPR's and profiles
        /// that this Host has.
        /// NOTE: Uses synchronized object of a Netowrk Drive Letter.
        /// </summary>
        private void Connect()
        {
            string _tnd       = null;
            bool   _connected = false;

            IPAddress[] _localIPs;

            //-------------------------------------------------------------------------------------------------------
            //Verify that the hostname is good.  if we can't find it via dns - then remove it from the list.
            try
            {
                _localIPs = Dns.GetHostAddresses(HostName);
                if (_localIPs.Length > 0)
                {
                    var _isOn = new System.Net.NetworkInformation.Ping();
                    if (_isOn.Send(HostName).Status == System.Net.NetworkInformation.IPStatus.Success)
                    {
                        mainIPAddress = _localIPs[0];
                    }
                    else
                    {
                        WorkStatus = HostVMStatus.Error;
                        GenUtils.HangError("Cannot connect with " + HostName + ". Make sure it is powered up.");
                        return;
                    }
                }
            }
            catch (Exception)
            {
                GenUtils.HangError(HostName + " is an unknown host?");
                WorkStatus = HostVMStatus.Error;
                return;
            }
            //-------------------------------------------------------------------------------------------------------
            // In order to connect, we will first assume that the EPR Service is actually running on the Host VM
            // and just attempt to establish communications.  If they fail for a timeout, then we will know that
            // we need to atempt to start the service on the remote host.
            try
            {
//				eprHostChannel = new DeviceSimulatorChannel(HostName);
                eprHostChannel    = RemOpWithTimedRetries(() => (new DeviceSimulatorChannel(HostName)), TimeSpan.FromSeconds(3), 3);
                InstalledProfiles = eprHostChannel.IntalledProfiles;
                _connected        = true;
            }
            catch (Exception _ex)
            {
                //-----------------------------------------------------------------------------------------------------
                // Landing here *usually* means that the EPR service is not running on the remote system.  So, we will
                // attempt to start the service. In order to start the remote service, we will check to see if the
                // remote dservice is running.  If it is, then there is prossibly a firewall blocking us.  If it is
                // not, then we check to see if the executable exists. If it does not, then the EPR is not installed
                // (or usable) on the remote system.  If the executable does exist, then start it up.
                if (((_ex.Message.Contains("timed out")) || _ex.Message.Contains("No endpoint", StringComparison.OrdinalIgnoreCase)) && (forceConn))
                {
                    if (!GenUtils.CheckForRemoteProcess(HostName, Program.EPRSERVICE))
                    {
                        try
                        {
                            _tnd = GenUtils.MapNetworkDrive(Path.Combine(@"\\", HostName, "C$"), @"ETL\jawa", "!QAZ2wsx");
                            bool _canStart = File.Exists(Path.Combine(_tnd, Program.EPRSERVICEFILEPATH));
                            GenUtils.DisconnectNetworkDrive(_tnd, true);
                            _tnd = null;
                            if (_canStart)
                            {
                                GenUtils.Exclaim("EPR Service is not running on " + HostName + ".  Attempting to start service...");
                                GenUtils.ExecuteRemoteProcess(HostName, Path.Combine(@"C:\", Program.EPRSERVICEFILEPATH), true, false);
                                eprHostChannel    = new DeviceSimulatorChannel(HostName);
                                InstalledProfiles = eprHostChannel.IntalledProfiles;
                                _connected        = true;
                                GenUtils.Exclaim("EPR Service started on " + HostName);
                            }
                            else
                            {
                                GenUtils.HangError("Does not appear that the EPR Service is installed on " + HostName);
                                WorkStatus = HostVMStatus.Error;
                            }
                        }
                        catch (Exception _inner)
                        {
                            if (!string.IsNullOrEmpty(_tnd))
                            {
                                GenUtils.DisconnectNetworkDrive(_tnd, true);
                                _tnd = null;
                            }
                            GenUtils.HangError("General network failure starting remote EPR service on  " + HostName + " :: " + _inner.Message);
                            WorkStatus = HostVMStatus.Error;
                        }
                    }
                    else
                    {
                        GenUtils.HangError("Could not connect with remote service on " + HostName +
                                           ". Verify the VM IP, and that it is powered on, or check for possible firewall blocking communications.");
                        WorkStatus = HostVMStatus.Error;
                    }
                }
                else if (forceConn)
                {
                    WorkStatus = HostVMStatus.Error;
                    GenUtils.HangError("General Network failure on " + HostName + " :: " + _ex.Message);
                }
                else
                {
                    WorkStatus = HostVMStatus.NotConnected;
                    GenUtils.HangError("Could not connect with " + HostName + " (-Skip specified). Host will be removed from Main Action list");
                }
            }
            //-----------------------------------------------------------------------------------------------------
            // If the connection is made, then pull all of the relevent information about the EPRs from the Host
            // VM.
            if (_connected)
            {
                try
                {
                    EPRs.Clear();
                    InstalledProfiles.Clear();
                    InstalledProfiles = eprHostChannel.IntalledProfiles;
                    foreach (IPAddress _ip in eprHostChannel.AvailableIPAddresses)
                    {
//						if ((!_ip.ToString().EndsWith(".0")) && (HP.ScalableTest.Network.NetworkUtil.IsNonRoutableIpAddress(_ip)))
                        if ((!_ip.ToString().EndsWith(".0")) &&
                            (((_localIPs.Length == 1) && (HP.ScalableTest.Network.NetworkUtil.IsNonRoutableIpAddress(_ip))) ||
                             ((_localIPs.Length > 1) && (!_ip.Equals(mainIPAddress)))))
                        {
                            //-----------------------------------------------------------------------------------------------
                            // If the user did not specify any IP address on the command line
                            //     (format -vm Host/IP1/IP2/...,Host,Host/IP1/IP2...)
                            // then we default to ALL of the IP addresses returned both in use and those that are available.
                            // If the user DID supply some IP's - then everything on this Host must be limited to those IP's
                            // ONLY - so skip anything that is not on that list.
                            if (specifiedIPs.Count == 0)
                            {
                                EPRs.Add(new EPRInstance(_ip));
                            }
                            else
                            {
                                if (specifiedIPs.Contains(_ip.ToString()))
                                {
                                    EPRs.Add(new EPRInstance(_ip));
                                }
                            }
                        }
                    }
                    EPRInstancesAvailable = eprHostChannel.AvailableIPAddresses.Count - 1;
                    foreach (DeviceInstance _di in eprHostChannel.Instances)
                    {
                        //-----------------------------------------------------------------------------------------------
                        // See the comment above...
                        if (specifiedIPs.Count == 0)
                        {
                            EPRs.Add(new EPRInstance(_di, true));
                        }
                        else
                        {
                            if (specifiedIPs.Contains(_di.Address.ToString()))
                            {
                                EPRs.Add(new EPRInstance(_di, true));
                            }
                        }
                    }
                    if (specifiedIPs.Count > 0)
                    {
                        //-------------------------------------------------------------------------------------------------
                        // If the user specified some IP's for this host on the command line, those are the ONLY IPs that
                        // can be operated on. So - check and see if they are valid.  Hang messages if not and if none
                        // are valid - then return an error so this host is removed from the Action list. This also
                        // prevents us from having to check the IP validity anywhere else!
                        int _sNdx = 0;
                        do
                        {
                            for ( ; _sNdx < specifiedIPs.Count; _sNdx++)
                            {
                                string _ip = specifiedIPs[_sNdx];
                                if (EPRs.FindIndex(_inst => string.Compare(_ip, _inst.IPAddress.ToString()) == 0) < 0)
                                {
                                    GenUtils.Exclaim(_ip + " is not a valid IP for host " + _ip + ". Removing from the IP List");
                                    break;
                                }
                            }
                            if (_sNdx < specifiedIPs.Count)
                            {
                                specifiedIPs.RemoveAt(_sNdx);
                            }
                        }while (_sNdx < specifiedIPs.Count);
                        WorkStatus = specifiedIPs.Count > 0 ? HostVMStatus.Done : HostVMStatus.Error;
                    }
                    else
                    {
                        WorkStatus = HostVMStatus.Done;
                    }
                }
                catch (Exception _ex)
                {
                    WorkStatus = HostVMStatus.Error;
                    GenUtils.HangError(HostName + " : Connection Exception caught: " + _ex.Message);
                    GenUtils.DisconnectNetworkDrive(_tnd, true);
                }
            }
        }