Merge remote-tracking branch 'origin/4.15'

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2021-03-11 13:33:44 +05:30
commit c8f7c0d823
13 changed files with 117 additions and 54 deletions

View File

@ -256,6 +256,7 @@ public class ApiConstants {
public static final String OLD_FORMAT = "oldformat"; public static final String OLD_FORMAT = "oldformat";
public static final String OP = "op"; public static final String OP = "op";
public static final String OS_CATEGORY_ID = "oscategoryid"; public static final String OS_CATEGORY_ID = "oscategoryid";
public static final String OS_CATEGORY_NAME = "oscategoryname";
public static final String OS_ID = "osid"; public static final String OS_ID = "osid";
public static final String OS_TYPE_ID = "ostypeid"; public static final String OS_TYPE_ID = "ostypeid";
public static final String OS_DISPLAY_NAME = "osdisplayname"; public static final String OS_DISPLAY_NAME = "osdisplayname";

View File

@ -16,16 +16,15 @@
// under the License. // under the License.
package org.apache.cloudstack.api.response; package org.apache.cloudstack.api.response;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import com.cloud.serializer.Param;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class UsageRecordResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse { public class UsageRecordResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse {
@SerializedName(ApiConstants.ACCOUNT) @SerializedName(ApiConstants.ACCOUNT)
@ -89,8 +88,20 @@ public class UsageRecordResponse extends BaseResponseWithTagInformation implemen
private String templateId; private String templateId;
@SerializedName(ApiConstants.OS_TYPE_ID) @SerializedName(ApiConstants.OS_TYPE_ID)
@Param(description = "virtual machine os type id") @Param(description = "virtual machine os type ID")
private Long osTypeId; private String osTypeId;
@SerializedName(ApiConstants.OS_DISPLAY_NAME)
@Param(description = "virtual machine os display name")
private String osDisplayName;
@SerializedName(ApiConstants.OS_CATEGORY_ID)
@Param(description = "virtual machine guest os category ID")
private String osCategoryId;
@SerializedName(ApiConstants.OS_CATEGORY_NAME)
@Param(description = "virtual machine os category name")
private String osCategoryName;
@SerializedName("usageid") @SerializedName("usageid")
@Param(description = "id of the resource") @Param(description = "id of the resource")
@ -206,10 +217,22 @@ public class UsageRecordResponse extends BaseResponseWithTagInformation implemen
this.templateId = templateId; this.templateId = templateId;
} }
public void setOsTypeId(Long osTypeId) { public void setOsTypeId(String osTypeId) {
this.osTypeId = osTypeId; this.osTypeId = osTypeId;
} }
public void setOsDisplayName(String osDisplayName) {
this.osDisplayName = osDisplayName;
}
public void setOsCategoryId(String osCategoryId) {
this.osCategoryId = osCategoryId;
}
public void setOsCategoryName(String osCategoryName) {
this.osCategoryName = osCategoryName;
}
public void setUsageId(String usageId) { public void setUsageId(String usageId) {
this.usageId = usageId; this.usageId = usageId;
} }

View File

@ -19,3 +19,7 @@
-- Schema upgrade from 4.15.0.0 to 4.15.1.0 -- Schema upgrade from 4.15.0.0 to 4.15.1.0
--; --;
-- Correct guest OS names
UPDATE `cloud`.`guest_os` SET display_name='Fedora Linux (32 bit)' WHERE id=320;
UPDATE `cloud`.`guest_os` SET display_name='Mandriva Linux (32 bit)' WHERE id=323;
UPDATE `cloud`.`guest_os` SET display_name='OpenSUSE Linux (32 bit)' WHERE id=327;

View File

@ -535,6 +535,12 @@ class libvirtConfigRedhat(serviceCfgBase):
cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'") cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")
cfo.addEntry("LIBVIRTD_ARGS", "-l") cfo.addEntry("LIBVIRTD_ARGS", "-l")
cfo.save() cfo.save()
if os.path.exists("/lib/systemd/system/libvirtd.socket"):
bash("/bin/systemctl mask libvirtd.socket");
bash("/bin/systemctl mask libvirtd-ro.socket");
bash("/bin/systemctl mask libvirtd-admin.socket");
bash("/bin/systemctl mask libvirtd-tls.socket");
bash("/bin/systemctl mask libvirtd-tcp.socket");
filename = "/etc/libvirt/qemu.conf" filename = "/etc/libvirt/qemu.conf"

View File

@ -306,6 +306,7 @@ import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOS;
import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSCategoryVO;
import com.cloud.storage.GuestOSHypervisor; import com.cloud.storage.GuestOSHypervisor;
import com.cloud.storage.GuestOsCategory;
import com.cloud.storage.ImageStore; import com.cloud.storage.ImageStore;
import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO; import com.cloud.storage.SnapshotVO;
@ -315,6 +316,8 @@ import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.storage.snapshot.SnapshotPolicy;
import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.storage.snapshot.SnapshotSchedule;
@ -394,6 +397,10 @@ public class ApiResponseHelper implements ResponseGenerator {
private VMSnapshotDao vmSnapshotDao; private VMSnapshotDao vmSnapshotDao;
@Inject @Inject
private BackupOfferingDao backupOfferingDao; private BackupOfferingDao backupOfferingDao;
@Inject
private GuestOSCategoryDao _guestOsCategoryDao;
@Inject
private GuestOSDao _guestOsDao;
@Override @Override
public UserResponse createUserResponse(User user) { public UserResponse createUserResponse(User user) {
@ -3401,7 +3408,16 @@ public class ApiResponseHelper implements ResponseGenerator {
resourceType = ResourceTag.ResourceObjectType.UserVm; resourceType = ResourceTag.ResourceObjectType.UserVm;
usageRecResponse.setUsageId(vm.getUuid()); usageRecResponse.setUsageId(vm.getUuid());
resourceId = vm.getId(); resourceId = vm.getId();
usageRecResponse.setOsTypeId(vm.getGuestOSId()); final GuestOS guestOS = _guestOsDao.findById(vm.getGuestOSId());
if (guestOS != null) {
usageRecResponse.setOsTypeId(guestOS.getUuid());
usageRecResponse.setOsDisplayName(guestOS.getDisplayName());
final GuestOsCategory guestOsCategory = _guestOsCategoryDao.findById(guestOS.getCategoryId());
if (guestOsCategory != null) {
usageRecResponse.setOsCategoryId(guestOsCategory.getUuid());
usageRecResponse.setOsCategoryName(guestOsCategory.getName());
}
}
} }
//Hypervisor Type //Hypervisor Type
usageRecResponse.setType(usageRecord.getType()); usageRecResponse.setType(usageRecord.getType());
@ -3962,7 +3978,6 @@ public class ApiResponseHelper implements ResponseGenerator {
NicResponse response = new NicResponse(); NicResponse response = new NicResponse();
NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId()); NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId()); VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId());
UserVmJoinVO userVm = _entityMgr.findById(UserVmJoinVO.class, result.getInstanceId());
List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOs = _nicExtraDhcpOptionDao.listByNicId(result.getId()); List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOs = _nicExtraDhcpOptionDao.listByNicId(result.getId());
// The numbered comments are to keep track of the data returned from here and UserVmJoinDaoImpl.setUserVmResponse() // The numbered comments are to keep track of the data returned from here and UserVmJoinDaoImpl.setUserVmResponse()
@ -3976,15 +3991,13 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setVmId(vm.getUuid()); response.setVmId(vm.getUuid());
} }
if (userVm != null){ if (network.getTrafficType() != null) {
if (userVm.getTrafficType() != null) { /*4: trafficType*/
/*4: trafficType*/ response.setTrafficType(network.getTrafficType().toString());
response.setTrafficType(userVm.getTrafficType().toString()); }
} if (network.getGuestType() != null) {
if (userVm.getGuestType() != null) { /*5: guestType*/
/*5: guestType*/ response.setType(network.getGuestType().toString());
response.setType(userVm.getGuestType().toString());
}
} }
/*6: ipAddress*/ /*6: ipAddress*/
response.setIpaddress(result.getIPv4Address()); response.setIpaddress(result.getIPv4Address());
@ -3993,9 +4006,7 @@ public class ApiResponseHelper implements ResponseGenerator {
/*8: netmask*/ /*8: netmask*/
response.setNetmask(result.getIPv4Netmask()); response.setNetmask(result.getIPv4Netmask());
/*9: networkName*/ /*9: networkName*/
if(userVm != null && userVm.getNetworkName() != null) { response.setNetworkName(network.getName());
response.setNetworkName(userVm.getNetworkName());
}
/*10: macAddress*/ /*10: macAddress*/
response.setMacAddress(result.getMacAddress()); response.setMacAddress(result.getMacAddress());
/*11: IPv6Address*/ /*11: IPv6Address*/

View File

@ -26,12 +26,6 @@ import java.util.concurrent.ExecutionException;
import javax.inject.Inject; import javax.inject.Inject;
import com.cloud.configuration.Config;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionStatus;
import org.apache.cloudstack.agent.directdownload.CheckUrlAnswer; import org.apache.cloudstack.agent.directdownload.CheckUrlAnswer;
import org.apache.cloudstack.agent.directdownload.CheckUrlCommand; import org.apache.cloudstack.agent.directdownload.CheckUrlCommand;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
@ -62,14 +56,17 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.cloudstack.utils.security.DigestHelper; import org.apache.cloudstack.utils.security.DigestHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.alert.AlertManager; import com.cloud.alert.AlertManager;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils; import com.cloud.event.UsageEventUtils;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
@ -87,6 +84,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.download.DownloadMonitor;
import com.cloud.template.VirtualMachineTemplate.State; import com.cloud.template.VirtualMachineTemplate.State;
@ -95,6 +93,9 @@ import com.cloud.utils.Pair;
import com.cloud.utils.UriUtils; import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
public class HypervisorTemplateAdapter extends TemplateAdapterBase { public class HypervisorTemplateAdapter extends TemplateAdapterBase {
@ -169,6 +170,12 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
return ans.getTemplateSize(); return ans.getTemplateSize();
} }
private void checkZoneImageStores(final List<Long> zoneIdList) {
if (zoneIdList != null && CollectionUtils.isEmpty(storeMgr.getImageStoresByScope(new ZoneScope(zoneIdList.get(0))))) {
throw new InvalidParameterValueException("Failed to find a secondary storage in the specified zone.");
}
}
@Override @Override
public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
TemplateProfile profile = super.prepare(cmd); TemplateProfile profile = super.prepare(cmd);
@ -637,29 +644,17 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
TemplateProfile profile = super.prepareDelete(cmd); TemplateProfile profile = super.prepareDelete(cmd);
VMTemplateVO template = profile.getTemplate(); VMTemplateVO template = profile.getTemplate();
List<Long> zoneIdList = profile.getZoneIdList();
if (template.getTemplateType() == TemplateType.SYSTEM) { if (template.getTemplateType() == TemplateType.SYSTEM) {
throw new InvalidParameterValueException("The DomR template cannot be deleted."); throw new InvalidParameterValueException("The DomR template cannot be deleted.");
} }
checkZoneImageStores(profile.getZoneIdList());
if (zoneIdList != null && (storeMgr.getImageStoreWithFreeCapacity(zoneIdList.get(0)) == null)) {
throw new InvalidParameterValueException("Failed to find a secondary storage in the specified zone.");
}
return profile; return profile;
} }
@Override @Override
public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
TemplateProfile profile = super.prepareDelete(cmd); TemplateProfile profile = super.prepareDelete(cmd);
List<Long> zoneIdList = profile.getZoneIdList(); checkZoneImageStores(profile.getZoneIdList());
if (zoneIdList != null &&
(storeMgr.getImageStoreWithFreeCapacity(zoneIdList.get(0)) == null)) {
throw new InvalidParameterValueException("Failed to find a secondary storage in the specified zone.");
}
return profile; return profile;
} }
} }

View File

@ -1363,7 +1363,7 @@ class TestMigrateVMwithVolume(cloudstackTestCase):
Volume.migrate(self.apiclient, storageid=target_pool.id, volumeid=volume1.id) Volume.migrate(self.apiclient, storageid=target_pool.id, volumeid=volume1.id)
vol = Volume.list(self.apiclient, volume=volume1.id)[0] vol = Volume.list(self.apiclient, id=volume1.id)[0]
self.assertEqual(vol.storageid, target_pool.id, "Storage pool was not the same as expected") self.assertEqual(vol.storageid, target_pool.id, "Storage pool was not the same as expected")

View File

@ -176,6 +176,13 @@ export default {
}) })
this.disableSettings = (this.$route.meta.name === 'vm' && this.resource.state !== 'Stopped') this.disableSettings = (this.$route.meta.name === 'vm' && this.resource.state !== 'Stopped')
}, },
filterOrReadOnlyDetails () {
for (var i = 0; i < this.details.length; i++) {
if (!this.allowEditOfDetail(this.details[i].name)) {
this.details.splice(i, 1)
}
}
},
allowEditOfDetail (name) { allowEditOfDetail (name) {
if (this.resource.readonlyuidetails) { if (this.resource.readonlyuidetails) {
if (this.resource.readonlyuidetails.split(',').map(item => item.trim()).includes(name)) { if (this.resource.readonlyuidetails.split(',').map(item => item.trim()).includes(name)) {
@ -257,13 +264,16 @@ export default {
} }
this.error = false this.error = false
this.details.push({ name: this.newKey, value: this.newValue }) this.details.push({ name: this.newKey, value: this.newValue })
this.filterOrReadOnlyDetails()
this.runApi() this.runApi()
}, },
updateDetail (index) { updateDetail (index) {
this.filterOrReadOnlyDetails()
this.runApi() this.runApi()
}, },
deleteDetail (index) { deleteDetail (index) {
this.details.splice(index, 1) this.details.splice(index, 1)
this.filterOrReadOnlyDetails()
this.runApi() this.runApi()
}, },
onShowAddDetail () { onShowAddDetail () {

View File

@ -713,7 +713,6 @@ export default {
}, },
data () { data () {
return { return {
name: '',
ipaddress: '', ipaddress: '',
resourceType: '', resourceType: '',
annotationType: '', annotationType: '',
@ -769,10 +768,14 @@ export default {
created () { created () {
this.setData() this.setData()
}, },
computed: {
name () {
return this.resource.displayname || this.resource.displaytext || this.resource.name || this.resource.username ||
this.resource.ipaddress || this.resource.virtualmachinename || this.resource.templatetype
}
},
methods: { methods: {
setData () { setData () {
this.name = this.resource.displayname || this.resource.displaytext || this.resource.name || this.resource.username ||
this.resource.ipaddress || this.resource.virtualmachinename || this.resource.templatetype
if (this.resource.nic && this.resource.nic.length > 0) { if (this.resource.nic && this.resource.nic.length > 0) {
this.ipaddress = this.resource.nic.filter(e => { return e.ipaddress }).map(e => { return e.ipaddress }).join(', ') this.ipaddress = this.resource.nic.filter(e => { return e.ipaddress }).map(e => { return e.ipaddress }).join(', ')
} else { } else {

View File

@ -26,12 +26,15 @@
{{ $t(item.meta.title) }} {{ $t(item.meta.title) }}
</router-link> </router-link>
<span v-else-if="$route.params.id"> <span v-else-if="$route.params.id">
<label v-if="'name' in resource"> <label
<span v-if="['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(resource.name)">{{ $t(resource.name.toLowerCase()) }}</span> v-if="'name' in resource &&
<span v-else>{{ resource.name }}</span> ['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(resource.name)">
<span>
{{ $t(resource.name.toLowerCase()) }}
</span>
</label> </label>
<label v-else> <label v-else>
{{ resource.name || resource.displayname || resource.displaytext || resource.hostname || resource.username || resource.ipaddress || $route.params.id }} {{ resource.displayname || resource.displaytext || resource.name || resource.hostname || resource.username || resource.ipaddress || $route.params.id }}
</label> </label>
</span> </span>
<span v-else> <span v-else>

View File

@ -38,7 +38,7 @@ export default {
return filters return filters
}, },
columns: () => { columns: () => {
const fields = ['name', 'state', 'ipaddress'] const fields = ['displayname', 'name', 'state', 'ipaddress']
const metricsFields = ['cpunumber', 'cpuused', 'cputotal', const metricsFields = ['cpunumber', 'cpuused', 'cputotal',
{ {
memoryused: (record) => { memoryused: (record) => {

View File

@ -603,7 +603,7 @@
</a-col> </a-col>
<a-col :md="24" :lg="7" v-if="!isMobile()"> <a-col :md="24" :lg="7" v-if="!isMobile()">
<a-affix :offsetTop="75"> <a-affix :offsetTop="75">
<info-card class="vm-info-card" :resource="vm" :title="vm.name ? this.$t('label.yourinstance') + ' : ' + vm.name : this.$t('label.yourinstance')" /> <info-card class="vm-info-card" :resource="vm" :title="this.$t('label.yourinstance')" />
</a-affix> </a-affix>
</a-col> </a-col>
</a-row> </a-row>

View File

@ -47,6 +47,9 @@
<div slot="memused" slot-scope="record"> <div slot="memused" slot-scope="record">
{{ record.memoryused | byteToGigabyte }} GB {{ record.memoryused | byteToGigabyte }} GB
</div> </div>
<div slot="memoryallocatedpercentage" slot-scope="record">
{{ record.memoryallocatedpercentage }}
</div>
<div slot="cluster" slot-scope="record"> <div slot="cluster" slot-scope="record">
{{ record.clustername }} {{ record.clustername }}
</div> </div>
@ -122,6 +125,10 @@ export default {
title: this.$t('label.cpuused'), title: this.$t('label.cpuused'),
dataIndex: 'cpuused' dataIndex: 'cpuused'
}, },
{
title: this.$t('label.memoryallocated'),
scopedSlots: { customRender: 'memoryallocatedpercentage' }
},
{ {
title: this.$t('label.memused'), title: this.$t('label.memused'),
scopedSlots: { customRender: 'memused' } scopedSlots: { customRender: 'memused' }