Skip to content
53 changes: 36 additions & 17 deletions core/src/com/cloud/storage/template/TemplateLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.Arrays;

import org.apache.log4j.Logger;

Expand Down Expand Up @@ -81,12 +82,12 @@ public boolean purge() {
boolean purged = true;
String[] files = _storage.listFiles(_templatePath);
for (String file : files) {
boolean r = _storage.delete(file);
if (!r) {
boolean isRemoved = _storage.delete(file);
if (!isRemoved) {
purged = false;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug((r ? "R" : "Unable to r") + "emove " + file);
s_logger.debug((isRemoved ? "Removed " : "Unable to remove") + file);
}
}

Expand All @@ -97,43 +98,60 @@ public boolean load() throws IOException {
try (FileInputStream strm = new FileInputStream(_file);) {
_props.load(strm);
} catch (IOException e) {
s_logger.warn("Unable to load the template properties", e);
s_logger.warn("Unable to load the template properties for '" + _file + "': ", e);
}

for (ImageFormat format : ImageFormat.values()) {
String ext = _props.getProperty(format.getFileExtension());
String currentExtension = format.getFileExtension();
String ext = _props.getProperty(currentExtension);
if (ext != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("File extension '" + currentExtension + "' was found in '" + _file + "'.");
}
FormatInfo info = new FormatInfo();
info.format = format;
info.filename = _props.getProperty(format.getFileExtension() + ".filename");
info.filename = _props.getProperty(currentExtension + ".filename");
if (info.filename == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Property '" + currentExtension + ".filename' was not found in '" + _file + "'. Current format is ignored.");
}
continue;
}
info.size = NumbersUtil.parseLong(_props.getProperty(format.getFileExtension() + ".size"), -1);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Property '" + currentExtension + ".filename' was found in '" + _file + "'. Current format will be parsed.");
}
info.size = NumbersUtil.parseLong(_props.getProperty(currentExtension + ".size"), -1);
_props.setProperty("physicalSize", Long.toString(info.size));
info.virtualSize = NumbersUtil.parseLong(_props.getProperty(format.getFileExtension() + ".virtualsize"), -1);
info.virtualSize = NumbersUtil.parseLong(_props.getProperty(currentExtension + ".virtualsize"), -1);
_formats.add(info);

if (!checkFormatValidity(info)) {
_isCorrupted = true;
s_logger.warn("Cleaning up inconsistent information for " + format);
}
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Format extension '" + currentExtension + "' wasn't found in '" + _file + "'.");
}
}
}

if (_props.getProperty("uniquename") == null || _props.getProperty("virtualsize") == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Property 'uniquename' or 'virtualsize' weren't found in '" + _file + "'. Loading failed.");
}
return false;
}

return (_formats.size() > 0);
}

public boolean save() {
for (FormatInfo info : _formats) {
_props.setProperty(info.format.getFileExtension(), "true");
_props.setProperty(info.format.getFileExtension() + ".filename", info.filename);
_props.setProperty(info.format.getFileExtension() + ".size", Long.toString(info.size));
_props.setProperty(info.format.getFileExtension() + ".virtualsize", Long.toString(info.virtualSize));
String formatExtension = info.format.getFileExtension();
_props.setProperty(formatExtension, "true");
_props.setProperty(formatExtension + ".filename", info.filename);
_props.setProperty(formatExtension + ".size", Long.toString(info.size));
_props.setProperty(formatExtension + ".virtualsize", Long.toString(info.virtualSize));
}
try (FileOutputStream strm = new FileOutputStream(_file);) {
_props.store(strm, "");
Expand Down Expand Up @@ -205,10 +223,11 @@ protected FormatInfo deleteFormat(ImageFormat format) {
FormatInfo info = it.next();
if (info.format == format) {
it.remove();
_props.remove(format.getFileExtension());
_props.remove(format.getFileExtension() + ".filename");
_props.remove(format.getFileExtension() + ".size");
_props.remove(format.getFileExtension() + ".virtualsize");
String formatExtension = format.getFileExtension();
_props.remove(formatExtension);
for(String propertySuffix : Arrays.asList("filename","size","virtualsize")) {
_props.remove(formatExtension + "." + propertySuffix);
}
return info;
}
}
Expand Down
9 changes: 9 additions & 0 deletions debian/cloudstack-agent.postinst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ case "$1" in
done
fi

BR_NETFILTER_MODULE=br_netfilter
MODULES_FILE=/etc/modules
if /sbin/modinfo $BR_NETFILTER_MODULE >/dev/null 2>&1; then
/sbin/modprobe $BR_NETFILTER_MODULE
if ! grep $BR_NETFILTER_MODULE $MODULES_FILE >/dev/null 2>&1; then
echo "$BR_NETFILTER_MODULE" >> $MODULES_FILE
fi
fi

# Running cloudstack-agent-upgrade to update bridge name for upgrade from CloudStack 4.0.x (and before) to CloudStack 4.1 (and later)
/usr/bin/cloudstack-agent-upgrade
if [ ! -d "/etc/libvirt/hooks" ] ; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2572,9 +2572,7 @@ protected void runInContext() {
s_logger.trace("VM Operation Thread Running");
try {
_workDao.cleanup(VmOpCleanupWait.value());

// TODO. hard-coded to one hour after job has been completed
final Date cutDate = new Date(new Date().getTime() - 3600000);
final Date cutDate = new Date(DateUtil.currentGMTTime().getTime() - VmOpCleanupInterval.value() * 1000);
_workJobDao.expungeCompletedWorkJobs(cutDate);
} catch (final Exception e) {
s_logger.error("VM Operations failed due to ", e);
Expand Down Expand Up @@ -2944,7 +2942,7 @@ protected void runInContext() {
try {
scanStalledVMInTransitionStateOnDisconnectedHosts();

final List<VMInstanceVO> instances = _vmDao.findVMInTransition(new Date(new Date().getTime() - AgentManager.Wait.value() * 1000), State.Starting, State.Stopping);
final List<VMInstanceVO> instances = _vmDao.findVMInTransition(new Date(DateUtil.currentGMTTime().getTime() - AgentManager.Wait.value() * 1000), State.Starting, State.Stopping);
for (final VMInstanceVO instance : instances) {
final State state = instance.getState();
if (state == State.Stopping) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@
//under the License.
package org.apache.cloudstack.api.response;

import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javax.inject.Inject;

import org.apache.cloudstack.api.command.QuotaBalanceCmd;
import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd;
Expand Down Expand Up @@ -53,24 +60,17 @@
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.ejb.Local;
import javax.inject.Inject;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;

@Component
@Local(value = QuotaResponseBuilderImpl.class)
public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
private static final Logger s_logger = Logger.getLogger(QuotaResponseBuilderImpl.class);

Expand Down Expand Up @@ -141,7 +141,9 @@ public List<QuotaSummaryResponse> createQuotaSummaryResponse(Boolean listAll) {
} else {
for (final QuotaAccountVO quotaAccount : _quotaAccountDao.listAllQuotaAccount()) {
AccountVO account = _accountDao.findById(quotaAccount.getId());
if (account == null) continue;
if (account == null) {
continue;
}
QuotaSummaryResponse qr = getQuotaSummaryResponse(account);
result.add(qr);
}
Expand Down Expand Up @@ -181,6 +183,7 @@ public QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quot
throw new InvalidParameterValueException("The request period does not contain balance entries.");
}
Collections.sort(quotaBalance, new Comparator<QuotaBalanceVO>() {
@Override
public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) {
o1 = o1 == null ? new QuotaBalanceVO() : o1;
o2 = o2 == null ? new QuotaBalanceVO() : o2;
Expand Down Expand Up @@ -287,13 +290,15 @@ public QuotaStatementResponse createQuotaStatementResponse(final List<QuotaUsage
if (s_logger.isDebugEnabled()) {
s_logger.debug(
"createQuotaStatementResponse Type=" + quotaUsage.get(0).getUsageType() + " usage=" + quotaUsage.get(0).getQuotaUsed().setScale(2, RoundingMode.HALF_EVEN)
+ " rec.id=" + quotaUsage.get(0).getUsageItemId() + " SD=" + quotaUsage.get(0).getStartDate() + " ED=" + quotaUsage.get(0).getEndDate());
+ " rec.id=" + quotaUsage.get(0).getUsageItemId() + " SD=" + quotaUsage.get(0).getStartDate() + " ED=" + quotaUsage.get(0).getEndDate());
}

Collections.sort(quotaUsage, new Comparator<QuotaUsageVO>() {
@Override
public int compare(QuotaUsageVO o1, QuotaUsageVO o2) {
if (o1.getUsageType() == o2.getUsageType())
if (o1.getUsageType() == o2.getUsageType()) {
return 0;
}
return o1.getUsageType() < o2.getUsageType() ? -1 : 1;
}
});
Expand Down Expand Up @@ -508,29 +513,21 @@ public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd) {
public List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd) {
return _quotaService.findQuotaBalanceVO(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getStartDate(), cmd.getEndDate());
}

@Override
public Date startOfNextDay(Date dt) {
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.DATE, 1);
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTime();
public Date startOfNextDay(Date date) {
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
return createDateAtTheStartOfNextDay(localDate);
}

@Override
public Date startOfNextDay() {
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, 1);
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTime();
LocalDate localDate = LocalDate.now();
return createDateAtTheStartOfNextDay(localDate);
}

private Date createDateAtTheStartOfNextDay(LocalDate localDate) {
LocalDate nextDayLocalDate = localDate.plusDays(1);
return Date.from(nextDayLocalDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@
// under the License.
package org.apache.cloudstack.api.response;

import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.db.TransactionLegacy;
import junit.framework.TestCase;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd;
import org.apache.cloudstack.api.command.QuotaEmailTemplateUpdateCmd;
import org.apache.cloudstack.quota.QuotaService;
Expand All @@ -36,21 +39,23 @@
import org.apache.cloudstack.quota.vo.QuotaCreditsVO;
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.db.TransactionLegacy;

import javax.inject.Inject;
import junit.framework.TestCase;

@RunWith(MockitoJUnitRunner.class)
public class QuotaResponseBuilderImplTest extends TestCase {
Expand Down Expand Up @@ -218,13 +223,24 @@ public void testCreateQuotaLastBalanceResponse() {
}

@Test
public void testStartOfNextDay() {
DateTime now = new DateTime();
DateTime nextDay = new DateTime(quotaResponseBuilder.startOfNextDay(now.toDate()));
DateTime nextDay2 = new DateTime(quotaResponseBuilder.startOfNextDay());
assertTrue(now.toLocalDate().equals(nextDay.minusDays(1).toLocalDate()));
assertTrue(now.toLocalDate().equals(nextDay2.minusDays(1).toLocalDate()));
public void testStartOfNextDayWithoutParameters() {
Date nextDate = quotaResponseBuilder.startOfNextDay();

LocalDateTime tomorrowAtStartOfTheDay = LocalDate.now().atStartOfDay().plusDays(1);
Date expectedNextDate = Date.from(tomorrowAtStartOfTheDay.atZone(ZoneId.systemDefault()).toInstant());

Assert.assertEquals(expectedNextDate, nextDate);
}

@Test
public void testStartOfNextDayWithParameter() {
Date anyDate = new Date(1242421545757532l);

Date nextDayDate = quotaResponseBuilder.startOfNextDay(anyDate);

LocalDateTime nextDayLocalDateTimeAtStartOfTheDay = anyDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().plusDays(1).atStartOfDay();
Date expectedNextDate = Date.from(nextDayLocalDateTimeAtStartOfTheDay.atZone(ZoneId.systemDefault()).toInstant());

Assert.assertEquals(expectedNextDate, nextDayDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3419,7 +3419,9 @@ public boolean addNetworkRules(final String vmName, final String vmId, final Str
cmd.add("--vmname", vmName);
cmd.add("--vmid", vmId);
cmd.add("--vmip", guestIP);
cmd.add("--vmip6", guestIP6);
if (guestIP6 != null) {
cmd.add("--vmip6", guestIP6);
}
cmd.add("--sig", sig);
cmd.add("--seq", seq);
cmd.add("--vmmac", mac);
Expand Down
Loading