Externalizes logrotate service frequency timer in VR (#6507)

Co-authored-by: Lopez <rodrigo@scclouds.com.br>
This commit is contained in:
Rodrigo D. Lopez 2022-10-26 04:04:12 -03:00 committed by GitHub
parent 14937e1adb
commit adfaa730b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 8 deletions

View File

@ -114,6 +114,12 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
static final ConfigKey<Double> RouterHealthChecksMaxMemoryUsageThreshold = new ConfigKey<Double>(Double.class, "router.health.checks.max.memory.usage.threshold", static final ConfigKey<Double> RouterHealthChecksMaxMemoryUsageThreshold = new ConfigKey<Double>(Double.class, "router.health.checks.max.memory.usage.threshold",
"Advanced", "100", "Max Memory Usage threshold as % above which check is considered a failure.", "Advanced", "100", "Max Memory Usage threshold as % above which check is considered a failure.",
true, ConfigKey.Scope.Zone, null); true, ConfigKey.Scope.Zone, null);
ConfigKey<String> RouterLogrotateFrequency = new ConfigKey<>(String.class, "router.logrotate.frequency", "Advanced", "*:00:00",
"Sets the frequency of the logrotate service on the virtual router. The default value is *:00:00 (hourly) and follows the last block of " +
"OnCalendar standard [Hour:Minute:Second]. e.g, *:*:00 is for every minute and */12:00:00 is for every 12 hours. See Systemd Timers for more options. " +
"Furthermore, the file's minimum size is hardcoded as 10MiB, meaning that the service of logrotate will run, but not rotate the log files if it does not " +
"reach the minimum size.",
true, ConfigKey.Scope.Zone, null);
public static final int DEFAULT_ROUTER_VM_RAMSIZE = 256; // 256M public static final int DEFAULT_ROUTER_VM_RAMSIZE = 256; // 256M
public static final int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz public static final int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz

View File

@ -43,6 +43,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
@ -289,6 +290,10 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
private static final String FILESYSTEM_WRITABLE_TEST = "filesystem.writable.test"; private static final String FILESYSTEM_WRITABLE_TEST = "filesystem.writable.test";
private static final String READONLY_FILESYSTEM_ERROR = "Read-only file system"; private static final String READONLY_FILESYSTEM_ERROR = "Read-only file system";
private static final String BACKUP_ROUTER_EXCLUDED_TESTS = "gateways_check.py"; private static final String BACKUP_ROUTER_EXCLUDED_TESTS = "gateways_check.py";
/**
* Used regex to ensure that the value that will be passed to the VR is an acceptable value
*/
public static final String LOGROTATE_REGEX = "((?i)(hourly)|(daily)|(monthly))|(\\*|\\d{2})\\:(\\*|\\d{2})\\:(\\*|\\d{2})";
@Inject private EntityManager _entityMgr; @Inject private EntityManager _entityMgr;
@Inject private DataCenterDao _dcDao; @Inject private DataCenterDao _dcDao;
@ -2126,6 +2131,17 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
} }
} }
String routerLogrotateFrequency = RouterLogrotateFrequency.valueIn(router.getDataCenterId());
if (!checkLogrotateTimerPattern(routerLogrotateFrequency)) {
s_logger.debug(String.format("Setting [%s] with value [%s] do not match with the used regex [%s], or any acceptable value ('hourly', 'daily', 'monthly'); " +
"therefore, we will use the default value [%s] to configure the logrotate service on the virtual router.",RouterLogrotateFrequency.key(),
routerLogrotateFrequency, LOGROTATE_REGEX, RouterLogrotateFrequency.defaultValue()));
routerLogrotateFrequency = RouterLogrotateFrequency.defaultValue();
}
s_logger.debug(String.format("The setting [%s] with value [%s] for the zone with UUID [%s], will be used to configure the logrotate service frequency" +
" on the virtual router.", RouterLogrotateFrequency.key(), routerLogrotateFrequency, dc.getUuid()));
buf.append(String.format(" logrotatefrequency=%s", routerLogrotateFrequency));
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
} }
@ -2133,6 +2149,18 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
return true; return true;
} }
/**
* @param routerLogrotateFrequency The string to be checked if matches with any acceptable values.
* Checks if the value in the global configuration is an acceptable value to be informed to the Virtual Router.
* @return true if the passed value match with any acceptable value based on the regex ((?i)(hourly)|(daily)|(monthly))|(\*|\d{2})\:(\*|\d{2})\:(\*|\d{2})
*/
protected boolean checkLogrotateTimerPattern(String routerLogrotateFrequency) {
if (Pattern.matches(LOGROTATE_REGEX, routerLogrotateFrequency)) {
return true;
}
return false;
}
protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) { protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) {
final long guestNetworkId = guestNic.getNetworkId(); final long guestNetworkId = guestNic.getNetworkId();
final NetworkVO guestNetwork = _networkDao.findById(guestNetworkId); final NetworkVO guestNetwork = _networkDao.findById(guestNetworkId);
@ -3298,7 +3326,8 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
RouterHealthChecksFreeDiskSpaceThreshold, RouterHealthChecksFreeDiskSpaceThreshold,
RouterHealthChecksMaxCpuUsageThreshold, RouterHealthChecksMaxCpuUsageThreshold,
RouterHealthChecksMaxMemoryUsageThreshold, RouterHealthChecksMaxMemoryUsageThreshold,
ExposeDnsAndBootpServer ExposeDnsAndBootpServer,
RouterLogrotateFrequency
}; };
} }

View File

@ -31,6 +31,7 @@ import java.util.List;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.cloudstack.utils.identity.ManagementServerNode;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
@ -306,6 +307,26 @@ public class VirtualNetworkApplianceManagerImplTest {
} }
} }
@Test
public void checkLogrotateTimerPatternTestDoNotMatchWithRegex(){
String foo = "non-sense";
boolean result = virtualNetworkApplianceManagerImpl.checkLogrotateTimerPattern(foo);
Assert.assertFalse(result);
foo = "*";
result = virtualNetworkApplianceManagerImpl.checkLogrotateTimerPattern(foo);
Assert.assertFalse(result);
}
@Test
public void checkLogrotateTimerPatternTestMatchesWithRegex(){
String foo = "hourly";
boolean result = virtualNetworkApplianceManagerImpl.checkLogrotateTimerPattern(foo);
Assert.assertTrue(result);
foo = "*:00:00";
result = virtualNetworkApplianceManagerImpl.checkLogrotateTimerPattern(foo);
Assert.assertTrue(result);
foo = "*:*:00";
result = virtualNetworkApplianceManagerImpl.checkLogrotateTimerPattern(foo);
Assert.assertTrue(result);
}
} }

View File

@ -882,6 +882,9 @@ parse_cmd_line() {
privatekey) privatekey)
export PRIVATEKEY=$VALUE export PRIVATEKEY=$VALUE
;; ;;
logrotatefrequency)
export LOGROTATE_FREQUENCY=$VALUE
;;
useHttpsToUpload) useHttpsToUpload)
export USEHTTPS=$VALUE export USEHTTPS=$VALUE
;; ;;

View File

@ -82,9 +82,10 @@ setup_router() {
mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
fi fi
# Setup hourly lograte in systemd timer # As ACS is changing the file, the description will also change to make it clear that ACS is handling this.
sed -i 's/OnCalendar=daily/OnCalendar=hourly/g' /usr/lib/systemd/system/logrotate.timer sed -i "s#^Description=.*#Description=Cloudstack configuration time for rotation of log files#g" /usr/lib/systemd/system/logrotate.timer
sed -i 's/AccuracySec=12h/AccuracySec=5m/g' /usr/lib/systemd/system/logrotate.timer sed -i "s#^OnCalendar=.*#OnCalendar=$LOGROTATE_FREQUENCY#g" /usr/lib/systemd/system/logrotate.timer
sed -i 's#^AccuracySec=.*#AccuracySec=5m#g' /usr/lib/systemd/system/logrotate.timer
# reload daemon # reload daemon
/usr/bin/systemctl daemon-reload /usr/bin/systemctl daemon-reload

View File

@ -123,9 +123,10 @@ EOF
mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
fi fi
# Setup hourly lograte in systemd timer # As ACS is changing the file, the description will also change to make it clear that ACS is handling this.
sed -i 's/OnCalendar=daily/OnCalendar=hourly/g' /usr/lib/systemd/system/logrotate.timer sed -i "s#^Description=.*#Description=Cloudstack configuration time for rotation of log files#g" /usr/lib/systemd/system/logrotate.timer
sed -i 's/AccuracySec=12h/AccuracySec=5m/g' /usr/lib/systemd/system/logrotate.timer sed -i "s#^OnCalendar=.*#OnCalendar=$LOGROTATE_FREQUENCY#g" /usr/lib/systemd/system/logrotate.timer
sed -i 's#^AccuracySec=.*#AccuracySec=5m#g' /usr/lib/systemd/system/logrotate.timer
# reload daemon # reload daemon
/usr/bin/systemctl daemon-reload /usr/bin/systemctl daemon-reload