mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 01:32:18 +02:00
Merge remote-tracking branch 'apache/4.20'
This commit is contained in:
commit
70a4503ea1
@ -31,20 +31,22 @@ import java.util.stream.Collectors;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.DirectDownloadTemplate;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.RootDiskSizeOverride;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.VmStorageMigration;
|
||||
import static com.cloud.hypervisor.Hypervisor.HypervisorType.Functionality.VmStorageMigrationWithSnapshots;
|
||||
|
||||
public class Hypervisor {
|
||||
public static class HypervisorType {
|
||||
public enum Functionality {
|
||||
DirectDownloadTemplate,
|
||||
RootDiskSizeOverride,
|
||||
VmStorageMigration
|
||||
VmStorageMigration,
|
||||
VmStorageMigrationWithSnapshots
|
||||
}
|
||||
|
||||
private static final Map<String, HypervisorType> hypervisorTypeMap = new LinkedHashMap<>();
|
||||
public static final HypervisorType None = new HypervisorType("None"); //for storage hosts
|
||||
public static final HypervisorType XenServer = new HypervisorType("XenServer", ImageFormat.VHD, EnumSet.of(RootDiskSizeOverride, VmStorageMigration));
|
||||
public static final HypervisorType KVM = new HypervisorType("KVM", ImageFormat.QCOW2, EnumSet.of(DirectDownloadTemplate, RootDiskSizeOverride, VmStorageMigration));
|
||||
public static final HypervisorType VMware = new HypervisorType("VMware", ImageFormat.OVA, EnumSet.of(RootDiskSizeOverride, VmStorageMigration));
|
||||
public static final HypervisorType VMware = new HypervisorType("VMware", ImageFormat.OVA, EnumSet.of(RootDiskSizeOverride, VmStorageMigration, VmStorageMigrationWithSnapshots));
|
||||
public static final HypervisorType Hyperv = new HypervisorType("Hyperv");
|
||||
public static final HypervisorType VirtualBox = new HypervisorType("VirtualBox");
|
||||
public static final HypervisorType Parralels = new HypervisorType("Parralels");
|
||||
|
||||
@ -60,6 +60,7 @@ public interface KubernetesCluster extends ControlledEntity, com.cloud.utils.fsm
|
||||
Stopping("Resources for the Kubernetes cluster are being destroyed"),
|
||||
Stopped("All resources for the Kubernetes cluster are destroyed, Kubernetes cluster may still have ephemeral resource like persistent volumes provisioned"),
|
||||
Scaling("Transient state in which resources are either getting scaled up/down"),
|
||||
ScalingStoppedCluster("Transient state in which the service offerings of stopped clusters are getting scaled"),
|
||||
Upgrading("Transient state in which cluster is getting upgraded"),
|
||||
Importing("Transient state in which additional nodes are added as worker nodes to a cluster"),
|
||||
RemovingNodes("Transient state in which additional nodes are removed from a cluster"),
|
||||
@ -93,8 +94,11 @@ public interface KubernetesCluster extends ControlledEntity, com.cloud.utils.fsm
|
||||
s_fsm.addTransition(State.Running, Event.AutoscaleRequested, State.Scaling);
|
||||
s_fsm.addTransition(State.Running, Event.ScaleUpRequested, State.Scaling);
|
||||
s_fsm.addTransition(State.Running, Event.ScaleDownRequested, State.Scaling);
|
||||
s_fsm.addTransition(State.Stopped, Event.ScaleUpRequested, State.ScalingStoppedCluster);
|
||||
s_fsm.addTransition(State.Scaling, Event.OperationSucceeded, State.Running);
|
||||
s_fsm.addTransition(State.Scaling, Event.OperationFailed, State.Alert);
|
||||
s_fsm.addTransition(State.ScalingStoppedCluster, Event.OperationSucceeded, State.Stopped);
|
||||
s_fsm.addTransition(State.ScalingStoppedCluster, Event.OperationFailed, State.Alert);
|
||||
|
||||
s_fsm.addTransition(State.Running, Event.UpgradeRequested, State.Upgrading);
|
||||
s_fsm.addTransition(State.Upgrading, Event.OperationSucceeded, State.Running);
|
||||
|
||||
@ -809,7 +809,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
||||
if (ObjectUtils.anyNotNull(uefiEnabled, virtv2vVersion, ovftoolVersion)) {
|
||||
_hostDao.loadDetails(host);
|
||||
boolean updateNeeded = false;
|
||||
if (!uefiEnabled.equals(host.getDetails().get(Host.HOST_UEFI_ENABLE))) {
|
||||
if (StringUtils.isNotBlank(uefiEnabled) && !uefiEnabled.equals(host.getDetails().get(Host.HOST_UEFI_ENABLE))) {
|
||||
host.getDetails().put(Host.HOST_UEFI_ENABLE, uefiEnabled);
|
||||
updateNeeded = true;
|
||||
}
|
||||
|
||||
@ -1902,6 +1902,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return "";
|
||||
}
|
||||
|
||||
public Integer getVlanIdForBridge(final String bridge) {
|
||||
String pif = matchPifFileInDirectory(bridge);
|
||||
final File vlanfile = new File("/proc/net/vlan/" + pif);
|
||||
if (vlanfile.isFile()) {
|
||||
String vlan = Script.runSimpleBashScript("awk '/VID:/ {print $3}' /proc/net/vlan/" + pif);
|
||||
try {
|
||||
return Integer.parseInt(vlan);
|
||||
} catch (final NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static String [] ifNamePatterns = {
|
||||
"^eth",
|
||||
"^bond",
|
||||
|
||||
@ -132,7 +132,7 @@ public final class LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
|
||||
}
|
||||
instance.setPowerState(getPowerState(libvirtComputingResource.getVmState(conn,domain.getName())));
|
||||
instance.setMemory((int) LibvirtComputingResource.getDomainMemory(domain) / 1024);
|
||||
instance.setNics(getUnmanagedInstanceNics(parser.getInterfaces()));
|
||||
instance.setNics(getUnmanagedInstanceNics(libvirtComputingResource, parser.getInterfaces()));
|
||||
instance.setDisks(getUnmanagedInstanceDisks(parser.getDisks(),libvirtComputingResource, conn, domain.getName()));
|
||||
instance.setVncPassword(getFormattedVncPassword(parser.getVncPasswd()));
|
||||
if (parser.getBootType() != null) {
|
||||
@ -169,7 +169,7 @@ public final class LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
|
||||
}
|
||||
}
|
||||
|
||||
private List<UnmanagedInstanceTO.Nic> getUnmanagedInstanceNics(List<LibvirtVMDef.InterfaceDef> interfaces) {
|
||||
private List<UnmanagedInstanceTO.Nic> getUnmanagedInstanceNics(LibvirtComputingResource libvirtComputingResource, List<LibvirtVMDef.InterfaceDef> interfaces) {
|
||||
final ArrayList<UnmanagedInstanceTO.Nic> nics = new ArrayList<>(interfaces.size());
|
||||
int counter = 0;
|
||||
for (LibvirtVMDef.InterfaceDef interfaceDef : interfaces) {
|
||||
@ -180,6 +180,10 @@ public final class LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
|
||||
nic.setNetwork(interfaceDef.getDevName());
|
||||
nic.setPciSlot(interfaceDef.getSlot().toString());
|
||||
nic.setVlan(interfaceDef.getVlanTag());
|
||||
if (nic.getVlan() == -1
|
||||
&& LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE.equals(interfaceDef.getNetType())) {
|
||||
nic.setVlan(libvirtComputingResource.getVlanIdForBridge(interfaceDef.getBrName()));
|
||||
}
|
||||
nics.add(nic);
|
||||
}
|
||||
return nics;
|
||||
|
||||
@ -358,7 +358,8 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
|
||||
private void scaleKubernetesClusterOffering(KubernetesClusterNodeType nodeType, ServiceOffering serviceOffering,
|
||||
boolean updateNodeOffering, boolean updateClusterOffering) throws CloudRuntimeException {
|
||||
validateKubernetesClusterScaleOfferingParameters();
|
||||
if (!kubernetesCluster.getState().equals(KubernetesCluster.State.Scaling)) {
|
||||
List<KubernetesCluster.State> scalingStates = List.of(KubernetesCluster.State.Scaling, KubernetesCluster.State.ScalingStoppedCluster);
|
||||
if (!scalingStates.contains(kubernetesCluster.getState())) {
|
||||
stateTransitTo(kubernetesCluster.getId(), KubernetesCluster.Event.ScaleUpRequested);
|
||||
}
|
||||
if (KubernetesCluster.State.Created.equals(originalState)) {
|
||||
@ -581,6 +582,8 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
|
||||
scaleKubernetesClusterOffering(nodeType, scalingServiceOffering, updateNodeOffering, updateClusterOffering);
|
||||
} else if (clusterSizeScalingNeeded) {
|
||||
scaleKubernetesClusterSize(nodeType);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7712,7 +7712,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
HypervisorType.getListOfHypervisorsSupportingFunctionality(Functionality.VmStorageMigration)));
|
||||
}
|
||||
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
|
||||
if (!vm.getHypervisorType().isFunctionalitySupported(Functionality.VmStorageMigrationWithSnapshots) &&
|
||||
CollectionUtils.isNotEmpty(_vmSnapshotDao.findByVm(vmId))) {
|
||||
throw new InvalidParameterValueException("VM with VM Snapshots cannot be migrated with storage, please remove all VM snapshots");
|
||||
}
|
||||
|
||||
|
||||
@ -85,9 +85,11 @@ import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.cloudstack.utils.security.DigestHelper;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
@ -2742,6 +2744,20 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
|
||||
}
|
||||
|
||||
protected void configureStorageNetwork(Map<String, Object> params) {
|
||||
_storageIp = MapUtils.getString(params, "storageip");
|
||||
_storageNetmask = (String) params.get("storagenetmask");
|
||||
_storageGateway = (String) params.get("storagegateway");
|
||||
if (_storageIp == null && _inSystemVM && _eth1ip != null) {
|
||||
String eth1Gateway = ObjectUtils.firstNonNull(_localgw, MapUtils.getString(params, "localgw"));
|
||||
logger.info("Storage network not configured, using management network[ip: {}, netmask: {}, gateway: {}] for storage traffic",
|
||||
_eth1ip, _eth1mask, eth1Gateway);
|
||||
_storageIp = _eth1ip;
|
||||
_storageNetmask = _eth1mask;
|
||||
_storageGateway = eth1Gateway;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_eth1ip = (String)params.get("eth1ip");
|
||||
@ -2764,12 +2780,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
_inSystemVM = true;
|
||||
}
|
||||
|
||||
_storageIp = (String)params.get("storageip");
|
||||
configureStorageNetwork(params);
|
||||
if (_storageIp == null && _inSystemVM) {
|
||||
logger.warn("There is no storageip in /proc/cmdline, something wrong!");
|
||||
logger.warn("No storageip in /proc/cmdline, something wrong! Even fallback to management network did not resolve storage IP.");
|
||||
}
|
||||
_storageNetmask = (String)params.get("storagenetmask");
|
||||
_storageGateway = (String)params.get("storagegateway");
|
||||
super.configure(name, params);
|
||||
|
||||
_params = params;
|
||||
|
||||
@ -18,35 +18,38 @@
|
||||
*/
|
||||
package org.apache.cloudstack.storage.resource;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.EncryptionUtil;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import org.apache.cloudstack.storage.command.DeleteCommand;
|
||||
import org.apache.cloudstack.storage.command.QuerySnapshotZoneCopyAnswer;
|
||||
import org.apache.cloudstack.storage.command.QuerySnapshotZoneCopyCommand;
|
||||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import static org.mockito.Mockito.times;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.EncryptionUtil;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NfsSecondaryStorageResourceTest {
|
||||
@ -241,4 +244,45 @@ public class NfsSecondaryStorageResourceTest {
|
||||
|
||||
Assert.assertEquals(NetUtils.HTTP_PROTO, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureStorageNetworkSetsStorageNetworkWhenParamsContainValues() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
String ip = "192.168.1.10";
|
||||
String netmask = "255.255.255.0";
|
||||
String gateway = "192.168.1.1";
|
||||
params.put("storageip", ip);
|
||||
params.put("storagenetmask", netmask);
|
||||
params.put("storagegateway", gateway);
|
||||
resource.configureStorageNetwork(params);
|
||||
Assert.assertEquals(ip, ReflectionTestUtils.getField(resource, "_storageIp"));
|
||||
Assert.assertEquals(netmask, ReflectionTestUtils.getField(resource, "_storageNetmask"));
|
||||
Assert.assertEquals(gateway, ReflectionTestUtils.getField(resource, "_storageGateway"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureStorageNetworkUsesManagementNetworkWhenStorageIpIsNullAndInSystemVM() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
resource._inSystemVM = true;
|
||||
String ip = "10.0.0.10";
|
||||
String netmask = "255.255.255.0";
|
||||
String gateway = "10.0.0.1";
|
||||
ReflectionTestUtils.setField(resource, "_eth1ip", ip);
|
||||
ReflectionTestUtils.setField(resource, "_eth1mask", netmask);
|
||||
ReflectionTestUtils.setField(resource, "_localgw", gateway);
|
||||
resource.configureStorageNetwork(params);
|
||||
Assert.assertEquals(ip, ReflectionTestUtils.getField(resource, "_storageIp"));
|
||||
Assert.assertEquals(netmask, ReflectionTestUtils.getField(resource, "_storageNetmask"));
|
||||
Assert.assertEquals(gateway, ReflectionTestUtils.getField(resource, "_storageGateway"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureStorageNetworkDoesNotSetStorageNetworkWhenNotInSystemVMAndStorageIpIsNull() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
resource._inSystemVM = false;
|
||||
resource.configureStorageNetwork(params);
|
||||
Assert.assertNull(ReflectionTestUtils.getField(resource, "_storageIp"));
|
||||
Assert.assertNull(ReflectionTestUtils.getField(resource, "_storageNetmask"));
|
||||
Assert.assertNull(ReflectionTestUtils.getField(resource, "_storageGateway"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,6 +232,8 @@ class CsNetfilters(object):
|
||||
if hook == "input" or hook == "output":
|
||||
CsHelper.execute("nft add rule %s %s %s icmpv6 type { echo-request, echo-reply, \
|
||||
nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept" % (address_family, table, chain))
|
||||
elif hook == "forward":
|
||||
CsHelper.execute("nft add rule %s %s %s ct state established,related accept" % (address_family, table, chain))
|
||||
|
||||
def add_ip4_chain(self, address_family, table, chain, hook, action):
|
||||
chain_policy = ""
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
<a-select
|
||||
style="width: 100%"
|
||||
v-if="validNetworks[record.id] && validNetworks[record.id].length > 0"
|
||||
:defaultValue="validNetworks[record.id][0].id"
|
||||
:defaultValue="getDefaultNetwork(record)"
|
||||
@change="val => handleNetworkChange(record, val)"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
@ -265,7 +265,16 @@ export default {
|
||||
this.values = {}
|
||||
this.ipAddresses = {}
|
||||
for (const item of this.items) {
|
||||
var network = this.validNetworks[item.id]?.[0] || null
|
||||
let network = null
|
||||
if (item.vlanid && item.vlanid !== -1) {
|
||||
const matched = this.validNetworks[item.id].filter(x => Number(x.vlan) === item.vlanid)
|
||||
if (matched.length > 0) {
|
||||
network = matched[0]
|
||||
}
|
||||
}
|
||||
if (!network) {
|
||||
network = this.validNetworks[item.id]?.[0] || null
|
||||
}
|
||||
this.values[item.id] = network ? network.id : ''
|
||||
this.ipAddresses[item.id] = (!network || network.type === 'L2') ? null : 'auto'
|
||||
this.setIpAddressEnabled(item, network)
|
||||
@ -280,6 +289,9 @@ export default {
|
||||
}
|
||||
this.sendValuesTimed()
|
||||
},
|
||||
getDefaultNetwork (record) {
|
||||
return this.values[record.id] || this.validNetworks[record.id]?.[0]?.id
|
||||
},
|
||||
sendValuesTimed () {
|
||||
clearTimeout(this.sendValuesTimer)
|
||||
this.sendValuesTimer = setTimeout(() => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user