Skip to content

Commit a4347d6

Browse files
Locharla, SandeepLocharla, Sandeep
authored andcommitted
CSTACKEX-050: Added some missing changes
1 parent 9319777 commit a4347d6

File tree

2 files changed

+166
-1
lines changed

2 files changed

+166
-1
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage.listener;
20+
21+
import com.cloud.agent.AgentManager;
22+
import com.cloud.agent.api.Answer;
23+
import com.cloud.agent.api.ModifyStoragePoolCommand;
24+
import com.cloud.host.HostVO;
25+
import com.cloud.host.dao.HostDao;
26+
import com.cloud.storage.DataStoreRole;
27+
import com.cloud.storage.StoragePool;
28+
import com.cloud.storage.StoragePoolHostVO;
29+
import com.cloud.storage.dao.StoragePoolHostDao;
30+
import com.cloud.utils.exception.CloudRuntimeException;
31+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
32+
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
33+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
34+
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
35+
import org.apache.logging.log4j.LogManager;
36+
import org.apache.logging.log4j.Logger;
37+
38+
import javax.inject.Inject;
39+
40+
/**
41+
* OntapHostListener handles host lifecycle events for ONTAP storage pools.
42+
*
43+
* For ONTAP iSCSI storage pools:
44+
* - The igroup (initiator group) is created/updated in OntapPrimaryDatastoreLifecycle.attachCluster()
45+
* - The actual iSCSI target discovery and login is handled by StorageManager via ModifyStoragePoolCommand
46+
* - This listener simply manages the storage pool-host relationship in the database
47+
*
48+
* For ONTAP NFS storage pools:
49+
* - The export policy is configured during storage pool creation
50+
* - The actual NFS mount is handled by StorageManager via ModifyStoragePoolCommand
51+
* - This listener simply manages the storage pool-host relationship in the database
52+
*/
53+
public class OntapHostListener implements HypervisorHostListener {
54+
protected Logger logger = LogManager.getLogger(getClass());
55+
56+
@Inject private HostDao hostDao;
57+
@Inject private AgentManager agentMgr;
58+
@Inject private PrimaryDataStoreDao storagePoolDao;
59+
@Inject private DataStoreManager dataStoreMgr;
60+
@Inject private StoragePoolDetailsDao storagePoolDetailsDao;
61+
@Inject private StoragePoolHostDao storagePoolHostDao;
62+
63+
@Override
64+
public boolean hostAdded(long hostId) {
65+
HostVO host = hostDao.findById(hostId);
66+
67+
if (host == null) {
68+
logger.error("hostAdded: Host {} not found", hostId);
69+
return false;
70+
}
71+
72+
if (host.getClusterId() == null) {
73+
logger.error("hostAdded: Host {} has no associated cluster", hostId);
74+
return false;
75+
}
76+
77+
logger.info("hostAdded: Host {} added to cluster {}", hostId, host.getClusterId());
78+
return true;
79+
}
80+
81+
@Override
82+
public boolean hostConnect(long hostId, long storagePoolId) {
83+
logger.debug("hostConnect: Connecting host {} to storage pool {}", hostId, storagePoolId);
84+
85+
HostVO host = hostDao.findById(hostId);
86+
if (host == null) {
87+
logger.error("hostConnect: Host {} not found", hostId);
88+
return false;
89+
}
90+
91+
// Create or update the storage pool host mapping in the database
92+
// The actual storage pool connection (iSCSI login or NFS mount) is handled
93+
// by the StorageManager via ModifyStoragePoolCommand sent to the host agent
94+
StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
95+
StoragePool storagePool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
96+
if (storagePoolHost == null) {
97+
storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, "");
98+
storagePoolHostDao.persist(storagePoolHost);
99+
ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
100+
Answer answer = agentMgr.easySend(host.getId(), cmd);
101+
if (answer == null || !answer.getResult()) {
102+
storagePoolDao.expunge(storagePool.getId());
103+
throw new CloudRuntimeException("attachCluster: Failed to attach storage pool to host: " + host.getId() +
104+
" due to " + (answer != null ? answer.getDetails() : "no answer from agent"));
105+
}
106+
logger.info("Connection established between storage pool {} and host {}", storagePool, host);
107+
} else {
108+
// TODO: Update any necessary details if needed, by fetching OntapVolume info from ONTAP
109+
logger.debug("hostConnect: Storage pool-host mapping already exists for pool {} and host {}",
110+
storagePool.getName(), host.getName());
111+
}
112+
113+
return true;
114+
}
115+
116+
@Override
117+
public boolean hostDisconnected(long hostId, long storagePoolId) {
118+
logger.debug("hostDisconnected: Disconnecting host {} from storage pool {}",
119+
hostId, storagePoolId);
120+
121+
StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
122+
if (storagePoolHost != null) {
123+
storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
124+
logger.info("hostDisconnected: Removed storage pool-host mapping for pool {} and host {}",
125+
storagePoolId, hostId);
126+
} else {
127+
logger.debug("hostDisconnected: No storage pool-host mapping found for pool {} and host {}",
128+
storagePoolId, hostId);
129+
}
130+
131+
return true;
132+
}
133+
134+
@Override
135+
public boolean hostAboutToBeRemoved(long hostId) {
136+
HostVO host = hostDao.findById(hostId);
137+
if (host == null) {
138+
logger.error("hostAboutToBeRemoved: Host {} not found", hostId);
139+
return false;
140+
}
141+
142+
logger.info("hostAboutToBeRemoved: Host {} about to be removed from cluster {}",
143+
hostId, host.getClusterId());
144+
145+
// Note: When a host is removed, the igroup initiator should be removed in
146+
// the appropriate lifecycle method, not here
147+
return true;
148+
}
149+
150+
@Override
151+
public boolean hostRemoved(long hostId, long clusterId) {
152+
logger.info("hostRemoved: Host {} removed from cluster {}", hostId, clusterId);
153+
return true;
154+
}
155+
156+
@Override
157+
public boolean hostEnabled(long hostId) {
158+
logger.debug("hostEnabled: Host {} enabled", hostId);
159+
return true;
160+
}
161+
}
162+

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/provider/OntapPrimaryDatastoreProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
2828
import org.apache.cloudstack.storage.driver.OntapPrimaryDatastoreDriver;
2929
import org.apache.cloudstack.storage.lifecycle.OntapPrimaryDatastoreLifecycle;
30+
import org.apache.cloudstack.storage.listener.OntapHostListener;
3031
import org.apache.logging.log4j.LogManager;
3132
import org.apache.logging.log4j.Logger;
3233
import org.springframework.stereotype.Component;
@@ -41,6 +42,7 @@ public class OntapPrimaryDatastoreProvider implements PrimaryDataStoreProvider {
4142
private static final Logger s_logger = LogManager.getLogger(OntapPrimaryDatastoreProvider.class);
4243
private OntapPrimaryDatastoreDriver primaryDatastoreDriver;
4344
private OntapPrimaryDatastoreLifecycle primaryDatastoreLifecycle;
45+
private OntapHostListener hostListener;
4446

4547
public OntapPrimaryDatastoreProvider() {
4648
s_logger.info("OntapPrimaryDatastoreProvider initialized");
@@ -57,7 +59,7 @@ public DataStoreDriver getDataStoreDriver() {
5759

5860
@Override
5961
public HypervisorHostListener getHostListener() {
60-
return null;
62+
return hostListener;
6163
}
6264

6365
@Override
@@ -71,6 +73,7 @@ public boolean configure(Map<String, Object> params) {
7173
s_logger.trace("OntapPrimaryDatastoreProvider: configure: Called");
7274
primaryDatastoreDriver = ComponentContext.inject(OntapPrimaryDatastoreDriver.class);
7375
primaryDatastoreLifecycle = ComponentContext.inject(OntapPrimaryDatastoreLifecycle.class);
76+
hostListener = ComponentContext.inject(OntapHostListener.class);
7477
return true;
7578
}
7679

0 commit comments

Comments
 (0)