use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class DeploymentPlanningManagerImpl method checkHostReservationRelease.
@DB
public boolean checkHostReservationRelease(final Long hostId) {
if (hostId != null) {
PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
if (reservationEntry != null && reservationEntry.getResourceUsage() != null) {
// check if any VMs are starting or running on this host
List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
if (vms.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host " + hostId);
}
return false;
}
List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
if (vmsByLastHostId.size() > 0) {
// cannot release the host
for (VMInstanceVO stoppedVM : vmsByLastHostId) {
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found VM: " + stoppedVM + " Stopped but reserved on host " + hostId);
}
return false;
}
}
}
// check if any VMs are stopping on or migrating to this host
List<VMInstanceVO> vmsStoppingMigratingByHostId = _vmInstanceDao.findByHostInStates(hostId, State.Stopping, State.Migrating, State.Starting);
if (vmsStoppingMigratingByHostId.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vmsStoppingMigratingByHostId.size() + " VMs stopping/migrating/starting on host " + hostId);
}
return false;
}
// check if any VMs are in starting state with no hostId set yet
// -
// just ignore host release to avoid race condition
List<VMInstanceVO> vmsStartingNoHost = _vmInstanceDao.listStartingWithNoHostId();
if (vmsStartingNoHost.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs starting as of now and no hostId yet stored");
}
return false;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId);
}
final long id = reservationEntry.getId();
return Transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
if (lockedEntry == null) {
s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
return false;
}
// check before updating
if (lockedEntry.getResourceUsage() != null) {
lockedEntry.setResourceUsage(null);
_plannerHostReserveDao.persist(lockedEntry);
return true;
}
return false;
}
});
}
}
return false;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class VpcManagerImpl method createStaticRoute.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create = true)
public StaticRoute createStaticRoute(final long gatewayId, final String cidr) throws NetworkRuleConflictException {
final Account caller = CallContext.current().getCallingAccount();
// parameters validation
final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
if (gateway == null) {
throw new InvalidParameterValueException("Invalid gateway id is given");
}
if (gateway.getState() != VpcGateway.State.Ready) {
throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState());
}
final Vpc vpc = getActiveVpc(gateway.getVpcId());
if (vpc == null) {
throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
}
_accountMgr.checkAccess(caller, null, false, vpc);
if (!NetUtils.isValidCIDR(cidr)) {
throw new InvalidParameterValueException("Invalid format for cidr " + cidr);
}
// 1) CIDR should be outside of VPC cidr for guest networks
if (NetUtils.isNetworksOverlap(vpc.getCidr(), cidr)) {
throw new InvalidParameterValueException("CIDR should be outside of VPC cidr " + vpc.getCidr());
}
// 2) CIDR should be outside of link-local cidr
if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR());
}
// 3) Verify against blacklisted routes
if (isCidrBlacklisted(cidr, vpc.getZoneId())) {
throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
}
return Transaction.execute(new TransactionCallbackWithException<StaticRouteVO, NetworkRuleConflictException>() {
@Override
public StaticRouteVO doInTransaction(final TransactionStatus status) throws NetworkRuleConflictException {
StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
s_logger.debug("Adding static route " + newRoute);
newRoute = _staticRouteDao.persist(newRoute);
detectRoutesConflict(newRoute);
if (!_staticRouteDao.setStateToAdd(newRoute)) {
throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
}
CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
return newRoute;
}
});
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class VpcManagerImpl method createVpcPrivateGateway.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating VPC private gateway", create = true)
public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway, final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
// Validate parameters
final Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
ex.addProxyObject(String.valueOf(vpcId), "VPC");
throw ex;
}
PhysicalNetwork physNet = null;
// Validate physical network
if (physicalNetworkId == null) {
final List<? extends PhysicalNetwork> pNtwks = _ntwkModel.getPhysicalNtwksSupportingTrafficType(vpc.getZoneId(), TrafficType.Guest);
if (pNtwks.isEmpty() || pNtwks.size() != 1) {
throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id");
}
physNet = pNtwks.get(0);
physicalNetworkId = physNet.getId();
}
if (physNet == null) {
physNet = _entityMgr.findById(PhysicalNetwork.class, physicalNetworkId);
}
final Long dcId = physNet.getDataCenterId();
final Long physicalNetworkIdFinal = physicalNetworkId;
final PhysicalNetwork physNetFinal = physNet;
VpcGatewayVO gatewayVO = null;
try {
gatewayVO = Transaction.execute(new TransactionCallbackWithException<VpcGatewayVO, Exception>() {
@Override
public VpcGatewayVO doInTransaction(final TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
s_logger.debug("Creating Private gateway for VPC " + vpc);
// 1) create private network unless it is existing and
// lswitch'd
Network privateNtwk = null;
if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, gatewayOwnerId, dcId, networkOfferingId);
// if the dcid is different we get no network so next we
// try to create it
}
if (privateNtwk == null) {
s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
final String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, broadcastUri, ipAddress, null, gateway, netmask, gatewayOwnerId, vpcId, isSourceNat, networkOfferingId);
} else {
// create the nic/ip as createPrivateNetwork
// doesn''t do that work for us now
s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
final DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
// add entry to private_ip_address table
PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
if (privateIp != null) {
throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + " in zone " + _entityMgr.findById(DataCenter.class, dcId).getName());
}
final Long mac = dc.getMacAddress();
final Long nextMac = mac + 1;
dc.setMacAddress(nextMac);
s_logger.info("creating private ip adress for vpc (" + ipAddress + ", " + privateNtwk.getId() + ", " + nextMac + ", " + vpcId + ", " + isSourceNat + ")");
privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, isSourceNat);
_privateIpDao.persist(privateIp);
_dcDao.update(dc.getId(), dc);
}
long networkAclId = NetworkACL.DEFAULT_DENY;
if (aclId != null) {
final NetworkACLVO aclVO = _networkAclDao.findById(aclId);
if (aclVO == null) {
throw new InvalidParameterValueException("Invalid network acl id passed ");
}
if (aclVO.getVpcId() != vpcId && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
}
networkAclId = aclId;
}
{
// experimental block, this is a hack
// set vpc id in network to null
// might be needed for all types of broadcast domains
// the ugly hack is that vpc gateway nets are created as
// guest network
// while they are not.
// A more permanent solution would be to define a type of
// 'gatewaynetwork'
// so that handling code is not mixed between the two
final NetworkVO gatewaynet = _ntwkDao.findById(privateNtwk.getId());
gatewaynet.setVpcId(null);
_ntwkDao.persist(gatewaynet);
}
// 2) create gateway entry
final VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), privateNtwk.getId(), broadcastUri, gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
_vpcGatewayDao.persist(gatewayVO);
s_logger.debug("Created vpc gateway entry " + gatewayVO);
return gatewayVO;
}
});
} catch (final Exception e) {
ExceptionUtil.rethrowRuntime(e);
ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
ExceptionUtil.rethrow(e, ResourceAllocationException.class);
throw new IllegalStateException(e);
}
CallContext.current().setEventDetails("Private Gateway Id: " + gatewayVO.getId());
return getVpcPrivateGateway(gatewayVO.getId());
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class SecurityGroupManagerImpl method authorizeSecurityGroupRule.
private List<SecurityGroupRuleVO> authorizeSecurityGroupRule(final Long securityGroupId, String protocol, Integer startPort, Integer endPort, Integer icmpType, Integer icmpCode, final List<String> cidrList, Map groupList, final SecurityRuleType ruleType) {
Integer startPortOrType = null;
Integer endPortOrCode = null;
// Validate parameters
SecurityGroup securityGroup = _securityGroupDao.findById(securityGroupId);
if (securityGroup == null) {
throw new InvalidParameterValueException("Unable to find security group by id " + securityGroupId);
}
if (cidrList == null && groupList == null) {
throw new InvalidParameterValueException("At least one cidr or at least one security group needs to be specified");
}
Account caller = CallContext.current().getCallingAccount();
Account owner = _accountMgr.getAccount(securityGroup.getAccountId());
if (owner == null) {
throw new InvalidParameterValueException("Unable to find security group owner by id=" + securityGroup.getAccountId());
}
// Verify permissions
_accountMgr.checkAccess(caller, null, true, securityGroup);
Long domainId = owner.getDomainId();
if (protocol == null) {
protocol = NetUtils.ALL_PROTO;
}
if (cidrList != null) {
for (String cidr : cidrList) {
if (!NetUtils.isValidCIDR(cidr)) {
throw new InvalidParameterValueException("Invalid cidr " + cidr);
}
}
}
if (!NetUtils.isValidSecurityGroupProto(protocol)) {
throw new InvalidParameterValueException("Invalid protocol " + protocol);
}
if ("icmp".equalsIgnoreCase(protocol)) {
if ((icmpType == null) || (icmpCode == null)) {
throw new InvalidParameterValueException("Invalid ICMP type/code specified, icmpType = " + icmpType + ", icmpCode = " + icmpCode);
}
if (icmpType == -1 && icmpCode != -1) {
throw new InvalidParameterValueException("Invalid icmp code");
}
if (icmpType != -1 && icmpCode == -1) {
throw new InvalidParameterValueException("Invalid icmp code: need non-negative icmp code ");
}
if (icmpCode > 255 || icmpType > 255 || icmpCode < -1 || icmpType < -1) {
throw new InvalidParameterValueException("Invalid icmp type/code ");
}
startPortOrType = icmpType;
endPortOrCode = icmpCode;
} else if (protocol.equals(NetUtils.ALL_PROTO)) {
if ((startPort != null) || (endPort != null)) {
throw new InvalidParameterValueException("Cannot specify startPort or endPort without specifying protocol");
}
startPortOrType = 0;
endPortOrCode = 0;
} else {
if ((startPort == null) || (endPort == null)) {
throw new InvalidParameterValueException("Invalid port range specified, startPort = " + startPort + ", endPort = " + endPort);
}
if (startPort == 0 && endPort == 0) {
endPort = 65535;
}
if (startPort > endPort) {
throw new InvalidParameterValueException("Invalid port range " + startPort + ":" + endPort);
}
if (startPort > 65535 || endPort > 65535 || startPort < -1 || endPort < -1) {
throw new InvalidParameterValueException("Invalid port numbers " + startPort + ":" + endPort);
}
if (startPort < 0 || endPort < 0) {
throw new InvalidParameterValueException("Invalid port range " + startPort + ":" + endPort);
}
startPortOrType = startPort;
endPortOrCode = endPort;
}
protocol = protocol.toLowerCase();
List<SecurityGroupVO> authorizedGroups = new ArrayList<SecurityGroupVO>();
if (groupList != null) {
Collection userGroupCollection = groupList.values();
Iterator iter = userGroupCollection.iterator();
while (iter.hasNext()) {
HashMap userGroup = (HashMap) iter.next();
String group = (String) userGroup.get("group");
String authorizedAccountName = (String) userGroup.get("account");
if ((group == null) || (authorizedAccountName == null)) {
throw new InvalidParameterValueException("Invalid user group specified, fields 'group' and 'account' cannot be null, please specify groups in the form: userGroupList[0].group=XXX&userGroupList[0].account=YYY");
}
Account authorizedAccount = _accountDao.findActiveAccount(authorizedAccountName, domainId);
if (authorizedAccount == null) {
throw new InvalidParameterValueException("Nonexistent account: " + authorizedAccountName + " when trying to authorize security group rule for " + securityGroupId + ":" + protocol + ":" + startPortOrType + ":" + endPortOrCode);
}
SecurityGroupVO groupVO = _securityGroupDao.findByAccountAndName(authorizedAccount.getId(), group);
if (groupVO == null) {
throw new InvalidParameterValueException("Nonexistent group " + group + " for account " + authorizedAccountName + "/" + domainId + " is given, unable to authorize security group rule.");
}
// Check permissions
if (domainId != groupVO.getDomainId()) {
throw new PermissionDeniedException("Can't add security group id=" + groupVO.getDomainId() + " as it belongs to different domain");
}
authorizedGroups.add(groupVO);
}
}
final Set<SecurityGroupVO> authorizedGroups2 = new TreeSet<SecurityGroupVO>(new SecurityGroupVOComparator());
// Ensure we don't re-lock the same row
authorizedGroups2.addAll(authorizedGroups);
final Integer startPortOrTypeFinal = startPortOrType;
final Integer endPortOrCodeFinal = endPortOrCode;
final String protocolFinal = protocol;
List<SecurityGroupRuleVO> newRules = Transaction.execute(new TransactionCallback<List<SecurityGroupRuleVO>>() {
@Override
public List<SecurityGroupRuleVO> doInTransaction(TransactionStatus status) {
// Prevents other threads/management servers from creating duplicate security rules
SecurityGroup securityGroup = _securityGroupDao.acquireInLockTable(securityGroupId);
if (securityGroup == null) {
s_logger.warn("Could not acquire lock on network security group: id= " + securityGroupId);
return null;
}
List<SecurityGroupRuleVO> newRules = new ArrayList<SecurityGroupRuleVO>();
try {
for (final SecurityGroupVO ngVO : authorizedGroups2) {
final Long ngId = ngVO.getId();
// Don't delete the referenced group from under us
if (ngVO.getId() != securityGroup.getId()) {
final SecurityGroupVO tmpGrp = _securityGroupDao.lockRow(ngId, false);
if (tmpGrp == null) {
s_logger.warn("Failed to acquire lock on security group: " + ngId);
throw new ConcurrentAccessException("Failed to acquire lock on security group: " + ngId);
}
}
SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndAllowedGroupId(securityGroup.getId(), protocolFinal, startPortOrTypeFinal, endPortOrCodeFinal, ngVO.getId());
if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) {
// rule already exists.
continue;
}
securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrTypeFinal, endPortOrCodeFinal, protocolFinal, ngVO.getId());
securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule);
newRules.add(securityGroupRule);
}
if (cidrList != null) {
for (String cidr : cidrList) {
SecurityGroupRuleVO securityGroupRule = _securityGroupRuleDao.findByProtoPortsAndCidr(securityGroup.getId(), protocolFinal, startPortOrTypeFinal, endPortOrCodeFinal, cidr);
if ((securityGroupRule != null) && (securityGroupRule.getRuleType() == ruleType)) {
continue;
}
securityGroupRule = new SecurityGroupRuleVO(ruleType, securityGroup.getId(), startPortOrTypeFinal, endPortOrCodeFinal, protocolFinal, cidr);
securityGroupRule = _securityGroupRuleDao.persist(securityGroupRule);
newRules.add(securityGroupRule);
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Added " + newRules.size() + " rules to security group " + securityGroup.getName());
}
return newRules;
} catch (Exception e) {
s_logger.warn("Exception caught when adding security group rules ", e);
throw new CloudRuntimeException("Exception caught when adding security group rules", e);
} finally {
if (securityGroup != null) {
_securityGroupDao.releaseFromLockTable(securityGroup.getId());
}
}
}
});
try {
final ArrayList<Long> affectedVms = new ArrayList<Long>();
affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId()));
scheduleRulesetUpdateToHosts(affectedVms, true, null);
} catch (Exception e) {
s_logger.debug("can't update rules on host, ignore", e);
}
return newRules;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class SecurityGroupManagerImpl method removeInstanceFromGroups.
@Override
@DB
public void removeInstanceFromGroups(final long userVmId) {
if (_securityGroupVMMapDao.countSGForVm(userVmId) < 1) {
s_logger.trace("No security groups found for vm id=" + userVmId + ", returning");
return;
}
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
// ensures that duplicate entries are not created in
UserVm userVm = _userVMDao.acquireInLockTable(userVmId);
// addInstance
if (userVm == null) {
s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
}
int n = _securityGroupVMMapDao.deleteVM(userVmId);
s_logger.info("Disassociated " + n + " network groups " + " from uservm " + userVmId);
_userVMDao.releaseFromLockTable(userVmId);
}
});
s_logger.debug("Security group mappings are removed successfully for vm id=" + userVmId);
}
Aggregations