Skip to content

Commit 431c352

Browse files
Pearl1594shatoboar
andauthored
Synchronization of network devices on newly added hosts for Persistent Networks (#5977)
* Persistent Network feature & Marvin component tests * Cleaned up comments and imports * fixed small error * add support to add setup persistent networks' resources when a disabled host is enabled * small fix * use wildcard instead of hard-coding the bridge name * allow clean up of resources when removing a host in maintenance mode * skip test for simulator hypervisor Co-authored-by: shatoboar <sang-woo.bae@campus.tu-berlin.de>
1 parent 5435b0a commit 431c352

File tree

17 files changed

+448
-149
lines changed

17 files changed

+448
-149
lines changed

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ public interface HypervisorHostListener {
3030
boolean hostAboutToBeRemoved(long hostId);
3131

3232
boolean hostRemoved(long hostId, long clusterId);
33+
34+
boolean hostEnabled(long hostId);
3335
}

engine/components-api/src/main/java/com/cloud/storage/StorageManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ public interface StorageManager extends StorageService {
280280

281281
void disconnectHostFromSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
282282

283+
void enableHost(long hostId) throws StorageUnavailableException, StorageConflictException;
284+
283285
void createCapacityEntry(long poolId);
284286

285287
DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws ConnectionException;

engine/orchestration/src/main/java/com/cloud/agent/manager/AgentAttache.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.concurrent.ScheduledExecutorService;
3232
import java.util.concurrent.TimeUnit;
3333

34+
import com.cloud.agent.api.CleanupPersistentNetworkResourceCommand;
3435
import org.apache.cloudstack.agent.lb.SetupMSListCommand;
3536
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
3637
import org.apache.log4j.Logger;
@@ -118,7 +119,8 @@ public int compare(final Object o1, final Object o2) {
118119
StopCommand.class.toString(), CheckVirtualMachineCommand.class.toString(), PingTestCommand.class.toString(), CheckHealthCommand.class.toString(),
119120
ReadyCommand.class.toString(), ShutdownCommand.class.toString(), SetupCommand.class.toString(),
120121
CleanupNetworkRulesCmd.class.toString(), CheckNetworkCommand.class.toString(), PvlanSetupCommand.class.toString(), CheckOnHostCommand.class.toString(),
121-
ModifyTargetsCommand.class.toString(), ModifySshKeysCommand.class.toString(), ModifyStoragePoolCommand.class.toString(), SetupMSListCommand.class.toString(), RollingMaintenanceCommand.class.toString()};
122+
ModifyTargetsCommand.class.toString(), ModifySshKeysCommand.class.toString(), ModifyStoragePoolCommand.class.toString(), SetupMSListCommand.class.toString(), RollingMaintenanceCommand.class.toString(),
123+
CleanupPersistentNetworkResourceCommand.class.toString()};
122124
protected final static String[] s_commandsNotAllowedInConnectingMode = new String[] { StartCommand.class.toString(), CreateCommand.class.toString() };
123125
static {
124126
Arrays.sort(s_commandsAllowedInMaintenanceMode);

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 123 additions & 118 deletions
Large diffs are not rendered by default.

engine/schema/src/main/java/com/cloud/network/dao/NetworkDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,6 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
130130
List<NetworkVO> listByPhysicalNetworkPvlan(long physicalNetworkId, String broadcastUri, Network.PVlanType pVlanType);
131131

132132
List<NetworkVO> listByPhysicalNetworkPvlan(long physicalNetworkId, String broadcastUri);
133+
134+
List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId);
133135
}

engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,16 @@ public int getOtherPersistentNetworksCount(long id, String broadcastURI, boolean
419419
return persistentNetworks.size();
420420
}
421421

422+
@Override
423+
public List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId) {
424+
Object[] guestTypes = {"Isolated", "L2"};
425+
final SearchCriteria<NetworkVO> sc = PersistentNetworkSearch.create();
426+
sc.setParameters("guestType", guestTypes);
427+
sc.setParameters("dc", dataCenterId);
428+
sc.setJoinParameters("persistent", "persistent", true);
429+
return search(sc, null);
430+
}
431+
422432
@Override
423433
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
424434
final SequenceFetcher fetch = SequenceFetcher.getInstance();

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,21 @@
2020

2121
import com.cloud.agent.AgentManager;
2222
import com.cloud.agent.api.Answer;
23+
import com.cloud.agent.api.CleanupPersistentNetworkResourceCommand;
2324
import com.cloud.agent.api.ModifyStoragePoolAnswer;
2425
import com.cloud.agent.api.ModifyStoragePoolCommand;
26+
import com.cloud.agent.api.SetupPersistentNetworkCommand;
27+
import com.cloud.agent.api.to.NicTO;
2528
import com.cloud.alert.AlertManager;
29+
import com.cloud.configuration.ConfigurationManager;
2630
import com.cloud.exception.StorageConflictException;
31+
import com.cloud.host.HostVO;
32+
import com.cloud.host.dao.HostDao;
33+
import com.cloud.network.NetworkModel;
34+
import com.cloud.network.dao.NetworkDao;
35+
import com.cloud.network.dao.NetworkVO;
36+
import com.cloud.offerings.NetworkOfferingVO;
37+
import com.cloud.offerings.dao.NetworkOfferingDao;
2738
import com.cloud.storage.DataStoreRole;
2839
import com.cloud.storage.Storage;
2940
import com.cloud.storage.StorageManager;
@@ -62,12 +73,50 @@ public class DefaultHostListener implements HypervisorHostListener {
6273
StorageManager storageManager;
6374
@Inject
6475
StorageService storageService;
76+
@Inject
77+
NetworkOfferingDao networkOfferingDao;
78+
@Inject
79+
HostDao hostDao;
80+
@Inject
81+
NetworkModel networkModel;
82+
@Inject
83+
ConfigurationManager configManager;
84+
@Inject
85+
NetworkDao networkDao;
86+
6587

6688
@Override
6789
public boolean hostAdded(long hostId) {
6890
return true;
6991
}
7092

93+
private boolean createPersistentNetworkResourcesOnHost(long hostId) {
94+
HostVO host = hostDao.findById(hostId);
95+
if (host == null) {
96+
s_logger.warn(String.format("Host with id %ld can't be found", hostId));
97+
return false;
98+
}
99+
setupPersistentNetwork(host);
100+
return true;
101+
}
102+
103+
/**
104+
* Creates a dummy NicTO object which is used by the respective hypervisors to setup network elements / resources
105+
* - bridges(KVM), VLANs(Xen) and portgroups(VMWare) for L2 network
106+
*/
107+
private NicTO createNicTOFromNetworkAndOffering(NetworkVO networkVO, NetworkOfferingVO networkOfferingVO, HostVO hostVO) {
108+
NicTO to = new NicTO();
109+
to.setName(networkModel.getNetworkTag(hostVO.getHypervisorType(), networkVO));
110+
to.setBroadcastType(networkVO.getBroadcastDomainType());
111+
to.setType(networkVO.getTrafficType());
112+
to.setBroadcastUri(networkVO.getBroadcastUri());
113+
to.setIsolationuri(networkVO.getBroadcastUri());
114+
to.setNetworkRateMbps(configManager.getNetworkOfferingNetworkRate(networkOfferingVO.getId(), networkVO.getDataCenterId()));
115+
to.setSecurityGroupEnabled(networkModel.isSecurityGroupSupportedInNetwork(networkVO));
116+
return to;
117+
}
118+
119+
71120
@Override
72121
public boolean hostConnect(long hostId, long poolId) throws StorageConflictException {
73122
StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
@@ -109,7 +158,8 @@ public boolean hostConnect(long hostId, long poolId) throws StorageConflictExcep
109158
storageService.updateStorageCapabilities(poolId, false);
110159

111160
s_logger.info("Connection established between storage pool " + pool + " and host " + hostId);
112-
return true;
161+
162+
return createPersistentNetworkResourcesOnHost(hostId);
113163
}
114164

115165
private void updateStoragePoolHostVOAndDetails(StoragePool pool, long hostId, ModifyStoragePoolAnswer mspAnswer) {
@@ -124,7 +174,7 @@ private void updateStoragePoolHostVOAndDetails(StoragePool pool, long hostId, Mo
124174
StoragePoolVO poolVO = this.primaryStoreDao.findById(pool.getId());
125175
poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes());
126176
poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes());
127-
if(StringUtils.isNotEmpty(mspAnswer.getPoolType())) {
177+
if (StringUtils.isNotEmpty(mspAnswer.getPoolType())) {
128178
StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(pool.getId(), "pool_type");
129179
if (poolType == null) {
130180
StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(pool.getId(), "pool_type", mspAnswer.getPoolType(), false);
@@ -142,11 +192,62 @@ public boolean hostDisconnected(long hostId, long poolId) {
142192

143193
@Override
144194
public boolean hostAboutToBeRemoved(long hostId) {
195+
// send host the cleanup persistent network resources
196+
HostVO host = hostDao.findById(hostId);
197+
if (host == null) {
198+
s_logger.warn("Host with id " + hostId + " can't be found");
199+
return false;
200+
}
201+
202+
List<NetworkVO> allPersistentNetworks = networkDao.getAllPersistentNetworksFromZone(host.getDataCenterId()); // find zoneId of host
203+
for (NetworkVO persistentNetworkVO : allPersistentNetworks) {
204+
NetworkOfferingVO networkOfferingVO = networkOfferingDao.findById(persistentNetworkVO.getNetworkOfferingId());
205+
CleanupPersistentNetworkResourceCommand cleanupCmd =
206+
new CleanupPersistentNetworkResourceCommand(createNicTOFromNetworkAndOffering(persistentNetworkVO, networkOfferingVO, host));
207+
Answer answer = agentMgr.easySend(hostId, cleanupCmd);
208+
if (answer == null) {
209+
s_logger.error("Unable to get answer to the cleanup persistent network command " + persistentNetworkVO.getId());
210+
continue;
211+
}
212+
if (!answer.getResult()) {
213+
String msg = String.format("Unable to cleanup persistent network resources from network %d on the host %d", persistentNetworkVO.getId(), hostId);
214+
s_logger.error(msg);
215+
}
216+
}
145217
return true;
146218
}
147219

148220
@Override
149221
public boolean hostRemoved(long hostId, long clusterId) {
150222
return true;
151223
}
224+
225+
@Override
226+
public boolean hostEnabled(long hostId) {
227+
HostVO host = hostDao.findById(hostId);
228+
if (host == null) {
229+
s_logger.warn(String.format("Host with id %d can't be found", hostId));
230+
return false;
231+
}
232+
setupPersistentNetwork(host);
233+
return true;
234+
}
235+
236+
private void setupPersistentNetwork(HostVO host) {
237+
List<NetworkVO> allPersistentNetworks = networkDao.getAllPersistentNetworksFromZone(host.getDataCenterId());
238+
for (NetworkVO networkVO : allPersistentNetworks) {
239+
NetworkOfferingVO networkOfferingVO = networkOfferingDao.findById(networkVO.getNetworkOfferingId());
240+
241+
SetupPersistentNetworkCommand persistentNetworkCommand =
242+
new SetupPersistentNetworkCommand(createNicTOFromNetworkAndOffering(networkVO, networkOfferingVO, host));
243+
Answer answer = agentMgr.easySend(host.getId(), persistentNetworkCommand);
244+
if (answer == null) {
245+
throw new CloudRuntimeException("Unable to get answer to the setup persistent network command " + networkVO.getId());
246+
}
247+
if (!answer.getResult()) {
248+
String msg = String.format("Unable to create persistent network resources for network %d on the host %d in zone %d", networkVO.getId(), host.getId(), networkVO.getDataCenterId());
249+
s_logger.error(msg);
250+
}
251+
}
252+
}
152253
}

plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,9 @@ public boolean hostAboutToBeRemoved(long hostId) {
140140
public boolean hostRemoved(long hostId, long clusterId) {
141141
return true;
142142
}
143+
144+
@Override
145+
public boolean hostEnabled(long hostId) {
146+
return true;
147+
}
143148
}

plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/provider/DateraHostListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ public boolean hostRemoved(long hostId, long clusterId) {
178178
return true;
179179
}
180180

181+
@Override
182+
public boolean hostEnabled(long hostId) {
183+
return true;
184+
}
185+
181186
private void handleXenServer(long clusterId, long hostId, long storagePoolId) {
182187
List<String> storagePaths = getStoragePaths(clusterId, storagePoolId);
183188

plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,9 @@ public boolean hostRemoved(long hostId, long clusterId) {
5959

6060
return true;
6161
}
62+
63+
@Override
64+
public boolean hostEnabled(long hostId) {
65+
return true;
66+
}
6267
}

0 commit comments

Comments
 (0)