Skip to content

Commit 753b563

Browse files
Victor Rodionovsudison
authored andcommitted
NexentaStor iSCSI volume driver
This a NexentaStor iSCSI volume driver. Now implemented only following functions: * create volume * delete volume Currently delete volume still in progress. Signed-off-by: Edison Su <[email protected]>
1 parent cc2b1c4 commit 753b563

14 files changed

Lines changed: 1925 additions & 0 deletions

File tree

plugins/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<module>storage/image/swift</module>
6363
<module>storage/image/default</module>
6464
<module>storage/image/sample</module>
65+
<module>storage/volume/nexenta</module>
6566
<module>storage/volume/solidfire</module>
6667
<module>storage/volume/default</module>
6768
<module>storage/volume/sample</module>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
2+
license agreements. See the NOTICE file distributed with this work for additional
3+
information regarding copyright ownership. The ASF licenses this file to
4+
you under the Apache License, Version 2.0 (the "License"); you may not use
5+
this file except in compliance with the License. You may obtain a copy of
6+
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
7+
by applicable law or agreed to in writing, software distributed under the
8+
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
9+
OF ANY KIND, either express or implied. See the License for the specific
10+
language governing permissions and limitations under the License. -->
11+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
12+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
13+
<modelVersion>4.0.0</modelVersion>
14+
<artifactId>cloud-plugin-storage-volume-nexenta</artifactId>
15+
<name>Apache CloudStack Plugin - Storage Volume Nexenta Provider</name>
16+
<parent>
17+
<groupId>org.apache.cloudstack</groupId>
18+
<artifactId>cloudstack-plugins</artifactId>
19+
<version>4.4.0-SNAPSHOT</version>
20+
<relativePath>../../../pom.xml</relativePath>
21+
</parent>
22+
<dependencies>
23+
<dependency>
24+
<groupId>org.apache.cloudstack</groupId>
25+
<artifactId>cloud-engine-storage-volume</artifactId>
26+
<version>${project.version}</version>
27+
</dependency>
28+
</dependencies>
29+
<build>
30+
<plugins>
31+
<plugin>
32+
<artifactId>maven-surefire-plugin</artifactId>
33+
<configuration>
34+
<skipTests>true</skipTests>
35+
</configuration>
36+
<executions>
37+
<execution>
38+
<phase>integration-test</phase>
39+
<goals>
40+
<goal>test</goal>
41+
</goals>
42+
</execution>
43+
</executions>
44+
</plugin>
45+
</plugins>
46+
</build>
47+
</project>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
name=storage-volume-nexenta
18+
parent=storage
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
<beans xmlns="http://www.springframework.org/schema/beans"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xmlns:context="http://www.springframework.org/schema/context"
22+
xmlns:aop="http://www.springframework.org/schema/aop"
23+
xsi:schemaLocation="http://www.springframework.org/schema/beans
24+
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
25+
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
26+
http://www.springframework.org/schema/context
27+
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
28+
29+
<bean id="nexentaStorDataStoreProvider"
30+
class="org.apache.cloudstack.storage.datastore.provider.NexentaPrimaryDataStoreProvider" />
31+
32+
</beans>
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
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.datastore.driver;
20+
21+
import static org.apache.cloudstack.storage.datastore.util.NexentaUtil.NexentaPluginParameters;
22+
23+
import java.util.Map;
24+
25+
import javax.inject.Inject;
26+
27+
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
28+
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
29+
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
30+
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
31+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
32+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
33+
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
34+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
35+
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
36+
import org.apache.cloudstack.storage.command.CommandResult;
37+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
38+
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
39+
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
40+
import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance;
41+
import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.NexentaStorZvol;
42+
import org.apache.cloudstack.storage.datastore.util.NexentaUtil;
43+
import org.apache.log4j.Logger;
44+
45+
import com.cloud.agent.api.Answer;
46+
import com.cloud.agent.api.to.DataObjectType;
47+
import com.cloud.agent.api.to.DataStoreTO;
48+
import com.cloud.agent.api.to.DataTO;
49+
import com.cloud.host.Host;
50+
import com.cloud.storage.Storage;
51+
import com.cloud.storage.StoragePool;
52+
import com.cloud.storage.Volume;
53+
import com.cloud.storage.VolumeVO;
54+
import com.cloud.storage.dao.VolumeDao;
55+
import com.cloud.user.dao.AccountDao;
56+
57+
public class NexentaPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
58+
private static final Logger logger = Logger.getLogger(NexentaPrimaryDataStoreDriver.class);
59+
60+
@Override
61+
public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
62+
return false; //To change body of implemented methods use File | Settings | File Templates.
63+
}
64+
65+
@Override
66+
public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
67+
//To change body of implemented methods use File | Settings | File Templates.
68+
}
69+
70+
@Override
71+
public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
72+
return 0; //To change body of implemented methods use File | Settings | File Templates.
73+
}
74+
75+
@Inject
76+
private VolumeDao _volumeDao;
77+
@Inject
78+
PrimaryDataStoreDao _storagePoolDao;
79+
@Inject
80+
private StoragePoolDetailsDao _storagePoolDetailsDao;
81+
@Inject
82+
private AccountDao _accountDao;
83+
84+
@Override
85+
public Map<String, String> getCapabilities() {
86+
return null;
87+
}
88+
89+
@Override
90+
public ChapInfo getChapInfo(VolumeInfo volumeInfo) {
91+
return null;
92+
}
93+
94+
@Override
95+
public DataTO getTO(DataObject data) {
96+
return null;
97+
}
98+
99+
@Override
100+
public DataStoreTO getStoreTO(DataStore store) {
101+
return null;
102+
}
103+
104+
private NexentaStorAppliance getNexentaStorAppliance(long storagePoolId) {
105+
NexentaPluginParameters parameters = new NexentaPluginParameters();
106+
107+
parameters.setNmsUrl(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.NMS_URL).getValue());
108+
parameters.setVolume(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME).getValue());
109+
parameters.setStorageType(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_TYPE).getValue());
110+
parameters.setStorageHost(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_HOST).getValue());
111+
parameters.setStoragePort(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PORT).getValue());
112+
parameters.setStoragePath(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PATH).getValue());
113+
parameters.setSparseVolumes(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.SPARSE_VOLUMES).getValue());
114+
parameters.setVolumeBlockSize(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME_BLOCK_SIZE).getValue());
115+
116+
return new NexentaStorAppliance(parameters);
117+
}
118+
119+
@Override
120+
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {}
121+
122+
@Override
123+
public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback) {}
124+
125+
@Override
126+
public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
127+
String iqn = null;
128+
String errorMessage = null;
129+
130+
if (dataObject.getType() != DataObjectType.VOLUME) {
131+
errorMessage = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
132+
} else {
133+
VolumeInfo volumeInfo = (VolumeInfo) dataObject;
134+
135+
long storagePoolId = dataStore.getId();
136+
NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
137+
138+
// TODO: maybe we should use md5(volume name) as volume name
139+
NexentaStorZvol zvol = (NexentaStorZvol) appliance.createVolume(volumeInfo.getName(), volumeInfo.getSize());
140+
iqn = zvol.getIqn();
141+
142+
VolumeVO volume = this._volumeDao.findById(volumeInfo.getId());
143+
volume.set_iScsiName(iqn);
144+
volume.setFolder(zvol.getName());
145+
volume.setPoolType(Storage.StoragePoolType.IscsiLUN);
146+
volume.setPoolId(storagePoolId);
147+
_volumeDao.update(volume.getId(), volume);
148+
149+
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
150+
long capacityBytes = storagePool.getCapacityBytes();
151+
long usedBytes = storagePool.getUsedBytes();
152+
usedBytes += volumeInfo.getSize();
153+
storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
154+
_storagePoolDao.update(storagePoolId, storagePool);
155+
}
156+
157+
CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errorMessage == null, errorMessage));
158+
result.setResult(errorMessage);
159+
callback.complete(result);
160+
}
161+
162+
@Override
163+
public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
164+
String errorMessage = null;
165+
if (data.getType() == DataObjectType.VOLUME) {
166+
VolumeInfo volumeInfo = (VolumeInfo) data;
167+
long storagePoolId = store.getId();
168+
NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
169+
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
170+
171+
172+
173+
// _storagePoolDao.update(stoagePoolId);
174+
} else {
175+
errorMessage = String.format(
176+
"Invalid DataObjectType(%s) passed to deleteAsync",
177+
data.getType());
178+
}
179+
CommandResult result = new CommandResult();
180+
result.setResult(errorMessage);
181+
callback.complete(result);
182+
}
183+
184+
@Override
185+
public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {}
186+
187+
@Override
188+
public boolean canCopy(DataObject srcData, DataObject destData) {
189+
return false;
190+
}
191+
192+
@Override
193+
public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {}
194+
}

0 commit comments

Comments
 (0)