mirror of https://github.com/apache/cloudstack.git
Merge branch 'main' into disk-controller-mappings
This commit is contained in:
commit
5459efe3ad
|
|
@ -51,16 +51,13 @@ github:
|
|||
|
||||
collaborators:
|
||||
- acs-robot
|
||||
- rajujith
|
||||
- GaOrtiga
|
||||
- SadiJr
|
||||
- winterhazel
|
||||
- gpordeus
|
||||
- hsato03
|
||||
- bernardodemarco
|
||||
- abh1sar
|
||||
- FelipeM525
|
||||
- lucas-a-martins
|
||||
- nicoschmdt
|
||||
|
||||
protected_branches: ~
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.6
|
||||
3.10
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Apache CloudStack [](https://github.com/apache/cloudstack/actions/workflows/build.yml) [](https://github.com/apache/cloudstack/actions/workflows/ui.yml) [](https://github.com/apache/cloudstack/actions/workflows/rat.yml) [](https://github.com/apache/cloudstack/actions/workflows/ci.yml) [](https://sonarcloud.io/dashboard?id=apache_cloudstack) [](https://codecov.io/gh/apache/cloudstack)
|
||||
|
||||
[](https://cloudstack.apache.org/)
|
||||
[](https://cloudstack.apache.org/)
|
||||
|
||||
Apache CloudStack is open source software designed to deploy and manage large
|
||||
networks of virtual machines, as a highly available, highly scalable
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ hypervisor.type=kvm
|
|||
# the management server would send.
|
||||
# In case of arm64 (aarch64), this will change the machine type to 'virt' and
|
||||
# adds a SCSI and a USB controller in the domain xml.
|
||||
# Possible values: x86_64 | aarch64
|
||||
# Possible values: x86_64 | aarch64 | s390x
|
||||
# If null (default), defaults to the VM's OS architecture
|
||||
#guest.cpu.arch=
|
||||
|
||||
|
|
@ -434,3 +434,10 @@ iscsi.session.cleanup.enabled=false
|
|||
|
||||
# Implicit host tags managed by agent.properties
|
||||
# host.tags=
|
||||
|
||||
# Timeout(in seconds) for SSL handshake when agent connects to server. When no value is set then default value of 30s
|
||||
# will be used
|
||||
#ssl.handshake.timeout=
|
||||
|
||||
# Wait(in seconds) during agent reconnections. When no value is set then default value of 5s will be used
|
||||
#backoff.seconds=
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,29 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.agent;
|
||||
|
||||
import com.cloud.agent.Agent.ExitStatus;
|
||||
import com.cloud.agent.dao.StorageComponent;
|
||||
import com.cloud.agent.dao.impl.PropertiesStorage;
|
||||
import com.cloud.agent.properties.AgentProperties;
|
||||
import com.cloud.agent.properties.AgentPropertiesFileHandler;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.LogUtils;
|
||||
import com.cloud.utils.ProcessUtil;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.backoff.BackoffAlgorithm;
|
||||
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.commons.daemon.Daemon;
|
||||
import org.apache.commons.daemon.DaemonContext;
|
||||
import org.apache.commons.daemon.DaemonInitException;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
|
@ -53,6 +30,31 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.commons.daemon.Daemon;
|
||||
import org.apache.commons.daemon.DaemonContext;
|
||||
import org.apache.commons.daemon.DaemonInitException;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
|
||||
import com.cloud.agent.Agent.ExitStatus;
|
||||
import com.cloud.agent.dao.StorageComponent;
|
||||
import com.cloud.agent.dao.impl.PropertiesStorage;
|
||||
import com.cloud.agent.properties.AgentProperties;
|
||||
import com.cloud.agent.properties.AgentPropertiesFileHandler;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.LogUtils;
|
||||
import com.cloud.utils.ProcessUtil;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.backoff.BackoffAlgorithm;
|
||||
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public class AgentShell implements IAgentShell, Daemon {
|
||||
protected static Logger LOGGER = LogManager.getLogger(AgentShell.class);
|
||||
|
||||
|
|
@ -415,7 +417,9 @@ public class AgentShell implements IAgentShell, Daemon {
|
|||
|
||||
LOGGER.info("Defaulting to the constant time backoff algorithm");
|
||||
_backoff = new ConstantTimeBackoff();
|
||||
_backoff.configure("ConstantTimeBackoff", new HashMap<String, Object>());
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("seconds", _properties.getProperty("backoff.seconds"));
|
||||
_backoff.configure("ConstantTimeBackoff", map);
|
||||
}
|
||||
|
||||
private void launchAgent() throws ConfigurationException {
|
||||
|
|
@ -464,6 +468,11 @@ public class AgentShell implements IAgentShell, Daemon {
|
|||
agent.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSslHandshakeTimeout() {
|
||||
return AgentPropertiesFileHandler.getPropertyValue(AgentProperties.SSL_HANDSHAKE_TIMEOUT);
|
||||
}
|
||||
|
||||
public synchronized int getNextAgentId() {
|
||||
return _nextAgentId++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,4 +74,6 @@ public interface IAgentShell {
|
|||
boolean isConnectionTransfer();
|
||||
|
||||
void setConnectionTransfer(boolean connectionTransfer);
|
||||
|
||||
Integer getSslHandshakeTimeout();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ public class AgentProperties{
|
|||
/**
|
||||
* This param will set the CPU architecture for the domain to override what the management server would send.<br>
|
||||
* In case of arm64 (aarch64), this will change the machine type to 'virt' and add a SCSI and a USB controller in the domain XML.<br>
|
||||
* Possible values: x86_64 | aarch64 <br>
|
||||
* Possible values: x86_64 | aarch64 | s390x <br>
|
||||
* Data type: String.<br>
|
||||
* Default value: <code>null</code> (will set use the architecture of the VM's OS).
|
||||
*/
|
||||
|
|
@ -811,6 +811,13 @@ public class AgentProperties{
|
|||
*/
|
||||
public static final Property<String> HOST_TAGS = new Property<>("host.tags", null, String.class);
|
||||
|
||||
/**
|
||||
* Timeout for SSL handshake in seconds
|
||||
* Data type: Integer.<br>
|
||||
* Default value: <code>null</code>
|
||||
*/
|
||||
public static final Property<Integer> SSL_HANDSHAKE_TIMEOUT = new Property<>("ssl.handshake.timeout", null, Integer.class);
|
||||
|
||||
public static class Property <T>{
|
||||
private String name;
|
||||
private T defaultValue;
|
||||
|
|
|
|||
|
|
@ -362,4 +362,11 @@ public class AgentShellTest {
|
|||
|
||||
Assert.assertEquals(expected, shell.getConnectedHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSslHandshakeTimeout() {
|
||||
Integer expected = 1;
|
||||
agentPropertiesFileHandlerMocked.when(() -> AgentPropertiesFileHandler.getPropertyValue(Mockito.eq(AgentProperties.SSL_HANDSHAKE_TIMEOUT))).thenReturn(expected);
|
||||
Assert.assertEquals(expected, agentShellSpy.getSslHandshakeTimeout());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,257 @@
|
|||
// 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.agent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
|
||||
import com.cloud.utils.nio.Link;
|
||||
import com.cloud.utils.nio.NioConnection;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AgentTest {
|
||||
Agent agent;
|
||||
private AgentShell shell;
|
||||
private ServerResource serverResource;
|
||||
private Logger logger;
|
||||
|
||||
@Before
|
||||
public void setUp() throws ConfigurationException {
|
||||
shell = mock(AgentShell.class);
|
||||
serverResource = mock(ServerResource.class);
|
||||
doReturn(true).when(serverResource).configure(any(), any());
|
||||
doReturn(1).when(shell).getWorkers();
|
||||
doReturn(1).when(shell).getPingRetries();
|
||||
agent = new Agent(shell, 1, serverResource);
|
||||
logger = mock(Logger.class);
|
||||
ReflectionTestUtils.setField(agent, "logger", logger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLinkLogNullLinkReturnsEmptyString() {
|
||||
Link link = null;
|
||||
String result = agent.getLinkLog(link);
|
||||
assertEquals("", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLinkLogLinkWithTraceEnabledReturnsLinkLogWithHashCode() {
|
||||
Link link = mock(Link.class);
|
||||
InetSocketAddress socketAddress = new InetSocketAddress("192.168.1.100", 1111);
|
||||
when(link.getSocketAddress()).thenReturn(socketAddress);
|
||||
when(logger.isTraceEnabled()).thenReturn(true);
|
||||
|
||||
String result = agent.getLinkLog(link);
|
||||
System.out.println(result);
|
||||
assertTrue(result.startsWith(System.identityHashCode(link) + "-"));
|
||||
assertTrue(result.contains("192.168.1.100"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAgentNameWhenServerResourceIsNull() {
|
||||
ReflectionTestUtils.setField(agent, "serverResource", null);
|
||||
assertEquals("Agent", agent.getAgentName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAgentNameWhenAppendAgentNameIsTrue() {
|
||||
when(serverResource.isAppendAgentNameToLogs()).thenReturn(true);
|
||||
when(serverResource.getName()).thenReturn("TestAgent");
|
||||
|
||||
String agentName = agent.getAgentName();
|
||||
assertEquals("TestAgent", agentName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAgentNameWhenAppendAgentNameIsFalse() {
|
||||
when(serverResource.isAppendAgentNameToLogs()).thenReturn(false);
|
||||
|
||||
String agentName = agent.getAgentName();
|
||||
assertEquals("Agent", agentName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgentInitialization() {
|
||||
Runtime.getRuntime().removeShutdownHook(agent.shutdownThread);
|
||||
when(shell.getPingRetries()).thenReturn(3);
|
||||
when(shell.getWorkers()).thenReturn(5);
|
||||
agent.setupShutdownHookAndInitExecutors();
|
||||
assertNotNull(agent.selfTaskExecutor);
|
||||
assertNotNull(agent.outRequestHandler);
|
||||
assertNotNull(agent.requestHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgentShutdownHookAdded() {
|
||||
Runtime.getRuntime().removeShutdownHook(agent.shutdownThread);
|
||||
agent.setupShutdownHookAndInitExecutors();
|
||||
verify(logger).trace("Adding shutdown hook");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceGuidValidGuidAndResourceName() {
|
||||
when(shell.getGuid()).thenReturn("12345");
|
||||
String result = agent.getResourceGuid();
|
||||
assertTrue(result.startsWith("12345-" + ServerResource.class.getSimpleName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetZoneReturnsValidZone() {
|
||||
when(shell.getZone()).thenReturn("ZoneA");
|
||||
String result = agent.getZone();
|
||||
assertEquals("ZoneA", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPodReturnsValidPod() {
|
||||
when(shell.getPod()).thenReturn("PodA");
|
||||
String result = agent.getPod();
|
||||
assertEquals("PodA", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLinkAssignsLink() {
|
||||
Link mockLink = mock(Link.class);
|
||||
agent.setLink(mockLink);
|
||||
assertEquals(mockLink, agent.link);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceReturnsServerResource() {
|
||||
ServerResource mockResource = mock(ServerResource.class);
|
||||
ReflectionTestUtils.setField(agent, "serverResource", mockResource);
|
||||
ServerResource result = agent.getResource();
|
||||
assertSame(mockResource, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceName() {
|
||||
String result = agent.getResourceName();
|
||||
assertTrue(result.startsWith(ServerResource.class.getSimpleName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLastPingResponseTimeUpdatesCurrentTime() {
|
||||
long beforeUpdate = System.currentTimeMillis();
|
||||
agent.updateLastPingResponseTime();
|
||||
long updatedTime = agent.lastPingResponseTime.get();
|
||||
assertTrue(updatedTime >= beforeUpdate);
|
||||
assertTrue(updatedTime <= System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextSequenceIncrementsSequence() {
|
||||
long initialSequence = agent.getNextSequence();
|
||||
long nextSequence = agent.getNextSequence();
|
||||
assertEquals(initialSequence + 1, nextSequence);
|
||||
long thirdSequence = agent.getNextSequence();
|
||||
assertEquals(nextSequence + 1, thirdSequence);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterControlListenerAddsListener() {
|
||||
IAgentControlListener listener = mock(IAgentControlListener.class);
|
||||
agent.registerControlListener(listener);
|
||||
assertTrue(agent.controlListeners.contains(listener));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregisterControlListenerRemovesListener() {
|
||||
IAgentControlListener listener = mock(IAgentControlListener.class);
|
||||
agent.registerControlListener(listener);
|
||||
assertTrue(agent.controlListeners.contains(listener));
|
||||
agent.unregisterControlListener(listener);
|
||||
assertFalse(agent.controlListeners.contains(listener));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseAndTerminateLinkLinkIsNullDoesNothing() {
|
||||
agent.closeAndTerminateLink(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseAndTerminateLinkValidLinkCallsCloseAndTerminate() {
|
||||
Link mockLink = mock(Link.class);
|
||||
agent.closeAndTerminateLink(mockLink);
|
||||
verify(mockLink).close();
|
||||
verify(mockLink).terminated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopAndCleanupConnectionConnectionIsNullDoesNothing() {
|
||||
agent.connection = null;
|
||||
agent.stopAndCleanupConnection(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopAndCleanupConnectionValidConnectionNoWaitStopsAndCleansUp() throws IOException {
|
||||
NioConnection mockConnection = mock(NioConnection.class);
|
||||
agent.connection = mockConnection;
|
||||
agent.stopAndCleanupConnection(false);
|
||||
verify(mockConnection).stop();
|
||||
verify(mockConnection).cleanUp();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopAndCleanupConnectionCleanupThrowsIOExceptionLogsWarning() throws IOException {
|
||||
NioConnection mockConnection = mock(NioConnection.class);
|
||||
agent.connection = mockConnection;
|
||||
doThrow(new IOException("Cleanup failed")).when(mockConnection).cleanUp();
|
||||
agent.stopAndCleanupConnection(false);
|
||||
verify(mockConnection).stop();
|
||||
verify(logger).warn(eq("Fail to clean up old connection. {}"), any(IOException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopAndCleanupConnectionValidConnectionWaitForStopWaitsForStartupToStop() throws IOException {
|
||||
NioConnection mockConnection = mock(NioConnection.class);
|
||||
ConstantTimeBackoff mockBackoff = mock(ConstantTimeBackoff.class);
|
||||
mockBackoff.setTimeToWait(0);
|
||||
agent.connection = mockConnection;
|
||||
when(shell.getBackoffAlgorithm()).thenReturn(mockBackoff);
|
||||
when(mockConnection.isStartup()).thenReturn(true, true, false);
|
||||
agent.stopAndCleanupConnection(true);
|
||||
verify(mockConnection).stop();
|
||||
verify(mockConnection).cleanUp();
|
||||
verify(mockBackoff, times(3)).waitBeforeRetry();
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ public class RemoteInstanceTO implements Serializable {
|
|||
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
private String instanceName;
|
||||
private String instancePath;
|
||||
|
||||
// VMware Remote Instances parameters (required for exporting OVA through ovftool)
|
||||
// TODO: cloud.agent.transport.Request#getCommands() cannot handle gsoc decode for polymorphic classes
|
||||
|
|
@ -44,9 +45,10 @@ public class RemoteInstanceTO implements Serializable {
|
|||
this.instanceName = instanceName;
|
||||
}
|
||||
|
||||
public RemoteInstanceTO(String instanceName, String vcenterHost, String vcenterUsername, String vcenterPassword, String datacenterName) {
|
||||
public RemoteInstanceTO(String instanceName, String instancePath, String vcenterHost, String vcenterUsername, String vcenterPassword, String datacenterName) {
|
||||
this.hypervisorType = Hypervisor.HypervisorType.VMware;
|
||||
this.instanceName = instanceName;
|
||||
this.instancePath = instancePath;
|
||||
this.vcenterHost = vcenterHost;
|
||||
this.vcenterUsername = vcenterUsername;
|
||||
this.vcenterPassword = vcenterPassword;
|
||||
|
|
@ -61,6 +63,10 @@ public class RemoteInstanceTO implements Serializable {
|
|||
return this.instanceName;
|
||||
}
|
||||
|
||||
public String getInstancePath() {
|
||||
return this.instancePath;
|
||||
}
|
||||
|
||||
public String getVcenterUsername() {
|
||||
return vcenterUsername;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public interface Resource {
|
|||
short RESOURCE_UNLIMITED = -1;
|
||||
String UNLIMITED = "Unlimited";
|
||||
|
||||
enum ResourceType { // Primary and Secondary storage are allocated_storage and not the physical storage.
|
||||
enum ResourceType { // All storage type resources are allocated_storage and not the physical storage.
|
||||
user_vm("user_vm", 0),
|
||||
public_ip("public_ip", 1),
|
||||
volume("volume", 2),
|
||||
|
|
@ -33,7 +33,11 @@ public interface Resource {
|
|||
cpu("cpu", 8),
|
||||
memory("memory", 9),
|
||||
primary_storage("primary_storage", 10),
|
||||
secondary_storage("secondary_storage", 11);
|
||||
secondary_storage("secondary_storage", 11),
|
||||
backup("backup", 12),
|
||||
backup_storage("backup_storage", 13),
|
||||
bucket("bucket", 14),
|
||||
object_storage("object_storage", 15);
|
||||
|
||||
private String name;
|
||||
private int ordinal;
|
||||
|
|
@ -62,6 +66,10 @@ public interface Resource {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Boolean isStorageType(ResourceType type) {
|
||||
return (type == primary_storage || type == secondary_storage || type == backup_storage || type == object_storage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ResourceOwnerType {
|
||||
|
|
|
|||
|
|
@ -785,6 +785,9 @@ public class EventTypes {
|
|||
public static final String EVENT_SHAREDFS_EXPUNGE = "SHAREDFS.EXPUNGE";
|
||||
public static final String EVENT_SHAREDFS_RECOVER = "SHAREDFS.RECOVER";
|
||||
|
||||
// Resource Limit
|
||||
public static final String EVENT_RESOURCE_LIMIT_UPDATE = "RESOURCE.LIMIT.UPDATE";
|
||||
|
||||
static {
|
||||
|
||||
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import com.cloud.utils.SerialVersionUID;
|
|||
public class StorageAccessException extends RuntimeException {
|
||||
private static final long serialVersionUID = SerialVersionUID.StorageAccessException;
|
||||
|
||||
public StorageAccessException(String message) {
|
||||
super(message);
|
||||
public StorageAccessException(String message, Exception causer) {
|
||||
super(message, causer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,10 @@
|
|||
// under the License.
|
||||
package com.cloud.storage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Storage {
|
||||
public static enum ImageFormat {
|
||||
|
|
@ -139,6 +135,21 @@ public class Storage {
|
|||
ISODISK /* Template corresponding to a iso (non root disk) present in an OVA */
|
||||
}
|
||||
|
||||
public enum EncryptionSupport {
|
||||
/**
|
||||
* Encryption not supported.
|
||||
*/
|
||||
Unsupported,
|
||||
/**
|
||||
* Will use hypervisor encryption driver (qemu -> luks)
|
||||
*/
|
||||
Hypervisor,
|
||||
/**
|
||||
* Storage pool handles encryption and just provides an encrypted volume
|
||||
*/
|
||||
Storage
|
||||
}
|
||||
|
||||
/**
|
||||
* StoragePoolTypes carry some details about the format and capabilities of a storage pool. While not necessarily a
|
||||
* 1:1 with PrimaryDataStoreDriver (and for KVM agent, KVMStoragePool and StorageAdaptor) implementations, it is
|
||||
|
|
@ -150,61 +161,37 @@ public class Storage {
|
|||
* ensure this is available on the agent side as well. This is best done by defining the StoragePoolType in a common
|
||||
* package available on both management server and agent plugin jars.
|
||||
*/
|
||||
public static class StoragePoolType {
|
||||
private static final Map<String, StoragePoolType> map = new LinkedHashMap<>();
|
||||
public static enum StoragePoolType {
|
||||
Filesystem(false, true, EncryptionSupport.Hypervisor), // local directory
|
||||
NetworkFilesystem(true, true, EncryptionSupport.Hypervisor), // NFS
|
||||
IscsiLUN(true, false, EncryptionSupport.Unsupported), // shared LUN, with a clusterfs overlay
|
||||
Iscsi(true, false, EncryptionSupport.Unsupported), // for e.g., ZFS Comstar
|
||||
ISO(false, false, EncryptionSupport.Unsupported), // for iso image
|
||||
LVM(false, false, EncryptionSupport.Unsupported), // XenServer local LVM SR
|
||||
CLVM(true, false, EncryptionSupport.Unsupported),
|
||||
RBD(true, true, EncryptionSupport.Unsupported), // http://libvirt.org/storage.html#StorageBackendRBD
|
||||
SharedMountPoint(true, true, EncryptionSupport.Hypervisor),
|
||||
VMFS(true, true, EncryptionSupport.Unsupported), // VMware VMFS storage
|
||||
PreSetup(true, true, EncryptionSupport.Unsupported), // for XenServer, Storage Pool is set up by customers.
|
||||
EXT(false, true, EncryptionSupport.Unsupported), // XenServer local EXT SR
|
||||
OCFS2(true, false, EncryptionSupport.Unsupported),
|
||||
SMB(true, false, EncryptionSupport.Unsupported),
|
||||
Gluster(true, false, EncryptionSupport.Unsupported),
|
||||
PowerFlex(true, true, EncryptionSupport.Hypervisor), // Dell EMC PowerFlex/ScaleIO (formerly VxFlexOS)
|
||||
ManagedNFS(true, false, EncryptionSupport.Unsupported),
|
||||
Linstor(true, true, EncryptionSupport.Storage),
|
||||
DatastoreCluster(true, true, EncryptionSupport.Unsupported), // for VMware, to abstract pool of clusters
|
||||
StorPool(true, true, EncryptionSupport.Hypervisor),
|
||||
FiberChannel(true, true, EncryptionSupport.Unsupported); // Fiber Channel Pool for KVM hypervisors is used to find the volume by WWN value (/dev/disk/by-id/wwn-<wwnvalue>)
|
||||
|
||||
public static final StoragePoolType Filesystem = new StoragePoolType("Filesystem", false, true, true);
|
||||
public static final StoragePoolType NetworkFilesystem = new StoragePoolType("NetworkFilesystem", true, true, true);
|
||||
public static final StoragePoolType IscsiLUN = new StoragePoolType("IscsiLUN", true, false, false);
|
||||
public static final StoragePoolType Iscsi = new StoragePoolType("Iscsi", true, false, false);
|
||||
public static final StoragePoolType ISO = new StoragePoolType("ISO", false, false, false);
|
||||
public static final StoragePoolType LVM = new StoragePoolType("LVM", false, false, false);
|
||||
public static final StoragePoolType CLVM = new StoragePoolType("CLVM", true, false, false);
|
||||
public static final StoragePoolType RBD = new StoragePoolType("RBD", true, true, false);
|
||||
public static final StoragePoolType SharedMountPoint = new StoragePoolType("SharedMountPoint", true, true, true);
|
||||
public static final StoragePoolType VMFS = new StoragePoolType("VMFS", true, true, false);
|
||||
public static final StoragePoolType PreSetup = new StoragePoolType("PreSetup", true, true, false);
|
||||
public static final StoragePoolType EXT = new StoragePoolType("EXT", false, true, false);
|
||||
public static final StoragePoolType OCFS2 = new StoragePoolType("OCFS2", true, false, false);
|
||||
public static final StoragePoolType SMB = new StoragePoolType("SMB", true, false, false);
|
||||
public static final StoragePoolType Gluster = new StoragePoolType("Gluster", true, false, false);
|
||||
public static final StoragePoolType PowerFlex = new StoragePoolType("PowerFlex", true, true, true);
|
||||
public static final StoragePoolType ManagedNFS = new StoragePoolType("ManagedNFS", true, false, false);
|
||||
public static final StoragePoolType Linstor = new StoragePoolType("Linstor", true, true, false);
|
||||
public static final StoragePoolType DatastoreCluster = new StoragePoolType("DatastoreCluster", true, true, false);
|
||||
public static final StoragePoolType StorPool = new StoragePoolType("StorPool", true,true,true);
|
||||
public static final StoragePoolType FiberChannel = new StoragePoolType("FiberChannel", true,true,false);
|
||||
|
||||
|
||||
private final String name;
|
||||
private final boolean shared;
|
||||
private final boolean overProvisioning;
|
||||
private final boolean encryption;
|
||||
private final EncryptionSupport encryption;
|
||||
|
||||
/**
|
||||
* New StoragePoolType, set the name to check with it in Dao (Note: Do not register it into the map of pool types).
|
||||
* @param name name of the StoragePoolType.
|
||||
*/
|
||||
public StoragePoolType(String name) {
|
||||
this.name = name;
|
||||
this.shared = false;
|
||||
this.overProvisioning = false;
|
||||
this.encryption = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a new StoragePoolType, and register it into the map of pool types known to the management server.
|
||||
* @param name Simple unique name of the StoragePoolType.
|
||||
* @param shared Storage pool is shared/accessible to multiple hypervisors
|
||||
* @param overProvisioning Storage pool supports overProvisioning
|
||||
* @param encryption Storage pool supports encrypted volumes
|
||||
*/
|
||||
public StoragePoolType(String name, boolean shared, boolean overProvisioning, boolean encryption) {
|
||||
this.name = name;
|
||||
StoragePoolType(boolean shared, boolean overProvisioning, EncryptionSupport encryption) {
|
||||
this.shared = shared;
|
||||
this.overProvisioning = overProvisioning;
|
||||
this.encryption = encryption;
|
||||
addStoragePoolType(this);
|
||||
}
|
||||
|
||||
public boolean isShared() {
|
||||
|
|
@ -216,50 +203,12 @@ public class Storage {
|
|||
}
|
||||
|
||||
public boolean supportsEncryption() {
|
||||
return encryption == EncryptionSupport.Hypervisor || encryption == EncryptionSupport.Storage;
|
||||
}
|
||||
|
||||
public EncryptionSupport encryptionSupportMode() {
|
||||
return encryption;
|
||||
}
|
||||
|
||||
private static void addStoragePoolType(StoragePoolType storagePoolType) {
|
||||
map.putIfAbsent(storagePoolType.name, storagePoolType);
|
||||
}
|
||||
|
||||
public static StoragePoolType[] values() {
|
||||
return map.values().toArray(StoragePoolType[]::new).clone();
|
||||
}
|
||||
|
||||
public static StoragePoolType valueOf(String name) {
|
||||
if (StringUtils.isBlank(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StoragePoolType storage = map.get(name);
|
||||
if (storage == null) {
|
||||
throw new IllegalArgumentException("StoragePoolType '" + name + "' not found");
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StoragePoolType that = (StoragePoolType) o;
|
||||
return Objects.equals(name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<StoragePoolType> getNonSharedStoragePoolTypes() {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@ import java.net.MalformedURLException;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.volume.AssignVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ChangeOfferingForVolumeCmd;
|
||||
|
|
@ -37,13 +42,9 @@ import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
|||
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
|
||||
public interface VolumeApiService {
|
||||
|
||||
ConfigKey<Long> ConcurrentMigrationsThresholdPerDatastore = new ConfigKey<Long>("Advanced"
|
||||
ConfigKey<Long> ConcurrentMigrationsThresholdPerDatastore = new ConfigKey<>("Advanced"
|
||||
, Long.class
|
||||
, "concurrent.migrations.per.target.datastore"
|
||||
, "0"
|
||||
|
|
@ -51,7 +52,7 @@ public interface VolumeApiService {
|
|||
, true // not sure if this is to be dynamic
|
||||
, ConfigKey.Scope.Global);
|
||||
|
||||
ConfigKey<Boolean> UseHttpsToUpload = new ConfigKey<Boolean>("Advanced",
|
||||
ConfigKey<Boolean> UseHttpsToUpload = new ConfigKey<>("Advanced",
|
||||
Boolean.class,
|
||||
"use.https.to.upload",
|
||||
"true",
|
||||
|
|
@ -85,7 +86,7 @@ public interface VolumeApiService {
|
|||
* @param cmd
|
||||
* the API command wrapping the criteria
|
||||
* @return the volume object
|
||||
* @throws ResourceAllocationException
|
||||
* @throws ResourceAllocationException no capacity to allocate the new volume size
|
||||
*/
|
||||
Volume resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
|
|
@ -139,13 +140,13 @@ public interface VolumeApiService {
|
|||
Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Checks if the target storage supports the disk offering.
|
||||
* Checks if the storage pool supports the disk offering tags.
|
||||
* This validation is consistent with the mechanism used to select a storage pool to deploy a volume when a virtual machine is deployed or when a data disk is allocated.
|
||||
*
|
||||
* The scenarios when this method returns true or false is presented in the following table.
|
||||
* <table border="1">
|
||||
* <tr>
|
||||
* <th>#</th><th>Disk offering tags</th><th>Storage tags</th><th>Does the storage support the disk offering?</th>
|
||||
* <th>#</th><th>Disk offering diskOfferingTags</th><th>Storage diskOfferingTags</th><th>Does the storage support the disk offering?</th>
|
||||
* </tr>
|
||||
* <body>
|
||||
* <tr>
|
||||
|
|
@ -169,7 +170,8 @@ public interface VolumeApiService {
|
|||
* </body>
|
||||
* </table>
|
||||
*/
|
||||
boolean doesTargetStorageSupportDiskOffering(StoragePool destPool, String diskOfferingTags);
|
||||
boolean doesStoragePoolSupportDiskOffering(StoragePool destPool, DiskOffering diskOffering);
|
||||
boolean doesStoragePoolSupportDiskOfferingTags(StoragePool destPool, String diskOfferingTags);
|
||||
|
||||
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
|
||||
|
||||
|
|
@ -190,4 +192,6 @@ public interface VolumeApiService {
|
|||
boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException;
|
||||
|
||||
Pair<String, String> checkAndRepairVolume(CheckAndRepairVolumeCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
Long getVolumePhysicalSize(Storage.ImageFormat format, String path, String chainInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ public interface RoleService {
|
|||
ConfigKey<Boolean> EnableDynamicApiChecker = new ConfigKey<>("Advanced", Boolean.class, "dynamic.apichecker.enabled", "false",
|
||||
"If set to true, this enables the dynamic role-based api access checker and disables the default static role-based api access checker.", true);
|
||||
|
||||
ConfigKey<Integer> DynamicApiCheckerCachePeriod = new ConfigKey<>("Advanced", Integer.class,
|
||||
"dynamic.apichecker.cache.period", "0",
|
||||
"Defines the expiration time in seconds for the Dynamic API Checker cache, determining how long cached data is retained before being refreshed. If set to zero then caching will be disabled",
|
||||
false);
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -51,12 +51,19 @@ public class ApiConstants {
|
|||
public static final String AVAILABLE = "available";
|
||||
public static final String AVAILABLE_SUBNETS = "availablesubnets";
|
||||
public static final String AVAILABLE_VIRTUAL_MACHINE_COUNT = "availablevirtualmachinecount";
|
||||
public static final String BACKUP_AVAILABLE = "backupavailable";
|
||||
public static final String BACKUP_ID = "backupid";
|
||||
public static final String BACKUP_LIMIT = "backuplimit";
|
||||
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
|
||||
public static final String BACKUP_OFFERING_ID = "backupofferingid";
|
||||
public static final String BACKUP_STORAGE_AVAILABLE = "backupstorageavailable";
|
||||
public static final String BACKUP_STORAGE_LIMIT = "backupstoragelimit";
|
||||
public static final String BACKUP_STORAGE_TOTAL = "backupstoragetotal";
|
||||
public static final String BACKUP_TOTAL = "backuptotal";
|
||||
public static final String BASE64_IMAGE = "base64image";
|
||||
public static final String BGP_PEERS = "bgppeers";
|
||||
public static final String BGP_PEER_IDS = "bgppeerids";
|
||||
public static final String BATCH_SIZE = "batchsize";
|
||||
public static final String BITS = "bits";
|
||||
public static final String BOOTABLE = "bootable";
|
||||
public static final String BIND_DN = "binddn";
|
||||
|
|
@ -322,6 +329,7 @@ public class ApiConstants {
|
|||
public static final String MAC_ADDRESS = "macaddress";
|
||||
public static final String MAX = "max";
|
||||
public static final String MAX_SNAPS = "maxsnaps";
|
||||
public static final String MAX_BACKUPS = "maxbackups";
|
||||
public static final String MAX_CPU_NUMBER = "maxcpunumber";
|
||||
public static final String MAX_MEMORY = "maxmemory";
|
||||
public static final String MIN_CPU_NUMBER = "mincpunumber";
|
||||
|
|
@ -436,6 +444,7 @@ public class ApiConstants {
|
|||
public static final String QUALIFIERS = "qualifiers";
|
||||
public static final String QUERY_FILTER = "queryfilter";
|
||||
public static final String SCHEDULE = "schedule";
|
||||
public static final String SCHEDULE_ID = "scheduleid";
|
||||
public static final String SCOPE = "scope";
|
||||
public static final String SEARCH_BASE = "searchbase";
|
||||
public static final String SECONDARY_IP = "secondaryip";
|
||||
|
|
@ -447,7 +456,6 @@ public class ApiConstants {
|
|||
public static final String SENT = "sent";
|
||||
public static final String SENT_BYTES = "sentbytes";
|
||||
public static final String SERIAL = "serial";
|
||||
public static final String SERVICE_IP = "serviceip";
|
||||
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
|
||||
public static final String SESSIONKEY = "sessionkey";
|
||||
public static final String SHOW_CAPACITIES = "showcapacities";
|
||||
|
|
@ -477,11 +485,12 @@ public class ApiConstants {
|
|||
public static final String STATE = "state";
|
||||
public static final String STATS = "stats";
|
||||
public static final String STATUS = "status";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
||||
public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_POOL = "storagepool";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String SUBNET = "subnet";
|
||||
public static final String OWNER = "owner";
|
||||
public static final String SWAP_OWNER = "swapowner";
|
||||
|
|
@ -954,7 +963,6 @@ public class ApiConstants {
|
|||
public static final String AUTOSCALE_VMGROUP_NAME = "autoscalevmgroupname";
|
||||
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
|
||||
public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
|
||||
public static final String BATCH_SIZE = "batchsize";
|
||||
public static final String UCS_DN = "ucsdn";
|
||||
public static final String GSLB_PROVIDER = "gslbprovider";
|
||||
public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
|
||||
|
|
@ -1148,7 +1156,6 @@ public class ApiConstants {
|
|||
public static final String MTU = "mtu";
|
||||
public static final String AUTO_ENABLE_KVM_HOST = "autoenablekvmhost";
|
||||
public static final String LIST_APIS = "listApis";
|
||||
public static final String OBJECT_STORAGE_ID = "objectstorageid";
|
||||
public static final String VERSIONING = "versioning";
|
||||
public static final String OBJECT_LOCKING = "objectlocking";
|
||||
public static final String ENCRYPTION = "encryption";
|
||||
|
|
@ -1162,7 +1169,6 @@ public class ApiConstants {
|
|||
public static final String DISK_PATH = "diskpath";
|
||||
public static final String IMPORT_SOURCE = "importsource";
|
||||
public static final String TEMP_PATH = "temppath";
|
||||
public static final String OBJECT_STORAGE = "objectstore";
|
||||
public static final String HEURISTIC_RULE = "heuristicrule";
|
||||
public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, TEMPLATE and VOLUME.";
|
||||
public static final String MANAGEMENT = "management";
|
||||
|
|
@ -1190,6 +1196,16 @@ public class ApiConstants {
|
|||
public static final String SHAREDFSVM_MIN_CPU_COUNT = "sharedfsvmmincpucount";
|
||||
public static final String SHAREDFSVM_MIN_RAM_SIZE = "sharedfsvmminramsize";
|
||||
|
||||
// Object Storage related
|
||||
public static final String BUCKET_AVAILABLE = "bucketavailable";
|
||||
public static final String BUCKET_LIMIT = "bucketlimit";
|
||||
public static final String BUCKET_TOTAL = "buckettotal";
|
||||
public static final String OBJECT_STORAGE_ID = "objectstorageid";
|
||||
public static final String OBJECT_STORAGE = "objectstore";
|
||||
public static final String OBJECT_STORAGE_AVAILABLE = "objectstorageavailable";
|
||||
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
|
||||
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
|
||||
|
||||
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
|
||||
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
|
||||
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
|
||||
|
|
@ -1203,6 +1219,8 @@ public class ApiConstants {
|
|||
"however, the following formats are also accepted: \"yyyy-MM-dd HH:mm:ss\" (e.g.: \"2023-01-01 12:00:00\") and \"yyyy-MM-dd\" (e.g.: \"2023-01-01\" - if the time is not " +
|
||||
"added, it will be interpreted as \"23:59:59\"). If the recommended format is not used, the date will be considered in the server timezone.";
|
||||
|
||||
public static final String VMWARE_DC = "vmwaredc";
|
||||
|
||||
/**
|
||||
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
||||
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
dv = EnumSet.of(DomainDetails.all);
|
||||
} else {
|
||||
try {
|
||||
ArrayList<DomainDetails> dc = new ArrayList<DomainDetails>();
|
||||
ArrayList<DomainDetails> dc = new ArrayList<>();
|
||||
for (String detail : viewDetails) {
|
||||
dc.add(DomainDetails.valueOf(detail));
|
||||
}
|
||||
|
|
@ -142,7 +142,10 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
|
|||
if (CollectionUtils.isEmpty(response)) {
|
||||
return;
|
||||
}
|
||||
_resourceLimitService.updateTaggedResourceLimitsAndCountsForDomains(response, getTag());
|
||||
EnumSet<DomainDetails> details = getDetails();
|
||||
if (details.contains(DomainDetails.all) || details.contains(DomainDetails.resource)) {
|
||||
_resourceLimitService.updateTaggedResourceLimitsAndCountsForDomains(response, getTag());
|
||||
}
|
||||
if (!getShowIcon()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.apache.cloudstack.api.response.IsAccountAllowedToCreateOfferingsWithT
|
|||
responseObject = IsAccountAllowedToCreateOfferingsWithTagsResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class IsAccountAllowedToCreateOfferingsWithTagsCmd extends BaseCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID")
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID", required = true)
|
||||
private Long id;
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -157,7 +157,10 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd implements UserC
|
|||
if (CollectionUtils.isEmpty(response)) {
|
||||
return;
|
||||
}
|
||||
_resourceLimitService.updateTaggedResourceLimitsAndCountsForAccounts(response, getTag());
|
||||
EnumSet<DomainDetails> details = getDetails();
|
||||
if (details.contains(DomainDetails.all) || details.contains(DomainDetails.resource)) {
|
||||
_resourceLimitService.updateTaggedResourceLimitsAndCountsForAccounts(response, getTag());
|
||||
}
|
||||
if (!getShowIcon()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.backup;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.storage.Snapshot;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
|
|
@ -27,6 +28,7 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
|||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
|
|
@ -60,6 +62,13 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
|||
description = "ID of the VM")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.SCHEDULE_ID,
|
||||
type = CommandType.LONG,
|
||||
entityType = BackupScheduleResponse.class,
|
||||
description = "backup schedule ID of the VM, if this is null, it indicates that it is a manual backup.",
|
||||
since = "4.21.0")
|
||||
private Long scheduleId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -68,6 +77,14 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
|||
return vmId;
|
||||
}
|
||||
|
||||
public Long getScheduleId() {
|
||||
if (scheduleId != null) {
|
||||
return scheduleId;
|
||||
} else {
|
||||
return Snapshot.MANUAL_POLICY_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -75,7 +92,7 @@ public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
|||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.createBackup(getVmId());
|
||||
boolean result = backupManager.createBackup(getVmId(), getScheduleId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ public class CreateBackupScheduleCmd extends BaseCmd {
|
|||
description = "Specifies a timezone for this command. For more information on the timezone parameter, see TimeZone Format.")
|
||||
private String timezone;
|
||||
|
||||
@Parameter(name = ApiConstants.MAX_BACKUPS,
|
||||
type = CommandType.INTEGER,
|
||||
description = "maximum number of backups to retain",
|
||||
since = "4.21.0")
|
||||
private Integer maxBackups;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -95,6 +101,10 @@ public class CreateBackupScheduleCmd extends BaseCmd {
|
|||
return timezone;
|
||||
}
|
||||
|
||||
public Integer getMaxBackups() {
|
||||
return maxBackups;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class CreateBucketCmd extends BaseAsyncCreateCmd implements UserCmd {
|
|||
description = "Id of the Object Storage Pool where bucket is created")
|
||||
private long objectStoragePoolId;
|
||||
|
||||
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
|
||||
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER, required = true, description = "Bucket Quota in GiB")
|
||||
private Integer quota;
|
||||
|
||||
@Parameter(name = ApiConstants.ENCRYPTION, type = CommandType.BOOLEAN, description = "Enable bucket encryption")
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class UpdateBucketCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.POLICY, type = CommandType.STRING, description = "Bucket Access Policy")
|
||||
private String policy;
|
||||
|
||||
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
|
||||
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER, description = "Bucket Quota in GiB")
|
||||
private Integer quota;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.firewall;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -40,6 +41,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@APICommand(name = "createFirewallRule", description = "Creates a firewall rule for a given IP address", responseObject = FirewallResponse.class, entityType = {FirewallRule.class},
|
||||
|
|
@ -125,14 +127,13 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
|||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
if (cidrlist != null) {
|
||||
if (CollectionUtils.isNotEmpty(cidrlist) && !(cidrlist.size() == 1 && StringUtils.isBlank(cidrlist.get(0)))) {
|
||||
return cidrlist;
|
||||
} else {
|
||||
List<String> oneCidrList = new ArrayList<String>();
|
||||
List<String> oneCidrList = new ArrayList<>();
|
||||
oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
|
||||
return oneCidrList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -127,6 +127,30 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the total number of snapshots available for this account")
|
||||
private String snapshotAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_LIMIT)
|
||||
@Param(description = "the total number of backups which can be stored by this account", since = "4.21.0")
|
||||
private String backupLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_TOTAL)
|
||||
@Param(description = "the total number of backups stored by this account", since = "4.21.0")
|
||||
private Long backupTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_AVAILABLE)
|
||||
@Param(description = "the total number of backups available to this account", since = "4.21.0")
|
||||
private String backupAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_LIMIT)
|
||||
@Param(description = "the total backup storage space (in GiB) the account can own", since = "4.21.0")
|
||||
private String backupStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_TOTAL)
|
||||
@Param(description = "the total backup storage space (in GiB) owned by the account", since = "4.21.0")
|
||||
private Long backupStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total backup storage space (in GiB) available to the account", since = "4.21.0")
|
||||
private String backupStorageAvailable;
|
||||
|
||||
@SerializedName("templatelimit")
|
||||
@Param(description = "the total number of templates which can be created by this account")
|
||||
private String templateLimit;
|
||||
|
|
@ -231,6 +255,30 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the total secondary storage space (in GiB) available to be used for this account", since = "4.2.0")
|
||||
private String secondaryStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_LIMIT)
|
||||
@Param(description = "the total number of buckets which can be stored by this account", since = "4.21.0")
|
||||
private String bucketLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_TOTAL)
|
||||
@Param(description = "the total number of buckets stored by this account", since = "4.21.0")
|
||||
private Long bucketTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_AVAILABLE)
|
||||
@Param(description = "the total number of buckets available to this account", since = "4.21.0")
|
||||
private String bucketAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_LIMIT)
|
||||
@Param(description = "the total object storage space (in GiB) the account can own", since = "4.21.0")
|
||||
private String objectStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_TOTAL)
|
||||
@Param(description = "the total object storage space (in GiB) owned by the account", since = "4.21.0")
|
||||
private Long objectStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total object storage space (in GiB) available to the account", since = "4.21.0")
|
||||
private String objectStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.STATE)
|
||||
@Param(description = "the state of the account")
|
||||
private String state;
|
||||
|
|
@ -386,6 +434,36 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.snapshotAvailable = snapshotAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupLimit(String backupLimit) {
|
||||
this.backupLimit = backupLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupTotal(Long backupTotal) {
|
||||
this.backupTotal = backupTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupAvailable(String backupAvailable) {
|
||||
this.backupAvailable = backupAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageLimit(String backupStorageLimit) {
|
||||
this.backupStorageLimit = backupStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageTotal(Long backupStorageTotal) {
|
||||
this.backupStorageTotal = backupStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageAvailable(String backupStorageAvailable) {
|
||||
this.backupStorageAvailable = backupStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplateLimit(String templateLimit) {
|
||||
this.templateLimit = templateLimit;
|
||||
|
|
@ -537,6 +615,36 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.secondaryStorageAvailable = secondaryStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketLimit(String bucketLimit) {
|
||||
this.bucketLimit = bucketLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketTotal(Long bucketTotal) {
|
||||
this.bucketTotal = bucketTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketAvailable(String bucketAvailable) {
|
||||
this.bucketAvailable = bucketAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageLimit(String objectStorageLimit) {
|
||||
this.objectStorageLimit = objectStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageTotal(Long objectStorageTotal) {
|
||||
this.objectStorageTotal = objectStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageAvailable(String objectStorageAvailable) {
|
||||
this.objectStorageAvailable = objectStorageAvailable;
|
||||
}
|
||||
|
||||
public void setDefaultZone(String defaultZoneId) {
|
||||
this.defaultZoneId = defaultZoneId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,18 +37,22 @@ public class BackupScheduleResponse extends BaseResponse {
|
|||
@Param(description = "ID of the VM")
|
||||
private String vmId;
|
||||
|
||||
@SerializedName("schedule")
|
||||
@SerializedName(ApiConstants.SCHEDULE)
|
||||
@Param(description = "time the backup is scheduled to be taken.")
|
||||
private String schedule;
|
||||
|
||||
@SerializedName("intervaltype")
|
||||
@SerializedName(ApiConstants.INTERVAL_TYPE)
|
||||
@Param(description = "the interval type of the backup schedule")
|
||||
private DateUtil.IntervalType intervalType;
|
||||
|
||||
@SerializedName("timezone")
|
||||
@SerializedName(ApiConstants.TIMEZONE)
|
||||
@Param(description = "the time zone of the backup schedule")
|
||||
private String timezone;
|
||||
|
||||
@SerializedName(ApiConstants.MAX_BACKUPS)
|
||||
@Param(description = "maximum number of backups retained")
|
||||
private Integer maxBakups;
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
|
@ -88,4 +92,8 @@ public class BackupScheduleResponse extends BaseResponse {
|
|||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public void setMaxBakups(Integer maxBakups) {
|
||||
this.maxBakups = maxBakups;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class BucketResponse extends BaseResponseWithTagInformation implements Co
|
|||
private String state;
|
||||
|
||||
@SerializedName(ApiConstants.QUOTA)
|
||||
@Param(description = "Bucket Quota in GB")
|
||||
@Param(description = "Bucket Quota in GiB")
|
||||
private Integer quota;
|
||||
|
||||
@SerializedName(ApiConstants.ENCRYPTION)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,30 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
@SerializedName("snapshotavailable") @Param(description="the total number of snapshots available for this domain")
|
||||
private String snapshotAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_LIMIT)
|
||||
@Param(description = "the total number of backups which can be stored by this domain", since = "4.21.0")
|
||||
private String backupLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_TOTAL)
|
||||
@Param(description = "the total number of backups stored by this domain", since = "4.21.0")
|
||||
private Long backupTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_AVAILABLE)
|
||||
@Param(description = "the total number of backups available to this domain", since = "4.21.0")
|
||||
private String backupAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_LIMIT)
|
||||
@Param(description = "the total backup storage space (in GiB) the domain can own", since = "4.21.0")
|
||||
private String backupStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_TOTAL)
|
||||
@Param(description = "the total backup storage space (in GiB) owned by the domain", since = "4.21.0")
|
||||
private Long backupStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total backup storage space (in GiB) available to the domain", since = "4.21.0")
|
||||
private String backupStorageAvailable;
|
||||
|
||||
@SerializedName("templatelimit") @Param(description="the total number of templates which can be created by this domain")
|
||||
private String templateLimit;
|
||||
|
||||
|
|
@ -177,6 +201,30 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
@SerializedName("secondarystorageavailable") @Param(description="the total secondary storage space (in GiB) available to be used for this domain", since="4.2.0")
|
||||
private String secondaryStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_LIMIT)
|
||||
@Param(description = "the total number of buckets which can be stored by this domain", since = "4.21.0")
|
||||
private String bucketLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_TOTAL)
|
||||
@Param(description = "the total number of buckets stored by this domain", since = "4.21.0")
|
||||
private Long bucketTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_AVAILABLE)
|
||||
@Param(description = "the total number of buckets available to this domain", since = "4.21.0")
|
||||
private String bucketAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_LIMIT)
|
||||
@Param(description = "the total object storage space (in GiB) the domain can own", since = "4.21.0")
|
||||
private String objectStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_TOTAL)
|
||||
@Param(description = "the total object storage space (in GiB) owned by the domain", since = "4.21.0")
|
||||
private Long objectStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total object storage space (in GiB) available to the domain", since = "4.21.0")
|
||||
private String objectStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_ICON)
|
||||
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
|
||||
ResourceIconResponse icon;
|
||||
|
|
@ -313,6 +361,36 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
this.snapshotAvailable = snapshotAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupLimit(String backupLimit) {
|
||||
this.backupLimit = backupLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupTotal(Long backupTotal) {
|
||||
this.backupTotal = backupTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupAvailable(String backupAvailable) {
|
||||
this.backupAvailable = backupAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageLimit(String backupStorageLimit) {
|
||||
this.backupStorageLimit = backupStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageTotal(Long backupStorageTotal) {
|
||||
this.backupStorageTotal = backupStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageAvailable(String backupStorageAvailable) {
|
||||
this.backupStorageAvailable = backupStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplateLimit(String templateLimit) {
|
||||
this.templateLimit = templateLimit;
|
||||
|
|
@ -430,6 +508,36 @@ public class DomainResponse extends BaseResponseWithAnnotations implements Resou
|
|||
this.secondaryStorageAvailable = secondaryStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketLimit(String bucketLimit) {
|
||||
this.bucketLimit = bucketLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketTotal(Long bucketTotal) {
|
||||
this.bucketTotal = bucketTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketAvailable(String bucketAvailable) {
|
||||
this.bucketAvailable = bucketAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageLimit(String objectStorageLimit) {
|
||||
this.objectStorageLimit = objectStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageTotal(Long objectStorageTotal) {
|
||||
this.objectStorageTotal = objectStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageAvailable(String objectStorageAvailable) {
|
||||
this.objectStorageAvailable = objectStorageAvailable;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||
@Deprecated
|
||||
@SerializedName("memoryallocated")
|
||||
@Param(description = "the amount of the host's memory currently allocated")
|
||||
private long memoryAllocated;
|
||||
private Long memoryAllocated;
|
||||
|
||||
@SerializedName("memoryallocatedpercentage")
|
||||
@Param(description = "the amount of the host's memory currently allocated in percentage")
|
||||
|
|
@ -415,7 +415,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||
this.memWithOverprovisioning=memWithOverprovisioning;
|
||||
}
|
||||
|
||||
public void setMemoryAllocated(long memoryAllocated) {
|
||||
public void setMemoryAllocated(Long memoryAllocated) {
|
||||
this.memoryAllocated = memoryAllocated;
|
||||
}
|
||||
|
||||
|
|
@ -703,8 +703,8 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||
return memoryTotal;
|
||||
}
|
||||
|
||||
public long getMemoryAllocated() {
|
||||
return memoryAllocated;
|
||||
public Long getMemoryAllocated() {
|
||||
return memoryAllocated == null ? 0 : memoryAllocated;
|
||||
}
|
||||
|
||||
public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
|
||||
|
|
|
|||
|
|
@ -74,9 +74,9 @@ public class ManagementServerResponse extends BaseResponse {
|
|||
@Param(description = "the running OS kernel version for this Management Server")
|
||||
private String kernelVersion;
|
||||
|
||||
@SerializedName(ApiConstants.SERVICE_IP)
|
||||
@SerializedName(ApiConstants.IP_ADDRESS)
|
||||
@Param(description = "the IP Address for this Management Server")
|
||||
private String serviceIp;
|
||||
private String ipAddress;
|
||||
|
||||
@SerializedName(ApiConstants.PEERS)
|
||||
@Param(description = "the Management Server Peers")
|
||||
|
|
@ -130,8 +130,8 @@ public class ManagementServerResponse extends BaseResponse {
|
|||
return lastBoot;
|
||||
}
|
||||
|
||||
public String getServiceIp() {
|
||||
return serviceIp;
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public Long getAgentsCount() {
|
||||
|
|
@ -186,8 +186,8 @@ public class ManagementServerResponse extends BaseResponse {
|
|||
this.kernelVersion = kernelVersion;
|
||||
}
|
||||
|
||||
public void setServiceIp(String serviceIp) {
|
||||
this.serviceIp = serviceIp;
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public void setAgentsCount(Long agentsCount) {
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
|
|||
@Param(description = "true network requires restart")
|
||||
private Boolean restartRequired;
|
||||
|
||||
@SerializedName(ApiConstants.SPECIFY_VLAN)
|
||||
@Param(description = "true if network supports specifying vlan, false otherwise")
|
||||
private Boolean specifyVlan;
|
||||
|
||||
@SerializedName(ApiConstants.SPECIFY_IP_RANGES)
|
||||
@Param(description = "true if network supports specifying ip ranges, false otherwise")
|
||||
private Boolean specifyIpRanges;
|
||||
|
|
@ -516,6 +520,10 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
|
|||
this.restartRequired = restartRequired;
|
||||
}
|
||||
|
||||
public void setSpecifyVlan(Boolean specifyVlan) {
|
||||
this.specifyVlan = specifyVlan;
|
||||
}
|
||||
|
||||
public void setSpecifyIpRanges(Boolean specifyIpRanges) {
|
||||
this.specifyIpRanges = specifyIpRanges;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,30 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the total secondary storage space (in GiB) available to be used for this project", since = "4.2.0")
|
||||
private String secondaryStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_LIMIT)
|
||||
@Param(description = "the total number of buckets which can be stored by this project", since = "4.21.0")
|
||||
private String bucketLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_TOTAL)
|
||||
@Param(description = "the total number of buckets stored by this project", since = "4.21.0")
|
||||
private Long bucketTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BUCKET_AVAILABLE)
|
||||
@Param(description = "the total number of buckets available to this project", since = "4.21.0")
|
||||
private String bucketAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_LIMIT)
|
||||
@Param(description = "the total object storage space (in GiB) the project can own", since = "4.21.0")
|
||||
private String objectStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_TOTAL)
|
||||
@Param(description = "the total object storage space (in GiB) owned by the project", since = "4.21.0")
|
||||
private Long objectStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.OBJECT_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total object storage space (in GiB) available to the project", since = "4.21.0")
|
||||
private String objectStorageAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.VM_LIMIT)
|
||||
@Param(description = "the total number of virtual machines that can be deployed by this project", since = "4.2.0")
|
||||
private String vmLimit;
|
||||
|
|
@ -188,6 +212,30 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
@Param(description = "the total number of snapshots available for this project", since = "4.2.0")
|
||||
private String snapshotAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_LIMIT)
|
||||
@Param(description = "the total number of backups which can be stored by this project", since = "4.21.0")
|
||||
private String backupLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_TOTAL)
|
||||
@Param(description = "the total number of backups stored by this project", since = "4.21.0")
|
||||
private Long backupTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_AVAILABLE)
|
||||
@Param(description = "the total number of backups available to this project", since = "4.21.0")
|
||||
private String backupAvailable;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_LIMIT)
|
||||
@Param(description = "the total backup storage space (in GiB) the project can own", since = "4.21.0")
|
||||
private String backupStorageLimit;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_TOTAL)
|
||||
@Param(description = "the total backup storage space (in GiB) owned by the project", since = "4.21.0")
|
||||
private Long backupStorageTotal;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_STORAGE_AVAILABLE)
|
||||
@Param(description = "the total backup storage space (in GiB) available to the project", since = "4.21.0")
|
||||
private String backupStorageAvailable;
|
||||
|
||||
@SerializedName("templatelimit")
|
||||
@Param(description = "the total number of templates which can be created by this project", since = "4.2.0")
|
||||
private String templateLimit;
|
||||
|
|
@ -320,6 +368,36 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.snapshotAvailable = snapshotAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupLimit(String backupLimit) {
|
||||
this.backupLimit = backupLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupTotal(Long backupTotal) {
|
||||
this.backupTotal = backupTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupAvailable(String backupAvailable) {
|
||||
this.backupAvailable = backupAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageLimit(String backupStorageLimit) {
|
||||
this.backupStorageLimit = backupStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageTotal(Long backupStorageTotal) {
|
||||
this.backupStorageTotal = backupStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackupStorageAvailable(String backupStorageAvailable) {
|
||||
this.backupStorageAvailable = backupStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplateLimit(String templateLimit) {
|
||||
this.templateLimit = templateLimit;
|
||||
|
|
@ -435,6 +513,36 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
|||
this.secondaryStorageAvailable = secondaryStorageAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketLimit(String bucketLimit) {
|
||||
this.bucketLimit = bucketLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketTotal(Long bucketTotal) {
|
||||
this.bucketTotal = bucketTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBucketAvailable(String bucketAvailable) {
|
||||
this.bucketAvailable = bucketAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageLimit(String objectStorageLimit) {
|
||||
this.objectStorageLimit = objectStorageLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageTotal(Long objectStorageTotal) {
|
||||
this.objectStorageTotal = objectStorageTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectStorageAvailable(String objectStorageAvailable) {
|
||||
this.objectStorageAvailable = objectStorageAvailable;
|
||||
}
|
||||
|
||||
public void setOwners(List<Map<String, String>> owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,30 @@ public interface ResourceLimitAndCountResponse {
|
|||
|
||||
public void setSnapshotAvailable(String snapshotAvailable);
|
||||
|
||||
public void setBackupLimit(String backupLimit);
|
||||
|
||||
public void setBackupTotal(Long backupTotal);
|
||||
|
||||
public void setBackupAvailable(String backupAvailable);
|
||||
|
||||
public void setBackupStorageLimit(String backupStorageLimit);
|
||||
|
||||
public void setBackupStorageTotal(Long backupStorageTotal);
|
||||
|
||||
public void setBackupStorageAvailable(String backupStorageAvailable);
|
||||
|
||||
void setBucketLimit(String bucketLimit);
|
||||
|
||||
void setBucketTotal(Long bucketTotal);
|
||||
|
||||
void setBucketAvailable(String bucketAvailable);
|
||||
|
||||
void setObjectStorageLimit(String objectStorageLimit);
|
||||
|
||||
void setObjectStorageTotal(Long objectStorageTotal);
|
||||
|
||||
void setObjectStorageAvailable(String objectStorageAvailable);
|
||||
|
||||
public void setTemplateLimit(String templateLimit);
|
||||
|
||||
public void setTemplateTotal(Long templateTotal);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,28 @@ public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
|||
Allocated, Queued, BackingUp, BackedUp, Error, Failed, Restoring, Removed, Expunged
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
MANUAL, HOURLY, DAILY, WEEKLY, MONTHLY;
|
||||
private int max = 8;
|
||||
|
||||
public void setMax(int max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
public boolean equals(String snapshotType) {
|
||||
return this.toString().equalsIgnoreCase(snapshotType);
|
||||
}
|
||||
}
|
||||
|
||||
class Metric {
|
||||
private Long backupSize = 0L;
|
||||
private Long dataSize = 0L;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.backup;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.api.command.admin.backup.ImportBackupOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.UpdateBackupOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.CreateBackupScheduleCmd;
|
||||
|
|
@ -56,6 +57,86 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
"false",
|
||||
"Enable volume attach/detach operations for VMs that are assigned to Backup Offerings.", true);
|
||||
|
||||
ConfigKey<Integer> BackupHourlyMax = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
"backup.max.hourly",
|
||||
"8",
|
||||
"Maximum recurring hourly backups to be retained for an instance. If the limit is reached, early backups from the start of the hour are deleted so that newer ones can be saved. This limit does not apply to manual backups. If set to 0, recurring hourly backups can not be scheduled.",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Integer> BackupDailyMax = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
"backup.max.daily",
|
||||
"8",
|
||||
"Maximum recurring daily backups to be retained for an instance. If the limit is reached, backups from the start of the day are deleted so that newer ones can be saved. This limit does not apply to manual backups. If set to 0, recurring daily backups can not be scheduled.",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Integer> BackupWeeklyMax = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
"backup.max.weekly",
|
||||
"8",
|
||||
"Maximum recurring weekly backups to be retained for an instance. If the limit is reached, backups from the beginning of the week are deleted so that newer ones can be saved. This limit does not apply to manual backups. If set to 0, recurring weekly backups can not be scheduled.",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Integer> BackupMonthlyMax = new ConfigKey<Integer>("Advanced", Integer.class,
|
||||
"backup.max.monthly",
|
||||
"8",
|
||||
"Maximum recurring monthly backups to be retained for an instance. If the limit is reached, backups from the beginning of the month are deleted so that newer ones can be saved. This limit does not apply to manual backups. If set to 0, recurring monthly backups can not be scheduled.",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxAccountBackups = new ConfigKey<Long>("Account Defaults", Long.class,
|
||||
"max.account.backups",
|
||||
"20",
|
||||
"The default maximum number of backups that can be created for an account",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxAccountBackupStorage = new ConfigKey<Long>("Account Defaults", Long.class,
|
||||
"max.account.backup.storage",
|
||||
"400",
|
||||
"The default maximum backup storage space (in GiB) that can be used for an account",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxProjectBackups = new ConfigKey<Long>("Project Defaults", Long.class,
|
||||
"max.project.backups",
|
||||
"20",
|
||||
"The default maximum number of backups that can be created for a project",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxProjectBackupStorage = new ConfigKey<Long>("Project Defaults", Long.class,
|
||||
"max.project.backup.storage",
|
||||
"400",
|
||||
"The default maximum backup storage space (in GiB) that can be used for a project",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxDomainBackups = new ConfigKey<Long>("Domain Defaults", Long.class,
|
||||
"max.domain.backups",
|
||||
"40",
|
||||
"The default maximum number of backups that can be created for a domain",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxDomainBackupStorage = new ConfigKey<Long>("Domain Defaults", Long.class,
|
||||
"max.domain.backup.storage",
|
||||
"800",
|
||||
"The default maximum backup storage space (in GiB) that can be used for a domain",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
/**
|
||||
* List backup provider offerings
|
||||
* @param zoneId zone id
|
||||
|
|
@ -119,9 +200,10 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
/**
|
||||
* Creates backup of a VM
|
||||
* @param vmId Virtual Machine ID
|
||||
* @param scheduleId Virtual Machine Backup Schedule ID
|
||||
* @return returns operation success
|
||||
*/
|
||||
boolean createBackup(final Long vmId);
|
||||
boolean createBackup(final Long vmId, final Long scheduleId) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* List existing backups for a VM
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public interface BackupProvider {
|
|||
* @param backup
|
||||
* @return
|
||||
*/
|
||||
boolean takeBackup(VirtualMachine vm);
|
||||
Pair<Boolean, Backup> takeBackup(VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Delete an existing backup
|
||||
|
|
@ -104,9 +104,16 @@ public interface BackupProvider {
|
|||
Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms);
|
||||
|
||||
/**
|
||||
* This method should reconcile and create backup entries for any backups created out-of-band
|
||||
* @param vm
|
||||
* This method should TODO
|
||||
* @param
|
||||
*/
|
||||
public List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* This method should TODO
|
||||
* @param
|
||||
* @param
|
||||
* @param metric
|
||||
*/
|
||||
void syncBackups(VirtualMachine vm, Backup.Metric metric);
|
||||
Backup createNewBackupEntryForRestorePoint(Backup.RestorePoint restorePoint, VirtualMachine vm, Backup.Metric metric);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@ public interface BackupSchedule extends InternalIdentity {
|
|||
String getTimezone();
|
||||
Date getScheduledTimestamp();
|
||||
Long getAsyncJobId();
|
||||
Integer getMaxBackups();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public interface OutOfBandManagementService {
|
|||
long getId();
|
||||
boolean isOutOfBandManagementEnabled(Host host);
|
||||
void submitBackgroundPowerSyncTask(Host host);
|
||||
boolean transitionPowerStateToDisabled(List<? extends Host> hosts);
|
||||
boolean transitionPowerStateToDisabled(List<Long> hostIds);
|
||||
|
||||
OutOfBandManagementResponse enableOutOfBandManagement(DataCenter zone);
|
||||
OutOfBandManagementResponse enableOutOfBandManagement(Cluster cluster);
|
||||
|
|
|
|||
|
|
@ -22,10 +22,59 @@ import com.cloud.exception.ResourceAllocationException;
|
|||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.api.command.user.bucket.CreateBucketCmd;
|
||||
import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
public interface BucketApiService {
|
||||
|
||||
|
||||
ConfigKey<Long> DefaultMaxAccountBuckets = new ConfigKey<Long>("Account Defaults", Long.class,
|
||||
"max.account.buckets",
|
||||
"20",
|
||||
"The default maximum number of buckets that can be created for an account",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxAccountObjectStorage = new ConfigKey<Long>("Account Defaults", Long.class,
|
||||
"max.account.object.storage",
|
||||
"400",
|
||||
"The default maximum object storage space (in GiB) that can be used for an account",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxProjectBuckets = new ConfigKey<Long>("Project Defaults", Long.class,
|
||||
"max.project.buckets",
|
||||
"20",
|
||||
"The default maximum number of buckets that can be created for a project",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxProjectObjectStorage = new ConfigKey<Long>("Project Defaults", Long.class,
|
||||
"max.project.object.storage",
|
||||
"400",
|
||||
"The default maximum object storage space (in GiB) that can be used for a project",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxDomainBuckets = new ConfigKey<Long>("Domain Defaults", Long.class,
|
||||
"max.domain.buckets",
|
||||
"20",
|
||||
"The default maximum number of buckets that can be created for a domain",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
ConfigKey<Long> DefaultMaxDomainObjectStorage = new ConfigKey<Long>("Domain Defaults", Long.class,
|
||||
"max.domain.object.storage",
|
||||
"400",
|
||||
"The default maximum object storage space (in GiB) that can be used for a domain",
|
||||
false,
|
||||
ConfigKey.Scope.Global,
|
||||
null);
|
||||
|
||||
/**
|
||||
* Creates the database object for a Bucket based on the given criteria
|
||||
*
|
||||
|
|
@ -48,7 +97,7 @@ public interface BucketApiService {
|
|||
|
||||
boolean deleteBucket(long bucketId, Account caller);
|
||||
|
||||
boolean updateBucket(UpdateBucketCmd cmd, Account caller);
|
||||
boolean updateBucket(UpdateBucketCmd cmd, Account caller) throws ResourceAllocationException;
|
||||
|
||||
void getBucketUsage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ public class UnmanagedInstanceTO {
|
|||
|
||||
private String internalCSName;
|
||||
|
||||
private String path;
|
||||
|
||||
private PowerState powerState;
|
||||
|
||||
private PowerState cloneSourcePowerState;
|
||||
|
|
@ -75,6 +77,14 @@ public class UnmanagedInstanceTO {
|
|||
this.internalCSName = internalCSName;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public PowerState getPowerState() {
|
||||
return powerState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.admin.domain;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
|
@ -71,7 +72,17 @@ public class ListDomainsCmdTest {
|
|||
cmd._resourceLimitService = resourceLimitService;
|
||||
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||
cmd.updateDomainResponse(List.of(Mockito.mock(DomainResponse.class)));
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).updateTaggedResourceLimitsAndCountsForDomains(Mockito.any(), Mockito.any());
|
||||
Mockito.verify(resourceLimitService).updateTaggedResourceLimitsAndCountsForDomains(Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDomainResponseWithDomainsMinDetails() {
|
||||
ListDomainsCmd cmd = new ListDomainsCmd();
|
||||
ReflectionTestUtils.setField(cmd, "viewDetails", List.of(ApiConstants.DomainDetails.min.toString()));
|
||||
cmd._resourceLimitService = resourceLimitService;
|
||||
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||
cmd.updateDomainResponse(List.of(Mockito.mock(DomainResponse.class)));
|
||||
Mockito.verify(resourceLimitService, Mockito.never()).updateTaggedResourceLimitsAndCountsForDomains(Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.account;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
|
@ -58,7 +59,7 @@ public class ListAccountsCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDomainResponseNoDomains() {
|
||||
public void testUpdateAccountResponseNoAccounts() {
|
||||
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||
cmd._resourceLimitService = resourceLimitService;
|
||||
cmd.updateAccountResponse(null);
|
||||
|
|
@ -66,11 +67,21 @@ public class ListAccountsCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDomainResponseWithDomains() {
|
||||
public void testUpdateDomainResponseWithAccounts() {
|
||||
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||
cmd._resourceLimitService = resourceLimitService;
|
||||
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||
cmd.updateAccountResponse(List.of(Mockito.mock(AccountResponse.class)));
|
||||
Mockito.verify(resourceLimitService, Mockito.times(1)).updateTaggedResourceLimitsAndCountsForAccounts(Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDomainResponseWithAccountsMinDetails() {
|
||||
ListAccountsCmd cmd = new ListAccountsCmd();
|
||||
ReflectionTestUtils.setField(cmd, "viewDetails", List.of(ApiConstants.DomainDetails.min.toString()));
|
||||
cmd._resourceLimitService = resourceLimitService;
|
||||
ReflectionTestUtils.setField(cmd, "tag", "abc");
|
||||
cmd.updateAccountResponse(List.of(Mockito.mock(AccountResponse.class)));
|
||||
Mockito.verify(resourceLimitService, Mockito.never()).updateTaggedResourceLimitsAndCountsForAccounts(Mockito.any(), Mockito.any());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
// 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 org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CreateFirewallRuleCmdTest {
|
||||
|
||||
private void validateAllIp4Cidr(final CreateFirewallRuleCmd cmd) {
|
||||
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
|
||||
Assert.assertEquals(1, cmd.getSourceCidrList().size());
|
||||
Assert.assertEquals(NetUtils.ALL_IP4_CIDRS, cmd.getSourceCidrList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_Null() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", null);
|
||||
validateAllIp4Cidr(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_Empty() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", new ArrayList<>());
|
||||
validateAllIp4Cidr(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_NullFirstElement() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(null);
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", list);
|
||||
validateAllIp4Cidr(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_EmptyFirstElement() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", Collections.singletonList(" "));
|
||||
validateAllIp4Cidr(cmd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_Valid() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
String cidr = "10.1.1.1/22";
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", Collections.singletonList(cidr));
|
||||
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
|
||||
Assert.assertEquals(1, cmd.getSourceCidrList().size());
|
||||
Assert.assertEquals(cidr, cmd.getSourceCidrList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSourceCidrList_EmptyFirstElementButMore() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
String cidr = "10.1.1.1/22";
|
||||
ReflectionTestUtils.setField(cmd, "cidrlist", Arrays.asList(" ", cidr));
|
||||
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
|
||||
Assert.assertEquals(2, cmd.getSourceCidrList().size());
|
||||
Assert.assertEquals(cidr, cmd.getSourceCidrList().get(1));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// 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.agent.api;
|
||||
|
||||
/**
|
||||
* This command will destroy a leftover VM during the expunge process if it wasn't destroyed before.
|
||||
*
|
||||
*/
|
||||
public class CleanupVMCommand extends Command {
|
||||
String vmName;
|
||||
boolean executeInSequence;
|
||||
|
||||
public CleanupVMCommand(String vmName) {
|
||||
this(vmName, false);
|
||||
}
|
||||
public CleanupVMCommand(String vmName, boolean executeInSequence) {
|
||||
this.vmName = vmName;
|
||||
this.executeInSequence = executeInSequence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return executeInSequence;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
}
|
||||
|
|
@ -82,4 +82,12 @@ public interface ServerResource extends Manager {
|
|||
|
||||
void setAgentControl(IAgentControl agentControl);
|
||||
|
||||
default boolean isExitOnFailures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean isAppendAgentNameToLogs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Source: cloudstack
|
||||
Section: libs
|
||||
Priority: extra
|
||||
Maintainer: Wido den Hollander <wido@widodh.nl>
|
||||
Maintainer: The Apache CloudStack Team <dev@cloudstack.apache.org>
|
||||
Build-Depends: debhelper (>= 9), openjdk-17-jdk | java17-sdk | java17-jdk | zulu-17 | openjdk-11-jdk | java11-sdk | java11-jdk | zulu-11, genisoimage,
|
||||
python-mysql.connector | python3-mysql.connector | mysql-connector-python-py3, maven (>= 3) | maven3,
|
||||
python (>= 2.7) | python2 (>= 2.7), python3 (>= 3), python-setuptools, python3-setuptools,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
|
|
@ -38,6 +37,7 @@ import com.cloud.exception.ConcurrentOperationException;
|
|||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
|
|
@ -101,6 +101,10 @@ public interface VirtualMachineManager extends Manager {
|
|||
"refer documentation",
|
||||
true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<Boolean> VmSyncPowerStateTransitioning = new ConfigKey<>("Advanced", Boolean.class, "vm.sync.power.state.transitioning", "true",
|
||||
"Whether to sync power states of the transitioning and stalled VMs while processing VM power reports.", false);
|
||||
|
||||
|
||||
interface Topics {
|
||||
String VM_POWER_STATE = "vm.powerstate";
|
||||
}
|
||||
|
|
@ -286,24 +290,22 @@ public interface VirtualMachineManager extends Manager {
|
|||
|
||||
/**
|
||||
* Obtains statistics for a list of VMs; CPU and network utilization
|
||||
* @param hostId ID of the host
|
||||
* @param hostName name of the host
|
||||
* @param host host
|
||||
* @param vmIds list of VM IDs
|
||||
* @return map of VM ID and stats entry for the VM
|
||||
*/
|
||||
HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds);
|
||||
HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(Host host, List<Long> vmIds);
|
||||
/**
|
||||
* Obtains statistics for a list of VMs; CPU and network utilization
|
||||
* @param hostId ID of the host
|
||||
* @param hostName name of the host
|
||||
* @param vmMap map of VM IDs and the corresponding VirtualMachine object
|
||||
* @param host host
|
||||
* @param vmMap map of VM instanceName and its ID
|
||||
* @return map of VM ID and stats entry for the VM
|
||||
*/
|
||||
HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
||||
HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(Host host, Map<String, Long> vmMap);
|
||||
|
||||
HashMap<Long, List<? extends VmDiskStats>> getVmDiskStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
||||
HashMap<Long, List<? extends VmDiskStats>> getVmDiskStatistics(Host host, Map<String, Long> vmInstanceNameIdMap);
|
||||
|
||||
HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap);
|
||||
HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(Host host, Map<String, Long> vmInstanceNameIdMap);
|
||||
|
||||
Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds);
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ public interface NetworkOrchestrationService {
|
|||
ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600",
|
||||
"Lock wait timeout (seconds) while implementing network", true, Scope.Global, null);
|
||||
|
||||
ConfigKey<String> DeniedRoutes = new ConfigKey<String>(String.class, "denied.routes", "Network", "",
|
||||
"Routes that are denied, can not be used for Static Routes creation for the VPC Private Gateway", true, ConfigKey.Scope.Zone, null);
|
||||
|
||||
ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal",
|
||||
"Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,13 @@
|
|||
// under the License.
|
||||
package com.cloud.capacity;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
|
@ -70,7 +69,7 @@ public interface CapacityManager {
|
|||
"0.85",
|
||||
"Percentage (as a value between 0 and 1) of storage utilization above which allocators will disable using the pool for low storage available.",
|
||||
true,
|
||||
ConfigKey.Scope.Zone);
|
||||
List.of(ConfigKey.Scope.StoragePool, ConfigKey.Scope.Zone));
|
||||
static final ConfigKey<Double> StorageOverprovisioningFactor =
|
||||
new ConfigKey<>(
|
||||
"Storage",
|
||||
|
|
@ -88,7 +87,7 @@ public interface CapacityManager {
|
|||
"0.85",
|
||||
"Percentage (as a value between 0 and 1) of allocated storage utilization above which allocators will disable using the pool for low allocated storage available.",
|
||||
true,
|
||||
ConfigKey.Scope.Zone);
|
||||
List.of(ConfigKey.Scope.StoragePool, ConfigKey.Scope.Zone));
|
||||
static final ConfigKey<Boolean> StorageOperationsExcludeCluster =
|
||||
new ConfigKey<>(
|
||||
Boolean.class,
|
||||
|
|
@ -128,7 +127,11 @@ public interface CapacityManager {
|
|||
"Percentage (as a value between 0 and 1) of allocated storage utilization above which allocators will disable using the pool for volume resize. " +
|
||||
"This is applicable only when volume.resize.allowed.beyond.allocation is set to true.",
|
||||
true,
|
||||
ConfigKey.Scope.Zone);
|
||||
List.of(ConfigKey.Scope.StoragePool, ConfigKey.Scope.Zone));
|
||||
|
||||
ConfigKey<Integer> CapacityCalculateWorkers = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class,
|
||||
"capacity.calculate.workers", "1",
|
||||
"Number of worker threads to be used for capacities calculation", true);
|
||||
|
||||
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
|
||||
|
||||
|
|
@ -145,8 +148,6 @@ public interface CapacityManager {
|
|||
|
||||
void updateCapacityForHost(Host host);
|
||||
|
||||
void updateCapacityForHost(Host host, Map<Long, ServiceOfferingVO> offeringsMap);
|
||||
|
||||
/**
|
||||
* @param pool storage pool
|
||||
* @param templateForVmCreation template that will be used for vm creation
|
||||
|
|
@ -163,12 +164,12 @@ public interface CapacityManager {
|
|||
|
||||
/**
|
||||
* Check if specified host has capability to support cpu cores and speed freq
|
||||
* @param hostId the host to be checked
|
||||
* @param host the host to be checked
|
||||
* @param cpuNum cpu number to check
|
||||
* @param cpuSpeed cpu Speed to check
|
||||
* @return true if the count of host's running VMs >= hypervisor limit
|
||||
*/
|
||||
boolean checkIfHostHasCpuCapability(long hostId, Integer cpuNum, Integer cpuSpeed);
|
||||
boolean checkIfHostHasCpuCapability(Host host, Integer cpuNum, Integer cpuSpeed);
|
||||
|
||||
/**
|
||||
* Check if cluster will cross threshold if the cpu/memory requested are accommodated
|
||||
|
|
|
|||
|
|
@ -140,13 +140,13 @@ public interface ResourceManager extends ResourceService, Configurable {
|
|||
|
||||
public List<HostVO> listAllHostsInOneZoneNotInClusterByHypervisors(List<HypervisorType> types, long dcId, long clusterId);
|
||||
|
||||
public List<HypervisorType> listAvailHypervisorInZone(Long hostId, Long zoneId);
|
||||
public List<HypervisorType> listAvailHypervisorInZone(Long zoneId);
|
||||
|
||||
public HostVO findHostByGuid(String guid);
|
||||
|
||||
public HostVO findHostByName(String name);
|
||||
|
||||
HostStats getHostStatistics(long hostId);
|
||||
HostStats getHostStatistics(Host host);
|
||||
|
||||
Long getGuestOSCategoryId(long hostId);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ import com.cloud.offering.DiskOffering;
|
|||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
|
||||
|
|
@ -212,7 +214,11 @@ public interface StorageManager extends StorageService {
|
|||
ConfigKey<Boolean> AllowVolumeReSizeBeyondAllocation = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.resize.allowed.beyond.allocation", "false",
|
||||
"Determines whether volume size can exceed the pool capacity allocation disable threshold (pool.storage.allocated.capacity.disablethreshold) " +
|
||||
"when resize a volume upto resize capacity disable threshold (pool.storage.allocated.resize.capacity.disablethreshold)",
|
||||
true, ConfigKey.Scope.Zone);
|
||||
true, List.of(ConfigKey.Scope.StoragePool, ConfigKey.Scope.Zone));
|
||||
|
||||
ConfigKey<Integer> StoragePoolHostConnectWorkers = new ConfigKey<>("Storage", Integer.class,
|
||||
"storage.pool.host.connect.workers", "1",
|
||||
"Number of worker threads to be used to connect hosts to a primary storage", true);
|
||||
|
||||
/**
|
||||
* should we execute in sequence not involving any storages?
|
||||
|
|
@ -365,6 +371,9 @@ public interface StorageManager extends StorageService {
|
|||
|
||||
String getStoragePoolMountFailureReason(String error);
|
||||
|
||||
void connectHostsToPool(DataStore primaryStore, List<Long> hostIds, Scope scope,
|
||||
boolean handleStorageConflictException, boolean errorOnNoUpHost) throws CloudRuntimeException;
|
||||
|
||||
boolean connectHostToSharedPool(Host host, long poolId) throws StorageUnavailableException, StorageConflictException;
|
||||
|
||||
void disconnectHostFromSharedPool(Host host, StoragePool pool) throws StorageUnavailableException, StorageConflictException;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.cloud.agent.manager;
|
|||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -26,25 +27,20 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.cluster.ManagementServerHostVO;
|
||||
import com.cloud.cluster.dao.ManagementServerHostDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
import org.apache.cloudstack.agent.lb.IndirectAgentLB;
|
||||
import org.apache.cloudstack.ca.CAManager;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
|
|
@ -62,6 +58,8 @@ import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
|||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.ThreadContext;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.Listener;
|
||||
|
|
@ -88,6 +86,9 @@ import com.cloud.agent.api.UnsupportedAnswer;
|
|||
import com.cloud.agent.transport.Request;
|
||||
import com.cloud.agent.transport.Response;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.cluster.ManagementServerHostVO;
|
||||
import com.cloud.cluster.dao.ManagementServerHostDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ManagementServiceConfiguration;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
|
|
@ -107,15 +108,18 @@ import com.cloud.host.Status.Event;
|
|||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.resource.Discoverer;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
|
@ -130,8 +134,6 @@ import com.cloud.utils.nio.Link;
|
|||
import com.cloud.utils.nio.NioServer;
|
||||
import com.cloud.utils.nio.Task;
|
||||
import com.cloud.utils.time.InaccurateClock;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.ThreadContext;
|
||||
|
||||
/**
|
||||
* Implementation of the Agent Manager. This class controls the connection to the agents.
|
||||
|
|
@ -142,14 +144,13 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
* _agents is a ConcurrentHashMap, but it is used from within a synchronized block. This will be reported by findbugs as JLM_JSR166_UTILCONCURRENT_MONITORENTER. Maybe a
|
||||
* ConcurrentHashMap is not the right thing to use here, but i'm not sure so i leave it alone.
|
||||
*/
|
||||
protected ConcurrentHashMap<Long, AgentAttache> _agents = new ConcurrentHashMap<Long, AgentAttache>(10007);
|
||||
protected List<Pair<Integer, Listener>> _hostMonitors = new ArrayList<Pair<Integer, Listener>>(17);
|
||||
protected List<Pair<Integer, Listener>> _cmdMonitors = new ArrayList<Pair<Integer, Listener>>(17);
|
||||
protected List<Pair<Integer, StartupCommandProcessor>> _creationMonitors = new ArrayList<Pair<Integer, StartupCommandProcessor>>(17);
|
||||
protected List<Long> _loadingAgents = new ArrayList<Long>();
|
||||
protected ConcurrentHashMap<Long, AgentAttache> _agents = new ConcurrentHashMap<>(10007);
|
||||
protected List<Pair<Integer, Listener>> _hostMonitors = new ArrayList<>(17);
|
||||
protected List<Pair<Integer, Listener>> _cmdMonitors = new ArrayList<>(17);
|
||||
protected List<Pair<Integer, StartupCommandProcessor>> _creationMonitors = new ArrayList<>(17);
|
||||
protected List<Long> _loadingAgents = new ArrayList<>();
|
||||
protected Map<String, Integer> _commandTimeouts = new HashMap<>();
|
||||
private int _monitorId = 0;
|
||||
private final Lock _agentStatusLock = new ReentrantLock();
|
||||
|
||||
@Inject
|
||||
protected CAManager caService;
|
||||
|
|
@ -201,25 +202,36 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
private List<String> lastAgents = null;
|
||||
|
||||
protected StateMachine2<Status, Status.Event, Host> _statusStateMachine = Status.getStateMachine();
|
||||
private final ConcurrentHashMap<Long, Long> _pingMap = new ConcurrentHashMap<Long, Long>(10007);
|
||||
private final ConcurrentHashMap<Long, Long> _pingMap = new ConcurrentHashMap<>(10007);
|
||||
private int maxConcurrentNewAgentConnections;
|
||||
private final ConcurrentHashMap<String, Long> newAgentConnections = new ConcurrentHashMap<>();
|
||||
protected ScheduledExecutorService newAgentConnectionsMonitor;
|
||||
|
||||
@Inject
|
||||
ResourceManager _resourceMgr;
|
||||
@Inject
|
||||
ManagementServiceConfiguration mgmtServiceConf;
|
||||
|
||||
protected final ConfigKey<Integer> Workers = new ConfigKey<Integer>("Advanced", Integer.class, "workers", "5",
|
||||
protected final ConfigKey<Integer> Workers = new ConfigKey<>("Advanced", Integer.class, "workers", "5",
|
||||
"Number of worker threads handling remote agent connections.", false);
|
||||
protected final ConfigKey<Integer> Port = new ConfigKey<Integer>("Advanced", Integer.class, "port", "8250", "Port to listen on for remote agent connections.", false);
|
||||
protected final ConfigKey<Integer> AlertWait = new ConfigKey<Integer>("Advanced", Integer.class, "alert.wait", "1800",
|
||||
protected final ConfigKey<Integer> Port = new ConfigKey<>("Advanced", Integer.class, "port", "8250", "Port to listen on for remote agent connections.", false);
|
||||
protected final ConfigKey<Integer> RemoteAgentSslHandshakeTimeout = new ConfigKey<>("Advanced",
|
||||
Integer.class, "agent.ssl.handshake.timeout", "30",
|
||||
"Seconds after which SSL handshake times out during remote agent connections.", false);
|
||||
protected final ConfigKey<Integer> RemoteAgentMaxConcurrentNewConnections = new ConfigKey<>("Advanced",
|
||||
Integer.class, "agent.max.concurrent.new.connections", "0",
|
||||
"Number of maximum concurrent new connections server allows for remote agents. " +
|
||||
"If set to zero (default value) then no limit will be enforced on concurrent new connections",
|
||||
false);
|
||||
protected final ConfigKey<Integer> AlertWait = new ConfigKey<>("Advanced", Integer.class, "alert.wait", "1800",
|
||||
"Seconds to wait before alerting on a disconnected agent", true);
|
||||
protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.load.size", "16",
|
||||
protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<>("Advanced", Integer.class, "direct.agent.load.size", "16",
|
||||
"The number of direct agents to load each time", false);
|
||||
protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.pool.size", "500",
|
||||
protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<>("Advanced", Integer.class, "direct.agent.pool.size", "500",
|
||||
"Default size for DirectAgentPool", false);
|
||||
protected final ConfigKey<Float> DirectAgentThreadCap = new ConfigKey<Float>("Advanced", Float.class, "direct.agent.thread.cap", "1",
|
||||
protected final ConfigKey<Float> DirectAgentThreadCap = new ConfigKey<>("Advanced", Float.class, "direct.agent.thread.cap", "1",
|
||||
"Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false);
|
||||
protected final ConfigKey<Boolean> CheckTxnBeforeSending = new ConfigKey<Boolean>("Developer", Boolean.class, "check.txn.before.sending.agent.commands", "false",
|
||||
protected final ConfigKey<Boolean> CheckTxnBeforeSending = new ConfigKey<>("Developer", Boolean.class, "check.txn.before.sending.agent.commands", "false",
|
||||
"This parameter allows developers to enable a check to see if a transaction wraps commands that are sent to the resource. This is not to be enabled on production systems.", true);
|
||||
|
||||
@Override
|
||||
|
|
@ -227,8 +239,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
logger.info("Ping Timeout is {}.", mgmtServiceConf.getPingTimeout());
|
||||
|
||||
final int threads = DirectAgentLoadSize.value();
|
||||
|
||||
_nodeId = ManagementServerNode.getManagementServerId();
|
||||
logger.info("Configuring AgentManagerImpl. management server node id(msid): {}.", _nodeId);
|
||||
|
||||
|
|
@ -241,24 +251,32 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
managementServerMaintenanceManager.registerListener(this);
|
||||
|
||||
_executor = new ThreadPoolExecutor(threads, threads, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("AgentTaskPool"));
|
||||
final int agentTaskThreads = DirectAgentLoadSize.value();
|
||||
|
||||
_connectExecutor = new ThreadPoolExecutor(100, 500, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("AgentConnectTaskPool"));
|
||||
_executor = new ThreadPoolExecutor(agentTaskThreads, agentTaskThreads, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("AgentTaskPool"));
|
||||
|
||||
_connectExecutor = new ThreadPoolExecutor(100, 500, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("AgentConnectTaskPool"));
|
||||
// allow core threads to time out even when there are no items in the queue
|
||||
_connectExecutor.allowCoreThreadTimeOut(true);
|
||||
|
||||
_connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10, this, caService);
|
||||
maxConcurrentNewAgentConnections = RemoteAgentMaxConcurrentNewConnections.value();
|
||||
|
||||
_connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10,
|
||||
this, caService, RemoteAgentSslHandshakeTimeout.value());
|
||||
logger.info("Listening on {} with {} workers.", Port.value(), Workers.value());
|
||||
|
||||
final int directAgentPoolSize = DirectAgentPoolSize.value();
|
||||
// executes all agent commands other than cron and ping
|
||||
_directAgentExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgent"));
|
||||
_directAgentExecutor = new ScheduledThreadPoolExecutor(directAgentPoolSize, new NamedThreadFactory("DirectAgent"));
|
||||
// executes cron and ping agent commands
|
||||
_cronJobExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgentCronJob"));
|
||||
logger.debug("Created DirectAgentAttache pool with size: {}.", DirectAgentPoolSize.value());
|
||||
_directAgentThreadCap = Math.round(DirectAgentPoolSize.value() * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0
|
||||
_cronJobExecutor = new ScheduledThreadPoolExecutor(directAgentPoolSize, new NamedThreadFactory("DirectAgentCronJob"));
|
||||
logger.debug("Created DirectAgentAttache pool with size: {}.", directAgentPoolSize);
|
||||
_directAgentThreadCap = Math.round(directAgentPoolSize * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0
|
||||
|
||||
_monitorExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("AgentMonitor"));
|
||||
|
||||
newAgentConnectionsMonitor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NewAgentConnectionsMonitor"));
|
||||
|
||||
initializeCommandTimeouts();
|
||||
|
||||
return true;
|
||||
|
|
@ -269,22 +287,44 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
return new AgentHandler(type, link, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxConcurrentNewConnectionsCount() {
|
||||
return maxConcurrentNewAgentConnections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewConnectionsCount() {
|
||||
return newAgentConnections.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNewConnection(SocketAddress address) {
|
||||
logger.trace("Adding new agent connection from {}", address.toString());
|
||||
newAgentConnections.putIfAbsent(address.toString(), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNewConnection(SocketAddress address) {
|
||||
logger.trace("Removing new agent connection for {}", address.toString());
|
||||
newAgentConnections.remove(address.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerForHostEvents(final Listener listener, final boolean connections, final boolean commands, final boolean priority) {
|
||||
synchronized (_hostMonitors) {
|
||||
_monitorId++;
|
||||
if (connections) {
|
||||
if (priority) {
|
||||
_hostMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
|
||||
_hostMonitors.add(0, new Pair<>(_monitorId, listener));
|
||||
} else {
|
||||
_hostMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
|
||||
_hostMonitors.add(new Pair<>(_monitorId, listener));
|
||||
}
|
||||
}
|
||||
if (commands) {
|
||||
if (priority) {
|
||||
_cmdMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
|
||||
_cmdMonitors.add(0, new Pair<>(_monitorId, listener));
|
||||
} else {
|
||||
_cmdMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
|
||||
_cmdMonitors.add(new Pair<>(_monitorId, listener));
|
||||
}
|
||||
}
|
||||
logger.debug("Registering listener {} with id {}", listener.getClass().getSimpleName(), _monitorId);
|
||||
|
|
@ -297,9 +337,9 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
synchronized (_hostMonitors) {
|
||||
_monitorId++;
|
||||
if (priority) {
|
||||
_creationMonitors.add(0, new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
|
||||
_creationMonitors.add(0, new Pair<>(_monitorId, creator));
|
||||
} else {
|
||||
_creationMonitors.add(new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
|
||||
_creationMonitors.add(new Pair<>(_monitorId, creator));
|
||||
}
|
||||
return _monitorId;
|
||||
}
|
||||
|
|
@ -331,7 +371,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
public void onManagementServerCancelMaintenance() {
|
||||
logger.debug("Management server maintenance disabled");
|
||||
if (_connectExecutor.isShutdown()) {
|
||||
_connectExecutor = new ThreadPoolExecutor(100, 500, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("AgentConnectTaskPool"));
|
||||
_connectExecutor = new ThreadPoolExecutor(100, 500, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("AgentConnectTaskPool"));
|
||||
_connectExecutor.allowCoreThreadTimeOut(true);
|
||||
}
|
||||
|
||||
|
|
@ -351,7 +391,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
private AgentControlAnswer handleControlCommand(final AgentAttache attache, final AgentControlCommand cmd) {
|
||||
AgentControlAnswer answer = null;
|
||||
AgentControlAnswer answer;
|
||||
|
||||
for (final Pair<Integer, Listener> listener : _cmdMonitors) {
|
||||
answer = listener.second().processControlCommand(attache.getId(), cmd);
|
||||
|
|
@ -379,7 +419,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
public AgentAttache findAttache(final long hostId) {
|
||||
AgentAttache attache = null;
|
||||
AgentAttache attache;
|
||||
synchronized (_agents) {
|
||||
attache = _agents.get(hostId);
|
||||
}
|
||||
|
|
@ -431,12 +471,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
cmds.addCommand(cmd);
|
||||
send(hostId, cmds, cmd.getWait());
|
||||
final Answer[] answers = cmds.getAnswers();
|
||||
if (answers != null && !(answers[0] instanceof UnsupportedAnswer)) {
|
||||
return answers[0];
|
||||
}
|
||||
|
||||
if (answers != null && answers[0] instanceof UnsupportedAnswer) {
|
||||
logger.warn("Unsupported Command: {}", answers[0].getDetails());
|
||||
if (answers != null) {
|
||||
if (answers[0] instanceof UnsupportedAnswer) {
|
||||
logger.warn("Unsupported Command: {}", answers[0].getDetails());
|
||||
}
|
||||
return answers[0];
|
||||
}
|
||||
|
||||
|
|
@ -467,8 +505,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
/**
|
||||
* @param commands
|
||||
* @return
|
||||
* @param commands object container of commands
|
||||
* @return array of commands
|
||||
*/
|
||||
private Command[] checkForCommandsAndTag(final Commands commands) {
|
||||
final Command[] cmds = commands.toCommands();
|
||||
|
|
@ -484,8 +522,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
/**
|
||||
* @param commands
|
||||
* @param cmds
|
||||
* @param commands object container of commands
|
||||
* @param cmds array of commands
|
||||
*/
|
||||
private void setEmptyAnswers(final Commands commands, final Command[] cmds) {
|
||||
if (cmds.length == 0) {
|
||||
|
|
@ -524,7 +562,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
String commandWaits = GranularWaitTimeForCommands.value().trim();
|
||||
if (StringUtils.isNotEmpty(commandWaits)) {
|
||||
_commandTimeouts = getCommandTimeoutsMap(commandWaits);
|
||||
logger.info(String.format("Timeouts for management server internal commands successfully initialized from global setting commands.timeout: %s", _commandTimeouts));
|
||||
logger.info("Timeouts for management server internal commands successfully initialized from global setting commands.timeout: {}", _commandTimeouts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -540,10 +578,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
int commandTimeout = Integer.parseInt(parts[1].trim());
|
||||
commandTimeouts.put(commandName, commandTimeout);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error(String.format("Initialising the timeouts using commands.timeout: %s for management server internal commands failed with error %s", commandPair, e.getMessage()));
|
||||
logger.error("Initialising the timeouts using commands.timeout: {} for management server internal commands failed with error {}", commandPair, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
logger.error(String.format("Error initialising the timeouts for management server internal commands. Invalid format in commands.timeout: %s", commandPair));
|
||||
logger.error("Error initialising the timeouts for management server internal commands. Invalid format in commands.timeout: {}", commandPair);
|
||||
}
|
||||
}
|
||||
return commandTimeouts;
|
||||
|
|
@ -557,7 +595,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
int wait = getTimeout(commands, timeout);
|
||||
logger.debug(String.format("Wait time setting on %s is %d seconds", commands, wait));
|
||||
logger.debug("Wait time setting on {} is {} seconds", commands, wait);
|
||||
for (Command cmd : commands) {
|
||||
String simpleCommandName = cmd.getClass().getSimpleName();
|
||||
Integer commandTimeout = _commandTimeouts.get(simpleCommandName);
|
||||
|
|
@ -644,7 +682,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
final long hostId = attache.getId();
|
||||
logger.debug("Remove Agent : {}", attache);
|
||||
AgentAttache removed = null;
|
||||
AgentAttache removed;
|
||||
boolean conflict = false;
|
||||
synchronized (_agents) {
|
||||
removed = _agents.remove(hostId);
|
||||
|
|
@ -697,16 +735,15 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
} catch (final HypervisorVersionChangedException hvce) {
|
||||
handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true);
|
||||
throw new CloudRuntimeException("Unable to connect " + (attache == null ? "<unknown agent>" : attache.getId()), hvce);
|
||||
throw new CloudRuntimeException("Unable to connect " + attache.getId(), hvce);
|
||||
} catch (final Exception e) {
|
||||
logger.error("Monitor {} says there is an error in the connect process for {} due to {}", monitor.second().getClass().getSimpleName(), hostId, e.getMessage(), e);
|
||||
handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
|
||||
throw new CloudRuntimeException("Unable to connect " + (attache == null ? "<unknown agent>" : attache.getId()), e);
|
||||
throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Long dcId = host.getDataCenterId();
|
||||
final ReadyCommand ready = new ReadyCommand(host, NumbersUtil.enableHumanReadableSizes);
|
||||
ready.setWait(ReadyCommandWait.value());
|
||||
final Answer answer = easySend(hostId, ready);
|
||||
|
|
@ -757,6 +794,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
_monitorExecutor.scheduleWithFixedDelay(new MonitorTask(), mgmtServiceConf.getPingInterval(), mgmtServiceConf.getPingInterval(), TimeUnit.SECONDS);
|
||||
|
||||
final int cleanupTime = Wait.value();
|
||||
newAgentConnectionsMonitor.scheduleAtFixedRate(new AgentNewConnectionsMonitorTask(), cleanupTime,
|
||||
cleanupTime, TimeUnit.MINUTES);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -775,25 +816,25 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
final Constructor<?> constructor = clazz.getConstructor();
|
||||
resource = (ServerResource)constructor.newInstance();
|
||||
} catch (final ClassNotFoundException e) {
|
||||
logger.warn("Unable to find class " + host.getResource(), e);
|
||||
logger.warn("Unable to find class {}", host.getResource(), e);
|
||||
} catch (final InstantiationException e) {
|
||||
logger.warn("Unable to instantiate class " + host.getResource(), e);
|
||||
logger.warn("Unable to instantiate class {}", host.getResource(), e);
|
||||
} catch (final IllegalAccessException e) {
|
||||
logger.warn("Illegal access " + host.getResource(), e);
|
||||
logger.warn("Illegal access {}", host.getResource(), e);
|
||||
} catch (final SecurityException e) {
|
||||
logger.warn("Security error on " + host.getResource(), e);
|
||||
logger.warn("Security error on {}", host.getResource(), e);
|
||||
} catch (final NoSuchMethodException e) {
|
||||
logger.warn("NoSuchMethodException error on " + host.getResource(), e);
|
||||
logger.warn("NoSuchMethodException error on {}", host.getResource(), e);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
logger.warn("IllegalArgumentException error on " + host.getResource(), e);
|
||||
logger.warn("IllegalArgumentException error on {}", host.getResource(), e);
|
||||
} catch (final InvocationTargetException e) {
|
||||
logger.warn("InvocationTargetException error on " + host.getResource(), e);
|
||||
logger.warn("InvocationTargetException error on {}", host.getResource(), e);
|
||||
}
|
||||
|
||||
if (resource != null) {
|
||||
_hostDao.loadDetails(host);
|
||||
|
||||
final HashMap<String, Object> params = new HashMap<String, Object>(host.getDetails().size() + 5);
|
||||
final HashMap<String, Object> params = new HashMap<>(host.getDetails().size() + 5);
|
||||
params.putAll(host.getDetails());
|
||||
|
||||
params.put("guid", host.getGuid());
|
||||
|
|
@ -803,7 +844,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
if (host.getClusterId() != null) {
|
||||
params.put("cluster", Long.toString(host.getClusterId()));
|
||||
String guid = null;
|
||||
String guid;
|
||||
final ClusterVO cluster = _clusterDao.findById(host.getClusterId());
|
||||
if (cluster.getGuid() == null) {
|
||||
guid = host.getDetail("pool");
|
||||
|
|
@ -843,7 +884,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
protected boolean loadDirectlyConnectedHost(final HostVO host, final boolean forRebalance, final boolean isTransferredConnection) {
|
||||
boolean initialized = false;
|
||||
ServerResource resource = null;
|
||||
ServerResource resource;
|
||||
try {
|
||||
// load the respective discoverer
|
||||
final Discoverer discoverer = _resourceMgr.getMatchingDiscover(host.getHypervisorType());
|
||||
|
|
@ -873,18 +914,18 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
final Host h = _resourceMgr.createHostAndAgent(host.getId(), resource, host.getDetails(), false, null, true, isTransferredConnection);
|
||||
tapLoadingAgents(host.getId(), TapAgentsAction.Del);
|
||||
|
||||
return h == null ? false : true;
|
||||
return h != null;
|
||||
} else {
|
||||
_executor.execute(new SimulateStartTask(host.getId(), host.getUuid(), host.getName(), resource, host.getDetails()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) throws ConnectionException {
|
||||
protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) {
|
||||
logger.debug("create DirectAgentAttache for {}", host);
|
||||
final DirectAgentAttache attache = new DirectAgentAttache(this, host.getId(), host.getUuid(), host.getName(), resource, host.isInMaintenanceStates());
|
||||
|
||||
AgentAttache old = null;
|
||||
AgentAttache old;
|
||||
synchronized (_agents) {
|
||||
old = _agents.put(host.getId(), attache);
|
||||
}
|
||||
|
|
@ -918,6 +959,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
_connectExecutor.shutdownNow();
|
||||
_monitorExecutor.shutdownNow();
|
||||
newAgentConnectionsMonitor.shutdownNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -949,7 +991,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
try {
|
||||
logger.info("Host {} is disconnecting with event {}",
|
||||
attache, event);
|
||||
Status nextStatus = null;
|
||||
Status nextStatus;
|
||||
final HostVO host = _hostDao.findById(hostId);
|
||||
if (host == null) {
|
||||
logger.warn("Can't find host with {} ({})", hostId, attache);
|
||||
|
|
@ -1082,7 +1124,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
@Override
|
||||
protected void runInContext() {
|
||||
try {
|
||||
if (_investigate == true) {
|
||||
if (_investigate) {
|
||||
handleDisconnectWithInvestigation(_attache, _event);
|
||||
} else {
|
||||
handleDisconnectWithoutInvestigation(_attache, _event, true, false);
|
||||
|
|
@ -1134,8 +1176,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
public Answer[] send(final Long hostId, final Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
|
||||
int wait = 0;
|
||||
if (cmds.size() > 1) {
|
||||
logger.debug(String.format("Checking the wait time in seconds to be used for the following commands : %s. If there are multiple commands sent at once," +
|
||||
"then max wait time of those will be used", cmds));
|
||||
logger.debug("Checking the wait time in seconds to be used for the following commands : {}. If there are multiple commands sent at once," +
|
||||
"then max wait time of those will be used", cmds);
|
||||
}
|
||||
|
||||
for (final Command cmd : cmds) {
|
||||
|
|
@ -1198,7 +1240,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
public boolean executeUserRequest(final long hostId, final Event event) throws AgentUnavailableException {
|
||||
if (event == Event.AgentDisconnected) {
|
||||
AgentAttache attache = null;
|
||||
AgentAttache attache;
|
||||
attache = findAttache(hostId);
|
||||
logger.debug("Received agent disconnect event for host {} ({})", hostId, attache);
|
||||
if (attache != null) {
|
||||
|
|
@ -1224,12 +1266,12 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
return agentAttache != null;
|
||||
}
|
||||
|
||||
protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) throws ConnectionException {
|
||||
protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) {
|
||||
logger.debug("create ConnectedAgentAttache for {}", host);
|
||||
final AgentAttache attache = new ConnectedAgentAttache(this, host.getId(), host.getUuid(), host.getName(), link, host.isInMaintenanceStates());
|
||||
link.attach(attache);
|
||||
|
||||
AgentAttache old = null;
|
||||
AgentAttache old;
|
||||
synchronized (_agents) {
|
||||
old = _agents.put(host.getId(), attache);
|
||||
}
|
||||
|
|
@ -1254,7 +1296,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
}
|
||||
ready.setArch(host.getArch().getType());
|
||||
AgentAttache attache = null;
|
||||
AgentAttache attache;
|
||||
GlobalLock joinLock = getHostJoinLock(host.getId());
|
||||
if (joinLock.lock(60)) {
|
||||
try {
|
||||
|
|
@ -1280,7 +1322,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
return attache;
|
||||
}
|
||||
|
||||
private AgentAttache handleConnectedAgent(final Link link, final StartupCommand[] startup, final Request request) {
|
||||
private AgentAttache handleConnectedAgent(final Link link, final StartupCommand[] startup) {
|
||||
AgentAttache attache = null;
|
||||
ReadyCommand ready = null;
|
||||
try {
|
||||
|
|
@ -1308,7 +1350,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
easySend(attache.getId(), ready);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
logger.debug("Failed to send ready command:" + e.toString());
|
||||
logger.debug("Failed to send ready command:", e);
|
||||
}
|
||||
return attache;
|
||||
}
|
||||
|
|
@ -1334,6 +1376,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
this.id = id;
|
||||
this.resource = resource;
|
||||
this.details = details;
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1382,10 +1426,11 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
startups[i] = (StartupCommand)_cmds[i];
|
||||
}
|
||||
|
||||
final AgentAttache attache = handleConnectedAgent(_link, startups, _request);
|
||||
final AgentAttache attache = handleConnectedAgent(_link, startups);
|
||||
if (attache == null) {
|
||||
logger.warn("Unable to create attache for agent: {}", _request);
|
||||
}
|
||||
unregisterNewConnection(_link.getSocketAddress());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1402,7 +1447,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
break;
|
||||
}
|
||||
}
|
||||
Response response = null;
|
||||
Response response;
|
||||
response = new Response(request, answers[0], _nodeId, -1);
|
||||
try {
|
||||
link.send(response.toBytes());
|
||||
|
|
@ -1483,7 +1528,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
final long hostId = attache.getId();
|
||||
final String hostName = attache.getName();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (cmd instanceof PingRoutingCommand) {
|
||||
|
|
@ -1502,7 +1546,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
final Answer[] answers = new Answer[cmds.length];
|
||||
for (int i = 0; i < cmds.length; i++) {
|
||||
cmd = cmds[i];
|
||||
Answer answer = null;
|
||||
Answer answer;
|
||||
try {
|
||||
if (cmd instanceof StartupRoutingCommand) {
|
||||
final StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
|
||||
|
|
@ -1536,7 +1580,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
final long cmdHostId = ((PingCommand)cmd).getHostId();
|
||||
boolean requestStartupCommand = false;
|
||||
|
||||
final HostVO host = _hostDao.findById(Long.valueOf(cmdHostId));
|
||||
final HostVO host = _hostDao.findById(cmdHostId);
|
||||
boolean gatewayAccessible = true;
|
||||
// if the router is sending a ping, verify the
|
||||
// gateway was pingable
|
||||
|
|
@ -1586,7 +1630,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
if (logD) {
|
||||
logger.debug("SeqA {}-: Sending {}", attache.getId(), response.getSequence(), response);
|
||||
} else {
|
||||
logger.trace("SeqA {}-: Sending {}" + attache.getId(), response.getSequence(), response);
|
||||
logger.trace("SeqA {}-: Sending {} {}", response.getSequence(), response, attache.getId());
|
||||
}
|
||||
try {
|
||||
link.send(response.toBytes());
|
||||
|
|
@ -1606,15 +1650,14 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
@Override
|
||||
protected void doTask(final Task task) throws TaskExecutionException {
|
||||
final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||
try {
|
||||
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB)) {
|
||||
final Type type = task.getType();
|
||||
if (type == Task.Type.DATA) {
|
||||
if (type == Type.DATA) {
|
||||
final byte[] data = task.getData();
|
||||
try {
|
||||
final Request event = Request.parse(data);
|
||||
if (event instanceof Response) {
|
||||
processResponse(task.getLink(), (Response)event);
|
||||
processResponse(task.getLink(), (Response) event);
|
||||
} else {
|
||||
processRequest(task.getLink(), event);
|
||||
}
|
||||
|
|
@ -1626,10 +1669,10 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
logger.error(message);
|
||||
throw new TaskExecutionException(message, e);
|
||||
}
|
||||
} else if (type == Task.Type.CONNECT) {
|
||||
} else if (type == Task.Type.DISCONNECT) {
|
||||
} else if (type == Type.CONNECT) {
|
||||
} else if (type == Type.DISCONNECT) {
|
||||
final Link link = task.getLink();
|
||||
final AgentAttache attache = (AgentAttache)link.attachment();
|
||||
final AgentAttache attache = (AgentAttache) link.attachment();
|
||||
if (attache != null) {
|
||||
disconnectWithInvestigation(attache, Event.AgentDisconnected);
|
||||
} else {
|
||||
|
|
@ -1638,8 +1681,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
link.terminated();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1668,21 +1709,16 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
|
||||
@Override
|
||||
public boolean agentStatusTransitTo(final HostVO host, final Status.Event e, final long msId) {
|
||||
try {
|
||||
_agentStatusLock.lock();
|
||||
logger.debug("[Resource state = {}, Agent event = , Host = {}]",
|
||||
host.getResourceState(), e.toString(), host);
|
||||
logger.debug("[Resource state = {}, Agent event = , Host = {}]",
|
||||
host.getResourceState(), e.toString(), host);
|
||||
|
||||
host.setManagementServerId(msId);
|
||||
try {
|
||||
return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
|
||||
} catch (final NoTransitionException e1) {
|
||||
logger.debug("Cannot transit agent status with event {} for host {}, management server id is {}", e, host, msId);
|
||||
throw new CloudRuntimeException(String.format(
|
||||
"Cannot transit agent status with event %s for host %s, management server id is %d, %s", e, host, msId, e1.getMessage()));
|
||||
}
|
||||
} finally {
|
||||
_agentStatusLock.unlock();
|
||||
host.setManagementServerId(msId);
|
||||
try {
|
||||
return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
|
||||
} catch (final NoTransitionException e1) {
|
||||
logger.debug("Cannot transit agent status with event {} for host {}, management server id is {}", e, host, msId);
|
||||
throw new CloudRuntimeException(String.format(
|
||||
"Cannot transit agent status with event %s for host %s, management server id is %d, %s", e, host, msId, e1.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1871,7 +1907,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
protected List<Long> findAgentsBehindOnPing() {
|
||||
final List<Long> agentsBehind = new ArrayList<Long>();
|
||||
final List<Long> agentsBehind = new ArrayList<>();
|
||||
final long cutoffTime = InaccurateClock.getTimeInSeconds() - mgmtServiceConf.getTimeout();
|
||||
for (final Map.Entry<Long, Long> entry : _pingMap.entrySet()) {
|
||||
if (entry.getValue() < cutoffTime) {
|
||||
|
|
@ -1879,7 +1915,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
}
|
||||
|
||||
if (agentsBehind.size() > 0) {
|
||||
if (!agentsBehind.isEmpty()) {
|
||||
logger.info("Found the following agents behind on ping: {}", agentsBehind);
|
||||
}
|
||||
|
||||
|
|
@ -1887,6 +1923,35 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
}
|
||||
|
||||
protected class AgentNewConnectionsMonitorTask extends ManagedContextRunnable {
|
||||
@Override
|
||||
protected void runInContext() {
|
||||
logger.trace("Agent New Connections Monitor is started.");
|
||||
final int cleanupTime = Wait.value();
|
||||
Set<Map.Entry<String, Long>> entrySet = newAgentConnections.entrySet();
|
||||
long cutOff = System.currentTimeMillis() - (cleanupTime * 60 * 1000L);
|
||||
if (logger.isDebugEnabled()) {
|
||||
List<String> expiredConnections = newAgentConnections.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue() <= cutOff)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
logger.debug("Currently {} active new connections, of which {} have expired - {}",
|
||||
entrySet.size(),
|
||||
expiredConnections.size(),
|
||||
StringUtils.join(expiredConnections));
|
||||
}
|
||||
for (Map.Entry<String, Long> entry : entrySet) {
|
||||
if (entry.getValue() <= cutOff) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Cleaning up new agent connection for {}", entry.getKey());
|
||||
}
|
||||
newAgentConnections.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class BehindOnPingListener implements Listener {
|
||||
@Override
|
||||
public boolean isRecurring() {
|
||||
|
|
@ -1962,7 +2027,8 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize,
|
||||
DirectAgentPoolSize, DirectAgentThreadCap, EnableKVMAutoEnableDisable, ReadyCommandWait, GranularWaitTimeForCommands };
|
||||
DirectAgentPoolSize, DirectAgentThreadCap, EnableKVMAutoEnableDisable, ReadyCommandWait,
|
||||
GranularWaitTimeForCommands, RemoteAgentSslHandshakeTimeout, RemoteAgentMaxConcurrentNewConnections };
|
||||
}
|
||||
|
||||
protected class SetHostParamsListener implements Listener {
|
||||
|
|
@ -1997,7 +2063,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
}
|
||||
|
||||
if (((StartupRoutingCommand)cmd).getHypervisorType() == HypervisorType.KVM || ((StartupRoutingCommand)cmd).getHypervisorType() == HypervisorType.LXC) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(Config.RouterAggregationCommandEachTimeout.toString(), _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
|
||||
params.put(Config.MigrateWait.toString(), _configDao.getValue(Config.MigrateWait.toString()));
|
||||
params.put(NetworkOrchestrationService.TUNGSTEN_ENABLED.key(), String.valueOf(NetworkOrchestrationService.TUNGSTEN_ENABLED.valueIn(host.getDataCenterId())));
|
||||
|
|
@ -2042,13 +2108,13 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
if (allHosts == null) {
|
||||
return null;
|
||||
}
|
||||
Map<Long, List<Long>> hostsByZone = new HashMap<Long, List<Long>>();
|
||||
Map<Long, List<Long>> hostsByZone = new HashMap<>();
|
||||
for (HostVO host : allHosts) {
|
||||
if (host.getHypervisorType() == HypervisorType.KVM || host.getHypervisorType() == HypervisorType.LXC) {
|
||||
Long zoneId = host.getDataCenterId();
|
||||
List<Long> hostIds = hostsByZone.get(zoneId);
|
||||
if (hostIds == null) {
|
||||
hostIds = new ArrayList<Long>();
|
||||
hostIds = new ArrayList<>();
|
||||
}
|
||||
hostIds.add(host.getId());
|
||||
hostsByZone.put(zoneId, hostIds);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import org.apache.cloudstack.maintenance.command.PrepareForShutdownManagementSer
|
|||
import org.apache.cloudstack.maintenance.command.TriggerShutdownManagementServerHostCommand;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
|
||||
import org.apache.cloudstack.management.ManagementServerHost;
|
||||
import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
import org.apache.cloudstack.utils.security.SSLUtils;
|
||||
|
|
@ -75,9 +76,6 @@ import com.cloud.cluster.ClusterManager;
|
|||
import com.cloud.cluster.ClusterManagerListener;
|
||||
import com.cloud.cluster.ClusterServicePdu;
|
||||
import com.cloud.cluster.ClusteredAgentRebalanceService;
|
||||
import org.apache.cloudstack.management.ManagementServerHost;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.cluster.ManagementServerHostVO;
|
||||
import com.cloud.cluster.agentlb.AgentLoadBalancerPlanner;
|
||||
import com.cloud.cluster.agentlb.HostTransferMapVO;
|
||||
|
|
@ -107,6 +105,8 @@ import com.cloud.utils.nio.Link;
|
|||
import com.cloud.utils.nio.Task;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
public class ClusteredAgentManagerImpl extends AgentManagerImpl implements ClusterManagerListener, ClusteredAgentRebalanceService {
|
||||
private static ScheduledExecutorService s_transferExecutor = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Cluster-AgentRebalancingExecutor"));
|
||||
private final long rebalanceTimeOut = 300000; // 5 mins - after this time remove the agent from the transfer list
|
||||
|
|
@ -114,7 +114,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
public final static long STARTUP_DELAY = 5000;
|
||||
public final static long SCAN_INTERVAL = 90000; // 90 seconds, it takes 60 sec for xenserver to fail login
|
||||
public final static int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
|
||||
protected Set<Long> _agentToTransferIds = new HashSet<Long>();
|
||||
protected Set<Long> _agentToTransferIds = new HashSet<>();
|
||||
Gson _gson;
|
||||
protected HashMap<String, SocketChannel> _peers;
|
||||
protected HashMap<String, SSLEngine> _sslEngines;
|
||||
|
|
@ -151,17 +151,17 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
super();
|
||||
}
|
||||
|
||||
protected final ConfigKey<Boolean> EnableLB = new ConfigKey<Boolean>(Boolean.class, "agent.lb.enabled", "Advanced", "false", "Enable agent load balancing between management server nodes", true);
|
||||
protected final ConfigKey<Double> ConnectedAgentThreshold = new ConfigKey<Double>(Double.class, "agent.load.threshold", "Advanced", "0.7",
|
||||
protected final ConfigKey<Boolean> EnableLB = new ConfigKey<>(Boolean.class, "agent.lb.enabled", "Advanced", "false", "Enable agent load balancing between management server nodes", true);
|
||||
protected final ConfigKey<Double> ConnectedAgentThreshold = new ConfigKey<>(Double.class, "agent.load.threshold", "Advanced", "0.7",
|
||||
"What percentage of the agents can be held by one management server before load balancing happens", true, EnableLB.key());
|
||||
protected final ConfigKey<Integer> LoadSize = new ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advanced", "16", "How many agents to connect to in each round", true);
|
||||
protected final ConfigKey<Integer> ScanInterval = new ConfigKey<Integer>(Integer.class, "direct.agent.scan.interval", "Advanced", "90", "Interval between scans to load agents", false,
|
||||
protected final ConfigKey<Integer> LoadSize = new ConfigKey<>(Integer.class, "direct.agent.load.size", "Advanced", "16", "How many agents to connect to in each round", true);
|
||||
protected final ConfigKey<Integer> ScanInterval = new ConfigKey<>(Integer.class, "direct.agent.scan.interval", "Advanced", "90", "Interval between scans to load agents", false,
|
||||
ConfigKey.Scope.Global, 1000);
|
||||
|
||||
@Override
|
||||
public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
|
||||
_peers = new HashMap<String, SocketChannel>(7);
|
||||
_sslEngines = new HashMap<String, SSLEngine>(7);
|
||||
_peers = new HashMap<>(7);
|
||||
_sslEngines = new HashMap<>(7);
|
||||
_nodeId = ManagementServerNode.getManagementServerId();
|
||||
|
||||
logger.info("Configuring ClusterAgentManagerImpl. management server node id(msid): {}", _nodeId);
|
||||
|
|
@ -220,7 +220,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
|
||||
if (hosts != null) {
|
||||
hosts.addAll(appliances);
|
||||
if (hosts.size() > 0) {
|
||||
if (!hosts.isEmpty()) {
|
||||
logger.debug("Found {} unmanaged direct hosts, processing connect for them...", hosts.size());
|
||||
for (final HostVO host : hosts) {
|
||||
try {
|
||||
|
|
@ -234,12 +234,10 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Loading directly connected host {}", host);
|
||||
logger.debug("Loading directly connected {}", host);
|
||||
loadDirectlyConnectedHost(host, false);
|
||||
} catch (final Throwable e) {
|
||||
logger.warn(" can not load directly connected host {}({}) due to ",
|
||||
host, e);
|
||||
logger.warn(" can not load directly connected {} due to ", host, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -267,10 +265,10 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
logger.debug("create forwarding ClusteredAgentAttache for {}", host);
|
||||
long id = host.getId();
|
||||
final AgentAttache attache = new ClusteredAgentAttache(this, id, host.getUuid(), host.getName());
|
||||
AgentAttache old = null;
|
||||
AgentAttache old;
|
||||
synchronized (_agents) {
|
||||
old = _agents.get(id);
|
||||
_agents.put(id, attache);
|
||||
old = _agents.get(host.getId());
|
||||
_agents.put(host.getId(), attache);
|
||||
}
|
||||
if (old != null) {
|
||||
logger.debug("Remove stale agent attache from current management server");
|
||||
|
|
@ -284,7 +282,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
logger.debug("create ClusteredAgentAttache for {}", host);
|
||||
final AgentAttache attache = new ClusteredAgentAttache(this, host.getId(), host.getUuid(), host.getName(), link, host.isInMaintenanceStates());
|
||||
link.attach(attache);
|
||||
AgentAttache old = null;
|
||||
AgentAttache old;
|
||||
synchronized (_agents) {
|
||||
old = _agents.get(host.getId());
|
||||
_agents.put(host.getId(), attache);
|
||||
|
|
@ -299,7 +297,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) {
|
||||
logger.debug("Create ClusteredDirectAgentAttache for {}.", host);
|
||||
final DirectAgentAttache attache = new ClusteredDirectAgentAttache(this, host.getId(), host.getUuid(), host.getName(), _nodeId, resource, host.isInMaintenanceStates());
|
||||
AgentAttache old = null;
|
||||
AgentAttache old;
|
||||
synchronized (_agents) {
|
||||
old = _agents.get(host.getId());
|
||||
_agents.put(host.getId(), attache);
|
||||
|
|
@ -418,12 +416,12 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
public boolean routeToPeer(final String peer, final byte[] bytes) {
|
||||
int i = 0;
|
||||
SocketChannel ch = null;
|
||||
SSLEngine sslEngine = null;
|
||||
SSLEngine sslEngine;
|
||||
while (i++ < 5) {
|
||||
ch = connectToPeer(peer, ch);
|
||||
if (ch == null) {
|
||||
try {
|
||||
logD(bytes, "Unable to route to peer: " + Request.parse(bytes).toString());
|
||||
logD(bytes, "Unable to route to peer: " + Request.parse(bytes));
|
||||
} catch (ClassNotFoundException | UnsupportedVersionException e) {
|
||||
// Request.parse thrown exception when we try to log it, log as much as we can
|
||||
logD(bytes, "Unable to route to peer, and Request.parse further caught exception" + e.getMessage());
|
||||
|
|
@ -441,7 +439,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
return true;
|
||||
} catch (final IOException e) {
|
||||
try {
|
||||
logI(bytes, "Unable to route to peer: " + Request.parse(bytes).toString() + " due to " + e.getMessage());
|
||||
logI(bytes, "Unable to route to peer: " + Request.parse(bytes) + " due to " + e.getMessage());
|
||||
} catch (ClassNotFoundException | UnsupportedVersionException ex) {
|
||||
// Request.parse thrown exception when we try to log it, log as much as we can
|
||||
logI(bytes, "Unable to route to peer due to" + e.getMessage() + ". Also caught exception when parsing request: " + ex.getMessage());
|
||||
|
|
@ -484,7 +482,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
public SocketChannel connectToPeer(final String peerName, final SocketChannel prevCh) {
|
||||
synchronized (_peers) {
|
||||
final SocketChannel ch = _peers.get(peerName);
|
||||
SSLEngine sslEngine = null;
|
||||
SSLEngine sslEngine;
|
||||
if (prevCh != null) {
|
||||
try {
|
||||
prevCh.close();
|
||||
|
|
@ -569,13 +567,13 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
AgentAttache agent = findAttache(hostId);
|
||||
if (agent == null || !agent.forForward()) {
|
||||
if (isHostOwnerSwitched(host)) {
|
||||
logger.debug("Host {} has switched to another management server, need to update agent map with a forwarding agent attache", host);
|
||||
logger.debug("{} has switched to another management server, need to update agent map with a forwarding agent attache", host);
|
||||
agent = createAttache(host);
|
||||
}
|
||||
}
|
||||
if (agent == null) {
|
||||
final AgentUnavailableException ex = new AgentUnavailableException("Host with specified id is not in the right state: " + host.getStatus(), hostId);
|
||||
ex.addProxyObject(_entityMgr.findById(Host.class, hostId).getUuid());
|
||||
ex.addProxyObject(host.getUuid());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
|
|
@ -617,9 +615,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
|
||||
@Override
|
||||
protected void doTask(final Task task) throws TaskExecutionException {
|
||||
final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||
try {
|
||||
if (task.getType() != Task.Type.DATA) {
|
||||
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB)) {
|
||||
if (task.getType() != Type.DATA) {
|
||||
super.doTask(task);
|
||||
return;
|
||||
}
|
||||
|
|
@ -646,7 +643,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
}
|
||||
final Request req = Request.parse(data);
|
||||
final Command[] cmds = req.getCommands();
|
||||
final CancelCommand cancel = (CancelCommand)cmds[0];
|
||||
final CancelCommand cancel = (CancelCommand) cmds[0];
|
||||
logD(data, "Cancel request received");
|
||||
agent.cancel(cancel.getSequence());
|
||||
final Long current = agent._currentSequence;
|
||||
|
|
@ -670,10 +667,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
// to deserialize this and send it through the agent attache.
|
||||
final Request req = Request.parse(data);
|
||||
agent.send(req, null);
|
||||
return;
|
||||
} else {
|
||||
if (agent instanceof Routable) {
|
||||
final Routable cluster = (Routable)agent;
|
||||
final Routable cluster = (Routable) agent;
|
||||
cluster.routeToAgent(data);
|
||||
} else {
|
||||
agent.send(Request.parse(data));
|
||||
|
|
@ -690,13 +686,12 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
if (mgmtId != -1 && mgmtId != _nodeId) {
|
||||
routeToPeer(Long.toString(mgmtId), data);
|
||||
if (Request.requiresSequentialExecution(data)) {
|
||||
final AgentAttache attache = (AgentAttache)link.attachment();
|
||||
final AgentAttache attache = (AgentAttache) link.attachment();
|
||||
if (attache != null) {
|
||||
attache.sendNext(Request.getSequence(data));
|
||||
}
|
||||
logD(data, "No attache to process " + Request.parse(data).toString());
|
||||
logD(data, "No attache to process " + Request.parse(data));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (Request.isRequest(data)) {
|
||||
super.doTask(task);
|
||||
|
|
@ -712,7 +707,6 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
logger.info("SeqA {}-{}: Response is not processed: {}", attache.getId(), response.getSequence(), response.toString());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (final ClassNotFoundException e) {
|
||||
|
|
@ -723,8 +717,6 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
final String message = String.format("UnsupportedVersionException occurred when executing tasks! Error '%s'", e.getMessage());
|
||||
logger.error(message);
|
||||
throw new TaskExecutionException(message, e);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -768,7 +760,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
public boolean executeRebalanceRequest(final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event, boolean isConnectionTransfer) throws AgentUnavailableException, OperationTimedoutException {
|
||||
boolean result = false;
|
||||
if (event == Event.RequestAgentRebalance) {
|
||||
return setToWaitForRebalance(agentId, currentOwnerId, futureOwnerId);
|
||||
return setToWaitForRebalance(agentId);
|
||||
} else if (event == Event.StartAgentRebalance) {
|
||||
try {
|
||||
result = rebalanceHost(agentId, currentOwnerId, futureOwnerId, isConnectionTransfer);
|
||||
|
|
@ -823,7 +815,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
|
||||
final List<HostVO> allManagedAgents = sc.list();
|
||||
|
||||
int avLoad = 0;
|
||||
int avLoad;
|
||||
|
||||
if (!allManagedAgents.isEmpty() && !allMS.isEmpty()) {
|
||||
avLoad = allManagedAgents.size() / allMS.size();
|
||||
|
|
@ -841,7 +833,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
for (final ManagementServerHostVO node : allMS) {
|
||||
if (node.getMsid() != _nodeId) {
|
||||
|
||||
List<HostVO> hostsToRebalance = new ArrayList<HostVO>();
|
||||
List<HostVO> hostsToRebalance = new ArrayList<>();
|
||||
for (final AgentLoadBalancerPlanner lbPlanner : _lbPlanners) {
|
||||
hostsToRebalance = lbPlanner.getHostsToRebalance(node, avLoad);
|
||||
if (hostsToRebalance != null && !hostsToRebalance.isEmpty()) {
|
||||
|
|
@ -867,7 +859,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
HostTransferMapVO transfer = null;
|
||||
try {
|
||||
transfer = _hostTransferDao.startAgentTransfering(hostId, node.getMsid(), _nodeId);
|
||||
final Answer[] answer = sendRebalanceCommand(node.getMsid(), hostId, node.getMsid(), _nodeId, Event.RequestAgentRebalance);
|
||||
final Answer[] answer = sendRebalanceCommand(node.getMsid(), hostId, node.getMsid(), _nodeId);
|
||||
if (answer == null) {
|
||||
logger.warn("Failed to get host {} from management server {}", host, node);
|
||||
result = false;
|
||||
|
|
@ -894,8 +886,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
}
|
||||
}
|
||||
|
||||
private Answer[] sendRebalanceCommand(final long peer, final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event) {
|
||||
return sendRebalanceCommand(peer, agentId, currentOwnerId, futureOwnerId, event, false);
|
||||
private Answer[] sendRebalanceCommand(final long peer, final long agentId, final long currentOwnerId, final long futureOwnerId) {
|
||||
return sendRebalanceCommand(peer, agentId, currentOwnerId, futureOwnerId, Event.RequestAgentRebalance, false);
|
||||
}
|
||||
|
||||
private Answer[] sendRebalanceCommand(final long peer, final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event, final boolean isConnectionTransfer) {
|
||||
|
|
@ -910,8 +902,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
final String peerName = Long.toString(peer);
|
||||
final String cmdStr = _gson.toJson(cmds);
|
||||
final String ansStr = _clusterMgr.execute(peerName, agentId, cmdStr, true);
|
||||
final Answer[] answers = _gson.fromJson(ansStr, Answer[].class);
|
||||
return answers;
|
||||
return _gson.fromJson(ansStr, Answer[].class);
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Caught exception while talking to {}", currentOwnerId, e);
|
||||
return null;
|
||||
|
|
@ -960,7 +951,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
try {
|
||||
logger.trace("Clustered agent transfer scan check, management server id: {}", _nodeId);
|
||||
synchronized (_agentToTransferIds) {
|
||||
if (_agentToTransferIds.size() > 0) {
|
||||
if (!_agentToTransferIds.isEmpty()) {
|
||||
logger.debug("Found {} agents to transfer", _agentToTransferIds.size());
|
||||
// for (Long hostId : _agentToTransferIds) {
|
||||
for (final Iterator<Long> iterator = _agentToTransferIds.iterator(); iterator.hasNext();) {
|
||||
|
|
@ -984,7 +975,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
}
|
||||
|
||||
if (transferMap.getInitialOwner() != _nodeId || attache == null || attache.forForward()) {
|
||||
logger.debug(String.format("Management server %d doesn't own host id=%d (%s) any more, skipping rebalance for the host", _nodeId, hostId, attache));
|
||||
logger.debug("Management server {} doesn't own host id={} ({}) any more, skipping rebalance for the host", _nodeId, hostId, attache);
|
||||
iterator.remove();
|
||||
_hostTransferDao.completeAgentTransfer(hostId);
|
||||
continue;
|
||||
|
|
@ -1004,9 +995,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
_executor.execute(new RebalanceTask(hostId, transferMap.getInitialOwner(), transferMap.getFutureOwner()));
|
||||
} catch (final RejectedExecutionException ex) {
|
||||
logger.warn("Failed to submit rebalance task for host id={} ({}); postponing the execution", hostId, attache);
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.debug("Agent {} ({}) can't be transferred yet as its request queue size is {} and listener queue size is {}",
|
||||
hostId, attache, attache.getQueueSize(), attache.getNonRecurringListenersSize());
|
||||
|
|
@ -1016,7 +1005,6 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
logger.trace("Found no agents to be transferred by the management server {}", _nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (final Throwable e) {
|
||||
logger.error("Problem with the clustered agent transfer scan check!", e);
|
||||
}
|
||||
|
|
@ -1024,7 +1012,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
};
|
||||
}
|
||||
|
||||
private boolean setToWaitForRebalance(final long hostId, final long currentOwnerId, final long futureOwnerId) {
|
||||
private boolean setToWaitForRebalance(final long hostId) {
|
||||
logger.debug("Adding agent {} ({}) to the list of agents to transfer", hostId, findAttache(hostId));
|
||||
synchronized (_agentToTransferIds) {
|
||||
return _agentToTransferIds.add(hostId);
|
||||
|
|
@ -1065,7 +1053,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
} else if (futureOwnerId == _nodeId) {
|
||||
final HostVO host = _hostDao.findById(hostId);
|
||||
try {
|
||||
logger.debug("Disconnecting host {} as a part of rebalance process without notification", host);
|
||||
logger.debug("Disconnecting {} as a part of rebalance process without notification", host);
|
||||
|
||||
final AgentAttache attache = findAttache(hostId);
|
||||
if (attache != null) {
|
||||
|
|
@ -1085,9 +1073,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
}
|
||||
|
||||
if (result) {
|
||||
logger.debug("Successfully loaded directly connected host {} to the management server {} a part of rebalance process without notification", host, _nodeId);
|
||||
logger.debug("Successfully loaded directly connected {} to the management server {} a part of rebalance process without notification", host, _nodeId);
|
||||
} else {
|
||||
logger.warn("Failed to load directly connected host {} to the management server {} a part of rebalance process without notification", host, _nodeId);
|
||||
logger.warn("Failed to load directly connected {} to the management server {} a part of rebalance process without notification", host, _nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1096,12 +1084,12 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
|
||||
protected void finishRebalance(final long hostId, final long futureOwnerId, final Event event) {
|
||||
|
||||
final boolean success = event == Event.RebalanceCompleted ? true : false;
|
||||
final boolean success = event == Event.RebalanceCompleted;
|
||||
|
||||
final AgentAttache attache = findAttache(hostId);
|
||||
logger.debug("Finishing rebalancing for the agent {} ({}) with event {}", hostId, attache, event);
|
||||
|
||||
if (attache == null || !(attache instanceof ClusteredAgentAttache)) {
|
||||
if (!(attache instanceof ClusteredAgentAttache)) {
|
||||
logger.debug("Unable to find forward attache for the host id={} assuming that the agent disconnected already", hostId);
|
||||
_hostTransferDao.completeAgentTransfer(hostId);
|
||||
return;
|
||||
|
|
@ -1197,9 +1185,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
}
|
||||
|
||||
protected class RebalanceTask extends ManagedContextRunnable {
|
||||
Long hostId = null;
|
||||
Long currentOwnerId = null;
|
||||
Long futureOwnerId = null;
|
||||
Long hostId;
|
||||
Long currentOwnerId;
|
||||
Long futureOwnerId;
|
||||
|
||||
public RebalanceTask(final long hostId, final long currentOwnerId, final long futureOwnerId) {
|
||||
this.hostId = hostId;
|
||||
|
|
@ -1268,7 +1256,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
final ChangeAgentCommand cmd = (ChangeAgentCommand)cmds[0];
|
||||
|
||||
logger.debug("Intercepting command for agent change: agent {} event: {}", cmd.getAgentId(), cmd.getEvent());
|
||||
boolean result = false;
|
||||
boolean result;
|
||||
try {
|
||||
result = executeAgentUserRequest(cmd.getAgentId(), cmd.getEvent());
|
||||
logger.debug("Result is {}", result);
|
||||
|
|
@ -1285,7 +1273,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
final TransferAgentCommand cmd = (TransferAgentCommand)cmds[0];
|
||||
|
||||
logger.debug("Intercepting command for agent rebalancing: agent: {}, event: {}, connection transfer: {}", cmd.getAgentId(), cmd.getEvent(), cmd.isConnectionTransfer());
|
||||
boolean result = false;
|
||||
boolean result;
|
||||
try {
|
||||
result = rebalanceAgent(cmd.getAgentId(), cmd.getEvent(), cmd.getCurrentOwner(), cmd.getFutureOwner(), cmd.isConnectionTransfer());
|
||||
logger.debug("Result is {}", result);
|
||||
|
|
@ -1305,7 +1293,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
|
||||
logger.debug("Intercepting command to propagate event {} for host {} ({})", () -> cmd.getEvent().name(), cmd::getHostId, () -> _hostDao.findById(cmd.getHostId()));
|
||||
|
||||
boolean result = false;
|
||||
boolean result;
|
||||
try {
|
||||
result = _resourceMgr.executeUserRequest(cmd.getHostId(), cmd.getEvent());
|
||||
logger.debug("Result is {}", result);
|
||||
|
|
@ -1403,23 +1391,23 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
@Override
|
||||
public boolean transferDirectAgentsFromMS(String fromMsUuid, long fromMsId, long timeoutDurationInMs) {
|
||||
if (timeoutDurationInMs <= 0) {
|
||||
logger.debug(String.format("Not transferring direct agents from management server node %d (id: %s) to other nodes, invalid timeout duration", fromMsId, fromMsUuid));
|
||||
logger.debug("Not transferring direct agents from management server node {} (id: {}) to other nodes, invalid timeout duration", fromMsId, fromMsUuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
long transferStartTime = System.currentTimeMillis();
|
||||
if (CollectionUtils.isEmpty(getDirectAgentHosts(fromMsId))) {
|
||||
logger.info(String.format("No direct agent hosts available on management server node %d (id: %s), to transfer", fromMsId, fromMsUuid));
|
||||
logger.info("No direct agent hosts available on management server node {} (id: {}), to transfer", fromMsId, fromMsUuid);
|
||||
return true;
|
||||
}
|
||||
|
||||
List<ManagementServerHostVO> msHosts = getUpMsHostsExcludingMs(fromMsId);
|
||||
if (msHosts.isEmpty()) {
|
||||
logger.warn(String.format("No management server nodes available to transfer agents from management server node %d (id: %s)", fromMsId, fromMsUuid));
|
||||
logger.warn("No management server nodes available to transfer agents from management server node {} (id: {})", fromMsId, fromMsUuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.debug(String.format("Transferring direct agents from management server node %d (id: %s) to other nodes", fromMsId, fromMsUuid));
|
||||
logger.debug("Transferring direct agents from management server node {} (id: {}) to other nodes", fromMsId, fromMsUuid);
|
||||
int agentTransferFailedCount = 0;
|
||||
List<DataCenterVO> dataCenterList = dcDao.listAll();
|
||||
for (DataCenterVO dc : dataCenterList) {
|
||||
|
|
@ -1427,11 +1415,11 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
if (CollectionUtils.isEmpty(directAgentHostsInDc)) {
|
||||
continue;
|
||||
}
|
||||
logger.debug(String.format("Transferring %d direct agents from management server node %d (id: %s) of zone %s", directAgentHostsInDc.size(), fromMsId, fromMsUuid, dc.toString()));
|
||||
logger.debug("Transferring {} direct agents from management server node {} (id: {}) of zone {}", directAgentHostsInDc.size(), fromMsId, fromMsUuid, dc);
|
||||
for (HostVO host : directAgentHostsInDc) {
|
||||
long transferElapsedTimeInMs = System.currentTimeMillis() - transferStartTime;
|
||||
if (transferElapsedTimeInMs >= timeoutDurationInMs) {
|
||||
logger.debug(String.format("Stop transferring remaining direct agents from management server node %d (id: %s), timed out", fromMsId, fromMsUuid));
|
||||
logger.debug("Stop transferring remaining direct agents from management server node {} (id: {}), timed out", fromMsId, fromMsUuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1449,7 +1437,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
updateLastManagementServer(host.getId(), fromMsId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn(String.format("Failed to transfer direct agent of the host %s from management server node %d (id: %s), due to %s", host, fromMsId, fromMsUuid, e.getMessage()));
|
||||
logger.warn("Failed to transfer direct agent of the host {} from management server node {} (id: {}), due to {}", host, fromMsId, fromMsUuid, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1462,7 +1450,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
List<HostVO> hosts = _hostDao.listHostsByMs(msId);
|
||||
for (HostVO host : hosts) {
|
||||
AgentAttache agent = findAttache(host.getId());
|
||||
if (agent != null && agent instanceof DirectAgentAttache) {
|
||||
if (agent instanceof DirectAgentAttache) {
|
||||
directAgentHosts.add(host);
|
||||
}
|
||||
}
|
||||
|
|
@ -1475,7 +1463,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
List<HostVO> hosts = _hostDao.listHostsByMsAndDc(msId, dcId);
|
||||
for (HostVO host : hosts) {
|
||||
AgentAttache agent = findAttache(host.getId());
|
||||
if (agent != null && agent instanceof DirectAgentAttache) {
|
||||
if (agent instanceof DirectAgentAttache) {
|
||||
directAgentHosts.add(host);
|
||||
}
|
||||
}
|
||||
|
|
@ -1485,13 +1473,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
|
||||
private List<ManagementServerHostVO> getUpMsHostsExcludingMs(long avoidMsId) {
|
||||
final List<ManagementServerHostVO> msHosts = _mshostDao.listBy(ManagementServerHost.State.Up);
|
||||
Iterator<ManagementServerHostVO> iterator = msHosts.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ManagementServerHostVO ms = iterator.next();
|
||||
if (ms.getMsid() == avoidMsId || _mshostPeerDao.findByPeerMsAndState(ms.getId(), ManagementServerHost.State.Up) == null) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
msHosts.removeIf(ms -> ms.getMsid() == avoidMsId || _mshostPeerDao.findByPeerMsAndState(ms.getId(), ManagementServerHost.State.Up) == null);
|
||||
|
||||
return msHosts;
|
||||
}
|
||||
|
|
@ -1593,8 +1575,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
|
|||
public ConfigKey<?>[] getConfigKeys() {
|
||||
final ConfigKey<?>[] keys = super.getConfigKeys();
|
||||
|
||||
final List<ConfigKey<?>> keysLst = new ArrayList<ConfigKey<?>>();
|
||||
keysLst.addAll(Arrays.asList(keys));
|
||||
final List<ConfigKey<?>> keysLst = new ArrayList<>(Arrays.asList(keys));
|
||||
keysLst.add(EnableLB);
|
||||
keysLst.add(ConnectedAgentThreshold);
|
||||
keysLst.add(LoadSize);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ import org.apache.cloudstack.resource.ResourceCleanupService;
|
|||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.cloudstack.utils.cache.SingleCache;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.cloudstack.vm.UnmanagedVMsManager;
|
||||
|
|
@ -406,6 +407,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
private DomainDao domainDao;
|
||||
@Inject
|
||||
ResourceCleanupService resourceCleanupService;
|
||||
@Inject
|
||||
VmWorkJobDao vmWorkJobDao;
|
||||
|
||||
private SingleCache<List<Long>> vmIdsInProgressCache;
|
||||
|
||||
VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
|
||||
|
||||
|
|
@ -450,6 +455,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
Long.class, "systemvm.root.disk.size", "-1",
|
||||
"Size of root volume (in GB) of system VMs and virtual routers", true);
|
||||
|
||||
private boolean syncTransitioningVmPowerState;
|
||||
|
||||
ScheduledExecutorService _executor = null;
|
||||
|
||||
private long _nodeId;
|
||||
|
|
@ -700,7 +707,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
private void handleUnsuccessfulExpungeOperation(List<Command> finalizeExpungeCommands, List<Command> nicExpungeCommands,
|
||||
VMInstanceVO vm, Long hostId) throws OperationTimedoutException, AgentUnavailableException {
|
||||
if (CollectionUtils.isNotEmpty(finalizeExpungeCommands) || CollectionUtils.isNotEmpty(nicExpungeCommands) && (hostId != null)) {
|
||||
if ((CollectionUtils.isNotEmpty(finalizeExpungeCommands) || CollectionUtils.isNotEmpty(nicExpungeCommands)) && hostId != null) {
|
||||
final Commands cmds = new Commands(Command.OnError.Stop);
|
||||
addAllExpungeCommandsFromList(finalizeExpungeCommands, cmds, vm);
|
||||
addAllExpungeCommandsFromList(nicExpungeCommands, cmds, vm);
|
||||
|
|
@ -816,6 +823,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
@Override
|
||||
public boolean start() {
|
||||
vmIdsInProgressCache = new SingleCache<>(10, vmWorkJobDao::listVmIdsWithPendingJob);
|
||||
_executor.scheduleAtFixedRate(new CleanupTask(), 5, VmJobStateReportInterval.value(), TimeUnit.SECONDS);
|
||||
_executor.scheduleAtFixedRate(new TransitionTask(), VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS);
|
||||
cancelWorkItems(_nodeId);
|
||||
|
|
@ -843,6 +851,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
_messageBus.subscribe(VirtualMachineManager.Topics.VM_POWER_STATE, MessageDispatcher.getDispatcher(this));
|
||||
|
||||
syncTransitioningVmPowerState = Boolean.TRUE.equals(VmSyncPowerStateTransitioning.value());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3506,7 +3516,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
if (MIGRATE_VM_ACROSS_CLUSTERS.valueIn(host.getDataCenterId()) &&
|
||||
(HypervisorType.VMware.equals(host.getHypervisorType()) || !checkIfVmHasClusterWideVolumes(vm.getId()))) {
|
||||
logger.info("Searching for hosts in the zone for vm migration");
|
||||
List<Long> clustersToExclude = _clusterDao.listAllClusters(host.getDataCenterId());
|
||||
List<Long> clustersToExclude = _clusterDao.listAllClusterIds(host.getDataCenterId());
|
||||
List<ClusterVO> clusterList = _clusterDao.listByDcHyType(host.getDataCenterId(), host.getHypervisorType().toString());
|
||||
for (ClusterVO cluster : clusterList) {
|
||||
clustersToExclude.remove(cluster.getId());
|
||||
|
|
@ -3800,7 +3810,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
if (ping.getHostVmStateReport() != null) {
|
||||
_syncMgr.processHostVmStatePingReport(agentId, ping.getHostVmStateReport(), ping.getOutOfBand());
|
||||
}
|
||||
|
||||
scanStalledVMInTransitionStateOnUpHost(agentId);
|
||||
processed = true;
|
||||
}
|
||||
|
|
@ -4757,7 +4766,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
VmOpLockStateRetry, VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval,
|
||||
VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, VmConfigDriveForceHostCacheUse, VmConfigDriveUseHostCacheOnUnsupportedPool,
|
||||
HaVmRestartHostUp, ResourceCountRunningVMsonly, AllowExposeHypervisorHostname, AllowExposeHypervisorHostnameAccountLevel, SystemVmRootDiskSize,
|
||||
AllowExposeDomainInMetadata, MetadataCustomCloudName, VmMetadataManufacturer, VmMetadataProductName
|
||||
AllowExposeDomainInMetadata, MetadataCustomCloudName, VmMetadataManufacturer, VmMetadataProductName,
|
||||
VmSyncPowerStateTransitioning
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -4955,20 +4965,46 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans stalled VMs in transition states on an UP host and processes them accordingly.
|
||||
*
|
||||
* <p>This method is executed only when the {@code syncTransitioningVmPowerState} flag is enabled. It identifies
|
||||
* VMs stuck in specific states (e.g., Starting, Stopping, Migrating) on a host that is UP, except for those
|
||||
* in the Expunging state, which require special handling.</p>
|
||||
*
|
||||
* <p>The following conditions are checked during the scan:
|
||||
* <ul>
|
||||
* <li>No pending {@code VmWork} job exists for the VM.</li>
|
||||
* <li>The VM is associated with the given {@code hostId}, and the host is UP.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p>When a host is UP, a state report for the VMs will typically be received. However, certain scenarios
|
||||
* (e.g., out-of-band changes or behavior specific to hypervisors like XenServer or KVM) might result in
|
||||
* missing reports, preventing the state-sync logic from running. To address this, the method scans VMs
|
||||
* based on their last update timestamp. If a VM remains stalled without a status update while its host is UP,
|
||||
* it is assumed to be powered off, which is generally a safe assumption.</p>
|
||||
*
|
||||
* @param hostId the ID of the host to scan for stalled VMs in transition states.
|
||||
*/
|
||||
private void scanStalledVMInTransitionStateOnUpHost(final long hostId) {
|
||||
final long stallThresholdInMs = VmJobStateReportInterval.value() + (VmJobStateReportInterval.value() >> 1);
|
||||
final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - stallThresholdInMs);
|
||||
final List<Long> mostlikelyStoppedVMs = listStalledVMInTransitionStateOnUpHost(hostId, cutTime);
|
||||
for (final Long vmId : mostlikelyStoppedVMs) {
|
||||
final VMInstanceVO vm = _vmDao.findById(vmId);
|
||||
assert vm != null;
|
||||
if (!syncTransitioningVmPowerState) {
|
||||
return;
|
||||
}
|
||||
if (!_hostDao.isHostUp(hostId)) {
|
||||
return;
|
||||
}
|
||||
final long stallThresholdInMs = VmJobStateReportInterval.value() * 2;
|
||||
final long cutTime = new Date(DateUtil.currentGMTTime().getTime() - stallThresholdInMs).getTime();
|
||||
final List<VMInstanceVO> hostTransitionVms = _vmDao.listByHostAndState(hostId, State.Starting, State.Stopping, State.Migrating);
|
||||
|
||||
final List<VMInstanceVO> mostLikelyStoppedVMs = listStalledVMInTransitionStateOnUpHost(hostTransitionVms, cutTime);
|
||||
for (final VMInstanceVO vm : mostLikelyStoppedVMs) {
|
||||
handlePowerOffReportWithNoPendingJobsOnVM(vm);
|
||||
}
|
||||
|
||||
final List<Long> vmsWithRecentReport = listVMInTransitionStateWithRecentReportOnUpHost(hostId, cutTime);
|
||||
for (final Long vmId : vmsWithRecentReport) {
|
||||
final VMInstanceVO vm = _vmDao.findById(vmId);
|
||||
assert vm != null;
|
||||
final List<VMInstanceVO> vmsWithRecentReport = listVMInTransitionStateWithRecentReportOnUpHost(hostTransitionVms, cutTime);
|
||||
for (final VMInstanceVO vm : vmsWithRecentReport) {
|
||||
if (vm.getPowerState() == PowerState.PowerOn) {
|
||||
handlePowerOnReportWithNoPendingJobsOnVM(vm);
|
||||
} else {
|
||||
|
|
@ -4977,6 +5013,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void scanStalledVMInTransitionStateOnDisconnectedHosts() {
|
||||
final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - VmOpWaitInterval.value() * 1000);
|
||||
final List<Long> stuckAndUncontrollableVMs = listStalledVMInTransitionStateOnDisconnectedHosts(cutTime);
|
||||
|
|
@ -4989,89 +5026,58 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
|
||||
private List<Long> listStalledVMInTransitionStateOnUpHost(final long hostId, final Date cutTime) {
|
||||
final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
|
||||
"AND h.id = ? AND i.power_state_update_time < ? AND i.host_id = h.id " +
|
||||
"AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
|
||||
"AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
|
||||
"AND i.removed IS NULL";
|
||||
|
||||
final List<Long> l = new ArrayList<>();
|
||||
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB)) {
|
||||
String cutTimeStr = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
|
||||
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
|
||||
pstmt.setLong(1, hostId);
|
||||
pstmt.setString(2, cutTimeStr);
|
||||
pstmt.setInt(3, JobInfo.Status.IN_PROGRESS.ordinal());
|
||||
final ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
l.add(rs.getLong(1));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.error("Unable to execute SQL [{}] with params {\"h.id\": {}, \"i.power_state_update_time\": \"{}\"} due to [{}].", sql, hostId, cutTimeStr, e.getMessage(), e);
|
||||
}
|
||||
private List<VMInstanceVO> listStalledVMInTransitionStateOnUpHost(
|
||||
final List<VMInstanceVO> transitioningVms, final long cutTime) {
|
||||
if (CollectionUtils.isEmpty(transitioningVms)) {
|
||||
return transitioningVms;
|
||||
}
|
||||
return l;
|
||||
List<Long> vmIdsInProgress = vmIdsInProgressCache.get();
|
||||
return transitioningVms.stream()
|
||||
.filter(v -> v.getPowerStateUpdateTime().getTime() < cutTime && !vmIdsInProgress.contains(v.getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Long> listVMInTransitionStateWithRecentReportOnUpHost(final long hostId, final Date cutTime) {
|
||||
final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
|
||||
"AND h.id = ? AND i.power_state_update_time > ? AND i.host_id = h.id " +
|
||||
"AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
|
||||
"AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
|
||||
"AND i.removed IS NULL";
|
||||
|
||||
final List<Long> l = new ArrayList<>();
|
||||
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB)) {
|
||||
String cutTimeStr = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
|
||||
int jobStatusInProgress = JobInfo.Status.IN_PROGRESS.ordinal();
|
||||
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
|
||||
pstmt.setLong(1, hostId);
|
||||
pstmt.setString(2, cutTimeStr);
|
||||
pstmt.setInt(3, jobStatusInProgress);
|
||||
final ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
l.add(rs.getLong(1));
|
||||
}
|
||||
} catch (final SQLException e) {
|
||||
logger.error("Unable to execute SQL [{}] with params {\"h.id\": {}, \"i.power_state_update_time\": \"{}\", \"j.job_status\": {}} due to [{}].", sql, hostId, cutTimeStr, jobStatusInProgress, e.getMessage(), e);
|
||||
}
|
||||
return l;
|
||||
private List<VMInstanceVO> listVMInTransitionStateWithRecentReportOnUpHost(
|
||||
final List<VMInstanceVO> transitioningVms, final long cutTime) {
|
||||
if (CollectionUtils.isEmpty(transitioningVms)) {
|
||||
return transitioningVms;
|
||||
}
|
||||
List<Long> vmIdsInProgress = vmIdsInProgressCache.get();
|
||||
return transitioningVms.stream()
|
||||
.filter(v -> v.getPowerStateUpdateTime().getTime() > cutTime && !vmIdsInProgress.contains(v.getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Long> listStalledVMInTransitionStateOnDisconnectedHosts(final Date cutTime) {
|
||||
final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " +
|
||||
"AND i.power_state_update_time < ? AND i.host_id = h.id " +
|
||||
"AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
|
||||
"AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
|
||||
"AND i.removed IS NULL";
|
||||
final String sql = "SELECT i.* " +
|
||||
"FROM vm_instance AS i " +
|
||||
"INNER JOIN host AS h ON i.host_id = h.id " +
|
||||
"WHERE h.status != 'UP' " +
|
||||
" AND i.power_state_update_time < ? " +
|
||||
" AND i.state IN ('Starting', 'Stopping', 'Migrating') " +
|
||||
" AND i.id NOT IN (SELECT vm_instance_id FROM vm_work_job AS w " +
|
||||
" INNER JOIN async_job AS j ON w.id = j.id " +
|
||||
" WHERE j.job_status = ?) " +
|
||||
" AND i.removed IS NULL";
|
||||
|
||||
final List<Long> l = new ArrayList<>();
|
||||
try (TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB)) {
|
||||
String cutTimeStr = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
|
||||
int jobStatusInProgress = JobInfo.Status.IN_PROGRESS.ordinal();
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
String cutTimeStr = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
|
||||
int jobStatusInProgress = JobInfo.Status.IN_PROGRESS.ordinal();
|
||||
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
try {
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
|
||||
pstmt.setString(1, cutTimeStr);
|
||||
pstmt.setInt(2, jobStatusInProgress);
|
||||
final ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
l.add(rs.getLong(1));
|
||||
}
|
||||
} catch (final SQLException e) {
|
||||
logger.error("Unable to execute SQL [{}] with params {\"i.power_state_update_time\": \"{}\", \"j.job_status\": {}} due to [{}].", sql, cutTimeStr, jobStatusInProgress, e.getMessage(), e);
|
||||
pstmt.setString(1, cutTimeStr);
|
||||
pstmt.setInt(2, jobStatusInProgress);
|
||||
final ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
l.add(rs.getLong(1));
|
||||
}
|
||||
return l;
|
||||
} catch (final SQLException e) {
|
||||
logger.error("Unable to execute SQL [{}] with params {\"i.power_state_update_time\": \"{}\", \"j.job_status\": {}} due to [{}].", sql, cutTimeStr, jobStatusInProgress, e.getMessage(), e);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public class VmStateSyncOutcome extends OutcomeImpl<VirtualMachine> {
|
||||
|
|
@ -5953,29 +5959,23 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) {
|
||||
public HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(Host host, List<Long> vmIds) {
|
||||
HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<>();
|
||||
if (CollectionUtils.isEmpty(vmIds)) {
|
||||
return vmStatsById;
|
||||
}
|
||||
Map<Long, VMInstanceVO> vmMap = new HashMap<>();
|
||||
for (Long vmId : vmIds) {
|
||||
vmMap.put(vmId, _vmDao.findById(vmId));
|
||||
}
|
||||
return getVirtualMachineStatistics(hostId, hostName, vmMap);
|
||||
Map<String, Long> vmMap = _vmDao.getNameIdMapForVmIds(vmIds);
|
||||
return getVirtualMachineStatistics(host, vmMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap) {
|
||||
public HashMap<Long, ? extends VmStats> getVirtualMachineStatistics(Host host, Map<String, Long> vmInstanceNameIdMap) {
|
||||
HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<>();
|
||||
if (MapUtils.isEmpty(vmMap)) {
|
||||
if (MapUtils.isEmpty(vmInstanceNameIdMap)) {
|
||||
return vmStatsById;
|
||||
}
|
||||
Map<String, Long> vmNames = new HashMap<>();
|
||||
for (Map.Entry<Long, ? extends VirtualMachine> vmEntry : vmMap.entrySet()) {
|
||||
vmNames.put(vmEntry.getValue().getInstanceName(), vmEntry.getKey());
|
||||
}
|
||||
Answer answer = _agentMgr.easySend(hostId, new GetVmStatsCommand(new ArrayList<>(vmNames.keySet()), _hostDao.findById(hostId).getGuid(), hostName));
|
||||
Answer answer = _agentMgr.easySend(host.getId(), new GetVmStatsCommand(
|
||||
new ArrayList<>(vmInstanceNameIdMap.keySet()), host.getGuid(), host.getName()));
|
||||
if (answer == null || !answer.getResult()) {
|
||||
logger.warn("Unable to obtain VM statistics.");
|
||||
return vmStatsById;
|
||||
|
|
@ -5986,23 +5986,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return vmStatsById;
|
||||
}
|
||||
for (Map.Entry<String, VmStatsEntry> entry : vmStatsByName.entrySet()) {
|
||||
vmStatsById.put(vmNames.get(entry.getKey()), entry.getValue());
|
||||
vmStatsById.put(vmInstanceNameIdMap.get(entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return vmStatsById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, List<? extends VmDiskStats>> getVmDiskStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap) {
|
||||
public HashMap<Long, List<? extends VmDiskStats>> getVmDiskStatistics(Host host, Map<String, Long> vmInstanceNameIdMap) {
|
||||
HashMap<Long, List<? extends VmDiskStats>> vmDiskStatsById = new HashMap<>();
|
||||
if (MapUtils.isEmpty(vmMap)) {
|
||||
if (MapUtils.isEmpty(vmInstanceNameIdMap)) {
|
||||
return vmDiskStatsById;
|
||||
}
|
||||
Map<String, Long> vmNames = new HashMap<>();
|
||||
for (Map.Entry<Long, ? extends VirtualMachine> vmEntry : vmMap.entrySet()) {
|
||||
vmNames.put(vmEntry.getValue().getInstanceName(), vmEntry.getKey());
|
||||
}
|
||||
Answer answer = _agentMgr.easySend(hostId, new GetVmDiskStatsCommand(new ArrayList<>(vmNames.keySet()), _hostDao.findById(hostId).getGuid(), hostName));
|
||||
Answer answer = _agentMgr.easySend(host.getId(), new GetVmDiskStatsCommand(
|
||||
new ArrayList<>(vmInstanceNameIdMap.keySet()), host.getGuid(), host.getName()));
|
||||
if (answer == null || !answer.getResult()) {
|
||||
logger.warn("Unable to obtain VM disk statistics.");
|
||||
return vmDiskStatsById;
|
||||
|
|
@ -6013,23 +6010,20 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return vmDiskStatsById;
|
||||
}
|
||||
for (Map.Entry<String, List<VmDiskStatsEntry>> entry: vmDiskStatsByName.entrySet()) {
|
||||
vmDiskStatsById.put(vmNames.get(entry.getKey()), entry.getValue());
|
||||
vmDiskStatsById.put(vmInstanceNameIdMap.get(entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return vmDiskStatsById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(long hostId, String hostName, Map<Long, ? extends VirtualMachine> vmMap) {
|
||||
public HashMap<Long, List<? extends VmNetworkStats>> getVmNetworkStatistics(Host host, Map<String, Long> vmInstanceNameIdMap) {
|
||||
HashMap<Long, List<? extends VmNetworkStats>> vmNetworkStatsById = new HashMap<>();
|
||||
if (MapUtils.isEmpty(vmMap)) {
|
||||
if (MapUtils.isEmpty(vmInstanceNameIdMap)) {
|
||||
return vmNetworkStatsById;
|
||||
}
|
||||
Map<String, Long> vmNames = new HashMap<>();
|
||||
for (Map.Entry<Long, ? extends VirtualMachine> vmEntry : vmMap.entrySet()) {
|
||||
vmNames.put(vmEntry.getValue().getInstanceName(), vmEntry.getKey());
|
||||
}
|
||||
Answer answer = _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(new ArrayList<>(vmNames.keySet()), _hostDao.findById(hostId).getGuid(), hostName));
|
||||
Answer answer = _agentMgr.easySend(host.getId(), new GetVmNetworkStatsCommand(
|
||||
new ArrayList<>(vmInstanceNameIdMap.keySet()), host.getGuid(), host.getName()));
|
||||
if (answer == null || !answer.getResult()) {
|
||||
logger.warn("Unable to obtain VM network statistics.");
|
||||
return vmNetworkStatsById;
|
||||
|
|
@ -6040,7 +6034,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return vmNetworkStatsById;
|
||||
}
|
||||
for (Map.Entry<String, List<VmNetworkStatsEntry>> entry: vmNetworkStatsByName.entrySet()) {
|
||||
vmNetworkStatsById.put(vmNames.get(entry.getKey()), entry.getValue());
|
||||
vmNetworkStatsById.put(vmInstanceNameIdMap.get(entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
return vmNetworkStatsById;
|
||||
|
|
|
|||
|
|
@ -16,27 +16,29 @@
|
|||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.cloudstack.utils.cache.LazyCache;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.HostVmStateReportEntry;
|
||||
import com.cloud.configuration.ManagementServiceConfiguration;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStateSync {
|
||||
|
|
@ -47,7 +49,12 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
|
|||
@Inject HostDao hostDao;
|
||||
@Inject ManagementServiceConfiguration mgmtServiceConf;
|
||||
|
||||
private LazyCache<Long, VMInstanceVO> vmCache;
|
||||
private LazyCache<Long, HostVO> hostCache;
|
||||
|
||||
public VirtualMachinePowerStateSyncImpl() {
|
||||
vmCache = new LazyCache<>(16, 10, this::getVmFromId);
|
||||
hostCache = new LazyCache<>(16, 10, this::getHostFromId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -58,130 +65,141 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
|
|||
|
||||
@Override
|
||||
public void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report) {
|
||||
HostVO host = hostDao.findById(hostId);
|
||||
logger.debug("Process host VM state report. host: {}", host);
|
||||
|
||||
Map<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> translatedInfo = convertVmStateReport(report);
|
||||
processReport(host, translatedInfo, false);
|
||||
logger.debug("Process host VM state report. host: {}", hostCache.get(hostId));
|
||||
Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
|
||||
processReport(hostId, translatedInfo, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report, boolean force) {
|
||||
HostVO host = hostDao.findById(hostId);
|
||||
logger.debug("Process host VM state report from ping process. host: {}", host);
|
||||
|
||||
Map<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> translatedInfo = convertVmStateReport(report);
|
||||
processReport(host, translatedInfo, force);
|
||||
logger.debug("Process host VM state report from ping process. host: {}", hostCache.get(hostId));
|
||||
Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
|
||||
processReport(hostId, translatedInfo, force);
|
||||
}
|
||||
|
||||
private void processReport(HostVO host, Map<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> translatedInfo, boolean force) {
|
||||
|
||||
logger.debug("Process VM state report. host: {}, number of records in report: {}.", host, translatedInfo.size());
|
||||
|
||||
for (Map.Entry<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> entry : translatedInfo.entrySet()) {
|
||||
|
||||
logger.debug("VM state report. host: {}, vm: {}, power state: {}", host, entry.getValue().second(), entry.getValue().first());
|
||||
|
||||
if (_instanceDao.updatePowerState(entry.getKey(), host.getId(), entry.getValue().first(), DateUtil.currentGMTTime())) {
|
||||
logger.debug("VM state report is updated. host: {}, vm: {}, power state: {}", host, entry.getValue().second(), entry.getValue().first());
|
||||
|
||||
_messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, entry.getKey());
|
||||
} else {
|
||||
logger.trace("VM power state does not change, skip DB writing. vm: {}", entry.getValue().second());
|
||||
}
|
||||
private void updateAndPublishVmPowerStates(long hostId, Map<Long, VirtualMachine.PowerState> instancePowerStates,
|
||||
Date updateTime) {
|
||||
if (instancePowerStates.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Long> vmIds = instancePowerStates.keySet();
|
||||
Map<Long, VirtualMachine.PowerState> notUpdated = _instanceDao.updatePowerState(instancePowerStates, hostId,
|
||||
updateTime);
|
||||
if (notUpdated.size() > vmIds.size()) {
|
||||
return;
|
||||
}
|
||||
for (Long vmId : vmIds) {
|
||||
if (!notUpdated.isEmpty() && !notUpdated.containsKey(vmId)) {
|
||||
logger.debug("VM state report is updated. {}, {}, power state: {}",
|
||||
() -> hostCache.get(hostId), () -> vmCache.get(vmId), () -> instancePowerStates.get(vmId));
|
||||
_messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE,
|
||||
PublishScope.GLOBAL, vmId);
|
||||
continue;
|
||||
}
|
||||
logger.trace("VM power state does not change, skip DB writing. {}", () -> vmCache.get(vmId));
|
||||
}
|
||||
}
|
||||
|
||||
private List<VMInstanceVO> filterOutdatedFromMissingVmReport(List<VMInstanceVO> vmsThatAreMissingReport) {
|
||||
List<Long> outdatedVms = vmsThatAreMissingReport.stream()
|
||||
.filter(v -> !_instanceDao.isPowerStateUpToDate(v))
|
||||
.map(VMInstanceVO::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(outdatedVms)) {
|
||||
return vmsThatAreMissingReport;
|
||||
}
|
||||
_instanceDao.resetVmPowerStateTracking(outdatedVms);
|
||||
return vmsThatAreMissingReport.stream()
|
||||
.filter(v -> !outdatedVms.contains(v.getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void processMissingVmReport(long hostId, Set<Long> vmIds, boolean force) {
|
||||
// any state outdates should be checked against the time before this list was retrieved
|
||||
Date startTime = DateUtil.currentGMTTime();
|
||||
// for all running/stopping VMs, we provide monitoring of missing report
|
||||
List<VMInstanceVO> vmsThatAreMissingReport = _instanceDao.findByHostInStates(host.getId(), VirtualMachine.State.Running,
|
||||
VirtualMachine.State.Stopping, VirtualMachine.State.Starting);
|
||||
java.util.Iterator<VMInstanceVO> it = vmsThatAreMissingReport.iterator();
|
||||
while (it.hasNext()) {
|
||||
VMInstanceVO instance = it.next();
|
||||
if (translatedInfo.get(instance.getId()) != null)
|
||||
it.remove();
|
||||
List<VMInstanceVO> vmsThatAreMissingReport = _instanceDao.findByHostInStatesExcluding(hostId, vmIds,
|
||||
VirtualMachine.State.Running, VirtualMachine.State.Stopping, VirtualMachine.State.Starting);
|
||||
// here we need to be wary of out of band migration as opposed to other, more unexpected state changes
|
||||
if (vmsThatAreMissingReport.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Date currentTime = DateUtil.currentGMTTime();
|
||||
logger.debug("Run missing VM report. current time: {}", currentTime.getTime());
|
||||
if (!force) {
|
||||
vmsThatAreMissingReport = filterOutdatedFromMissingVmReport(vmsThatAreMissingReport);
|
||||
}
|
||||
|
||||
// here we need to be wary of out of band migration as opposed to other, more unexpected state changes
|
||||
if (vmsThatAreMissingReport.size() > 0) {
|
||||
Date currentTime = DateUtil.currentGMTTime();
|
||||
logger.debug("Run missing VM report for host {}. current time: {}", host, currentTime.getTime());
|
||||
|
||||
// 2 times of sync-update interval for graceful period
|
||||
long milliSecondsGracefullPeriod = mgmtServiceConf.getPingInterval() * 2000L;
|
||||
|
||||
for (VMInstanceVO instance : vmsThatAreMissingReport) {
|
||||
|
||||
// Make sure powerState is up to date for missing VMs
|
||||
try {
|
||||
if (!force && !_instanceDao.isPowerStateUpToDate(instance.getId())) {
|
||||
logger.warn("Detected missing VM but power state is outdated, wait for another process report run for VM: {}", instance);
|
||||
_instanceDao.resetVmPowerStateTracking(instance.getId());
|
||||
continue;
|
||||
}
|
||||
} catch (CloudRuntimeException e) {
|
||||
logger.warn("Checked for missing powerstate of a none existing vm {}", instance, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
Date vmStateUpdateTime = instance.getPowerStateUpdateTime();
|
||||
// 2 times of sync-update interval for graceful period
|
||||
long milliSecondsGracefulPeriod = mgmtServiceConf.getPingInterval() * 2000L;
|
||||
Map<Long, VirtualMachine.PowerState> instancePowerStates = new HashMap<>();
|
||||
for (VMInstanceVO instance : vmsThatAreMissingReport) {
|
||||
Date vmStateUpdateTime = instance.getPowerStateUpdateTime();
|
||||
if (vmStateUpdateTime == null) {
|
||||
logger.warn("VM power state update time is null, falling back to update time for {}", instance);
|
||||
vmStateUpdateTime = instance.getUpdateTime();
|
||||
if (vmStateUpdateTime == null) {
|
||||
logger.warn("VM power state update time is null, falling back to update time for vm: {}", instance);
|
||||
vmStateUpdateTime = instance.getUpdateTime();
|
||||
if (vmStateUpdateTime == null) {
|
||||
logger.warn("VM update time is null, falling back to creation time for vm: {}", instance);
|
||||
vmStateUpdateTime = instance.getCreated();
|
||||
}
|
||||
}
|
||||
|
||||
String lastTime = new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS'Z'").format(vmStateUpdateTime);
|
||||
logger.debug("Detected missing VM. host: {}, vm: {}, power state: {}, last state update: {}",
|
||||
host, instance, VirtualMachine.PowerState.PowerReportMissing, lastTime);
|
||||
|
||||
long milliSecondsSinceLastStateUpdate = currentTime.getTime() - vmStateUpdateTime.getTime();
|
||||
|
||||
if (force || milliSecondsSinceLastStateUpdate > milliSecondsGracefullPeriod) {
|
||||
logger.debug("vm: {} - time since last state update({}ms) has passed graceful period", instance, milliSecondsSinceLastStateUpdate);
|
||||
|
||||
// this is were a race condition might have happened if we don't re-fetch the instance;
|
||||
// between the startime of this job and the currentTime of this missing-branch
|
||||
// an update might have occurred that we should not override in case of out of band migration
|
||||
if (_instanceDao.updatePowerState(instance.getId(), host.getId(), VirtualMachine.PowerState.PowerReportMissing, startTime)) {
|
||||
logger.debug("VM state report is updated. host: {}, vm: {}, power state: PowerReportMissing ", host, instance);
|
||||
|
||||
_messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, instance.getId());
|
||||
} else {
|
||||
logger.debug("VM power state does not change, skip DB writing. vm: {}", instance);
|
||||
}
|
||||
} else {
|
||||
logger.debug("vm: {} - time since last state update({} ms) has not passed graceful period yet", instance, milliSecondsSinceLastStateUpdate);
|
||||
logger.warn("VM update time is null, falling back to creation time for {}", instance);
|
||||
vmStateUpdateTime = instance.getCreated();
|
||||
}
|
||||
}
|
||||
logger.debug("Detected missing VM. host: {}, vm id: {}({}), power state: {}, last state update: {}",
|
||||
hostId,
|
||||
instance.getId(),
|
||||
instance.getUuid(),
|
||||
VirtualMachine.PowerState.PowerReportMissing,
|
||||
DateUtil.getOutputString(vmStateUpdateTime));
|
||||
long milliSecondsSinceLastStateUpdate = currentTime.getTime() - vmStateUpdateTime.getTime();
|
||||
if (force || (milliSecondsSinceLastStateUpdate > milliSecondsGracefulPeriod)) {
|
||||
logger.debug("vm id: {} - time since last state update({} ms) has passed graceful period",
|
||||
instance.getId(), milliSecondsSinceLastStateUpdate);
|
||||
// this is where a race condition might have happened if we don't re-fetch the instance;
|
||||
// between the startime of this job and the currentTime of this missing-branch
|
||||
// an update might have occurred that we should not override in case of out of band migration
|
||||
instancePowerStates.put(instance.getId(), VirtualMachine.PowerState.PowerReportMissing);
|
||||
} else {
|
||||
logger.debug("vm id: {} - time since last state update({} ms) has not passed graceful period yet",
|
||||
instance.getId(), milliSecondsSinceLastStateUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Done with process of VM state report. host: {}", host);
|
||||
updateAndPublishVmPowerStates(hostId, instancePowerStates, startTime);
|
||||
}
|
||||
|
||||
public Map<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> convertVmStateReport(Map<String, HostVmStateReportEntry> states) {
|
||||
final HashMap<Long, Pair<VirtualMachine.PowerState, VMInstanceVO>> map = new HashMap<>();
|
||||
if (states == null) {
|
||||
private void processReport(long hostId, Map<Long, VirtualMachine.PowerState> translatedInfo, boolean force) {
|
||||
logger.debug("Process VM state report. {}, number of records in report: {}. VMs: [{}]",
|
||||
() -> hostCache.get(hostId),
|
||||
translatedInfo::size,
|
||||
() -> translatedInfo.entrySet().stream().map(entry -> entry.getKey() + ":" + entry.getValue())
|
||||
.collect(Collectors.joining(", ")) + "]");
|
||||
updateAndPublishVmPowerStates(hostId, translatedInfo, DateUtil.currentGMTTime());
|
||||
|
||||
processMissingVmReport(hostId, translatedInfo.keySet(), force);
|
||||
|
||||
logger.debug("Done with process of VM state report. host: {}", () -> hostCache.get(hostId));
|
||||
}
|
||||
|
||||
public Map<Long, VirtualMachine.PowerState> convertVmStateReport(Map<String, HostVmStateReportEntry> states) {
|
||||
final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<>();
|
||||
if (MapUtils.isEmpty(states)) {
|
||||
return map;
|
||||
}
|
||||
|
||||
Map<String, Long> nameIdMap = _instanceDao.getNameIdMapForVmInstanceNames(states.keySet());
|
||||
for (Map.Entry<String, HostVmStateReportEntry> entry : states.entrySet()) {
|
||||
VMInstanceVO vm = findVM(entry.getKey());
|
||||
if (vm != null) {
|
||||
map.put(vm.getId(), new Pair<>(entry.getValue().getState(), vm));
|
||||
Long id = nameIdMap.get(entry.getKey());
|
||||
if (id != null) {
|
||||
map.put(id, entry.getValue().getState());
|
||||
} else {
|
||||
logger.debug("Unable to find matched VM in CloudStack DB. name: {} powerstate: {}", entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private VMInstanceVO findVM(String vmName) {
|
||||
return _instanceDao.findVMByInstanceName(vmName);
|
||||
protected VMInstanceVO getVmFromId(long vmId) {
|
||||
return _instanceDao.findById(vmId);
|
||||
}
|
||||
|
||||
protected HostVO getHostFromId(long hostId) {
|
||||
return hostDao.findById(hostId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4872,7 +4872,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
|
||||
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, DeniedRoutes,
|
||||
GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
|
||||
PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RollingRestartEnabled,
|
||||
TUNGSTEN_ENABLED, NSX_ENABLED };
|
||||
|
|
|
|||
|
|
@ -1807,7 +1807,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
try {
|
||||
volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
|
||||
} catch (Exception e) {
|
||||
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host));
|
||||
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1847,7 +1847,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
try {
|
||||
volService.grantAccess(volFactory.getVolume(volumeId), host, volumeStore);
|
||||
} catch (Exception e) {
|
||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
|
||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1928,7 +1928,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
try {
|
||||
volService.grantAccess(volFactory.getVolume(vol.getId()), host, store);
|
||||
} catch (Exception e) {
|
||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
|
||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
|
||||
}
|
||||
} else {
|
||||
grantVolumeAccessToHostIfNeeded(store, vol.getId(), host, volToString);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import com.cloud.utils.db.GenericDao;
|
|||
public interface CapacityDao extends GenericDao<CapacityVO, Long> {
|
||||
CapacityVO findByHostIdType(Long hostId, short capacityType);
|
||||
|
||||
List<CapacityVO> listByHostIdTypes(Long hostId, List<Short> capacityTypes);
|
||||
|
||||
List<Long> listClustersInZoneOrPodByHostCapacities(long id, long vmId, int requiredCpu, long requiredRam, short capacityTypeForOrdering, boolean isZone);
|
||||
|
||||
List<Long> listHostsWithEnoughCapacity(int requiredCpu, long requiredRam, Long clusterId, String hostType);
|
||||
|
|
|
|||
|
|
@ -671,6 +671,18 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
|
|||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CapacityVO> listByHostIdTypes(Long hostId, List<Short> capacityTypes) {
|
||||
SearchBuilder<CapacityVO> sb = createSearchBuilder();
|
||||
sb.and("hostId", sb.entity().getHostOrPoolId(), SearchCriteria.Op.EQ);
|
||||
sb.and("type", sb.entity().getCapacityType(), SearchCriteria.Op.IN);
|
||||
sb.done();
|
||||
SearchCriteria<CapacityVO> sc = sb.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
sc.setParameters("type", capacityTypes.toArray());
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listClustersInZoneOrPodByHostCapacities(long id, long vmId, int requiredCpu, long requiredRam, short capacityTypeForOrdering, boolean isZone) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@
|
|||
// under the License.
|
||||
package com.cloud.dc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||
|
||||
public interface ClusterDetailsDao extends GenericDao<ClusterDetailsVO, Long> {
|
||||
public interface ClusterDetailsDao extends GenericDao<ClusterDetailsVO, Long>, ResourceDetailsDao<ClusterDetailsVO> {
|
||||
Map<String, String> findDetails(long clusterId);
|
||||
|
||||
void persist(long clusterId, Map<String, String> details);
|
||||
|
|
@ -29,6 +31,8 @@ public interface ClusterDetailsDao extends GenericDao<ClusterDetailsVO, Long> {
|
|||
|
||||
ClusterDetailsVO findDetail(long clusterId, String name);
|
||||
|
||||
Map<String, String> findDetails(long clusterId, Collection<String> names);
|
||||
|
||||
void deleteDetails(long clusterId);
|
||||
|
||||
String getVmwareDcName(Long clusterId);
|
||||
|
|
|
|||
|
|
@ -16,21 +16,33 @@
|
|||
// under the License.
|
||||
package com.cloud.dc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||
|
||||
public class ClusterDetailsDaoImpl extends ResourceDetailsDaoBase<ClusterDetailsVO> implements ClusterDetailsDao, ScopedConfigStorage {
|
||||
|
||||
@Inject
|
||||
ClusterDao clusterDao;
|
||||
|
||||
public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long> implements ClusterDetailsDao, ScopedConfigStorage {
|
||||
protected final SearchBuilder<ClusterDetailsVO> ClusterSearch;
|
||||
protected final SearchBuilder<ClusterDetailsVO> DetailSearch;
|
||||
|
||||
|
|
@ -41,11 +53,11 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||
|
||||
protected ClusterDetailsDaoImpl() {
|
||||
ClusterSearch = createSearchBuilder();
|
||||
ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
ClusterSearch.and("clusterId", ClusterSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
ClusterSearch.done();
|
||||
|
||||
DetailSearch = createSearchBuilder();
|
||||
DetailSearch.and("clusterId", DetailSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("clusterId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.done();
|
||||
}
|
||||
|
|
@ -65,6 +77,11 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||
return detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||
super.addDetail(new ClusterDetailsVO(resourceId, key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long clusterId) {
|
||||
SearchCriteria<ClusterDetailsVO> sc = ClusterSearch.create();
|
||||
|
|
@ -82,6 +99,23 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long clusterId, Collection<String> names) {
|
||||
if (CollectionUtils.isEmpty(names)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
SearchBuilder<ClusterDetailsVO> sb = createSearchBuilder();
|
||||
sb.and("clusterId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
sb.and("name", sb.entity().getName(), SearchCriteria.Op.IN);
|
||||
sb.done();
|
||||
SearchCriteria<ClusterDetailsVO> sc = sb.create();
|
||||
sc.setParameters("clusterId", clusterId);
|
||||
sc.setParameters("name", names.toArray());
|
||||
List<ClusterDetailsVO> results = search(sc, null);
|
||||
return results.stream()
|
||||
.collect(Collectors.toMap(ClusterDetailsVO::getName, ClusterDetailsVO::getValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long clusterId) {
|
||||
SearchCriteria<ClusterDetailsVO> sc = ClusterSearch.create();
|
||||
|
|
@ -160,4 +194,13 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Scope, Long> getParentScope(long id) {
|
||||
Cluster cluster = clusterDao.findById(id);
|
||||
if (cluster == null) {
|
||||
return null;
|
||||
}
|
||||
return new Pair<>(getScope().getParent(), cluster.getDataCenterId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
|
||||
@Entity
|
||||
@Table(name = "cluster_details")
|
||||
public class ClusterDetailsVO implements InternalIdentity {
|
||||
public class ClusterDetailsVO implements ResourceDetail {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
@ -35,7 +35,7 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||
private long id;
|
||||
|
||||
@Column(name = "cluster_id")
|
||||
private long clusterId;
|
||||
private long resourceId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
|
@ -47,13 +47,14 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||
}
|
||||
|
||||
public ClusterDetailsVO(long clusterId, String name, String value) {
|
||||
this.clusterId = clusterId;
|
||||
this.resourceId = clusterId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getClusterId() {
|
||||
return clusterId;
|
||||
@Override
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -64,6 +65,11 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,15 @@
|
|||
// under the License.
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
||||
List<ClusterVO> listByPodId(long podId);
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
|||
|
||||
List<HypervisorType> getAvailableHypervisorInZone(Long zoneId);
|
||||
|
||||
Set<HypervisorType> getDistictAvailableHypervisorsAcrossClusters();
|
||||
Set<HypervisorType> getDistinctAvailableHypervisorsAcrossClusters();
|
||||
|
||||
List<ClusterVO> listByDcHyType(long dcId, String hyType);
|
||||
|
||||
|
|
@ -46,9 +46,13 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
|
|||
|
||||
List<Long> listClustersWithDisabledPods(long zoneId);
|
||||
|
||||
Integer countAllByDcId(long zoneId);
|
||||
|
||||
Integer countAllManagedAndEnabledByDcId(long zoneId);
|
||||
|
||||
List<ClusterVO> listClustersByDcId(long zoneId);
|
||||
|
||||
List<Long> listAllClusters(Long zoneId);
|
||||
List<Long> listAllClusterIds(Long zoneId);
|
||||
|
||||
boolean getSupportsResigning(long clusterId);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,25 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
|
@ -46,6 +27,28 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.org.Managed;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements ClusterDao {
|
||||
|
||||
|
|
@ -58,7 +61,6 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
protected final SearchBuilder<ClusterVO> ClusterSearch;
|
||||
protected final SearchBuilder<ClusterVO> ClusterDistinctArchSearch;
|
||||
protected final SearchBuilder<ClusterVO> ClusterArchSearch;
|
||||
|
||||
protected GenericSearchBuilder<ClusterVO, Long> ClusterIdSearch;
|
||||
|
||||
private static final String GET_POD_CLUSTER_MAP_PREFIX = "SELECT pod_id, id FROM cloud.cluster WHERE cluster.id IN( ";
|
||||
|
|
@ -98,6 +100,8 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
|
||||
ZoneClusterSearch = createSearchBuilder();
|
||||
ZoneClusterSearch.and("dataCenterId", ZoneClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
ZoneClusterSearch.and("allocationState", ZoneClusterSearch.entity().getAllocationState(), Op.EQ);
|
||||
ZoneClusterSearch.and("managedState", ZoneClusterSearch.entity().getManagedState(), Op.EQ);
|
||||
ZoneClusterSearch.done();
|
||||
|
||||
ClusterIdSearch = createSearchBuilder(Long.class);
|
||||
|
|
@ -167,23 +171,15 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
List<ClusterVO> clusters = listBy(sc);
|
||||
List<HypervisorType> hypers = new ArrayList<HypervisorType>(4);
|
||||
for (ClusterVO cluster : clusters) {
|
||||
hypers.add(cluster.getHypervisorType());
|
||||
}
|
||||
|
||||
return hypers;
|
||||
return clusters.stream()
|
||||
.map(ClusterVO::getHypervisorType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<HypervisorType> getDistictAvailableHypervisorsAcrossClusters() {
|
||||
SearchCriteria<ClusterVO> sc = ClusterSearch.create();
|
||||
List<ClusterVO> clusters = listBy(sc);
|
||||
Set<HypervisorType> hypers = new HashSet<>();
|
||||
for (ClusterVO cluster : clusters) {
|
||||
hypers.add(cluster.getHypervisorType());
|
||||
}
|
||||
return hypers;
|
||||
public Set<HypervisorType> getDistinctAvailableHypervisorsAcrossClusters() {
|
||||
return new HashSet<>(getAvailableHypervisorInZone(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -266,6 +262,23 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer countAllByDcId(long zoneId) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneClusterSearch.create();
|
||||
sc.setParameters("dataCenterId", zoneId);
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer countAllManagedAndEnabledByDcId(long zoneId) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneClusterSearch.create();
|
||||
sc.setParameters("dataCenterId", zoneId);
|
||||
sc.setParameters("allocationState", Grouping.AllocationState.Enabled);
|
||||
sc.setParameters("managedState", Managed.ManagedState.Managed);
|
||||
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClusterVO> listClustersByDcId(long zoneId) {
|
||||
SearchCriteria<ClusterVO> sc = ZoneClusterSearch.create();
|
||||
|
|
@ -289,7 +302,7 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listAllClusters(Long zoneId) {
|
||||
public List<Long> listAllClusterIds(Long zoneId) {
|
||||
SearchCriteria<Long> sc = ClusterIdSearch.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("dataCenterId", zoneId);
|
||||
|
|
|
|||
|
|
@ -294,8 +294,7 @@ public class DataCenterIpAddressDaoImpl extends GenericDaoBase<DataCenterIpAddre
|
|||
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
|
||||
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
|
||||
|
||||
List<DataCenterIpAddressVO> result = listBy(sc);
|
||||
return result.size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
public DataCenterIpAddressDaoImpl() {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
|
|||
public int countAllocatedVnets(long physicalNetworkId) {
|
||||
SearchCriteria<DataCenterVnetVO> sc = DcSearchAllocated.create();
|
||||
sc.setParameters("physicalNetworkId", physicalNetworkId);
|
||||
return listBy(sc).size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
|
||||
@Entity
|
||||
@Table(name = "domain_details")
|
||||
public class DomainDetailVO implements InternalIdentity {
|
||||
public class DomainDetailVO implements ResourceDetail {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private long domainId;
|
||||
private long resourceId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
|
@ -46,13 +46,14 @@ public class DomainDetailVO implements InternalIdentity {
|
|||
}
|
||||
|
||||
public DomainDetailVO(long domainId, String name, String value) {
|
||||
this.domainId = domainId;
|
||||
this.resourceId = domainId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
@Override
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -63,6 +64,11 @@ public class DomainDetailVO implements InternalIdentity {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ import java.util.Map;
|
|||
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||
|
||||
public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long> {
|
||||
public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long>, ResourceDetailsDao<DomainDetailVO> {
|
||||
Map<String, String> findDetails(long domainId);
|
||||
|
||||
void persist(long domainId, Map<String, String> details);
|
||||
|
|
@ -31,6 +32,4 @@ public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long> {
|
|||
void deleteDetails(long domainId);
|
||||
|
||||
void update(long domainId, Map<String, String> details);
|
||||
|
||||
String getActualValue(DomainDetailVO domainDetailVO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,19 +25,17 @@ import javax.inject.Inject;
|
|||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||
|
||||
public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> implements DomainDetailsDao, ScopedConfigStorage {
|
||||
public class DomainDetailsDaoImpl extends ResourceDetailsDaoBase<DomainDetailVO> implements DomainDetailsDao, ScopedConfigStorage {
|
||||
protected final SearchBuilder<DomainDetailVO> domainSearch;
|
||||
|
||||
@Inject
|
||||
|
|
@ -47,14 +45,14 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||
|
||||
protected DomainDetailsDaoImpl() {
|
||||
domainSearch = createSearchBuilder();
|
||||
domainSearch.and("domainId", domainSearch.entity().getDomainId(), Op.EQ);
|
||||
domainSearch.and("domainId", domainSearch.entity().getResourceId(), Op.EQ);
|
||||
domainSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long domainId) {
|
||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
||||
sc.and(sc.entity().getResourceId(), Op.EQ, domainId);
|
||||
List<DomainDetailVO> results = sc.list();
|
||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||
for (DomainDetailVO r : results) {
|
||||
|
|
@ -80,11 +78,16 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||
@Override
|
||||
public DomainDetailVO findDetail(long domainId, String name) {
|
||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
||||
sc.and(sc.entity().getResourceId(), Op.EQ, domainId);
|
||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||
super.addDetail(new DomainDetailVO(resourceId, key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long domainId) {
|
||||
SearchCriteria<DomainDetailVO> sc = domainSearch.create();
|
||||
|
|
@ -129,13 +132,4 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||
}
|
||||
return vo == null ? null : getActualValue(vo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActualValue(DomainDetailVO domainDetailVO) {
|
||||
ConfigurationVO configurationVO = _configDao.findByName(domainDetailVO.getName());
|
||||
if (configurationVO != null && configurationVO.isEncrypted()) {
|
||||
return DBEncryptionUtil.decrypt(domainDetailVO.getValue());
|
||||
}
|
||||
return domainDetailVO.getValue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import com.cloud.hypervisor.Hypervisor;
|
|||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.info.RunningHostCountInfo;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
|
||||
|
|
@ -39,8 +40,14 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
|||
|
||||
Integer countAllByType(final Host.Type type);
|
||||
|
||||
Integer countAllInClusterByTypeAndStates(Long clusterId, final Host.Type type, List<Status> status);
|
||||
|
||||
Integer countAllByTypeInZone(long zoneId, final Host.Type type);
|
||||
|
||||
Integer countUpAndEnabledHostsInZone(long zoneId);
|
||||
|
||||
Pair<Integer, Integer> countAllHostsAndCPUSocketsByType(Type type);
|
||||
|
||||
/**
|
||||
* Mark all hosts associated with a certain management server
|
||||
* as disconnected.
|
||||
|
|
@ -75,32 +82,41 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
|||
|
||||
List<HostVO> findHypervisorHostInCluster(long clusterId);
|
||||
|
||||
HostVO findAnyStateHypervisorHostInCluster(long clusterId);
|
||||
|
||||
HostVO findOldestExistentHypervisorHostInCluster(long clusterId);
|
||||
|
||||
List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag);
|
||||
|
||||
List<HostVO> findByDataCenterId(Long zoneId);
|
||||
|
||||
List<Long> listIdsByDataCenterId(Long zoneId);
|
||||
|
||||
List<HostVO> findByPodId(Long podId);
|
||||
|
||||
List<Long> listIdsByPodId(Long podId);
|
||||
|
||||
List<HostVO> findByClusterId(Long clusterId);
|
||||
|
||||
List<Long> listIdsByClusterId(Long clusterId);
|
||||
|
||||
List<Long> listIdsForUpRouting(Long zoneId, Long podId, Long clusterId);
|
||||
|
||||
List<Long> listIdsByType(Type type);
|
||||
|
||||
List<Long> listIdsForUpEnabledByZoneAndHypervisor(Long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
List<HostVO> findByClusterIdAndEncryptionSupport(Long clusterId);
|
||||
|
||||
/**
|
||||
* Returns hosts that are 'Up' and 'Enabled' from the given Data Center/Zone
|
||||
* Returns host Ids that are 'Up' and 'Enabled' from the given Data Center/Zone
|
||||
*/
|
||||
List<HostVO> listByDataCenterId(long id);
|
||||
List<Long> listEnabledIdsByDataCenterId(long id);
|
||||
|
||||
/**
|
||||
* Returns hosts that are from the given Data Center/Zone and at a given state (e.g. Creating, Enabled, Disabled, etc).
|
||||
* Returns host Ids that are 'Up' and 'Disabled' from the given Data Center/Zone
|
||||
*/
|
||||
List<HostVO> listByDataCenterIdAndState(long id, ResourceState state);
|
||||
|
||||
/**
|
||||
* Returns hosts that are 'Up' and 'Disabled' from the given Data Center/Zone
|
||||
*/
|
||||
List<HostVO> listDisabledByDataCenterId(long id);
|
||||
List<Long> listDisabledIdsByDataCenterId(long id);
|
||||
|
||||
List<HostVO> listByDataCenterIdAndHypervisorType(long zoneId, Hypervisor.HypervisorType hypervisorType);
|
||||
|
||||
|
|
@ -110,8 +126,6 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
|||
|
||||
List<HostVO> listAllHostsThatHaveNoRuleTag(Host.Type type, Long clusterId, Long podId, Long dcId);
|
||||
|
||||
List<HostVO> listAllHostsByType(Host.Type type);
|
||||
|
||||
HostVO findByPublicIp(String publicIp);
|
||||
|
||||
List<Long> listClustersByHostTag(String hostTagOnOffering);
|
||||
|
|
@ -182,4 +196,14 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
|
|||
List<Long> findClustersThatMatchHostTagRule(String computeOfferingTags);
|
||||
|
||||
List<Long> listSsvmHostsWithPendingMigrateJobsOrderedByJobCount();
|
||||
|
||||
boolean isHostUp(long hostId);
|
||||
|
||||
List<Long> findHostIdsByZoneClusterResourceStateTypeAndHypervisorType(final Long zoneId, final Long clusterId,
|
||||
final List<ResourceState> resourceStates, final List<Type> types,
|
||||
final List<Hypervisor.HypervisorType> hypervisorTypes);
|
||||
|
||||
List<HypervisorType> listDistinctHypervisorTypes(final Long zoneId);
|
||||
|
||||
List<HostVO> listByIds(final List<Long> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -45,8 +46,8 @@ import com.cloud.dc.ClusterVO;
|
|||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
||||
import com.cloud.gpu.dao.VGPUTypesDao;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.DetailVO;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.host.HostTagVO;
|
||||
import com.cloud.host.HostVO;
|
||||
|
|
@ -59,6 +60,8 @@ import com.cloud.org.Grouping;
|
|||
import com.cloud.org.Managed;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.db.Attribute;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
|
|
@ -74,19 +77,17 @@ import com.cloud.utils.db.TransactionLegacy;
|
|||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@DB
|
||||
@TableGenerator(name = "host_req_sq", table = "op_host", pkColumnName = "id", valueColumnName = "sequence", allocationSize = 1)
|
||||
public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao { //FIXME: , ExternalIdDao {
|
||||
|
||||
private static final String LIST_HOST_IDS_BY_COMPUTETAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
|
||||
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag) AS filtered "
|
||||
+ "WHERE tag IN(%s) AND is_tag_a_rule = 0 "
|
||||
private static final String LIST_HOST_IDS_BY_HOST_TAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
|
||||
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag,is_tag_a_rule) AS filtered "
|
||||
+ "WHERE tag IN (%s) AND (is_tag_a_rule = 0 OR is_tag_a_rule IS NULL) "
|
||||
+ "GROUP BY host_id "
|
||||
+ "HAVING tag_count = %s ";
|
||||
private static final String SEPARATOR = ",";
|
||||
private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
|
||||
private static final String LIST_CLUSTER_IDS_FOR_HOST_TAGS = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
|
||||
private static final String GET_HOSTS_OF_ACTIVE_VMS = "select h.id " +
|
||||
"from vm_instance vm " +
|
||||
"join host h on (vm.host_id=h.id) " +
|
||||
|
|
@ -98,6 +99,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
protected SearchBuilder<HostVO> TypePodDcStatusSearch;
|
||||
|
||||
protected SearchBuilder<HostVO> IdsSearch;
|
||||
protected SearchBuilder<HostVO> IdStatusSearch;
|
||||
protected SearchBuilder<HostVO> TypeDcSearch;
|
||||
protected SearchBuilder<HostVO> TypeDcStatusSearch;
|
||||
|
|
@ -127,6 +129,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
protected SearchBuilder<HostVO> ResponsibleMsSearch;
|
||||
protected SearchBuilder<HostVO> ResponsibleMsDcSearch;
|
||||
protected GenericSearchBuilder<HostVO, String> ResponsibleMsIdSearch;
|
||||
protected SearchBuilder<HostVO> HostTypeClusterCountSearch;
|
||||
protected SearchBuilder<HostVO> HostTypeZoneCountSearch;
|
||||
protected SearchBuilder<HostVO> ClusterStatusSearch;
|
||||
protected SearchBuilder<HostVO> TypeNameZoneSearch;
|
||||
|
|
@ -138,8 +141,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
protected SearchBuilder<HostVO> ManagedRoutingServersSearch;
|
||||
protected SearchBuilder<HostVO> SecondaryStorageVMSearch;
|
||||
|
||||
protected GenericSearchBuilder<HostVO, Long> HostIdSearch;
|
||||
protected GenericSearchBuilder<HostVO, Long> HostsInStatusSearch;
|
||||
protected GenericSearchBuilder<HostVO, Long> HostsInStatusesSearch;
|
||||
protected GenericSearchBuilder<HostVO, Long> CountRoutingByDc;
|
||||
protected SearchBuilder<HostTransferMapVO> HostTransferSearch;
|
||||
protected SearchBuilder<ClusterVO> ClusterManagedSearch;
|
||||
|
|
@ -189,6 +191,8 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
HostTypeCountSearch = createSearchBuilder();
|
||||
HostTypeCountSearch.and("type", HostTypeCountSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||
HostTypeCountSearch.and("zoneId", HostTypeCountSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
HostTypeCountSearch.and("resourceState", HostTypeCountSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||
HostTypeCountSearch.done();
|
||||
|
||||
ResponsibleMsSearch = createSearchBuilder();
|
||||
|
|
@ -205,6 +209,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
ResponsibleMsIdSearch.and("managementServerId", ResponsibleMsIdSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
|
||||
ResponsibleMsIdSearch.done();
|
||||
|
||||
HostTypeClusterCountSearch = createSearchBuilder();
|
||||
HostTypeClusterCountSearch.and("cluster", HostTypeClusterCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
HostTypeClusterCountSearch.and("type", HostTypeClusterCountSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||
HostTypeClusterCountSearch.and("status", HostTypeClusterCountSearch.entity().getStatus(), SearchCriteria.Op.IN);
|
||||
HostTypeClusterCountSearch.and("removed", HostTypeClusterCountSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
HostTypeClusterCountSearch.done();
|
||||
|
||||
HostTypeZoneCountSearch = createSearchBuilder();
|
||||
HostTypeZoneCountSearch.and("type", HostTypeZoneCountSearch.entity().getType(), SearchCriteria.Op.EQ);
|
||||
HostTypeZoneCountSearch.and("dc", HostTypeZoneCountSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -252,6 +263,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
TypeClusterStatusSearch.and("resourceState", TypeClusterStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||
TypeClusterStatusSearch.done();
|
||||
|
||||
IdsSearch = createSearchBuilder();
|
||||
IdsSearch.and("id", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
IdsSearch.done();
|
||||
|
||||
IdStatusSearch = createSearchBuilder();
|
||||
IdStatusSearch.and("id", IdStatusSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
IdStatusSearch.and("states", IdStatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
|
||||
|
|
@ -398,14 +413,14 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
AvailHypevisorInZone.groupBy(AvailHypevisorInZone.entity().getHypervisorType());
|
||||
AvailHypevisorInZone.done();
|
||||
|
||||
HostsInStatusSearch = createSearchBuilder(Long.class);
|
||||
HostsInStatusSearch.selectFields(HostsInStatusSearch.entity().getId());
|
||||
HostsInStatusSearch.and("dc", HostsInStatusSearch.entity().getDataCenterId(), Op.EQ);
|
||||
HostsInStatusSearch.and("pod", HostsInStatusSearch.entity().getPodId(), Op.EQ);
|
||||
HostsInStatusSearch.and("cluster", HostsInStatusSearch.entity().getClusterId(), Op.EQ);
|
||||
HostsInStatusSearch.and("type", HostsInStatusSearch.entity().getType(), Op.EQ);
|
||||
HostsInStatusSearch.and("statuses", HostsInStatusSearch.entity().getStatus(), Op.IN);
|
||||
HostsInStatusSearch.done();
|
||||
HostsInStatusesSearch = createSearchBuilder(Long.class);
|
||||
HostsInStatusesSearch.selectFields(HostsInStatusesSearch.entity().getId());
|
||||
HostsInStatusesSearch.and("dc", HostsInStatusesSearch.entity().getDataCenterId(), Op.EQ);
|
||||
HostsInStatusesSearch.and("pod", HostsInStatusesSearch.entity().getPodId(), Op.EQ);
|
||||
HostsInStatusesSearch.and("cluster", HostsInStatusesSearch.entity().getClusterId(), Op.EQ);
|
||||
HostsInStatusesSearch.and("type", HostsInStatusesSearch.entity().getType(), Op.EQ);
|
||||
HostsInStatusesSearch.and("statuses", HostsInStatusesSearch.entity().getStatus(), Op.IN);
|
||||
HostsInStatusesSearch.done();
|
||||
|
||||
CountRoutingByDc = createSearchBuilder(Long.class);
|
||||
CountRoutingByDc.select(null, Func.COUNT, null);
|
||||
|
|
@ -468,11 +483,6 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
HostsInClusterSearch.and("server", HostsInClusterSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
|
||||
HostsInClusterSearch.done();
|
||||
|
||||
HostIdSearch = createSearchBuilder(Long.class);
|
||||
HostIdSearch.selectFields(HostIdSearch.entity().getId());
|
||||
HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ);
|
||||
HostIdSearch.done();
|
||||
|
||||
searchBuilderFindByRuleTag = _hostTagsDao.createSearchBuilder();
|
||||
searchBuilderFindByRuleTag.and("is_tag_a_rule", searchBuilderFindByRuleTag.entity().getIsTagARule(), Op.EQ);
|
||||
searchBuilderFindByRuleTag.or("tagDoesNotExist", searchBuilderFindByRuleTag.entity().getIsTagARule(), Op.NULL);
|
||||
|
|
@ -504,8 +514,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sc.setParameters("resourceState", (Object[])states);
|
||||
sc.setParameters("cluster", clusterId);
|
||||
|
||||
List<HostVO> hosts = listBy(sc);
|
||||
return hosts.size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -516,36 +525,62 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer countAllByTypeInZone(long zoneId, Type type) {
|
||||
SearchCriteria<HostVO> sc = HostTypeCountSearch.create();
|
||||
sc.setParameters("type", type);
|
||||
sc.setParameters("dc", zoneId);
|
||||
public Integer countAllInClusterByTypeAndStates(Long clusterId, final Host.Type type, List<Status> status) {
|
||||
SearchCriteria<HostVO> sc = HostTypeClusterCountSearch.create();
|
||||
if (clusterId != null) {
|
||||
sc.setParameters("cluster", clusterId);
|
||||
}
|
||||
if (type != null) {
|
||||
sc.setParameters("type", type);
|
||||
}
|
||||
if (status != null) {
|
||||
sc.setParameters("status", status.toArray());
|
||||
}
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listByDataCenterId(long id) {
|
||||
return listByDataCenterIdAndState(id, ResourceState.Enabled);
|
||||
public Integer countAllByTypeInZone(long zoneId, Type type) {
|
||||
SearchCriteria<HostVO> sc = HostTypeCountSearch.create();
|
||||
sc.setParameters("type", type);
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listByDataCenterIdAndState(long id, ResourceState state) {
|
||||
SearchCriteria<HostVO> sc = scHostsFromZoneUpRouting(id);
|
||||
sc.setParameters("resourceState", state);
|
||||
return listBy(sc);
|
||||
public Integer countUpAndEnabledHostsInZone(long zoneId) {
|
||||
SearchCriteria<HostVO> sc = HostTypeCountSearch.create();
|
||||
sc.setParameters("type", Type.Routing);
|
||||
sc.setParameters("resourceState", ResourceState.Enabled);
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listDisabledByDataCenterId(long id) {
|
||||
return listByDataCenterIdAndState(id, ResourceState.Disabled);
|
||||
public Pair<Integer, Integer> countAllHostsAndCPUSocketsByType(Type type) {
|
||||
GenericSearchBuilder<HostVO, SumCount> sb = createSearchBuilder(SumCount.class);
|
||||
sb.select("sum", Func.SUM, sb.entity().getCpuSockets());
|
||||
sb.select("count", Func.COUNT, null);
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<SumCount> sc = sb.create();
|
||||
sc.setParameters("type", type);
|
||||
SumCount result = customSearch(sc, null).get(0);
|
||||
return new Pair<>((int)result.count, (int)result.sum);
|
||||
}
|
||||
|
||||
private SearchCriteria<HostVO> scHostsFromZoneUpRouting(long id) {
|
||||
SearchCriteria<HostVO> sc = DcSearch.create();
|
||||
sc.setParameters("dc", id);
|
||||
sc.setParameters("status", Status.Up);
|
||||
sc.setParameters("type", Host.Type.Routing);
|
||||
return sc;
|
||||
private List<Long> listIdsForRoutingByZoneIdAndResourceState(long zoneId, ResourceState state) {
|
||||
return listIdsBy(Type.Routing, Status.Up, state, null, zoneId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listEnabledIdsByDataCenterId(long id) {
|
||||
return listIdsForRoutingByZoneIdAndResourceState(id, ResourceState.Enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listDisabledIdsByDataCenterId(long id) {
|
||||
return listIdsForRoutingByZoneIdAndResourceState(id, ResourceState.Disabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -603,9 +638,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sb.append(" ");
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Following hosts got reset: " + sb.toString());
|
||||
}
|
||||
logger.trace("Following hosts got reset: {}", sb);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -615,8 +648,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
SearchCriteria<Long> sc = ClustersOwnedByMSSearch.create();
|
||||
sc.setParameters("server", managementServerId);
|
||||
|
||||
List<Long> clusters = customSearch(sc, null);
|
||||
return clusters;
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -626,13 +658,11 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
SearchCriteria<Long> sc = ClustersForHostsNotOwnedByAnyMSSearch.create();
|
||||
sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
|
||||
|
||||
List<Long> clusters = customSearch(sc, null);
|
||||
return clusters;
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This determines if hosts belonging to cluster(@clusterId) are up for grabs
|
||||
*
|
||||
* This is used for handling following cases:
|
||||
* 1. First host added in cluster
|
||||
* 2. During MS restart all hosts in a cluster are without any MS
|
||||
|
|
@ -642,9 +672,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sc.setParameters("cluster", clusterId);
|
||||
|
||||
List<HostVO> hosts = search(sc, null);
|
||||
boolean ownCluster = (hosts == null || hosts.size() == 0);
|
||||
|
||||
return ownCluster;
|
||||
return (hosts == null || hosts.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -661,14 +689,14 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
logger.debug("Completed resetting hosts suitable for reconnect");
|
||||
}
|
||||
|
||||
List<HostVO> assignedHosts = new ArrayList<HostVO>();
|
||||
List<HostVO> assignedHosts = new ArrayList<>();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Acquiring hosts for clusters already owned by this management server");
|
||||
}
|
||||
List<Long> clusters = findClustersOwnedByManagementServer(managementServerId);
|
||||
txn.start();
|
||||
if (clusters.size() > 0) {
|
||||
if (!clusters.isEmpty()) {
|
||||
// handle clusters already owned by @managementServerId
|
||||
SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
|
||||
sc.setParameters("lastPinged", lastPingSecondsAfter);
|
||||
|
|
@ -683,13 +711,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sb.append(host.getId());
|
||||
sb.append(" ");
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Following hosts got acquired for clusters already owned: " + sb.toString());
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Completed acquiring hosts for clusters already owned by this management server");
|
||||
logger.trace("Following hosts got acquired for clusters already owned: {}", sb);
|
||||
}
|
||||
logger.debug("Completed acquiring hosts for clusters already owned by this management server");
|
||||
|
||||
if (assignedHosts.size() < limit) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
@ -701,7 +725,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
if (clusters.size() > limit) {
|
||||
updatedClusters = clusters.subList(0, limit.intValue());
|
||||
}
|
||||
if (updatedClusters.size() > 0) {
|
||||
if (!updatedClusters.isEmpty()) {
|
||||
SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
|
||||
sc.setParameters("lastPinged", lastPingSecondsAfter);
|
||||
sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
|
||||
|
|
@ -709,10 +733,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
List<HostVO> unmanagedHosts = lockRows(sc, null, true);
|
||||
|
||||
// group hosts based on cluster
|
||||
Map<Long, List<HostVO>> hostMap = new HashMap<Long, List<HostVO>>();
|
||||
Map<Long, List<HostVO>> hostMap = new HashMap<>();
|
||||
for (HostVO host : unmanagedHosts) {
|
||||
if (hostMap.get(host.getClusterId()) == null) {
|
||||
hostMap.put(host.getClusterId(), new ArrayList<HostVO>());
|
||||
hostMap.put(host.getClusterId(), new ArrayList<>());
|
||||
}
|
||||
hostMap.get(host.getClusterId()).add(host);
|
||||
}
|
||||
|
|
@ -733,13 +757,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Following hosts got acquired from newly owned clusters: " + sb.toString());
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Completed acquiring hosts for clusters not owned by any management server");
|
||||
logger.trace("Following hosts got acquired from newly owned clusters: {}", sb);
|
||||
}
|
||||
logger.debug("Completed acquiring hosts for clusters not owned by any management server");
|
||||
}
|
||||
txn.commit();
|
||||
|
||||
|
|
@ -794,6 +814,15 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
@Override
|
||||
public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, Long dcId, String hostTag) {
|
||||
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, hostTag, true);
|
||||
}
|
||||
|
||||
private List<HostVO> listHostsWithOrWithoutHostTags(Host.Type type, Long clusterId, Long podId, Long dcId, String hostTags, boolean withHostTags) {
|
||||
if (StringUtils.isEmpty(hostTags)) {
|
||||
logger.debug("Host tags not specified, to list hosts");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
|
||||
HostVO entity = hostSearch.entity();
|
||||
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
|
||||
|
|
@ -804,7 +833,9 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
|
||||
|
||||
SearchCriteria<HostVO> sc = hostSearch.create();
|
||||
sc.setParameters("type", type.toString());
|
||||
if (type != null) {
|
||||
sc.setParameters("type", type.toString());
|
||||
}
|
||||
if (podId != null) {
|
||||
sc.setParameters("pod", podId);
|
||||
}
|
||||
|
|
@ -817,27 +848,38 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
sc.setParameters("status", Status.Up.toString());
|
||||
sc.setParameters("resourceState", ResourceState.Enabled.toString());
|
||||
|
||||
List<HostVO> tmpHosts = listBy(sc);
|
||||
List<HostVO> correctHostsByHostTags = new ArrayList();
|
||||
List<Long> hostIdsByComputeOffTags = findHostByComputeOfferings(hostTag);
|
||||
List<HostVO> upAndEnabledHosts = listBy(sc);
|
||||
if (CollectionUtils.isEmpty(upAndEnabledHosts)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
tmpHosts.forEach((host) -> { if(hostIdsByComputeOffTags.contains(host.getId())) correctHostsByHostTags.add(host);});
|
||||
List<Long> hostIdsByHostTags = findHostIdsByHostTags(hostTags);
|
||||
if (CollectionUtils.isEmpty(hostIdsByHostTags)) {
|
||||
return withHostTags ? new ArrayList<>() : upAndEnabledHosts;
|
||||
}
|
||||
|
||||
return correctHostsByHostTags;
|
||||
if (withHostTags) {
|
||||
List<HostVO> upAndEnabledHostsWithHostTags = new ArrayList<>();
|
||||
upAndEnabledHosts.forEach((host) -> { if (hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithHostTags.add(host);});
|
||||
return upAndEnabledHostsWithHostTags;
|
||||
} else {
|
||||
List<HostVO> upAndEnabledHostsWithoutHostTags = new ArrayList<>();
|
||||
upAndEnabledHosts.forEach((host) -> { if (!hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithoutHostTags.add(host);});
|
||||
return upAndEnabledHostsWithoutHostTags;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
|
||||
if (StringUtils.isNotEmpty(haTag)) {
|
||||
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, haTag, false);
|
||||
}
|
||||
|
||||
SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
|
||||
hostTagSearch.and();
|
||||
hostTagSearch.op("isTagARule", hostTagSearch.entity().getIsTagARule(), Op.EQ);
|
||||
hostTagSearch.or("tagDoesNotExist", hostTagSearch.entity().getIsTagARule(), Op.NULL);
|
||||
hostTagSearch.cp();
|
||||
if (haTag != null && !haTag.isEmpty()) {
|
||||
hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
|
||||
hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
|
||||
hostTagSearch.cp();
|
||||
}
|
||||
|
||||
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
|
||||
|
||||
|
|
@ -848,18 +890,12 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
|
||||
hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||
|
||||
|
||||
hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
|
||||
|
||||
|
||||
SearchCriteria<HostVO> sc = hostSearch.create();
|
||||
|
||||
sc.setJoinParameters("hostTagSearch", "isTagARule", false);
|
||||
|
||||
if (haTag != null && !haTag.isEmpty()) {
|
||||
sc.setJoinParameters("hostTagSearch", "tag", haTag);
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
sc.setParameters("type", type);
|
||||
}
|
||||
|
|
@ -899,12 +935,12 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
@DB
|
||||
@Override
|
||||
public List<HostVO> findLostHosts(long timeout) {
|
||||
List<HostVO> result = new ArrayList<HostVO>();
|
||||
List<HostVO> result = new ArrayList<>();
|
||||
String sql = "select h.id from host h left join cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage', 'L2Networking') and (h.cluster_id is null or c.managed_state = 'Managed') ;";
|
||||
try (TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = txn.prepareStatement(sql);) {
|
||||
PreparedStatement pstmt = txn.prepareStatement(sql)) {
|
||||
pstmt.setLong(1, timeout);
|
||||
try (ResultSet rs = pstmt.executeQuery();) {
|
||||
try (ResultSet rs = pstmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1); //ID column
|
||||
result.add(findById(id));
|
||||
|
|
@ -937,7 +973,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = host.getGpuGroupDetails();
|
||||
if (groupDetails != null) {
|
||||
// Create/Update GPU group entries
|
||||
_hostGpuGroupsDao.persist(host.getId(), new ArrayList<String>(groupDetails.keySet()));
|
||||
_hostGpuGroupsDao.persist(host.getId(), new ArrayList<>(groupDetails.keySet()));
|
||||
// Create/Update VGPU types entries
|
||||
_vgpuTypesDao.persist(host.getId(), groupDetails);
|
||||
}
|
||||
|
|
@ -980,7 +1016,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
boolean persisted = super.update(hostId, host);
|
||||
if (!persisted) {
|
||||
return persisted;
|
||||
return false;
|
||||
}
|
||||
|
||||
saveDetails(host);
|
||||
|
|
@ -989,7 +1025,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
txn.commit();
|
||||
|
||||
return persisted;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1000,11 +1036,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
+ "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid "
|
||||
+ "where h.status='Up' and h.type='Routing' and m.last_update > ? " + "group by h.data_center_id, h.type) as t " + "ORDER by t.data_center_id, t.type";
|
||||
|
||||
ArrayList<RunningHostCountInfo> l = new ArrayList<RunningHostCountInfo>();
|
||||
ArrayList<RunningHostCountInfo> l = new ArrayList<>();
|
||||
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
;
|
||||
PreparedStatement pstmt = null;
|
||||
PreparedStatement pstmt;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
|
||||
|
|
@ -1028,9 +1063,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
@Override
|
||||
public long getNextSequence(long hostId) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("getNextSequence(), hostId: " + hostId);
|
||||
}
|
||||
logger.trace("getNextSequence(), hostId: {}", hostId);
|
||||
|
||||
TableGenerator tg = _tgs.get("host_req_sq");
|
||||
assert tg != null : "how can this be wrong!";
|
||||
|
|
@ -1099,31 +1132,30 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
HostVO ho = findById(host.getId());
|
||||
assert ho != null : "How how how? : " + host.getId();
|
||||
|
||||
// TODO handle this if(debug){}else{log.debug} it makes no sense
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
StringBuilder str = new StringBuilder("Unable to update host for event:").append(event.toString());
|
||||
str.append(". Name=").append(host.getName());
|
||||
str.append("; New=[status=").append(newStatus.toString()).append(":msid=").append(newStatus.lostConnection() ? "null" : host.getManagementServerId())
|
||||
.append(":lastpinged=").append(host.getLastPinged()).append("]");
|
||||
str.append("; Old=[status=").append(oldStatus.toString()).append(":msid=").append(host.getManagementServerId()).append(":lastpinged=").append(oldPingTime)
|
||||
.append("]");
|
||||
str.append("; DB=[status=").append(vo.getStatus().toString()).append(":msid=").append(vo.getManagementServerId()).append(":lastpinged=").append(vo.getLastPinged())
|
||||
.append(":old update count=").append(oldUpdateCount).append("]");
|
||||
logger.debug(str.toString());
|
||||
String str = "Unable to update host for event:" + event +
|
||||
". Name=" + host.getName() +
|
||||
"; New=[status=" + newStatus + ":msid=" + (newStatus.lostConnection() ? "null" : host.getManagementServerId()) +
|
||||
":lastpinged=" + host.getLastPinged() + "]" +
|
||||
"; Old=[status=" + oldStatus.toString() + ":msid=" + host.getManagementServerId() + ":lastpinged=" + oldPingTime +
|
||||
"]" +
|
||||
"; DB=[status=" + vo.getStatus().toString() + ":msid=" + vo.getManagementServerId() + ":lastpinged=" + vo.getLastPinged() +
|
||||
":old update count=" + oldUpdateCount + "]";
|
||||
logger.debug(str);
|
||||
} else {
|
||||
StringBuilder msg = new StringBuilder("Agent status update: [");
|
||||
msg.append("id = " + host.getId());
|
||||
msg.append("; name = " + host.getName());
|
||||
msg.append("; old status = " + oldStatus);
|
||||
msg.append("; event = " + event);
|
||||
msg.append("; new status = " + newStatus);
|
||||
msg.append("; old update count = " + oldUpdateCount);
|
||||
msg.append("; new update count = " + newUpdateCount + "]");
|
||||
logger.debug(msg.toString());
|
||||
String msg = "Agent status update: [" + "id = " + host.getId() +
|
||||
"; name = " + host.getName() +
|
||||
"; old status = " + oldStatus +
|
||||
"; event = " + event +
|
||||
"; new status = " + newStatus +
|
||||
"; old update count = " + oldUpdateCount +
|
||||
"; new update count = " + newUpdateCount + "]";
|
||||
logger.debug(msg);
|
||||
}
|
||||
|
||||
if (ho.getState() == newStatus) {
|
||||
logger.debug("Host " + ho.getName() + " state has already been updated to " + newStatus);
|
||||
logger.debug("Host {} state has already been updated to {}", ho.getName(), newStatus);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1149,25 +1181,24 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
int result = update(ub, sc, null);
|
||||
assert result <= 1 : "How can this update " + result + " rows? ";
|
||||
|
||||
// TODO handle this if(debug){}else{log.debug} it makes no sense
|
||||
if (logger.isDebugEnabled() && result == 0) {
|
||||
HostVO ho = findById(host.getId());
|
||||
assert ho != null : "How how how? : " + host.getId();
|
||||
|
||||
StringBuilder str = new StringBuilder("Unable to update resource state: [");
|
||||
str.append("m = " + host.getId());
|
||||
str.append("; name = " + host.getName());
|
||||
str.append("; old state = " + oldState);
|
||||
str.append("; event = " + event);
|
||||
str.append("; new state = " + newState + "]");
|
||||
logger.debug(str.toString());
|
||||
String str = "Unable to update resource state: [" + "m = " + host.getId() +
|
||||
"; name = " + host.getName() +
|
||||
"; old state = " + oldState +
|
||||
"; event = " + event +
|
||||
"; new state = " + newState + "]";
|
||||
logger.debug(str);
|
||||
} else {
|
||||
StringBuilder msg = new StringBuilder("Resource state update: [");
|
||||
msg.append("id = " + host.getId());
|
||||
msg.append("; name = " + host.getName());
|
||||
msg.append("; old state = " + oldState);
|
||||
msg.append("; event = " + event);
|
||||
msg.append("; new state = " + newState + "]");
|
||||
logger.debug(msg.toString());
|
||||
String msg = "Resource state update: [" + "id = " + host.getId() +
|
||||
"; name = " + host.getName() +
|
||||
"; old state = " + oldState +
|
||||
"; event = " + event +
|
||||
"; new state = " + newState + "]";
|
||||
logger.debug(msg);
|
||||
}
|
||||
|
||||
return result > 0;
|
||||
|
|
@ -1190,6 +1221,11 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsByDataCenterId(Long zoneId) {
|
||||
return listIdsBy(Type.Routing, null, null, null, zoneId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findByPodId(Long podId) {
|
||||
SearchCriteria<HostVO> sc = PodSearch.create();
|
||||
|
|
@ -1197,6 +1233,11 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsByPodId(Long podId) {
|
||||
return listIdsBy(null, null, null, null, null, podId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findByClusterId(Long clusterId) {
|
||||
SearchCriteria<HostVO> sc = ClusterSearch.create();
|
||||
|
|
@ -1204,6 +1245,63 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
protected List<Long> listIdsBy(Host.Type type, Status status, ResourceState resourceState,
|
||||
HypervisorType hypervisorType, Long zoneId, Long podId, Long clusterId) {
|
||||
GenericSearchBuilder<HostVO, Long> sb = createSearchBuilder(Long.class);
|
||||
sb.selectFields(sb.entity().getId());
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
|
||||
sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
|
||||
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
|
||||
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<Long> sc = sb.create();
|
||||
if (type != null) {
|
||||
sc.setParameters("type", type);
|
||||
}
|
||||
if (status != null) {
|
||||
sc.setParameters("status", status);
|
||||
}
|
||||
if (resourceState != null) {
|
||||
sc.setParameters("resourceState", resourceState);
|
||||
}
|
||||
if (hypervisorType != null) {
|
||||
sc.setParameters("hypervisorType", hypervisorType);
|
||||
}
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
if (podId != null) {
|
||||
sc.setParameters("podId", podId);
|
||||
}
|
||||
if (clusterId != null) {
|
||||
sc.setParameters("clusterId", clusterId);
|
||||
}
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsByClusterId(Long clusterId) {
|
||||
return listIdsBy(null, null, null, null, null, null, clusterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsForUpRouting(Long zoneId, Long podId, Long clusterId) {
|
||||
return listIdsBy(Type.Routing, Status.Up, null, null, zoneId, podId, clusterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsByType(Type type) {
|
||||
return listIdsBy(type, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listIdsForUpEnabledByZoneAndHypervisor(Long zoneId, HypervisorType hypervisorType) {
|
||||
return listIdsBy(null, Status.Up, ResourceState.Enabled, hypervisorType, zoneId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> findByClusterIdAndEncryptionSupport(Long clusterId) {
|
||||
SearchBuilder<DetailVO> hostCapabilitySearch = _detailsDao.createSearchBuilder();
|
||||
|
|
@ -1256,6 +1354,15 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostVO findAnyStateHypervisorHostInCluster(long clusterId) {
|
||||
SearchCriteria<HostVO> sc = TypeClusterStatusSearch.create();
|
||||
sc.setParameters("type", Host.Type.Routing);
|
||||
sc.setParameters("cluster", clusterId);
|
||||
List<HostVO> list = listBy(sc, new Filter(1));
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostVO findOldestExistentHypervisorHostInCluster(long clusterId) {
|
||||
SearchCriteria<HostVO> sc = TypeClusterStatusSearch.create();
|
||||
|
|
@ -1266,7 +1373,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
Filter orderByFilter = new Filter(HostVO.class, "created", true, null, null);
|
||||
|
||||
List<HostVO> hosts = search(sc, orderByFilter, null, false);
|
||||
if (hosts != null && hosts.size() > 0) {
|
||||
if (hosts != null && !hosts.isEmpty()) {
|
||||
return hosts.get(0);
|
||||
}
|
||||
|
||||
|
|
@ -1275,9 +1382,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
@Override
|
||||
public List<Long> listAllHosts(long zoneId) {
|
||||
SearchCriteria<Long> sc = HostIdSearch.create();
|
||||
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
|
||||
return customSearch(sc, null);
|
||||
return listIdsBy(null, null, null, null, zoneId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1311,19 +1416,19 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listClustersByHostTag(String computeOfferingTags) {
|
||||
public List<Long> listClustersByHostTag(String hostTags) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
String sql = this.LIST_CLUSTERID_FOR_HOST_TAG;
|
||||
PreparedStatement pstmt = null;
|
||||
List<Long> result = new ArrayList();
|
||||
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
|
||||
String subselect = getHostIdsByComputeTags(tags);
|
||||
sql = String.format(sql, subselect);
|
||||
String selectStmtToListClusterIdsByHostTags = LIST_CLUSTER_IDS_FOR_HOST_TAGS;
|
||||
PreparedStatement pstmt;
|
||||
List<Long> result = new ArrayList<>();
|
||||
List<String> tags = Arrays.asList(hostTags.split(SEPARATOR));
|
||||
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
|
||||
selectStmtToListClusterIdsByHostTags = String.format(selectStmtToListClusterIdsByHostTags, selectStmtToListHostIdsByHostTags);
|
||||
|
||||
try {
|
||||
pstmt = txn.prepareStatement(sql);
|
||||
pstmt = txn.prepareStatement(selectStmtToListClusterIdsByHostTags);
|
||||
|
||||
for(int i = 0; i < tags.size(); i++){
|
||||
for (int i = 0; i < tags.size(); i++){
|
||||
pstmt.setString(i+1, tags.get(i));
|
||||
}
|
||||
|
||||
|
|
@ -1334,20 +1439,20 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
pstmt.close();
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("DB Exception on: " + sql, e);
|
||||
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListClusterIdsByHostTags, e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Long> findHostByComputeOfferings(String computeOfferingTags){
|
||||
private List<Long> findHostIdsByHostTags(String hostTags){
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
List<Long> result = new ArrayList();
|
||||
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
|
||||
String select = getHostIdsByComputeTags(tags);
|
||||
PreparedStatement pstmt;
|
||||
List<Long> result = new ArrayList<>();
|
||||
List<String> tags = Arrays.asList(hostTags.split(SEPARATOR));
|
||||
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
|
||||
try {
|
||||
pstmt = txn.prepareStatement(select);
|
||||
pstmt = txn.prepareStatement(selectStmtToListHostIdsByHostTags);
|
||||
|
||||
for(int i = 0; i < tags.size(); i++){
|
||||
for (int i = 0; i < tags.size(); i++){
|
||||
pstmt.setString(i+1, tags.get(i));
|
||||
}
|
||||
|
||||
|
|
@ -1358,7 +1463,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
pstmt.close();
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("DB Exception on: " + select, e);
|
||||
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListHostIdsByHostTags, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1408,16 +1513,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return result;
|
||||
}
|
||||
|
||||
private String getHostIdsByComputeTags(List<String> offeringTags){
|
||||
List<String> questionMarks = new ArrayList();
|
||||
offeringTags.forEach((tag) -> { questionMarks.add("?"); });
|
||||
return String.format(this.LIST_HOST_IDS_BY_COMPUTETAGS, String.join(",", questionMarks),questionMarks.size());
|
||||
private String getSelectStmtToListHostIdsByHostTags(List<String> hostTags){
|
||||
List<String> questionMarks = new ArrayList<>();
|
||||
hostTags.forEach((tag) -> questionMarks.add("?"));
|
||||
return String.format(LIST_HOST_IDS_BY_HOST_TAGS, String.join(SEPARATOR, questionMarks), questionMarks.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listHostsWithActiveVMs(long offeringId) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
PreparedStatement pstmt;
|
||||
List<HostVO> result = new ArrayList<>();
|
||||
StringBuilder sql = new StringBuilder(GET_HOSTS_OF_ACTIVE_VMS);
|
||||
try {
|
||||
|
|
@ -1466,7 +1571,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
|
||||
@Override
|
||||
public List<String> listOrderedHostsHypervisorVersionsInDatacenter(long datacenterId, HypervisorType hypervisorType) {
|
||||
PreparedStatement pstmt = null;
|
||||
PreparedStatement pstmt;
|
||||
List<String> result = new ArrayList<>();
|
||||
try {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
|
|
@ -1483,15 +1588,6 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listAllHostsByType(Host.Type type) {
|
||||
SearchCriteria<HostVO> sc = TypeSearch.create();
|
||||
sc.setParameters("type", type);
|
||||
sc.setParameters("resourceState", ResourceState.Enabled);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listByType(Host.Type type) {
|
||||
SearchCriteria<HostVO> sc = TypeSearch.create();
|
||||
|
|
@ -1636,4 +1732,71 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
}
|
||||
return String.format(sqlFindHostInZoneToExecuteCommand, hostResourceStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHostUp(long hostId) {
|
||||
GenericSearchBuilder<HostVO, Status> sb = createSearchBuilder(Status.class);
|
||||
sb.and("id", sb.entity().getId(), Op.EQ);
|
||||
sb.selectFields(sb.entity().getStatus());
|
||||
SearchCriteria<Status> sc = sb.create();
|
||||
sc.setParameters("id", hostId);
|
||||
List<Status> statuses = customSearch(sc, null);
|
||||
return CollectionUtils.isNotEmpty(statuses) && Status.Up.equals(statuses.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> findHostIdsByZoneClusterResourceStateTypeAndHypervisorType(final Long zoneId, final Long clusterId,
|
||||
final List<ResourceState> resourceStates, final List<Type> types,
|
||||
final List<Hypervisor.HypervisorType> hypervisorTypes) {
|
||||
GenericSearchBuilder<HostVO, Long> sb = createSearchBuilder(Long.class);
|
||||
sb.selectFields(sb.entity().getId());
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.IN);
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.IN);
|
||||
if (CollectionUtils.isNotEmpty(hypervisorTypes)) {
|
||||
sb.and().op(sb.entity().getHypervisorType(), SearchCriteria.Op.NULL);
|
||||
sb.or("hypervisorTypes", sb.entity().getHypervisorType(), SearchCriteria.Op.IN);
|
||||
sb.cp();
|
||||
}
|
||||
sb.done();
|
||||
SearchCriteria<Long> sc = sb.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
if (clusterId != null) {
|
||||
sc.setParameters("clusterId", clusterId);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(hypervisorTypes)) {
|
||||
sc.setParameters("hypervisorTypes", hypervisorTypes.toArray());
|
||||
}
|
||||
sc.setParameters("resourceState", resourceStates.toArray());
|
||||
sc.setParameters("type", types.toArray());
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HypervisorType> listDistinctHypervisorTypes(final Long zoneId) {
|
||||
GenericSearchBuilder<HostVO, HypervisorType> sb = createSearchBuilder(HypervisorType.class);
|
||||
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
|
||||
sb.select(null, Func.DISTINCT, sb.entity().getHypervisorType());
|
||||
sb.done();
|
||||
SearchCriteria<HypervisorType> sc = sb.create();
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zoneId", zoneId);
|
||||
}
|
||||
sc.setParameters("type", Type.Routing);
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> listByIds(List<Long> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
SearchCriteria<HostVO> sc = IdsSearch.create();
|
||||
sc.setParameters("id", ids.toArray());
|
||||
return search(sc, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
|
|||
|
||||
List<FirewallRuleVO> listStaticNatByVmId(long vmId);
|
||||
|
||||
List<FirewallRuleVO> listByIpPurposeAndProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol, FirewallRule.Purpose purpose);
|
||||
List<FirewallRuleVO> listByIpPurposePortsProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol, FirewallRule.Purpose purpose);
|
||||
|
||||
List<FirewallRuleVO> listByIpPurposeProtocolAndNotRevoked(long ipAddressId, FirewallRule.Purpose purpose, String protocol);
|
||||
|
||||
FirewallRuleVO findByRelatedId(long ruleId);
|
||||
|
||||
|
|
|
|||
|
|
@ -263,8 +263,25 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIpPurposeAndProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol,
|
||||
FirewallRule.Purpose purpose) {
|
||||
public List<FirewallRuleVO> listByIpPurposeProtocolAndNotRevoked(long ipAddressId, Purpose purpose, String protocol) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
sc.setParameters("ipId", ipAddressId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
|
||||
if (purpose != null) {
|
||||
sc.setParameters("purpose", purpose);
|
||||
}
|
||||
|
||||
if (protocol != null) {
|
||||
sc.setParameters("protocol", protocol);
|
||||
}
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIpPurposePortsProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol,
|
||||
FirewallRule.Purpose purpose) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
sc.setParameters("ipId", ipAddressId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
|
|||
public long countFreeIpsInVlan(long vlanDbId) {
|
||||
SearchCriteria<IPAddressVO> sc = VlanDbIdSearchUnallocated.create();
|
||||
sc.setParameters("vlanDbId", vlanDbId);
|
||||
return listBy(sc).size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -415,8 +415,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
|
|||
sc.setParameters("broadcastUri", broadcastURI);
|
||||
sc.setParameters("guestType", guestTypes);
|
||||
sc.setJoinParameters("persistent", "persistent", isPersistent);
|
||||
List<NetworkVO> persistentNetworks = search(sc, null);
|
||||
return persistentNetworks.size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -55,8 +55,7 @@ public class CommandExecLogDaoImpl extends GenericDaoBase<CommandExecLogVO, Long
|
|||
SearchCriteria<CommandExecLogVO> sc = CommandSearch.create();
|
||||
sc.setParameters("host_id", id);
|
||||
sc.setParameters("command_name", "CopyCommand");
|
||||
List<CommandExecLogVO> copyCmds = customSearch(sc, null);
|
||||
return copyCmds.size();
|
||||
return getCount(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long>
|
|||
|
||||
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
||||
|
||||
List<ServiceOfferingVO> listByHostTag(String tag);
|
||||
|
||||
ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId, boolean includingRemoved);
|
||||
|
||||
List<Long> listIdsByHostTag(String tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import com.cloud.service.ServiceOfferingVO;
|
|||
import com.cloud.storage.Storage.ProvisioningType;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
|
@ -293,8 +294,9 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceOfferingVO> listByHostTag(String tag) {
|
||||
SearchBuilder<ServiceOfferingVO> sb = createSearchBuilder();
|
||||
public List<Long> listIdsByHostTag(String tag) {
|
||||
GenericSearchBuilder<ServiceOfferingVO, Long> sb = createSearchBuilder(Long.class);
|
||||
sb.selectFields(sb.entity().getId());
|
||||
sb.and("tagNotNull", sb.entity().getHostTag(), SearchCriteria.Op.NNULL);
|
||||
sb.and().op("tagEq", sb.entity().getHostTag(), SearchCriteria.Op.EQ);
|
||||
sb.or("tagStartLike", sb.entity().getHostTag(), SearchCriteria.Op.LIKE);
|
||||
|
|
@ -302,11 +304,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||
sb.or("tagEndLike", sb.entity().getHostTag(), SearchCriteria.Op.LIKE);
|
||||
sb.cp();
|
||||
sb.done();
|
||||
SearchCriteria<ServiceOfferingVO> sc = sb.create();
|
||||
SearchCriteria<Long> sc = sb.create();
|
||||
|
||||
sc.setParameters("tagEq", tag);
|
||||
sc.setParameters("tagStartLike", tag + ",%");
|
||||
sc.setParameters("tagMidLike", "%," + tag + ",%");
|
||||
sc.setParameters("tagEndLike", "%," + tag);
|
||||
return listBy(sc);
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,8 @@ public interface BucketDao extends GenericDao<BucketVO, Long> {
|
|||
List<BucketVO> listByObjectStoreIdAndAccountId(long objectStoreId, long accountId);
|
||||
|
||||
List<BucketVO> searchByIds(Long[] ids);
|
||||
|
||||
Long countBucketsForAccount(long accountId);
|
||||
|
||||
Long calculateObjectStorageAllocationForAccount(long accountId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
// under the License.
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.storage.BucketVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
|
@ -31,6 +33,8 @@ public class BucketDaoImpl extends GenericDaoBase<BucketVO, Long> implements Buc
|
|||
private SearchBuilder<BucketVO> searchFilteringStoreId;
|
||||
|
||||
private SearchBuilder<BucketVO> bucketSearch;
|
||||
private GenericSearchBuilder<BucketVO, Long> CountBucketsByAccount;
|
||||
private GenericSearchBuilder<BucketVO, SumCount> CalculateBucketsQuotaByAccount;
|
||||
|
||||
private static final String STORE_ID = "store_id";
|
||||
private static final String STATE = "state";
|
||||
|
|
@ -54,6 +58,20 @@ public class BucketDaoImpl extends GenericDaoBase<BucketVO, Long> implements Buc
|
|||
bucketSearch.and("idIN", bucketSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
bucketSearch.done();
|
||||
|
||||
CountBucketsByAccount = createSearchBuilder(Long.class);
|
||||
CountBucketsByAccount.select(null, SearchCriteria.Func.COUNT, null);
|
||||
CountBucketsByAccount.and(ACCOUNT_ID, CountBucketsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
CountBucketsByAccount.and(STATE, CountBucketsByAccount.entity().getState(), SearchCriteria.Op.NIN);
|
||||
CountBucketsByAccount.and("removed", CountBucketsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
CountBucketsByAccount.done();
|
||||
|
||||
CalculateBucketsQuotaByAccount = createSearchBuilder(SumCount.class);
|
||||
CalculateBucketsQuotaByAccount.select("sum", SearchCriteria.Func.SUM, CalculateBucketsQuotaByAccount.entity().getQuota());
|
||||
CalculateBucketsQuotaByAccount.and(ACCOUNT_ID, CalculateBucketsQuotaByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
CalculateBucketsQuotaByAccount.and(STATE, CalculateBucketsQuotaByAccount.entity().getState(), SearchCriteria.Op.NIN);
|
||||
CalculateBucketsQuotaByAccount.and("removed", CalculateBucketsQuotaByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
CalculateBucketsQuotaByAccount.done();
|
||||
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
|
|
@ -79,4 +97,21 @@ public class BucketDaoImpl extends GenericDaoBase<BucketVO, Long> implements Buc
|
|||
sc.setParameters("idIN", ids);
|
||||
return search(sc, null, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countBucketsForAccount(long accountId) {
|
||||
SearchCriteria<Long> sc = CountBucketsByAccount.create();
|
||||
sc.setParameters(ACCOUNT_ID, accountId);
|
||||
sc.setParameters(STATE, BucketVO.State.Destroyed);
|
||||
return customSearch(sc, null).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long calculateObjectStorageAllocationForAccount(long accountId) {
|
||||
SearchCriteria<SumCount> sc = CalculateBucketsQuotaByAccount.create();
|
||||
sc.setParameters(ACCOUNT_ID, accountId);
|
||||
sc.setParameters(STATE, BucketVO.State.Destroyed);
|
||||
Long totalQuota = customSearch(sc, null).get(0).sum;
|
||||
return (totalQuota * Resource.ResourceType.bytesToGiB);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
|
|||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoolDetailVO> implements StoragePoolDetailsDao, ScopedConfigStorage {
|
||||
|
||||
@Inject
|
||||
|
|
@ -46,7 +48,7 @@ public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoo
|
|||
@Override
|
||||
public String getConfigValue(long id, String key) {
|
||||
StoragePoolDetailVO vo = findDetail(id, key);
|
||||
return vo == null ? null : vo.getValue();
|
||||
return vo == null ? null : getActualValue(vo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -57,4 +59,17 @@ public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoo
|
|||
}
|
||||
super.addDetail(new StoragePoolDetailVO(resourceId, key, value, display));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Scope, Long> getParentScope(long id) {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(id);
|
||||
if (pool != null) {
|
||||
if (pool.getClusterId() != null) {
|
||||
return new Pair<>(getScope().getParent(), pool.getClusterId());
|
||||
} else {
|
||||
return new Pair<>(ConfigKey.Scope.Zone, pool.getDataCenterId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public interface StoragePoolHostDao extends GenericDao<StoragePoolHostVO, Long>
|
|||
|
||||
List<Long> findHostsConnectedToPools(List<Long> poolIds);
|
||||
|
||||
List<Pair<Long, Integer>> getDatacenterStoragePoolHostInfo(long dcId, boolean sharedOnly);
|
||||
boolean hasDatacenterStoragePoolHostInfo(long dcId, boolean sharedOnly);
|
||||
|
||||
public void deletePrimaryRecordsForHost(long hostId);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase<StoragePoolHostVO, Lo
|
|||
|
||||
protected static final String HOSTS_FOR_POOLS_SEARCH = "SELECT DISTINCT(ph.host_id) FROM storage_pool_host_ref ph, host h WHERE ph.host_id = h.id AND h.status = 'Up' AND resource_state = 'Enabled' AND ph.pool_id IN (?)";
|
||||
|
||||
protected static final String STORAGE_POOL_HOST_INFO = "SELECT p.data_center_id, count(ph.host_id) " + " FROM storage_pool p, storage_pool_host_ref ph "
|
||||
+ " WHERE p.id = ph.pool_id AND p.data_center_id = ? " + " GROUP by p.data_center_id";
|
||||
protected static final String STORAGE_POOL_HOST_INFO = "SELECT (SELECT id FROM storage_pool_host_ref ph WHERE " +
|
||||
"ph.pool_id=p.id limit 1) AS sphr FROM storage_pool p WHERE p.data_center_id = ?";
|
||||
|
||||
protected static final String SHARED_STORAGE_POOL_HOST_INFO = "SELECT p.data_center_id, count(ph.host_id) " + " FROM storage_pool p, storage_pool_host_ref ph "
|
||||
+ " WHERE p.id = ph.pool_id AND p.data_center_id = ? " + " AND p.pool_type NOT IN ('LVM', 'Filesystem')" + " GROUP by p.data_center_id";
|
||||
protected static final String SHARED_STORAGE_POOL_HOST_INFO = "SELECT (SELECT id FROM storage_pool_host_ref ph " +
|
||||
"WHERE ph.pool_id=p.id limit 1) AS sphr FROM storage_pool p WHERE p.data_center_id = ? AND p.pool_type NOT IN ('LVM', 'Filesystem')";
|
||||
|
||||
protected static final String DELETE_PRIMARY_RECORDS = "DELETE " + "FROM storage_pool_host_ref " + "WHERE host_id = ?";
|
||||
|
||||
|
|
@ -169,23 +169,23 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase<StoragePoolHostVO, Lo
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<Long, Integer>> getDatacenterStoragePoolHostInfo(long dcId, boolean sharedOnly) {
|
||||
ArrayList<Pair<Long, Integer>> l = new ArrayList<Pair<Long, Integer>>();
|
||||
public boolean hasDatacenterStoragePoolHostInfo(long dcId, boolean sharedOnly) {
|
||||
Long poolCount = 0L;
|
||||
String sql = sharedOnly ? SHARED_STORAGE_POOL_HOST_INFO : STORAGE_POOL_HOST_INFO;
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql)) {
|
||||
pstmt.setLong(1, dcId);
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
l.add(new Pair<Long, Integer>(rs.getLong(1), rs.getInt(2)));
|
||||
poolCount = rs.getLong(1);
|
||||
if (poolCount > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.debug("SQLException: ", e);
|
||||
}
|
||||
return l;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
|||
|
||||
public List<VMTemplateVO> userIsoSearch(boolean listRemoved);
|
||||
|
||||
List<VMTemplateVO> listAllReadySystemVMTemplates(Long zoneId);
|
||||
|
||||
VMTemplateVO findSystemVMTemplate(long zoneId);
|
||||
|
||||
VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType);
|
||||
|
|
@ -91,6 +93,5 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
|
|||
|
||||
List<VMTemplateVO> listByIds(List<Long> ids);
|
||||
|
||||
List<VMTemplateVO> listByTemplateTag(String tag);
|
||||
|
||||
List<Long> listIdsByTemplateTag(String tag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,19 +344,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
readySystemTemplateSearch = createSearchBuilder();
|
||||
readySystemTemplateSearch.and("state", readySystemTemplateSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
readySystemTemplateSearch.and("templateType", readySystemTemplateSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
|
||||
readySystemTemplateSearch.and("hypervisorType", readySystemTemplateSearch.entity().getHypervisorType(), SearchCriteria.Op.IN);
|
||||
SearchBuilder<TemplateDataStoreVO> templateDownloadSearch = _templateDataStoreDao.createSearchBuilder();
|
||||
templateDownloadSearch.and("downloadState", templateDownloadSearch.entity().getDownloadState(), SearchCriteria.Op.IN);
|
||||
readySystemTemplateSearch.join("vmTemplateJoinTemplateStoreRef", templateDownloadSearch, templateDownloadSearch.entity().getTemplateId(),
|
||||
readySystemTemplateSearch.entity().getId(), JoinBuilder.JoinType.INNER);
|
||||
SearchBuilder<HostVO> hostHyperSearch2 = _hostDao.createSearchBuilder();
|
||||
hostHyperSearch2.and("type", hostHyperSearch2.entity().getType(), SearchCriteria.Op.EQ);
|
||||
hostHyperSearch2.and("zoneId", hostHyperSearch2.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
hostHyperSearch2.and("removed", hostHyperSearch2.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
hostHyperSearch2.groupBy(hostHyperSearch2.entity().getHypervisorType());
|
||||
|
||||
readySystemTemplateSearch.join("tmplHyper", hostHyperSearch2, hostHyperSearch2.entity().getHypervisorType(), readySystemTemplateSearch.entity()
|
||||
.getHypervisorType(), JoinBuilder.JoinType.INNER);
|
||||
hostHyperSearch2.done();
|
||||
readySystemTemplateSearch.groupBy(readySystemTemplateSearch.entity().getId());
|
||||
readySystemTemplateSearch.done();
|
||||
|
||||
tmpltTypeHyperSearch2 = createSearchBuilder();
|
||||
|
|
@ -556,29 +549,35 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) {
|
||||
public List<VMTemplateVO> listAllReadySystemVMTemplates(Long zoneId) {
|
||||
List<HypervisorType> availableHypervisors = _hostDao.listDistinctHypervisorTypes(zoneId);
|
||||
if (CollectionUtils.isEmpty(availableHypervisors)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
SearchCriteria<VMTemplateVO> sc = readySystemTemplateSearch.create();
|
||||
sc.setParameters("templateType", Storage.TemplateType.SYSTEM);
|
||||
sc.setParameters("state", VirtualMachineTemplate.State.Active);
|
||||
sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing);
|
||||
sc.setJoinParameters("tmplHyper", "zoneId", zoneId);
|
||||
sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState", new VMTemplateStorageResourceAssoc.Status[] {VMTemplateStorageResourceAssoc.Status.DOWNLOADED, VMTemplateStorageResourceAssoc.Status.BYPASSED});
|
||||
|
||||
sc.setParameters("hypervisorType", availableHypervisors.toArray());
|
||||
sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState",
|
||||
List.of(VMTemplateStorageResourceAssoc.Status.DOWNLOADED,
|
||||
VMTemplateStorageResourceAssoc.Status.BYPASSED).toArray());
|
||||
// order by descending order of id
|
||||
List<VMTemplateVO> tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null));
|
||||
|
||||
if (tmplts.size() > 0) {
|
||||
if (hypervisorType == HypervisorType.Any) {
|
||||
return tmplts.get(0);
|
||||
}
|
||||
for (VMTemplateVO tmplt : tmplts) {
|
||||
if (tmplt.getHypervisorType() == hypervisorType) {
|
||||
return tmplt;
|
||||
}
|
||||
}
|
||||
return listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) {
|
||||
List<VMTemplateVO> templates = listAllReadySystemVMTemplates(zoneId);
|
||||
if (CollectionUtils.isEmpty(templates)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
if (hypervisorType == HypervisorType.Any) {
|
||||
return templates.get(0);
|
||||
}
|
||||
return templates.stream()
|
||||
.filter(t -> t.getHypervisorType() == hypervisorType)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -687,13 +686,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<VMTemplateVO> listByTemplateTag(String tag) {
|
||||
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
|
||||
public List<Long> listIdsByTemplateTag(String tag) {
|
||||
GenericSearchBuilder<VMTemplateVO, Long> sb = createSearchBuilder(Long.class);
|
||||
sb.selectFields(sb.entity().getId());
|
||||
sb.and("tag", sb.entity().getTemplateTag(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
SearchCriteria<VMTemplateVO> sc = sb.create();
|
||||
SearchCriteria<Long> sc = sb.create();
|
||||
sc.setParameters("tag", tag);
|
||||
return listIncludingRemovedBy(sc);
|
||||
return customSearchIncludingRemoved(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -571,14 +571,6 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
}
|
||||
}
|
||||
|
||||
public static class SumCount {
|
||||
public long sum;
|
||||
public long count;
|
||||
|
||||
public SumCount() {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> listVolumesToBeDestroyed() {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public class ConfigurationGroupsAggregator {
|
|||
|
||||
public void updateConfigurationGroups() {
|
||||
LOG.debug("Updating configuration groups");
|
||||
List<ConfigurationVO> configs = configDao.listAllIncludingRemoved();
|
||||
List<ConfigurationVO> configs = configDao.searchPartialConfigurations();
|
||||
if (CollectionUtils.isEmpty(configs)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ public class SystemVmTemplateRegistration {
|
|||
}
|
||||
};
|
||||
|
||||
public static boolean validateIfSeeded(String url, String path, String nfsVersion) {
|
||||
public boolean validateIfSeeded(TemplateDataStoreVO templDataStoreVO, String url, String path, String nfsVersion) {
|
||||
String filePath = null;
|
||||
try {
|
||||
filePath = Files.createTempDirectory(TEMPORARY_SECONDARY_STORE).toString();
|
||||
|
|
@ -347,6 +347,9 @@ public class SystemVmTemplateRegistration {
|
|||
String templatePath = filePath + File.separator + partialDirPath;
|
||||
File templateProps = new File(templatePath + "/template.properties");
|
||||
if (templateProps.exists()) {
|
||||
Pair<Long, Long> templateSizes = readTemplatePropertiesSizes(templatePath + "/template.properties");
|
||||
updateSeededTemplateDetails(templDataStoreVO.getTemplateId(), templDataStoreVO.getDataStoreId(),
|
||||
templateSizes.first(), templateSizes.second());
|
||||
LOGGER.info("SystemVM template already seeded, skipping registration");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -542,6 +545,21 @@ public class SystemVmTemplateRegistration {
|
|||
}
|
||||
}
|
||||
|
||||
public void updateSeededTemplateDetails(long templateId, long storeId, long size, long physicalSize) {
|
||||
VMTemplateVO template = vmTemplateDao.findById(templateId);
|
||||
template.setSize(size);
|
||||
vmTemplateDao.update(template.getId(), template);
|
||||
|
||||
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeId, template.getId());
|
||||
templateDataStoreVO.setSize(size);
|
||||
templateDataStoreVO.setPhysicalSize(physicalSize);
|
||||
templateDataStoreVO.setLastUpdated(new Date(DateUtil.currentGMTTime().getTime()));
|
||||
boolean updated = templateDataStoreDao.update(templateDataStoreVO.getId(), templateDataStoreVO);
|
||||
if (!updated) {
|
||||
throw new CloudRuntimeException("Failed to update template_store_ref entry for seeded systemVM template");
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSystemVMEntries(Long templateId, Hypervisor.HypervisorType hypervisorType) {
|
||||
vmInstanceDao.updateSystemVmTemplateId(templateId, hypervisorType);
|
||||
}
|
||||
|
|
@ -555,7 +573,7 @@ public class SystemVmTemplateRegistration {
|
|||
}
|
||||
}
|
||||
|
||||
private static void readTemplateProperties(String path, SystemVMTemplateDetails details) {
|
||||
private static Pair<Long, Long> readTemplatePropertiesSizes(String path) {
|
||||
File tmpFile = new File(path);
|
||||
Long size = null;
|
||||
Long physicalSize = 0L;
|
||||
|
|
@ -574,8 +592,13 @@ public class SystemVmTemplateRegistration {
|
|||
} catch (IOException ex) {
|
||||
LOGGER.warn("Failed to read from template.properties", ex);
|
||||
}
|
||||
details.setSize(size);
|
||||
details.setPhysicalSize(physicalSize);
|
||||
return new Pair<>(size, physicalSize);
|
||||
}
|
||||
|
||||
public static void readTemplateProperties(String path, SystemVMTemplateDetails details) {
|
||||
Pair<Long, Long> templateSizes = readTemplatePropertiesSizes(path);
|
||||
details.setSize(templateSizes.first());
|
||||
details.setPhysicalSize(templateSizes.second());
|
||||
}
|
||||
|
||||
private void updateTemplateTablesOnFailure(long templateId) {
|
||||
|
|
@ -799,7 +822,7 @@ public class SystemVmTemplateRegistration {
|
|||
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateId);
|
||||
if (templateDataStoreVO != null) {
|
||||
String installPath = templateDataStoreVO.getInstallPath();
|
||||
if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) {
|
||||
if (validateIfSeeded(templateDataStoreVO, storeUrlAndId.first(), installPath, nfsVersion)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -870,7 +893,7 @@ public class SystemVmTemplateRegistration {
|
|||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||
Set<Hypervisor.HypervisorType> hypervisorsListInUse = new HashSet<Hypervisor.HypervisorType>();
|
||||
try {
|
||||
hypervisorsListInUse = clusterDao.getDistictAvailableHypervisorsAcrossClusters();
|
||||
hypervisorsListInUse = clusterDao.getDistinctAvailableHypervisorsAcrossClusters();
|
||||
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("updateSystemVmTemplates: Exception caught while getting hypervisor types from clusters: " + e.getMessage());
|
||||
|
|
|
|||
|
|
@ -87,6 +87,36 @@ public class DatabaseAccessObject {
|
|||
return columnExists;
|
||||
}
|
||||
|
||||
public String getColumnType(Connection conn, String tableName, String columnName) {
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(String.format("DESCRIBE %s %s", tableName, columnName));){
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getString("Type");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Type for column {} can not be retrieved in {} ignoring exception: {}", columnName, tableName, e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addColumn(Connection conn, String tableName, String columnName, String columnDefinition) {
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(String.format("ALTER TABLE %s ADD COLUMN %s %s", tableName, columnName, columnDefinition));){
|
||||
pstmt.executeUpdate();
|
||||
logger.debug("Column {} is added successfully from the table {}", columnName, tableName);
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Unable to add column {} to table {} due to exception", columnName, tableName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void changeColumn(Connection conn, String tableName, String oldColumnName, String newColumnName, String columnDefinition) {
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(String.format("ALTER TABLE %s CHANGE COLUMN %s %s %s", tableName, oldColumnName, newColumnName, columnDefinition));){
|
||||
pstmt.executeUpdate();
|
||||
logger.debug("Column {} is changed successfully to {} from the table {}", oldColumnName, newColumnName, tableName);
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Unable to add column {} to {} from the table {} due to exception", oldColumnName, newColumnName, tableName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public String generateIndexName(String tableName, String... columnName) {
|
||||
return String.format("i_%s__%s", tableName, StringUtils.join(columnName, "__"));
|
||||
}
|
||||
|
|
@ -114,6 +144,17 @@ public class DatabaseAccessObject {
|
|||
}
|
||||
}
|
||||
|
||||
public void renameIndex(Connection conn, String tableName, String oldName, String newName) {
|
||||
String stmt = String.format("ALTER TABLE %s RENAME INDEX %s TO %s", tableName, oldName, newName);
|
||||
logger.debug("Statement: {}", stmt);
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(stmt)) {
|
||||
pstmt.execute();
|
||||
logger.debug("Renamed index {} to {}", oldName, newName);
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Unable to rename index {} to {}", oldName, newName, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void closePreparedStatement(PreparedStatement pstmt, String errorMessage) {
|
||||
try {
|
||||
if (pstmt != null) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@ public class DbUpgradeUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void renameIndexIfNeeded(Connection conn, String tableName, String oldName, String newName) {
|
||||
if (!dao.indexExists(conn, tableName, oldName)) {
|
||||
dao.renameIndex(conn, tableName, oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addForeignKey(Connection conn, String tableName, String tableColumn, String foreignTableName, String foreignColumnName) {
|
||||
dao.addForeignKey(conn, tableName, tableColumn, foreignTableName, foreignColumnName);
|
||||
}
|
||||
|
|
@ -52,4 +58,20 @@ public class DbUpgradeUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getTableColumnType(Connection conn, String tableName, String columnName) {
|
||||
return dao.getColumnType(conn, tableName, columnName);
|
||||
}
|
||||
|
||||
public static void addTableColumnIfNotExist(Connection conn, String tableName, String columnName, String columnDefinition) {
|
||||
if (!dao.columnExists(conn, tableName, columnName)) {
|
||||
dao.addColumn(conn, tableName, columnName, columnDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
public static void changeTableColumnIfNotExist(Connection conn, String tableName, String oldColumnName, String newColumnName, String columnDefinition) {
|
||||
if (dao.columnExists(conn, tableName, oldColumnName)) {
|
||||
dao.changeColumn(conn, tableName, oldColumnName, newColumnName, columnDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public class Upgrade42000to42010 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
addIndexes(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,4 +81,42 @@ public class Upgrade42000to42010 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)");
|
||||
}
|
||||
}
|
||||
|
||||
private void addIndexes(Connection conn) {
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "host", "mgmt_server_id");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "host", "resource");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "host", "resource_state");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "host", "type");
|
||||
|
||||
DbUpgradeUtils.renameIndexIfNeeded(conn, "user_ip_address", "public_ip_address", "uk_public_ip_address");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "user_ip_address", "public_ip_address");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "user_ip_address", "data_center_id");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "user_ip_address", "vlan_db_id");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "user_ip_address", "removed");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "vlan", "vlan_type");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "vlan", "data_center_id");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "vlan", "removed");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "network_offering_details", "name");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "network_offering_details", "resource_id", "resource_type");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "service_offering", "cpu");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "service_offering", "speed");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "service_offering", "ram_size");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "op_host_planner_reservation", "resource_usage");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "storage_pool", "pool_type");
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "storage_pool", "data_center_id", "status", "scope", "hypervisor");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "router_network_ref", "guest_type");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "domain_router", "role");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "async_job", "instance_type", "job_status");
|
||||
|
||||
DbUpgradeUtils.addIndexIfNeeded(conn, "cluster", "managed_state");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,16 @@
|
|||
package com.cloud.upgrade.dao;
|
||||
|
||||
import com.cloud.upgrade.SystemVmTemplateRegistration;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
public class Upgrade42010to42100 extends DbUpgradeAbstractImpl implements DbUpgrade, DbUpgradeSystemVmTemplate {
|
||||
private SystemVmTemplateRegistration systemVmTemplateRegistration;
|
||||
|
|
@ -53,6 +59,7 @@ public class Upgrade42010to42100 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
migrateConfigurationScopeToBitmask(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,4 +87,35 @@ public class Upgrade42010to42100 extends DbUpgradeAbstractImpl implements DbUpgr
|
|||
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)");
|
||||
}
|
||||
}
|
||||
|
||||
protected void migrateConfigurationScopeToBitmask(Connection conn) {
|
||||
String scopeDataType = DbUpgradeUtils.getTableColumnType(conn, "configuration", "scope");
|
||||
logger.info("Data type of the column scope of table configuration is {}", scopeDataType);
|
||||
if (!"varchar(255)".equals(scopeDataType)) {
|
||||
return;
|
||||
}
|
||||
DbUpgradeUtils.addTableColumnIfNotExist(conn, "configuration", "new_scope", "BIGINT DEFAULT 0");
|
||||
migrateExistingConfigurationScopeValues(conn);
|
||||
DbUpgradeUtils.dropTableColumnsIfExist(conn, "configuration", List.of("scope"));
|
||||
DbUpgradeUtils.changeTableColumnIfNotExist(conn, "configuration", "new_scope", "scope", "BIGINT NOT NULL DEFAULT 0 COMMENT 'Bitmask for scope(s) of this parameter'");
|
||||
}
|
||||
|
||||
protected void migrateExistingConfigurationScopeValues(Connection conn) {
|
||||
StringBuilder sql = new StringBuilder("UPDATE configuration\n" +
|
||||
"SET new_scope = " +
|
||||
" CASE ");
|
||||
for (ConfigKey.Scope scope : ConfigKey.Scope.values()) {
|
||||
sql.append(" WHEN scope = '").append(scope.name()).append("' THEN ").append(scope.getBitValue()).append(" ");
|
||||
}
|
||||
sql.append(" ELSE 0 " +
|
||||
" END " +
|
||||
"WHERE scope IS NOT NULL;");
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql.toString())) {
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Failed to migrate existing configuration scope values to bitmask", e);
|
||||
throw new CloudRuntimeException(String.format("Failed to migrate existing configuration scope values to bitmask due to: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.usage.UsageNetworksVO;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
|
@ -70,11 +69,10 @@ public class UsageNetworksDaoImpl extends GenericDaoBase<UsageNetworksVO, Long>
|
|||
SearchCriteria<UsageNetworksVO> sc = this.createSearchCriteria();
|
||||
sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
UsageNetworksVO vo = findOneBy(sc);
|
||||
if (vo != null) {
|
||||
vo.setRemoved(removed);
|
||||
vo.setState(Network.State.Destroy.name());
|
||||
update(vo.getId(), vo);
|
||||
List<UsageNetworksVO> usageNetworksVOs = listBy(sc);
|
||||
for (UsageNetworksVO entry : usageNetworksVOs) {
|
||||
entry.setRemoved(removed);
|
||||
update(entry.getId(), entry);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
txn.rollback();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.usage.UsageVpcVO;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
|
@ -64,11 +63,10 @@ public class UsageVpcDaoImpl extends GenericDaoBase<UsageVpcVO, Long> implements
|
|||
SearchCriteria<UsageVpcVO> sc = this.createSearchCriteria();
|
||||
sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
|
||||
sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||
UsageVpcVO vo = findOneBy(sc);
|
||||
if (vo != null) {
|
||||
vo.setRemoved(removed);
|
||||
vo.setState(Vpc.State.Inactive.name());
|
||||
update(vo.getId(), vo);
|
||||
List<UsageVpcVO> usageVpcVOs = listBy(sc);
|
||||
for (UsageVpcVO entry : usageVpcVOs) {
|
||||
entry.setRemoved(removed);
|
||||
update(entry.getId(), entry);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
txn.rollback();
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
|
||||
@Entity
|
||||
@Table(name = "account_details")
|
||||
public class AccountDetailVO implements InternalIdentity {
|
||||
public class AccountDetailVO implements ResourceDetail {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
private long resourceId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
|
@ -46,13 +46,14 @@ public class AccountDetailVO implements InternalIdentity {
|
|||
}
|
||||
|
||||
public AccountDetailVO(long accountId, String name, String value) {
|
||||
this.accountId = accountId;
|
||||
this.resourceId = accountId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
@Override
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -63,6 +64,11 @@ public class AccountDetailVO implements InternalIdentity {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ package com.cloud.user;
|
|||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||
|
||||
public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long> {
|
||||
public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long>, ResourceDetailsDao<AccountDetailVO> {
|
||||
Map<String, String> findDetails(long accountId);
|
||||
|
||||
void persist(long accountId, Map<String, String> details);
|
||||
|
|
@ -34,6 +35,4 @@ public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long> {
|
|||
* they will get created
|
||||
*/
|
||||
void update(long accountId, Map<String, String> details);
|
||||
|
||||
String getActualValue(AccountDetailVO accountDetailVO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,22 +27,21 @@ import org.apache.cloudstack.framework.config.ConfigKey;
|
|||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||
|
||||
public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long> implements AccountDetailsDao, ScopedConfigStorage {
|
||||
public class AccountDetailsDaoImpl extends ResourceDetailsDaoBase<AccountDetailVO> implements AccountDetailsDao, ScopedConfigStorage {
|
||||
protected final SearchBuilder<AccountDetailVO> accountSearch;
|
||||
|
||||
@Inject
|
||||
|
|
@ -56,16 +55,16 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||
|
||||
protected AccountDetailsDaoImpl() {
|
||||
accountSearch = createSearchBuilder();
|
||||
accountSearch.and("accountId", accountSearch.entity().getAccountId(), Op.EQ);
|
||||
accountSearch.and("accountId", accountSearch.entity().getResourceId(), Op.EQ);
|
||||
accountSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long accountId) {
|
||||
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
||||
sc.and(sc.entity().getAccountId(), Op.EQ, accountId);
|
||||
sc.and(sc.entity().getResourceId(), Op.EQ, accountId);
|
||||
List<AccountDetailVO> results = sc.list();
|
||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||
Map<String, String> details = new HashMap<>(results.size());
|
||||
for (AccountDetailVO r : results) {
|
||||
details.put(r.getName(), r.getValue());
|
||||
}
|
||||
|
|
@ -89,11 +88,16 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||
@Override
|
||||
public AccountDetailVO findDetail(long accountId, String name) {
|
||||
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
||||
sc.and(sc.entity().getAccountId(), Op.EQ, accountId);
|
||||
sc.and(sc.entity().getResourceId(), Op.EQ, accountId);
|
||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||
super.addDetail(new AccountDetailVO(resourceId, key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long accountId) {
|
||||
SearchCriteria<AccountDetailVO> sc = accountSearch.create();
|
||||
|
|
@ -155,11 +159,11 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getActualValue(AccountDetailVO accountDetailVO) {
|
||||
ConfigurationVO configurationVO = _configDao.findByName(accountDetailVO.getName());
|
||||
if (configurationVO != null && configurationVO.isEncrypted()) {
|
||||
return DBEncryptionUtil.decrypt(accountDetailVO.getValue());
|
||||
public Pair<Scope, Long> getParentScope(long id) {
|
||||
Account account = _accountDao.findById(id);
|
||||
if (account == null) {
|
||||
return null;
|
||||
}
|
||||
return accountDetailVO.getValue();
|
||||
return new Pair<>(getScope().getParent(), account.getDomainId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ import javax.persistence.Table;
|
|||
import javax.persistence.Transient;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user")
|
||||
|
|
@ -131,12 +131,6 @@ public class UserAccountVO implements UserAccount, InternalIdentity {
|
|||
public UserAccountVO() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("UserAccount %s.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields
|
||||
(this, "id", "uuid", "username", "accountName"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
|
|
@ -379,4 +373,10 @@ public class UserAccountVO implements UserAccount, InternalIdentity {
|
|||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("UserAccount %s.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields
|
||||
(this, "id", "uuid", "username", "accountName"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue