[CalendarServer-changes] [15034] CalendarServer/trunk/calendarserver/tools
source_changes at macosforge.org
source_changes at macosforge.org
Thu Aug 6 14:04:52 PDT 2015
Revision: 15034
http://trac.calendarserver.org//changeset/15034
Author: sagen at apple.com
Date: 2015-08-06 14:04:52 -0700 (Thu, 06 Aug 2015)
Log Message:
-----------
calendarserver_config now has --logging and --accounting options
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tools/config.py
CalendarServer/trunk/calendarserver/tools/test/test_config.py
CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
Modified: CalendarServer/trunk/calendarserver/tools/config.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/config.py 2015-08-05 22:37:53 UTC (rev 15033)
+++ CalendarServer/trunk/calendarserver/tools/config.py 2015-08-06 21:04:52 UTC (rev 15034)
@@ -43,6 +43,7 @@
WRITABLE_CONFIG_KEYS = [
+ "AccountingCategories",
"Authentication.Basic.AllowedOverWireUnencrypted",
"Authentication.Basic.Enabled",
"Authentication.Digest.AllowedOverWireUnencrypted",
@@ -83,8 +84,21 @@
"ServerRoot",
]
+ACCOUNTING_CATEGORIES = {
+ "http": ("HTTP",),
+ "itip": ("iTIP", "iTIP-VFREEBUSY",),
+ "implicit": ("Implicit Errors",),
+ "autoscheduling": ("AutoScheduling",),
+ "ischedule": ("iSchedule",),
+ "migration": ("migration",),
+}
+LOGGING_CATEGORIES = {
+ "directory": ("twext^who", "txdav^who",),
+ "imip": ("txdav^caldav^datastore^scheduling^imip",),
+}
+
def usage(e=None):
if e:
print(e)
@@ -95,8 +109,10 @@
print("")
print("Print the value of the given config key.")
print("options:")
+ print(" -a --accounting: Specify accounting categories (combinations of http, itip, implicit, autoscheduling, ischedule, migration, or off)")
print(" -h --help: print this help and exit")
print(" -f --config: Specify caldavd.plist configuration path")
+ print(" -l --logging: Specify logging categories (combinations of directory, imip, or default)")
print(" -r --restart: Restart the calendar service")
print(" --start: Start the calendar service and agent")
print(" --stop: Stop the calendar service and agent")
@@ -125,13 +141,15 @@
try:
(optargs, args) = getopt(
- sys.argv[1:], "hf:rw:", [
+ sys.argv[1:], "hf:rw:a:l:", [
"help",
"config=",
"writeconfig=",
"restart",
"start",
"stop",
+ "accounting=",
+ "logging=",
],
)
except GetoptError, e:
@@ -139,6 +157,8 @@
configFileName = DEFAULT_CONFIG_FILE
writeConfigFileName = ""
+ accountingCategories = None
+ loggingCategories = None
doStop = False
doStart = False
doRestart = False
@@ -153,6 +173,12 @@
elif opt in ("-w", "--writeconfig"):
writeConfigFileName = arg
+ elif opt in ("-a", "--accounting"):
+ accountingCategories = arg.split(",")
+
+ elif opt in ("-l", "--logging"):
+ loggingCategories = arg.split(",")
+
if opt == "--stop":
doStop = True
@@ -198,6 +224,24 @@
writable = WritableConfig(config, writeConfigFileName)
writable.read()
+ # Convert logging categories to actual config key changes
+ if loggingCategories is not None:
+ args = ["LogLevels="]
+ if loggingCategories != ["default"]:
+ for cat in loggingCategories:
+ if cat in LOGGING_CATEGORIES:
+ for moduleName in LOGGING_CATEGORIES[cat]:
+ args.append("LogLevels.{}=debug".format(moduleName))
+
+ # Convert accounting categories to actual config key changes
+ if accountingCategories is not None:
+ args = ["AccountingCategories="]
+ if accountingCategories != ["off"]:
+ for cat in accountingCategories:
+ if cat in ACCOUNTING_CATEGORIES:
+ for key in ACCOUNTING_CATEGORIES[cat]:
+ args.append("AccountingCategories.{}=True".format(key))
+
processArgs(writable, args)
@@ -265,8 +309,12 @@
if "=" in configKey:
# This is an assignment
configKey, stringValue = configKey.split("=")
- value = writable.convertToValue(stringValue)
- writable.set({configKey: value})
+ if stringValue:
+ value = writable.convertToValue(stringValue)
+ valueDict = setKeyPath({}, configKey, value)
+ writable.set(valueDict)
+ else:
+ writable.delete(configKey)
else:
# This is a read
c = config
@@ -416,7 +464,14 @@
@return: parent
"""
original = parent
- parts = keyPath.split(".")
+
+ # Embedded ^ should be replaced by .
+ # That way, we can still use . as key path separator even though sometimes
+ # a key part wants to have a . in it (such as a LogLevels module).
+ # For example: LogLevels.twext^who, will get converted to a "LogLevels"
+ # dict containing a the key "twext.who"
+ parts = [p.replace("^", ".") for p in keyPath.split(".")]
+
for part in parts[:-1]:
child = parent.get(part, None)
if child is None:
@@ -531,6 +586,20 @@
self.dirty = True
+ def delete(self, key):
+ """
+ Deletes the specified key
+
+ @param key: the key to delete
+ @type key: C{str}
+ """
+ try:
+ del self.currentConfigSubset[key]
+ self.dirty = True
+ except:
+ pass
+
+
def read(self):
"""
Reads in the data contained in the writable plist file.
@@ -568,7 +637,7 @@
def convertToValue(cls, string):
"""
Inspect string and convert the value into an appropriate Python data type
- TODO: change this to look at actual types definied within stdconfig
+ TODO: change this to look at actual types defined within stdconfig
"""
if "." in string:
try:
Modified: CalendarServer/trunk/calendarserver/tools/test/test_config.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_config.py 2015-08-05 22:37:53 UTC (rev 15033)
+++ CalendarServer/trunk/calendarserver/tools/test/test_config.py 2015-08-06 21:04:52 UTC (rev 15034)
@@ -171,6 +171,247 @@
self.assertEquals(results["error"], "Unknown command 'bogus'")
+ @inlineCallbacks
+ def test_commandLineArgs(self):
+ """
+ Verify commandline assignments works
+ """
+
+ # Check current values
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(results["result"]["DefaultLogLevel"], "warn")
+ self.assertEquals(results["result"]["Scheduling"]["iMIP"]["Enabled"], False)
+
+ # Set a single-level key and a multi-level key
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["DefaultLogLevel=debug", "Scheduling.iMIP.Enabled=True"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(results["result"]["DefaultLogLevel"], "debug")
+ self.assertEquals(results["result"]["Scheduling"]["iMIP"]["Enabled"], True)
+ self.assertEquals(results["result"]["LogLevels"], {})
+
+ # Directly set some LogLevels sub-keys
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["LogLevels.testing=debug", "LogLevels.testing2=warn"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"],
+ {"testing": "debug", "testing2" : "warn"}
+ )
+
+ # Test that setting additional sub-keys retains previous sub-keys
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["LogLevels.testing3=info", "LogLevels.testing4=warn"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"],
+ {"testing": "debug", "testing2" : "warn", "testing3": "info", "testing4" : "warn"}
+ )
+
+ # Test that an empty value deletes the key
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["LogLevels="],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"], # now an empty dict
+ {}
+ )
+
+
+ @inlineCallbacks
+ def test_loggingCategories(self):
+ """
+ Verify logging categories get mapped to the correct python module names
+ """
+
+
+ # Check existing values
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(results["result"]["LogLevels"], {})
+
+ # Set to directory and imip
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["--logging=directory,imip"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"],
+ {
+ "twext.who": "debug",
+ "txdav.who": "debug",
+ "txdav.caldav.datastore.scheduling.imip": "debug",
+ }
+ )
+
+ # Set up to imip, and the directory modules should go away
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["--logging=imip"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"],
+ {
+ "txdav.caldav.datastore.scheduling.imip": "debug",
+ }
+ )
+
+ # Set to default, and all modules should go away
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["--logging=default"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["LogLevels"], {}
+ )
+
+
+ @inlineCallbacks
+ def test_accountingCategories(self):
+ """
+ Verify accounting categories get mapped to the correct keys
+ """
+ # Check existing values
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["AccountingCategories"],
+ {
+ 'AutoScheduling': False,
+ 'HTTP': False,
+ 'Implicit Errors': False,
+ 'iSchedule': False,
+ 'iTIP': False,
+ 'iTIP-VFREEBUSY': False,
+ 'migration': False,
+ }
+ )
+
+ # Set to http and itip
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["--accounting=http,itip"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["AccountingCategories"],
+ {
+ 'AutoScheduling': False,
+ 'HTTP': True,
+ 'Implicit Errors': False,
+ 'iSchedule': False,
+ 'iTIP': True,
+ 'iTIP-VFREEBUSY': True,
+ 'migration': False,
+ }
+ )
+
+ # Set to off, so all are off
+
+ results = yield self.runCommand(
+ None,
+ script="calendarserver_config",
+ additionalArgs=["--accounting=off"],
+ parseOutput=False
+ )
+
+ results = yield self.runCommand(
+ command_readConfig,
+ script="calendarserver_config")
+
+ self.assertEquals(
+ results["result"]["AccountingCategories"],
+ {
+ 'AutoScheduling': False,
+ 'HTTP': False,
+ 'Implicit Errors': False,
+ 'iSchedule': False,
+ 'iTIP': False,
+ 'iTIP-VFREEBUSY': False,
+ 'migration': False,
+ }
+ )
+
+
+
+
def test_keyPath(self):
d = ConfigDict()
setKeyPath(d, "one", "A")
Modified: CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_gateway.py 2015-08-05 22:37:53 UTC (rev 15033)
+++ CalendarServer/trunk/calendarserver/tools/test/test_gateway.py 2015-08-06 21:04:52 UTC (rev 15034)
@@ -144,7 +144,8 @@
@inlineCallbacks
def runCommand(
- self, command, error=False, script="calendarserver_command_gateway"
+ self, command, error=False, script="calendarserver_command_gateway",
+ additionalArgs=None, parseOutput=True
):
"""
Run the given command by feeding it as standard input to
@@ -163,18 +164,24 @@
if error:
args.append("--error")
+ if additionalArgs:
+ args.extend(additionalArgs)
+
cwd = sourceRoot
deferred = Deferred()
reactor.spawnProcess(CapturingProcessProtocol(deferred, command), cmd, args, env=os.environ, path=cwd)
output = yield deferred
- try:
- plist = readPlistFromString(output)
- except xml.parsers.expat.ExpatError, e:
- print("Error (%s) parsing (%s)" % (e, output))
- raise
+ if parseOutput:
+ try:
+ plist = readPlistFromString(output)
+ returnValue(plist)
+ except xml.parsers.expat.ExpatError, e:
+ print("Error (%s) parsing (%s)" % (e, output))
+ raise
+ else:
+ returnValue(output)
- returnValue(plist)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150806/d3a0c001/attachment-0001.html>
More information about the calendarserver-changes
mailing list