mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge branch '4.19'
This commit is contained in:
commit
db564b12b6
@ -31,6 +31,7 @@ import org.apache.cloudstack.config.Configuration;
|
||||
import org.apache.cloudstack.ha.HAConfig;
|
||||
import org.apache.cloudstack.storage.object.Bucket;
|
||||
import org.apache.cloudstack.storage.object.ObjectStore;
|
||||
import org.apache.cloudstack.quota.QuotaTariff;
|
||||
import org.apache.cloudstack.usage.Usage;
|
||||
import org.apache.cloudstack.vm.schedule.VMSchedule;
|
||||
|
||||
@ -729,6 +730,11 @@ public class EventTypes {
|
||||
public static final String EVENT_BUCKET_DELETE = "BUCKET.DELETE";
|
||||
public static final String EVENT_BUCKET_UPDATE = "BUCKET.UPDATE";
|
||||
|
||||
// Quota
|
||||
public static final String EVENT_QUOTA_TARIFF_CREATE = "QUOTA.TARIFF.CREATE";
|
||||
public static final String EVENT_QUOTA_TARIFF_DELETE = "QUOTA.TARIFF.DELETE";
|
||||
public static final String EVENT_QUOTA_TARIFF_UPDATE = "QUOTA.TARIFF.UPDATE";
|
||||
|
||||
static {
|
||||
|
||||
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
|
||||
@ -1178,6 +1184,11 @@ public class EventTypes {
|
||||
entityEventDetails.put(EVENT_BUCKET_CREATE, Bucket.class);
|
||||
entityEventDetails.put(EVENT_BUCKET_UPDATE, Bucket.class);
|
||||
entityEventDetails.put(EVENT_BUCKET_DELETE, Bucket.class);
|
||||
|
||||
// Quota
|
||||
entityEventDetails.put(EVENT_QUOTA_TARIFF_CREATE, QuotaTariff.class);
|
||||
entityEventDetails.put(EVENT_QUOTA_TARIFF_DELETE, QuotaTariff.class);
|
||||
entityEventDetails.put(EVENT_QUOTA_TARIFF_UPDATE, QuotaTariff.class);
|
||||
}
|
||||
|
||||
public static String getEntityForEvent(String eventName) {
|
||||
|
||||
@ -80,7 +80,8 @@ public enum ApiCommandResourceType {
|
||||
VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class),
|
||||
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class),
|
||||
ObjectStore(org.apache.cloudstack.storage.object.ObjectStore.class),
|
||||
Bucket(org.apache.cloudstack.storage.object.Bucket.class);
|
||||
Bucket(org.apache.cloudstack.storage.object.Bucket.class),
|
||||
QuotaTariff(org.apache.cloudstack.quota.QuotaTariff.class);
|
||||
|
||||
private final Class<?> clazz;
|
||||
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
// 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
|
||||
// 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 org.apache.cloudstack.quota;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface QuotaTariff extends InternalIdentity, Identity {
|
||||
|
||||
}
|
||||
@ -131,7 +131,7 @@ public class SecurityGroupVMMapDaoImpl extends GenericDaoBase<SecurityGroupVMMap
|
||||
SearchCriteria<SecurityGroupVMMapVO> sc = ListBySecurityGroupAndStates.create();
|
||||
sc.setParameters("securityGroupId", securityGroupId);
|
||||
sc.setParameters("states", (Object[])vmStates);
|
||||
return listBy(sc, null, true);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
// 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.upgrade.dao;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
|
||||
public class Upgrade41900to41910 implements DbUpgrade {
|
||||
|
||||
@Override
|
||||
public String[] getUpgradableVersionRange() {
|
||||
return new String[] {"4.19.0.0", "4.19.1.0"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUpgradedVersion() {
|
||||
return "4.19.1.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRollingUpgrade() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream[] getPrepareScripts() {
|
||||
final String scriptFile = "META-INF/db/schema-41900to41910.sql";
|
||||
final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
|
||||
if (script == null) {
|
||||
throw new CloudRuntimeException("Unable to find " + scriptFile);
|
||||
}
|
||||
|
||||
return new InputStream[] {script};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream[] getCleanupScripts() {
|
||||
final String scriptFile = "META-INF/db/schema-41900to41910-cleanup.sql";
|
||||
final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
|
||||
if (script == null) {
|
||||
throw new CloudRuntimeException("Unable to find " + scriptFile);
|
||||
}
|
||||
|
||||
return new InputStream[] {script};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
-- 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.
|
||||
|
||||
--;
|
||||
-- Schema upgrade cleanup from 4.19.0.0 to 4.19.1.0
|
||||
--;
|
||||
@ -0,0 +1,32 @@
|
||||
-- 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.
|
||||
|
||||
--;
|
||||
-- Schema upgrade from 4.19.0.0 to 4.19.1.0
|
||||
--;
|
||||
|
||||
-- Updates the populated Quota tariff's types VM_DISK_BYTES_READ, VM_DISK_BYTES_WRITE, VM_DISK_IO_READ and VM_DISK_IO_WRITE to the correct unit.
|
||||
|
||||
UPDATE cloud_usage.quota_tariff
|
||||
SET usage_unit = 'Bytes', updated_on = NOW()
|
||||
WHERE effective_on = '2010-05-04 00:00:00'
|
||||
AND name IN ('VM_DISK_BYTES_READ', 'VM_DISK_BYTES_WRITE');
|
||||
|
||||
UPDATE cloud_usage.quota_tariff
|
||||
SET usage_unit = 'IOPS', updated_on = NOW()
|
||||
WHERE effective_on = '2010-05-04 00:00:00'
|
||||
AND name IN ('VM_DISK_IO_READ', 'VM_DISK_IO_WRITE');
|
||||
@ -1502,9 +1502,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
||||
} else {
|
||||
_idField.set(entity, id);
|
||||
}
|
||||
} else {
|
||||
id = (ID)_idField.get(entity);
|
||||
}
|
||||
|
||||
id = (ID)_idField.get(entity);
|
||||
}
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new CloudRuntimeException("Yikes! ", e);
|
||||
|
||||
@ -229,4 +229,14 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
|
||||
|
||||
return quotaTariffs.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaTariffVO findByIdIncludingRemoved(Long id) {
|
||||
return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<QuotaTariffVO>) status -> super.findByIdIncludingRemoved(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaTariffVO findByUuidIncludingRemoved(String uuid) {
|
||||
return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<QuotaTariffVO>) status -> super.findByUuidIncludingRemoved(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
package org.apache.cloudstack.quota.vo;
|
||||
|
||||
import com.cloud.utils.DateUtil;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.quota.QuotaTariff;
|
||||
import org.apache.cloudstack.quota.constant.QuotaTypes;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
@ -40,7 +40,7 @@ import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_tariff")
|
||||
public class QuotaTariffVO implements InternalIdentity {
|
||||
public class QuotaTariffVO implements QuotaTariff {
|
||||
private static final long serialVersionUID = -7117933766387653203L;
|
||||
|
||||
@Id
|
||||
@ -243,6 +243,7 @@ public class QuotaTariffVO implements InternalIdentity {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.cloud.user.Account;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
@ -27,6 +28,7 @@ import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.QuotaTariffResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -68,6 +70,7 @@ public class QuotaTariffCreateCmd extends BaseCmd {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails(String.format("Tariff: %s, description: %s, value: %s", getName(), getDescription(), getValue()));
|
||||
QuotaTariffVO result = responseBuilder.createQuotaTariff(this);
|
||||
|
||||
if (result == null) {
|
||||
@ -132,4 +135,8 @@ public class QuotaTariffCreateCmd extends BaseCmd {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.QuotaTariff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,12 +21,14 @@ import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.QuotaTariffResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -47,6 +49,7 @@ public class QuotaTariffDeleteCmd extends BaseCmd {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails(String.format("Tariff id: %s", getId()));
|
||||
boolean result = responseBuilder.deleteQuotaTariff(getId());
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setSuccess(result);
|
||||
@ -58,4 +61,8 @@ public class QuotaTariffDeleteCmd extends BaseCmd {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.QuotaTariff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.cloud.user.Account;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
@ -27,6 +28,7 @@ import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.QuotaTariffResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -109,6 +111,7 @@ public class QuotaTariffUpdateCmd extends BaseCmd {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails(String.format("Tariff: %s, description: %s, value: %s", getName(), getDescription(), getValue()));
|
||||
final QuotaTariffVO result = _responseBuilder.updateQuotaTariffPlan(this);
|
||||
if (result == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update quota tariff plan");
|
||||
@ -123,4 +126,8 @@ public class QuotaTariffUpdateCmd extends BaseCmd {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.QuotaTariff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ import org.apache.cloudstack.api.command.QuotaStatementCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaTariffCreateCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaTariffListCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.QuotaManager;
|
||||
import org.apache.cloudstack.quota.QuotaManagerImpl;
|
||||
import org.apache.cloudstack.quota.QuotaService;
|
||||
@ -78,6 +79,8 @@ import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
|
||||
@Component
|
||||
public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
@ -383,6 +386,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_UPDATE, eventDescription = "updating Quota Tariff")
|
||||
public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) {
|
||||
String name = cmd.getName();
|
||||
Double value = cmd.getValue();
|
||||
@ -406,6 +410,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
QuotaTariffVO newQuotaTariff = persistNewQuotaTariff(currentQuotaTariff, name, 0, currentQuotaTariffStartDate, cmd.getEntityOwnerId(), endDate, value, description,
|
||||
activationRule);
|
||||
_quotaTariffDao.updateQuotaTariff(currentQuotaTariff);
|
||||
|
||||
CallContext.current().setEventResourceId(newQuotaTariff.getId());
|
||||
|
||||
return newQuotaTariff;
|
||||
}
|
||||
|
||||
@ -625,6 +632,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_CREATE, eventDescription = "creating Quota Tariff")
|
||||
public QuotaTariffVO createQuotaTariff(QuotaTariffCreateCmd cmd) {
|
||||
String name = cmd.getName();
|
||||
int usageType = cmd.getUsageType();
|
||||
@ -647,9 +655,14 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
"Please, inform a date in the future or do not pass the parameter to use the current date and time.", startDate));
|
||||
}
|
||||
|
||||
return persistNewQuotaTariff(null, name, usageType, startDate, cmd.getEntityOwnerId(), endDate, value, description, activationRule);
|
||||
QuotaTariffVO newQuotaTariff = persistNewQuotaTariff(null, name, usageType, startDate, cmd.getEntityOwnerId(), endDate, value, description, activationRule);
|
||||
|
||||
CallContext.current().setEventResourceId(newQuotaTariff.getId());
|
||||
|
||||
return newQuotaTariff;
|
||||
}
|
||||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_DELETE, eventDescription = "removing Quota Tariff")
|
||||
public boolean deleteQuotaTariff(String quotaTariffUuid) {
|
||||
QuotaTariffVO quotaTariff = _quotaTariffDao.findByUuid(quotaTariffUuid);
|
||||
|
||||
@ -658,6 +671,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
}
|
||||
|
||||
quotaTariff.setRemoved(_quotaService.computeAdjustedTime(new Date()));
|
||||
|
||||
CallContext.current().setEventResourceId(quotaTariff.getId());
|
||||
|
||||
return _quotaTariffDao.updateQuotaTariff(quotaTariff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,6 +420,9 @@ public class LibvirtDomainXMLParser {
|
||||
}
|
||||
|
||||
private static String getTagValue(String tag, Element eElement) {
|
||||
if (eElement == null) {
|
||||
return null;
|
||||
}
|
||||
NodeList tagNodeList = eElement.getElementsByTagName(tag);
|
||||
if (tagNodeList == null || tagNodeList.getLength() == 0) {
|
||||
return null;
|
||||
@ -427,14 +430,20 @@ public class LibvirtDomainXMLParser {
|
||||
|
||||
NodeList nlList = tagNodeList.item(0).getChildNodes();
|
||||
|
||||
if (nlList == null || nlList.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
Node nValue = nlList.item(0);
|
||||
|
||||
return nValue.getNodeValue();
|
||||
}
|
||||
|
||||
private static String getAttrValue(String tag, String attr, Element eElement) {
|
||||
if (eElement == null) {
|
||||
return null;
|
||||
}
|
||||
NodeList tagNode = eElement.getElementsByTagName(tag);
|
||||
if (tagNode.getLength() == 0) {
|
||||
if (tag == null || tagNode.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
Element node = (Element)tagNode.item(0);
|
||||
|
||||
@ -259,4 +259,126 @@ public class LibvirtDomainXMLParserTest extends TestCase {
|
||||
assertEquals(WatchDogDef.WatchDogModel.I6300ESB, watchDogs.get(0).getModel());
|
||||
assertEquals(WatchDogDef.WatchDogAction.RESET, watchDogs.get(0).getAction());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainXMLParserWithoutModelName() {
|
||||
String xml = "<domain type='kvm'>\n" +
|
||||
" <name>testkiran</name>\n" +
|
||||
" <uuid>aafaaabc-8657-4efc-9c52-3422d4e04088</uuid>\n" +
|
||||
" <memory unit='KiB'>2097152</memory>\n" +
|
||||
" <currentMemory unit='KiB'>2097152</currentMemory>\n" +
|
||||
" <vcpu placement='static'>2</vcpu>\n" +
|
||||
" <os>\n" +
|
||||
" <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
|
||||
" <boot dev='hd'/>\n" +
|
||||
" </os>\n" +
|
||||
" <features>\n" +
|
||||
" <acpi/>\n" +
|
||||
" <apic/>\n" +
|
||||
" </features>\n" +
|
||||
" <cpu mode='host-model' check='partial'>\n" +
|
||||
" <model fallback='allow'/>\n" +
|
||||
" </cpu>\n" +
|
||||
" <clock offset='utc'>\n" +
|
||||
" <timer name='rtc' tickpolicy='catchup'/>\n" +
|
||||
" <timer name='pit' tickpolicy='delay'/>\n" +
|
||||
" <timer name='hpet' present='no'/>\n" +
|
||||
" </clock>\n" +
|
||||
" <on_poweroff>destroy</on_poweroff>\n" +
|
||||
" <on_reboot>restart</on_reboot>\n" +
|
||||
" <on_crash>destroy</on_crash>\n" +
|
||||
" <pm>\n" +
|
||||
" <suspend-to-mem enabled='no'/>\n" +
|
||||
" <suspend-to-disk enabled='no'/>\n" +
|
||||
" </pm>\n" +
|
||||
" <devices>\n" +
|
||||
" <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
|
||||
" <disk type='file' device='disk'>\n" +
|
||||
" <driver name='qemu' type='qcow2'/>\n" +
|
||||
" <source file='/var/lib/libvirt/images/ubuntu-22.04.qcow2'/>\n" +
|
||||
" <target dev='vda' bus='virtio'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>\n" +
|
||||
" </disk>\n" +
|
||||
" <disk type='file' device='disk'>\n" +
|
||||
" <driver name='qemu' type='qcow2'/>\n" +
|
||||
" <source file='/var/lib/libvirt/images/testkiran.qcow2'/>\n" +
|
||||
" <target dev='vdb' bus='virtio'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>\n" +
|
||||
" </disk>\n" +
|
||||
" <controller type='usb' index='0' model='ich9-ehci1'>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>\n" +
|
||||
" </controller>\n" +
|
||||
" <controller type='usb' index='0' model='ich9-uhci1'>\n" +
|
||||
" <master startport='0'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>\n" +
|
||||
" </controller>\n" +
|
||||
" <controller type='usb' index='0' model='ich9-uhci2'>\n" +
|
||||
" <master startport='2'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>\n" +
|
||||
" </controller>\n" +
|
||||
" <controller type='usb' index='0' model='ich9-uhci3'>\n" +
|
||||
" <master startport='4'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/>\n" +
|
||||
" </controller>\n" +
|
||||
" <controller type='pci' index='0' model='pci-root'/>\n" +
|
||||
" <controller type='virtio-serial' index='0'>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>\n" +
|
||||
" </controller>\n" +
|
||||
" <interface type='network'>\n" +
|
||||
" <mac address='52:54:00:09:73:b8'/>\n" +
|
||||
" <source network='default'/>\n" +
|
||||
" <model type='virtio'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
|
||||
" </interface>\n" +
|
||||
" <serial type='pty'>\n" +
|
||||
" <target type='isa-serial' port='0'>\n" +
|
||||
" <model name='isa-serial'/>\n" +
|
||||
" </target>\n" +
|
||||
" </serial>\n" +
|
||||
" <console type='pty'>\n" +
|
||||
" <target type='serial' port='0'/>\n" +
|
||||
" </console>\n" +
|
||||
" <channel type='spicevmc'>\n" +
|
||||
" <target type='virtio' name='com.redhat.spice.0'/>\n" +
|
||||
" <address type='virtio-serial' controller='0' bus='0' port='1'/>\n" +
|
||||
" </channel>\n" +
|
||||
" <input type='tablet' bus='usb'>\n" +
|
||||
" <address type='usb' bus='0' port='1'/>\n" +
|
||||
" </input>\n" +
|
||||
" <input type='mouse' bus='ps2'/>\n" +
|
||||
" <input type='keyboard' bus='ps2'/>\n" +
|
||||
" <graphics type='vnc' port='-1' autoport='yes'>\n" +
|
||||
" <listen type='address'/>\n" +
|
||||
" </graphics>\n" +
|
||||
" <graphics type='spice' autoport='yes'>\n" +
|
||||
" <listen type='address'/>\n" +
|
||||
" <image compression='off'/>\n" +
|
||||
" </graphics>\n" +
|
||||
" <sound model='ich6'>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
|
||||
" </sound>\n" +
|
||||
" <video>\n" +
|
||||
" <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
|
||||
" </video>\n" +
|
||||
" <redirdev bus='usb' type='spicevmc'>\n" +
|
||||
" <address type='usb' bus='0' port='2'/>\n" +
|
||||
" </redirdev>\n" +
|
||||
" <redirdev bus='usb' type='spicevmc'>\n" +
|
||||
" <address type='usb' bus='0' port='3'/>\n" +
|
||||
" </redirdev>\n" +
|
||||
" <memballoon model='virtio'>\n" +
|
||||
" <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>\n" +
|
||||
" </memballoon>\n" +
|
||||
" </devices>\n" +
|
||||
"</domain>";
|
||||
|
||||
LibvirtDomainXMLParser libvirtDomainXMLParser = new LibvirtDomainXMLParser();
|
||||
try {
|
||||
libvirtDomainXMLParser.parseDomainXML(xml);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Got exception " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ import com.cloud.api.storage.LinstorRevertBackupSnapshotCommand;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.ResizeVolumePayload;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
@ -215,6 +216,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
}
|
||||
throw new CloudRuntimeException("Linstor: Unable to delete resource definition: " + rscDefName);
|
||||
}
|
||||
logger.info(String.format("Linstor: Deleted resource %s", rscDefName));
|
||||
} catch (ApiException apiEx)
|
||||
{
|
||||
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
||||
@ -865,7 +867,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
Host host = null;
|
||||
for (String nodeName : linstorNodeNames) {
|
||||
host = _hostDao.findByName(nodeName);
|
||||
if (host != null) {
|
||||
if (host != null && host.getResourceState() == ResourceState.Enabled) {
|
||||
logger.info(String.format("Linstor: Make resource %s available on node %s ...", rscName, nodeName));
|
||||
ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, nodeName, new ResourceMakeAvailable());
|
||||
if (!answers.hasError()) {
|
||||
@ -892,21 +894,16 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
}
|
||||
|
||||
private Optional<RemoteHostEndPoint> getDiskfullEP(DevelopersApi api, String rscName) throws ApiException {
|
||||
com.linbit.linstor.api.model.StoragePool linSP =
|
||||
LinstorUtil.getDiskfulStoragePool(api, rscName);
|
||||
if (linSP != null)
|
||||
{
|
||||
Host host = _hostDao.findByName(linSP.getNodeName());
|
||||
if (host == null)
|
||||
{
|
||||
logger.error("Linstor: Host '" + linSP.getNodeName() + "' not found.");
|
||||
return Optional.empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Optional.of(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
|
||||
List<com.linbit.linstor.api.model.StoragePool> linSPs = LinstorUtil.getDiskfulStoragePools(api, rscName);
|
||||
if (linSPs != null) {
|
||||
for (com.linbit.linstor.api.model.StoragePool sp : linSPs) {
|
||||
Host host = _hostDao.findByName(sp.getNodeName());
|
||||
if (host != null && host.getResourceState() == ResourceState.Enabled) {
|
||||
return Optional.of(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.error("Linstor: No diskfull host found.");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@ -958,9 +955,11 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
}
|
||||
else {
|
||||
answer = new Answer(cmd, false, "Unable to get matching Linstor endpoint.");
|
||||
deleteResourceDefinition(pool, rscName);
|
||||
}
|
||||
} catch (ApiException exc) {
|
||||
logger.error("copy template failed: ", exc);
|
||||
deleteResourceDefinition(pool, rscName);
|
||||
throw new CloudRuntimeException(exc.getBestMessage());
|
||||
}
|
||||
return answer;
|
||||
|
||||
@ -78,16 +78,16 @@ public class LinstorUtil {
|
||||
return nodes.stream().map(Node::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static com.linbit.linstor.api.model.StoragePool
|
||||
getDiskfulStoragePool(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
|
||||
public static List<com.linbit.linstor.api.model.StoragePool>
|
||||
getDiskfulStoragePools(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
|
||||
{
|
||||
List<ResourceWithVolumes> resources = api.viewResources(
|
||||
Collections.emptyList(),
|
||||
Collections.singletonList(rscName),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null);
|
||||
Collections.emptyList(),
|
||||
Collections.singletonList(rscName),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null);
|
||||
|
||||
String nodeName = null;
|
||||
String storagePoolName = null;
|
||||
@ -108,13 +108,23 @@ public class LinstorUtil {
|
||||
}
|
||||
|
||||
List<com.linbit.linstor.api.model.StoragePool> sps = api.viewStoragePools(
|
||||
Collections.singletonList(nodeName),
|
||||
Collections.singletonList(storagePoolName),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null
|
||||
Collections.singletonList(nodeName),
|
||||
Collections.singletonList(storagePoolName),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
return !sps.isEmpty() ? sps.get(0) : null;
|
||||
return sps != null ? sps : Collections.emptyList();
|
||||
}
|
||||
|
||||
public static com.linbit.linstor.api.model.StoragePool
|
||||
getDiskfulStoragePool(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
|
||||
{
|
||||
List<com.linbit.linstor.api.model.StoragePool> sps = getDiskfulStoragePools(api, rscName);
|
||||
if (sps != null) {
|
||||
return !sps.isEmpty() ? sps.get(0) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getSnapshotPath(com.linbit.linstor.api.model.StoragePool sp, String rscName, String snapshotName) {
|
||||
|
||||
@ -553,7 +553,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
||||
List<StoragePoolVO> pools = primaryDataStoreDao.listPoolsByCluster(cluster.getId());
|
||||
pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId()));
|
||||
for (StoragePool pool : pools) {
|
||||
if (StringUtils.contains(pool.getPath(), dsPath)) {
|
||||
String searchPoolParam = StringUtils.isNotBlank(dsPath) ? dsPath : dsName;
|
||||
if (StringUtils.contains(pool.getPath(), searchPoolParam)) {
|
||||
storagePool = pool;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -339,7 +339,8 @@ export default {
|
||||
{ value: 'Template' },
|
||||
{ value: 'User' },
|
||||
{ value: 'VirtualMachine' },
|
||||
{ value: 'Volume' }
|
||||
{ value: 'Volume' },
|
||||
{ value: 'QuotaTariff' }
|
||||
]
|
||||
this.fields[resourceTypeIndex].loading = false
|
||||
}
|
||||
|
||||
@ -58,11 +58,11 @@ export default {
|
||||
created () {
|
||||
if (this.resourceType) {
|
||||
var routePrefix = this.$getRouteFromResourceType(this.resourceType)
|
||||
if (routePrefix && this.resourceId) {
|
||||
if (routePrefix && this.resourceId && this.resourceType !== 'QuotaTariff') {
|
||||
this.resourceRoute = '/' + routePrefix + '/' + this.resourceId
|
||||
}
|
||||
this.resourceIcon = this.$getIconFromResourceType(this.resourceType)
|
||||
this.resourceIconTooltip = this.$t('label.' + this.resourceType.toString().toLowerCase())
|
||||
this.resourceIconTooltip = this.$t('label.' + this.resourceType.toString().match(/[A-Z][a-z]*/g).join('.').toLowerCase())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,9 +31,9 @@ export default {
|
||||
permission: ['listVirtualMachinesMetrics'],
|
||||
resourceType: 'UserVm',
|
||||
params: () => {
|
||||
var params = { details: 'servoff,tmpl,nics,backoff' }
|
||||
var params = { details: 'servoff,tmpl,iso,nics,backoff' }
|
||||
if (store.getters.metrics) {
|
||||
params = { details: 'servoff,tmpl,nics,backoff,stats' }
|
||||
params = { details: 'servoff,tmpl,iso,nics,backoff,stats' }
|
||||
}
|
||||
params.isvnf = false
|
||||
return params
|
||||
|
||||
@ -417,6 +417,7 @@ export const resourceTypePlugin = {
|
||||
case 'AffinityGroup':
|
||||
case 'VpnCustomerGateway':
|
||||
case 'AutoScaleVmGroup':
|
||||
case 'QuotaTariff':
|
||||
return resourceType.toLowerCase()
|
||||
}
|
||||
return ''
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user