Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
da5c6cd
add volume group handling
Feb 21, 2022
7ab0530
add VolumeGroup
Feb 21, 2022
8c8df11
add since parameter to AttachVolumeCmd
Feb 21, 2022
9fa59ec
adapt marvin for volumegroups
Mar 3, 2022
7541179
adapt/add test volumegroup handling
Mar 3, 2022
77232e9
add condition for volumes in group null in case of device count durin…
Mar 21, 2022
ee39c93
add groups for import/unmanage vm's
Mar 21, 2022
2ff2fac
adapt java test case
Mar 21, 2022
d55e26c
adapt marvin to import vms
Mar 21, 2022
f98e08d
add test group handling for import/unmanage vm's
Mar 21, 2022
fe51bd5
adapt code for special controller unit 7
Apr 5, 2022
40d0d1e
add test for special controller unit 7(attach volume and start vm)
Apr 5, 2022
29172ac
Add useConntrollerConfiguration to allow user to use the current cont…
Apr 12, 2022
3d73823
extend test call importUnmanagedVM
Apr 12, 2022
adb7462
Adapt test for useControllerConfiguration
Apr 12, 2022
541f4ac
Update api/src/main/java/org/apache/cloudstack/api/command/admin/vm/I…
DK101010 Apr 13, 2022
5d9e10f
Update vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/Virtu…
Apr 14, 2022
c7f1605
change license header to ASF
Apr 25, 2022
e792836
Merge branch 'main' of https://github.com/apache/cloudstack into feat…
Oct 14, 2022
677e34b
adapt test
Oct 14, 2022
3a84ea1
adapt test
Oct 14, 2022
c64aa68
Merge branch 'main' into feat/add_volume_groups
Oct 17, 2022
7f0de61
refactoring
Oct 17, 2022
323b69e
adapt importVolume
Oct 18, 2022
0785a99
Update vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/Virtu…
DK101010 Oct 19, 2022
699adbd
Apply suggestions from code review
DK101010 Oct 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion api/src/main/java/com/cloud/agent/api/to/DiskTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@ public class DiskTO {
private String path;
private Volume.Type type;
private Map<String, String> _details;
private int groupNumber;

public DiskTO() {

this.groupNumber = -1;
}

public DiskTO(DataTO data, Long diskSeq, String path, Volume.Type type) {
this.data = data;
this.diskSeq = diskSeq;
this.path = path;
this.type = type;
this.groupNumber = -1;
}

public DataTO getData() {
Expand Down Expand Up @@ -98,4 +100,12 @@ public void setDetails(Map<String, String> details) {
public Map<String, String> getDetails() {
return _details;
}

public int getGroupNumber() {
return groupNumber;
}

public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}
}
1 change: 1 addition & 0 deletions api/src/main/java/com/cloud/vm/VmDetailConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public interface VmDetailConstants {
String IP6_ADDRESS = "ip6Address";
String DISK = "disk";
String DISK_OFFERING = "diskOffering";
String VOLUME_GROUP = "volumeGroup";

String DEPLOY_AS_IS_CONFIGURATION = "configurationId";
String KEY_PAIR_NAMES = "keypairnames";
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ public class ApiConstants {
public static final String IS_VOLATILE = "isvolatile";
public static final String VOLUME_ID = "volumeid";
public static final String VOLUMES = "volumes";
public static final String VOLUME_GROUP = "volumegroup";
public static final String USE_CONTROLLER_CONFIGURATION = "usecontrollerconfiguration";
public static final String ZONE = "zone";
public static final String ZONE_ID = "zoneid";
public static final String ZONE_NAME = "zonename";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {
description = "VM is imported despite some of its NIC's MAC addresses are already present")
private Boolean forced;

@Parameter(name = ApiConstants.USE_CONTROLLER_CONFIGURATION,
type = CommandType.BOOLEAN,
description = "volumes automatically get volume groups based on their current controller connections",
since="4.17.0")
private Boolean useControllerConfiguration;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -259,6 +265,20 @@ public Map<String, Long> getDataDiskToDiskOfferingList() {
return dataDiskToDiskOfferingMap;
}

public Map<String, Integer> getVolumeGroups() {
Map<String, Integer> dataDiskVolumeGroups = new HashMap<>();
if (MapUtils.isNotEmpty(dataDiskToDiskOfferingList)) {
Comment thread
DK101010 marked this conversation as resolved.
for (Map<String, String> entry : (Collection<Map<String, String>>)dataDiskToDiskOfferingList.values()) {
String disk = entry.get(VmDetailConstants.DISK);
if(entry.get(VmDetailConstants.VOLUME_GROUP) != null){
Integer volumeGroup = Integer.parseInt(entry.get(VmDetailConstants.VOLUME_GROUP));
dataDiskVolumeGroups.put(disk, volumeGroup);
}
}
}
return dataDiskVolumeGroups;
}

public Map<String, String> getDetails() {
if (MapUtils.isEmpty(details)) {
return new HashMap<String, String>();
Expand Down Expand Up @@ -316,4 +336,8 @@ public long getEntityOwnerId() {
}
return accountId;
}

public Boolean isUseControllerConfiguration() {
return BooleanUtils.isTrue(this.useControllerConfiguration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public class AttachVolumeCmd extends BaseAsyncCmd implements UserCmd {
required=true, description=" the ID of the virtual machine")
private Long virtualMachineId;

@Parameter(name = ApiConstants.VOLUME_GROUP, type = CommandType.INTEGER, required = false, description = "group of volume", since = "4.17.0")
private int volumeGroup=-1;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -116,6 +119,10 @@ public String getEventDescription() {
return "attaching volume: " + this._uuidMgr.getUuid(Volume.class, getId()) + " to vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId());
}

public int getVolumeGroup() {
return volumeGroup;
}

@Override
public void execute() {
CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()) + " VmId: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,11 @@ List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering
* @param poolId ID of pool in which volume is stored
* @param path image path of the volume
* @param chainInfo chain info for the volume. Hypervisor specific.
* @param volumeGroup group of volume
* @return DiskProfile of imported volume
*/
DiskProfile importVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template,
Account owner, Long deviceId, Long poolId, String path, String chainInfo);
Account owner, Long deviceId, Long poolId, String path, String chainInfo, Integer volumeGroup);

/**
* Unmanage VM volumes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ public class VmWorkAttachVolume extends VmWork {

private Long volumeId;
private Long deviceId;
private int groupNumber;

public VmWorkAttachVolume(long userId, long accountId, long vmId, String handlerName, Long volumeId, Long deviceId) {
public VmWorkAttachVolume(long userId, long accountId, long vmId, String handlerName, Long volumeId, Long deviceId, int groupNumber) {
super(userId, accountId, vmId, handlerName);
this.volumeId = volumeId;
this.deviceId = deviceId;
this.groupNumber = groupNumber;
}

public Long getVolumeId() {
Expand All @@ -35,4 +37,8 @@ public Long getVolumeId() {
public Long getDeviceId() {
return deviceId;
}
}

public int getGroupNumber() {
return groupNumber;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeDetailsDao;
import com.cloud.storage.dao.VolumeGroupDao;
import com.cloud.template.TemplateManager;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
Expand Down Expand Up @@ -234,6 +235,7 @@ public enum UserVmCloneType {
@Inject
VolumeApiService _volumeApiService;
@Inject
private VolumeGroupDao volumeGroupDao;
PassphraseDao passphraseDao;

@Inject
Expand Down Expand Up @@ -2073,7 +2075,7 @@ public void updateVolumeDiskChain(long volumeId, String path, String chainInfo,
@Override
public DiskProfile importVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops,
VirtualMachine vm, VirtualMachineTemplate template, Account owner,
Long deviceId, Long poolId, String path, String chainInfo) {
Long deviceId, Long poolId, String path, String chainInfo, Integer volumeGroup) {
if (size == null) {
size = offering.getDiskSize();
} else {
Expand Down Expand Up @@ -2120,6 +2122,11 @@ public DiskProfile importVolume(Type type, String name, DiskOffering offering, L
vol.setState(Volume.State.Ready);
vol.setAttached(new Date());
vol = _volsDao.persist(vol);

if (volumeGroup != null) {
volumeGroupDao.addVolumeToGroup(vm.getId(), vol.getId(), vol.getDeviceId(), volumeGroup);
}

return toDiskProfile(vol, offering);
}

Expand All @@ -2142,6 +2149,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
s_logger.debug(String.format("Skipping Destroy for the volume [%s] as it is in [%s] state.", volToString, vol.getState().toString()));
} else {
volService.unmanageVolume(vol.getId());
volumeGroupDao.deleteVolumeFromGroup(vol.getId());
}
}
}
Expand Down
86 changes: 86 additions & 0 deletions engine/schema/src/main/java/com/cloud/storage/VolumeGroupVO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.storage;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;

@Entity
@Table(name = "volume_group")
public class VolumeGroupVO implements InternalIdentity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;

@Column(name = "vm_id")
private long vmId;

@Column(name = "volume_id")
private long volumeId;

@Column(name = "group_number")
private int groupNumber;


public VolumeGroupVO() {}

public VolumeGroupVO(long vmId, long volumeId, int groupNumber) {
this.vmId = vmId;
this.volumeId = volumeId;
this.groupNumber = groupNumber;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public long getVmId() {
return vmId;
}

public void setVmId(long vmId) {
this.vmId = vmId;
}

public int getGroupNumber() {
return groupNumber;
}

public void setGroupNumber(int groupNumber) {
this.groupNumber = groupNumber;
}

public long getVolumeId() {
return volumeId;
}

public void setVolumeId(long volumeId) {
this.volumeId = volumeId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.storage.dao;

import com.cloud.utils.db.GenericDao;
import com.cloud.storage.VolumeGroupVO;


public interface VolumeGroupDao extends GenericDao<VolumeGroupVO, Long> {
public void addVolumeToGroup(long vmId, long volumeId, long deviceId, int groupNumber);
public void deleteVolumeFromGroup(long volumeId);
public VolumeGroupVO findByVmAndVolume(long vmId, long volumeId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.storage.dao;

import com.cloud.utils.db.GenericDaoBase;
import com.cloud.storage.VolumeGroupVO;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;


public class VolumeGroupDaoImpl extends GenericDaoBase<VolumeGroupVO, Long> implements VolumeGroupDao {
protected final SearchBuilder<VolumeGroupVO> allFieldsSearch;
private static final String VOLUME_ID = "volumeId";
private static final String VM_ID = "vmId";
private static final String GROUP_NUMBER = "groupNumber";

public VolumeGroupDaoImpl(){
allFieldsSearch = createSearchBuilder();
allFieldsSearch.and(VM_ID, allFieldsSearch.entity().getVmId(), SearchCriteria.Op.EQ);
allFieldsSearch.and(VOLUME_ID, allFieldsSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
allFieldsSearch.and(GROUP_NUMBER, allFieldsSearch.entity().getGroupNumber(), SearchCriteria.Op.EQ);
allFieldsSearch.done();
}

@Override
public void addVolumeToGroup(long vmId, long volumeId, long deviceId, int groupNumber) {
if (groupNumber != -1) {
if (deviceId == 0L) {
groupNumber = 0;
}
VolumeGroupVO group = new VolumeGroupVO();
group.setVmId(vmId);
group.setVolumeId(volumeId);
group.setGroupNumber(groupNumber);
persist(group);
}
}

@Override
public void deleteVolumeFromGroup(long volumeId) {
SearchCriteria<VolumeGroupVO> sc = allFieldsSearch.create();
sc.setParameters(VOLUME_ID, volumeId);
expunge(sc);
}

@Override
public VolumeGroupVO findByVmAndVolume(long vmId, long volumeId){
SearchCriteria<VolumeGroupVO> sc = allFieldsSearch.create();
sc.setParameters(VM_ID, vmId);
sc.setParameters(VOLUME_ID, volumeId);
return findOneBy(sc);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@
<bean id="vMTemplateZoneDaoImpl" class="com.cloud.storage.dao.VMTemplateZoneDaoImpl" />
<bean id="virtualRouterProviderDaoImpl" class="com.cloud.network.dao.VirtualRouterProviderDaoImpl" />
<bean id="vmRulesetLogDaoImpl" class="com.cloud.network.security.dao.VmRulesetLogDaoImpl" />
<bean id="volumeDaoImpl" class="com.cloud.storage.dao.VolumeDaoImpl" />
<bean id="volumeGroupDaoImpl" class="com.cloud.storage.dao.VolumeGroupDaoImpl" />
<bean id="volumeDetailsDaoImpl" class="com.cloud.storage.dao.VolumeDetailsDaoImpl" />
<bean id="volumeJoinDaoImpl" class="com.cloud.api.query.dao.VolumeJoinDaoImpl" />
<bean id="volumeReservationDaoImpl" class="org.apache.cloudstack.engine.cloud.entity.api.db.dao.VolumeReservationDaoImpl" />
Expand Down
Loading