7171import com .cloud .agent .api .StopAnswer ;
7272import com .cloud .agent .api .StopCommand ;
7373import com .cloud .agent .api .to .VirtualMachineTO ;
74+ import com .cloud .host .Host ;
7475import com .cloud .host .HostVO ;
7576import com .cloud .host .dao .HostDao ;
7677import com .cloud .hypervisor .ExternalProvisioner ;
@@ -128,7 +129,7 @@ public class ExternalPathPayloadProvisioner extends ManagerBase implements Exter
128129 private ExecutorService payloadCleanupExecutor ;
129130 private ScheduledExecutorService payloadCleanupScheduler ;
130131 private static final List <String > TRIVIAL_ACTIONS = Arrays .asList (
131- "status"
132+ "status" , "statuses"
132133 );
133134
134135 @ Override
@@ -456,7 +457,7 @@ public StopAnswer expungeInstance(String hostName, String extensionName, String
456457 @ Override
457458 public Map <String , HostVmStateReportEntry > getHostVmStateReport (long hostId , String extensionName ,
458459 String extensionRelativePath ) {
459- final Map <String , HostVmStateReportEntry > vmStates = new HashMap <>();
460+ Map <String , HostVmStateReportEntry > vmStates = new HashMap <>();
460461 String extensionPath = getExtensionCheckedPath (extensionName , extensionRelativePath );
461462 if (StringUtils .isEmpty (extensionPath )) {
462463 return vmStates ;
@@ -466,14 +467,20 @@ public Map<String, HostVmStateReportEntry> getHostVmStateReport(long hostId, Str
466467 logger .error ("Host with ID: {} not found" , hostId );
467468 return vmStates ;
468469 }
470+ Map <String , Map <String , String >> accessDetails =
471+ extensionsManager .getExternalAccessDetails (host , null );
472+ vmStates = getVmPowerStates (host , accessDetails , extensionName , extensionPath );
473+ if (vmStates != null ) {
474+ logger .debug ("Found {} VMs on the host {}" , vmStates .size (), host );
475+ return vmStates ;
476+ }
477+ vmStates = new HashMap <>();
469478 List <UserVmVO > allVms = _uservmDao .listByHostId (hostId );
470479 allVms .addAll (_uservmDao .listByLastHostId (hostId ));
471480 if (CollectionUtils .isEmpty (allVms )) {
472481 logger .debug ("No VMs found for the {}" , host );
473482 return vmStates ;
474483 }
475- Map <String , Map <String , String >> accessDetails =
476- extensionsManager .getExternalAccessDetails (host , null );
477484 for (UserVmVO vm : allVms ) {
478485 VirtualMachine .PowerState powerState = getVmPowerState (vm , accessDetails , extensionName , extensionPath );
479486 vmStates .put (vm .getInstanceName (), new HostVmStateReportEntry (powerState , "host-" + hostId ));
@@ -714,7 +721,7 @@ protected VirtualMachine.PowerState parsePowerStateFromResponse(UserVmVO userVmV
714721 return getPowerStateFromString (response );
715722 }
716723 try {
717- JsonObject jsonObj = new JsonParser (). parse (response ).getAsJsonObject ();
724+ JsonObject jsonObj = JsonParser . parseString (response ).getAsJsonObject ();
718725 String powerState = jsonObj .has ("power_state" ) ? jsonObj .get ("power_state" ).getAsString () : null ;
719726 return getPowerStateFromString (powerState );
720727 } catch (Exception e ) {
@@ -724,7 +731,7 @@ protected VirtualMachine.PowerState parsePowerStateFromResponse(UserVmVO userVmV
724731 }
725732 }
726733
727- private VirtualMachine .PowerState getVmPowerState (UserVmVO userVmVO , Map <String , Map <String , String >> accessDetails ,
734+ protected VirtualMachine .PowerState getVmPowerState (UserVmVO userVmVO , Map <String , Map <String , String >> accessDetails ,
728735 String extensionName , String extensionPath ) {
729736 VirtualMachineTO virtualMachineTO = getVirtualMachineTO (userVmVO );
730737 accessDetails .put (ApiConstants .VIRTUAL_MACHINE , virtualMachineTO .getExternalDetails ());
@@ -740,6 +747,46 @@ private VirtualMachine.PowerState getVmPowerState(UserVmVO userVmVO, Map<String,
740747 }
741748 return parsePowerStateFromResponse (userVmVO , result .second ());
742749 }
750+
751+ protected Map <String , HostVmStateReportEntry > getVmPowerStates (Host host ,
752+ Map <String , Map <String , String >> accessDetails , String extensionName , String extensionPath ) {
753+ Map <String , Object > modifiedDetails = loadAccessDetails (accessDetails , null );
754+ logger .debug ("Trying to get VM power statuses from the external system for {}" , host );
755+ Pair <Boolean , String > result = getInstanceStatusesOnExternalSystem (extensionName , extensionPath ,
756+ host .getName (), modifiedDetails , AgentManager .Wait .value ());
757+ if (!result .first ()) {
758+ logger .warn ("Failure response received while trying to fetch the power statuses for {} : {}" ,
759+ host , result .second ());
760+ return null ;
761+ }
762+ if (StringUtils .isBlank (result .second ())) {
763+ logger .warn ("Empty response while trying to fetch VM power statuses for host: {}" , host );
764+ return null ;
765+ }
766+ try {
767+ JsonObject jsonObj = JsonParser .parseString (result .second ()).getAsJsonObject ();
768+ if (!jsonObj .has ("status" ) || !"success" .equalsIgnoreCase (jsonObj .get ("status" ).getAsString ())) {
769+ logger .warn ("Invalid status in response while trying to fetch VM power statuses for host: {}: {}" ,
770+ host , result .second ());
771+ return null ;
772+ }
773+ if (!jsonObj .has ("power_state" ) || !jsonObj .get ("power_state" ).isJsonObject ()) {
774+ logger .warn ("Missing or invalid power_state in response for host: {}: {}" , host , result .second ());
775+ return null ;
776+ }
777+ JsonObject powerStates = jsonObj .getAsJsonObject ("power_state" );
778+ Map <String , HostVmStateReportEntry > states = new HashMap <>();
779+ for (Map .Entry <String , com .google .gson .JsonElement > entry : powerStates .entrySet ()) {
780+ VirtualMachine .PowerState powerState = getPowerStateFromString (entry .getValue ().getAsString ());
781+ states .put (entry .getKey (), new HostVmStateReportEntry (powerState , "host-" + host .getId ()));
782+ }
783+ return states ;
784+ } catch (Exception e ) {
785+ logger .warn ("Failed to parse VM power statuses response for host: {}: {}" , host , e .getMessage ());
786+ return null ;
787+ }
788+ }
789+
743790 public Pair <Boolean , String > prepareExternalProvisioningInternal (String extensionName , String filename ,
744791 String vmUUID , Map <String , Object > accessDetails , int wait ) {
745792 return executeExternalCommand (extensionName , "prepare" , accessDetails , wait ,
@@ -783,8 +830,14 @@ public Pair<Boolean, String> getInstanceStatusOnExternalSystem(String extensionN
783830 String .format ("Failed to get the instance power status %s on external system" , vmUUID ), filename );
784831 }
785832
833+ public Pair <Boolean , String > getInstanceStatusesOnExternalSystem (String extensionName , String filename ,
834+ String hostName , Map <String , Object > accessDetails , int wait ) {
835+ return executeExternalCommand (extensionName , "statuses" , accessDetails , wait ,
836+ String .format ("Failed to get the %s instances power status on external system" , hostName ), filename );
837+ }
838+
786839 public Pair <Boolean , String > getInstanceConsoleOnExternalSystem (String extensionName , String filename ,
787- String vmUUID , Map <String , Object > accessDetails , int wait ) {
840+ String vmUUID , Map <String , Object > accessDetails , int wait ) {
788841 return executeExternalCommand (extensionName , "getconsole" , accessDetails , wait ,
789842 String .format ("Failed to get the instance console %s on external system" , vmUUID ), filename );
790843 }
0 commit comments