mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Refactoring the LibvirtComputingResource
- Adding LibvirtModifySshKeysCommandWrapper - 1 unit test added - KVM hypervisor plugin with 12.3% coverage
This commit is contained in:
		
							parent
							
								
									f14c7c2074
								
							
						
					
					
						commit
						6f757c6bf0
					
				| @ -105,7 +105,6 @@ import com.cloud.agent.api.MaintainAnswer; | ||||
| import com.cloud.agent.api.MaintainCommand; | ||||
| import com.cloud.agent.api.ManageSnapshotAnswer; | ||||
| import com.cloud.agent.api.ManageSnapshotCommand; | ||||
| import com.cloud.agent.api.ModifySshKeysCommand; | ||||
| import com.cloud.agent.api.ModifyStoragePoolAnswer; | ||||
| import com.cloud.agent.api.ModifyStoragePoolCommand; | ||||
| import com.cloud.agent.api.NetworkRulesSystemVmCommand; | ||||
| @ -279,19 +278,82 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | ||||
| 
 | ||||
|     private long _hvVersion; | ||||
|     private long _kernelVersion; | ||||
|     private int _timeout; | ||||
| 
 | ||||
|     private KVMHAMonitor _monitor; | ||||
|     private static final String SSHKEYSPATH = "/root/.ssh"; | ||||
|     private static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud"; | ||||
|     private static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud"; | ||||
|     public static final String SSHKEYSPATH = "/root/.ssh"; | ||||
|     public static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud"; | ||||
|     public static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud"; | ||||
| 
 | ||||
|     private String _mountPoint = "/mnt"; | ||||
|     StorageLayer _storage; | ||||
|     private KVMStoragePoolManager _storagePoolMgr; | ||||
| 
 | ||||
|     private VifDriver _defaultVifDriver; | ||||
|     private Map<TrafficType, VifDriver> _trafficTypeVifDrivers; | ||||
| 
 | ||||
|     protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; | ||||
|     protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; | ||||
| 
 | ||||
|     protected HypervisorType _hypervisorType; | ||||
|     protected String _hypervisorURI; | ||||
|     protected long _hypervisorLibvirtVersion; | ||||
|     protected long _hypervisorQemuVersion; | ||||
|     protected String _hypervisorPath; | ||||
|     protected String _networkDirectSourceMode; | ||||
|     protected String _networkDirectDevice; | ||||
|     protected String _sysvmISOPath; | ||||
|     protected String _privNwName; | ||||
|     protected String _privBridgeName; | ||||
|     protected String _linkLocalBridgeName; | ||||
|     protected String _publicBridgeName; | ||||
|     protected String _guestBridgeName; | ||||
|     protected String _privateIp; | ||||
|     protected String _pool; | ||||
|     protected String _localGateway; | ||||
|     private boolean _canBridgeFirewall; | ||||
|     protected String _localStoragePath; | ||||
|     protected String _localStorageUUID; | ||||
|     protected boolean _noMemBalloon = false; | ||||
|     protected String _guestCpuMode; | ||||
|     protected String _guestCpuModel; | ||||
|     protected boolean _noKvmClock; | ||||
|     protected String _videoHw; | ||||
|     protected int _videoRam; | ||||
|     protected Pair<Integer,Integer> hostOsVersion; | ||||
|     protected int _migrateSpeed; | ||||
|     protected int _migrateDowntime; | ||||
|     protected int _migratePauseAfter; | ||||
| 
 | ||||
|     private final Map <String, String> _pifs = new HashMap<String, String>(); | ||||
|     private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>(); | ||||
| 
 | ||||
|     protected static final MessageFormat SnapshotXML = new MessageFormat("   <domainsnapshot>" + "       <name>{0}</name>" + "          <domain>" | ||||
|             + "            <uuid>{1}</uuid>" + "        </domain>" + "    </domainsnapshot>"); | ||||
| 
 | ||||
|     protected static final HashMap<DomainState, PowerState> s_powerStatesTable; | ||||
|     static { | ||||
|         s_powerStatesTable = new HashMap<DomainState, PowerState>(); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff); | ||||
|     } | ||||
| 
 | ||||
|     protected List<String> _vmsKilled = new ArrayList<String>(); | ||||
| 
 | ||||
|     private VirtualRoutingResource _virtRouterResource; | ||||
| 
 | ||||
|     private String _pingTestPath; | ||||
| 
 | ||||
|     private int _dom0MinMem; | ||||
| 
 | ||||
|     protected boolean _disconnected = true; | ||||
|     protected int _cmdsTimeout; | ||||
|     protected int _stopTimeout; | ||||
| 
 | ||||
|     @Inject | ||||
|     private LibvirtConnectionWrapper libvirtConnectionWrapper; | ||||
| 
 | ||||
| @ -392,6 +454,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | ||||
|         return _pingTestPath; | ||||
|     } | ||||
| 
 | ||||
|     public int getTimeout() { | ||||
|         return _timeout; | ||||
|     } | ||||
| 
 | ||||
|     private static final class KeyValueInterpreter extends OutputInterpreter { | ||||
|         private final Map<String, String> map = new HashMap<String, String>(); | ||||
| 
 | ||||
| @ -424,66 +490,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     protected static final MessageFormat SnapshotXML = new MessageFormat("   <domainsnapshot>" + "       <name>{0}</name>" + "          <domain>" | ||||
|             + "            <uuid>{1}</uuid>" + "        </domain>" + "    </domainsnapshot>"); | ||||
| 
 | ||||
|     protected HypervisorType _hypervisorType; | ||||
|     protected String _hypervisorURI; | ||||
|     protected long _hypervisorLibvirtVersion; | ||||
|     protected long _hypervisorQemuVersion; | ||||
|     protected String _hypervisorPath; | ||||
|     protected String _networkDirectSourceMode; | ||||
|     protected String _networkDirectDevice; | ||||
|     protected String _sysvmISOPath; | ||||
|     protected String _privNwName; | ||||
|     protected String _privBridgeName; | ||||
|     protected String _linkLocalBridgeName; | ||||
|     protected String _publicBridgeName; | ||||
|     protected String _guestBridgeName; | ||||
|     protected String _privateIp; | ||||
|     protected String _pool; | ||||
|     protected String _localGateway; | ||||
|     private boolean _canBridgeFirewall; | ||||
|     protected String _localStoragePath; | ||||
|     protected String _localStorageUUID; | ||||
|     protected boolean _noMemBalloon = false; | ||||
|     protected String _guestCpuMode; | ||||
|     protected String _guestCpuModel; | ||||
|     protected List<String> _cpuFeatures; | ||||
|     protected boolean _noKvmClock; | ||||
|     protected String _videoHw; | ||||
|     protected int _videoRam; | ||||
|     protected Pair<Integer,Integer> hostOsVersion; | ||||
|     protected int _migrateSpeed; | ||||
|     protected int _migrateDowntime; | ||||
|     protected int _migratePauseAfter; | ||||
| 
 | ||||
|     private final Map <String, String> _pifs = new HashMap<String, String>(); | ||||
|     private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>(); | ||||
| 
 | ||||
|     protected boolean _disconnected = true; | ||||
|     protected int _timeout; | ||||
|     protected int _cmdsTimeout; | ||||
|     protected int _stopTimeout; | ||||
| 
 | ||||
|     protected static final HashMap<DomainState, PowerState> s_powerStatesTable; | ||||
|     static { | ||||
|         s_powerStatesTable = new HashMap<DomainState, PowerState>(); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown); | ||||
|         s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff); | ||||
|     } | ||||
| 
 | ||||
|     protected List<String> _vmsKilled = new ArrayList<String>(); | ||||
| 
 | ||||
|     private VirtualRoutingResource _virtRouterResource; | ||||
| 
 | ||||
|     private String _pingTestPath; | ||||
| 
 | ||||
|     private int _dom0MinMem; | ||||
| 
 | ||||
|     protected enum BridgeType { | ||||
|         NATIVE, OPENVSWITCH | ||||
| @ -1298,9 +1305,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             if (cmd instanceof ModifySshKeysCommand) { | ||||
|                 return execute((ModifySshKeysCommand)cmd); | ||||
|             } else if (cmd instanceof MaintainCommand) { | ||||
|             if (cmd instanceof MaintainCommand) { | ||||
|                 return execute((MaintainCommand)cmd); | ||||
|             } else if (cmd instanceof CreateCommand) { | ||||
|                 return execute((CreateCommand)cmd); | ||||
| @ -3001,79 +3006,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected Answer execute(final ModifySshKeysCommand cmd) { | ||||
|         final File sshKeysDir = new File(SSHKEYSPATH); | ||||
|         String result = null; | ||||
|         if (!sshKeysDir.exists()) { | ||||
|             // Change permissions for the 700 | ||||
|             final Script script = new Script("mkdir", _timeout, s_logger); | ||||
|             script.add("-m", "700"); | ||||
|             script.add(SSHKEYSPATH); | ||||
|             script.execute(); | ||||
| 
 | ||||
|             if (!sshKeysDir.exists()) { | ||||
|                 s_logger.debug("failed to create directory " + SSHKEYSPATH); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         final File pubKeyFile = new File(SSHPUBKEYPATH); | ||||
|         if (!pubKeyFile.exists()) { | ||||
|             try { | ||||
|                 pubKeyFile.createNewFile(); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Failed to create file: " + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (pubKeyFile.exists()) { | ||||
|             try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) { | ||||
|                 pubkStream.write(cmd.getPubKey().getBytes()); | ||||
|             } catch (final FileNotFoundException e) { | ||||
|                 result = "File" + SSHPUBKEYPATH + "is not found:" | ||||
|                         + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Write file " + SSHPUBKEYPATH + ":" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         final File prvKeyFile = new File(SSHPRVKEYPATH); | ||||
|         if (!prvKeyFile.exists()) { | ||||
|             try { | ||||
|                 prvKeyFile.createNewFile(); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Failed to create file: " + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (prvKeyFile.exists()) { | ||||
|             final String prvKey = cmd.getPrvKey(); | ||||
|             try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){ | ||||
|                 if ( prvKStream != null) { | ||||
|                     prvKStream.write(prvKey.getBytes()); | ||||
|                 } | ||||
|             } catch (final FileNotFoundException e) { | ||||
|                 result = "File" + SSHPRVKEYPATH + "is not found:" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Write file " + SSHPRVKEYPATH + ":" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|             final Script script = new Script("chmod", _timeout, s_logger); | ||||
|             script.add("600", SSHPRVKEYPATH); | ||||
|             script.execute(); | ||||
|         } | ||||
| 
 | ||||
|         if (result != null) { | ||||
|             return new Answer(cmd, false, result); | ||||
|         } else { | ||||
|             return new Answer(cmd, true, null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { | ||||
|         if (vm != null && vm.getDevices() != null) { | ||||
|             cleanupVMNetworks(conn, vm.getDevices().getInterfaces()); | ||||
|  | ||||
| @ -0,0 +1,112 @@ | ||||
| // | ||||
| // Licensed to the Apache Software Foundation (ASF) under one | ||||
| // or more contributor license agreements.  See the NOTICE file | ||||
| // distributed with this work for additional information | ||||
| // regarding copyright ownership.  The ASF licenses this file | ||||
| // to you under the Apache License, Version 2.0 (the | ||||
| // "License"); you may not use this file except in compliance | ||||
| // with the License.  You may obtain a copy of the License at | ||||
| // | ||||
| //   http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, | ||||
| // software distributed under the License is distributed on an | ||||
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
| // KIND, either express or implied.  See the License for the | ||||
| // specific language governing permissions and limitations | ||||
| // under the License. | ||||
| // | ||||
| 
 | ||||
| package com.cloud.hypervisor.kvm.resource.wrapper; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import org.apache.log4j.Logger; | ||||
| 
 | ||||
| import com.cloud.agent.api.Answer; | ||||
| import com.cloud.agent.api.ModifySshKeysCommand; | ||||
| import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; | ||||
| import com.cloud.resource.CommandWrapper; | ||||
| import com.cloud.utils.script.Script; | ||||
| 
 | ||||
| public final class LibvirtModifySshKeysCommandWrapper extends CommandWrapper<ModifySshKeysCommand, Answer, LibvirtComputingResource> { | ||||
| 
 | ||||
|     private static final Logger s_logger = Logger.getLogger(LibvirtModifySshKeysCommandWrapper.class); | ||||
| 
 | ||||
|     @Override | ||||
|     public Answer execute(final ModifySshKeysCommand command, final LibvirtComputingResource libvirtComputingResource) { | ||||
|         final File sshKeysDir = new File(LibvirtComputingResource.SSHKEYSPATH); | ||||
|         String result = null; | ||||
|         if (!sshKeysDir.exists()) { | ||||
|             // Change permissions for the 700 | ||||
|             final Script script = new Script("mkdir", libvirtComputingResource.getTimeout(), s_logger); | ||||
|             script.add("-m", "700"); | ||||
|             script.add(LibvirtComputingResource.SSHKEYSPATH); | ||||
|             script.execute(); | ||||
| 
 | ||||
|             if (!sshKeysDir.exists()) { | ||||
|                 s_logger.debug("failed to create directory " + LibvirtComputingResource.SSHKEYSPATH); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         final File pubKeyFile = new File(LibvirtComputingResource.SSHPUBKEYPATH); | ||||
|         if (!pubKeyFile.exists()) { | ||||
|             try { | ||||
|                 pubKeyFile.createNewFile(); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Failed to create file: " + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (pubKeyFile.exists()) { | ||||
|             try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) { | ||||
|                 pubkStream.write(command.getPubKey().getBytes()); | ||||
|             } catch (final FileNotFoundException e) { | ||||
|                 result = "File" + LibvirtComputingResource.SSHPUBKEYPATH + "is not found:" | ||||
|                         + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Write file " + LibvirtComputingResource.SSHPUBKEYPATH + ":" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         final File prvKeyFile = new File(LibvirtComputingResource.SSHPRVKEYPATH); | ||||
|         if (!prvKeyFile.exists()) { | ||||
|             try { | ||||
|                 prvKeyFile.createNewFile(); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Failed to create file: " + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (prvKeyFile.exists()) { | ||||
|             final String prvKey = command.getPrvKey(); | ||||
|             try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){ | ||||
|                 if ( prvKStream != null) { | ||||
|                     prvKStream.write(prvKey.getBytes()); | ||||
|                 } | ||||
|             } catch (final FileNotFoundException e) { | ||||
|                 result = "File" + LibvirtComputingResource.SSHPRVKEYPATH + "is not found:" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } catch (final IOException e) { | ||||
|                 result = "Write file " + LibvirtComputingResource.SSHPRVKEYPATH + ":" + e.toString(); | ||||
|                 s_logger.debug(result); | ||||
|             } | ||||
|             final Script script = new Script("chmod", libvirtComputingResource.getTimeout(), s_logger); | ||||
|             script.add("600", LibvirtComputingResource.SSHPRVKEYPATH); | ||||
|             script.execute(); | ||||
|         } | ||||
| 
 | ||||
|         if (result != null) { | ||||
|             return new Answer(command, false, result); | ||||
|         } else { | ||||
|             return new Answer(command, true, null); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -31,6 +31,7 @@ import com.cloud.agent.api.GetVmDiskStatsCommand; | ||||
| import com.cloud.agent.api.GetVmStatsCommand; | ||||
| import com.cloud.agent.api.GetVncPortCommand; | ||||
| import com.cloud.agent.api.MigrateCommand; | ||||
| import com.cloud.agent.api.ModifySshKeysCommand; | ||||
| import com.cloud.agent.api.PingTestCommand; | ||||
| import com.cloud.agent.api.PrepareForMigrationCommand; | ||||
| import com.cloud.agent.api.ReadyCommand; | ||||
| @ -78,6 +79,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { | ||||
|         linbvirtCommands.put(WatchConsoleProxyLoadCommand.class, new LibvirtWatchConsoleProxyLoadCommandWrapper()); | ||||
|         linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper()); | ||||
|         linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper()); | ||||
|         linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper()); | ||||
| 
 | ||||
|         resources.put(LibvirtComputingResource.class, linbvirtCommands); | ||||
|     } | ||||
|  | ||||
| @ -73,6 +73,7 @@ import com.cloud.agent.api.GetVmDiskStatsCommand; | ||||
| import com.cloud.agent.api.GetVmStatsCommand; | ||||
| import com.cloud.agent.api.GetVncPortCommand; | ||||
| import com.cloud.agent.api.MigrateCommand; | ||||
| import com.cloud.agent.api.ModifySshKeysCommand; | ||||
| import com.cloud.agent.api.PingTestCommand; | ||||
| import com.cloud.agent.api.PrepareForMigrationCommand; | ||||
| import com.cloud.agent.api.ReadyCommand; | ||||
| @ -1201,4 +1202,19 @@ public class LibvirtComputingResourceTest { | ||||
|             fail(e.getMessage()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testModifySshKeysCommand() { | ||||
|         final ModifySshKeysCommand command = new ModifySshKeysCommand("", ""); | ||||
| 
 | ||||
|         when(libvirtComputingResource.getTimeout()).thenReturn(0); | ||||
| 
 | ||||
|         final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); | ||||
|         assertNotNull(wrapper); | ||||
| 
 | ||||
|         final Answer answer = wrapper.execute(command, libvirtComputingResource); | ||||
|         assertFalse(answer.getResult()); | ||||
| 
 | ||||
|         verify(libvirtComputingResource, times(1)).getTimeout(); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user