diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 788a3e4bde8..62c71489229 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -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 _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 hostOsVersion; + protected int _migrateSpeed; + protected int _migrateDowntime; + protected int _migratePauseAfter; + + private final Map _pifs = new HashMap(); + private final Map _vmStats = new ConcurrentHashMap(); + + protected static final MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + " " + + " {1}" + " " + " "); + + protected static final HashMap s_powerStatesTable; + static { + s_powerStatesTable = new HashMap(); + 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 _vmsKilled = new ArrayList(); + + 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 map = new HashMap(); @@ -424,66 +490,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - protected static final MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + " " - + " {1}" + " " + " "); - - 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 _cpuFeatures; - protected boolean _noKvmClock; - protected String _videoHw; - protected int _videoRam; - protected Pair hostOsVersion; - protected int _migrateSpeed; - protected int _migrateDowntime; - protected int _migratePauseAfter; - - private final Map _pifs = new HashMap(); - private final Map _vmStats = new ConcurrentHashMap(); - - protected boolean _disconnected = true; - protected int _timeout; - protected int _cmdsTimeout; - protected int _stopTimeout; - - protected static final HashMap s_powerStatesTable; - static { - s_powerStatesTable = new HashMap(); - 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 _vmsKilled = new ArrayList(); - - 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()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java new file mode 100644 index 00000000000..d5943c5f034 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java @@ -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 { + + 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); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java index daa5a0ca39f..c5001c47386 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java @@ -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); } diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 09a9e369687..a2b3b7fc4ee 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -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(); + } } \ No newline at end of file