[CalendarServer-changes] [551]
CalendarServer/branches/caladmin-tool/caladmin
source_changes at macosforge.org
source_changes at macosforge.org
Wed Nov 22 09:38:15 PST 2006
Revision: 551
http://trac.macosforge.org/projects/calendarserver/changeset/551
Author: dreid at apple.com
Date: 2006-11-22 09:38:15 -0800 (Wed, 22 Nov 2006)
Log Message:
-----------
Rename commands.py to options.py so we can use the commands module in the stdlib. Add a bunch of stats gathering stuff. Move prepareValue to util.prepareByteValue and add support for -g
Modified Paths:
--------------
CalendarServer/branches/caladmin-tool/caladmin/quotas.py
CalendarServer/branches/caladmin-tool/caladmin/script.py
Added Paths:
-----------
CalendarServer/branches/caladmin-tool/caladmin/options.py
CalendarServer/branches/caladmin-tool/caladmin/stats.py
CalendarServer/branches/caladmin-tool/caladmin/util.py
Removed Paths:
-------------
CalendarServer/branches/caladmin-tool/caladmin/commands.py
Deleted: CalendarServer/branches/caladmin-tool/caladmin/commands.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/commands.py 2006-11-22 17:37:40 UTC (rev 550)
+++ CalendarServer/branches/caladmin-tool/caladmin/commands.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -1,162 +0,0 @@
-##
-# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
-#
-# Licensed 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.
-#
-# DRI: David Reid, dreid at apple.com
-##
-
-""" "pluggable" subcommands for the caladmin script
-"""
-
-from twisted.python import usage
-
-COMMANDS = {}
-
-def registerCommand(command):
- COMMANDS[command.name] = command
-
-def listCommands():
- return COMMANDS.keys()
-
-def genSubCommandsDef():
- sc = listCommands()
- sc.sort()
-
- for name in sc:
- command = COMMANDS[name]
- yield [command.name, command.shortcut, command, command.help]
-
-
-from twisted.python import reflect
-
-class SubCommand(usage.Options):
- name = None
- shortcut = None
- help = "FIXME"
- action = None
-
- params = ()
-
- def parseArgs(self, *rest):
- self.params += rest
-
- def postOptions(self):
- reflect.namedAny(self.action)(self).run()
-
-
-class QuotaOptions(SubCommand):
- name = 'quotas'
- help = 'Retrieve quota information for principals'
- action = 'caladmin.quotas.QuotaAction'
-
- optFlags = [
- ['human', 'h', 'Display quota values in a human readable form.'],
- ['megabytes', 'm', 'Display quota values in megabytes'],
- ['kilobytes', 'k', 'Display quota values in kilobytes'],
- ]
-
- def __init__(self):
- SubCommand.__init__(self)
-
- self['types'] = []
-
- def opt_users(self):
- """Show Quotas for user calendars.
- """
-
- self['types'].append('users')
- opt_u = opt_users
-
- def opt_groups(self):
- """Show Quotas for group calendars.
- """
-
- self['types'].append('groups')
- opt_g = opt_groups
-
- def opt_resources(self):
- """Show Quotas for resource calendars.
- """
-
- self['types'].append('resources')
- opt_r = opt_resources
-
-
-registerCommand(QuotaOptions)
-
-
-class UserOptions(SubCommand):
- name = 'users'
- help = 'Retrieve information about and perform actions on users.'
- action = 'caladmin.users.UserAction'
-
- optFlags = [
- ['list', '1', 'List only usernames, one per line.'],
- ['disabled', 'd', 'Limit display to disabled users.'],
- ['detailed', None, 'Detailed statistics for each account.'],
- ]
-
-registerCommand(UserOptions)
-
-
-class PurgeOptions(SubCommand):
- name = 'purge'
- help = ('Keep your store from becoming unnecessarily large by purging '
- 'old events.')
- action = 'caladmin.purge.PurgeAction'
-
- optParameters = [
- ['days', 'n', 30, 'Age threshold for purging events.'],
- ]
-
-registerCommand(PurgeOptions)
-
-
-class StatsOptions(SubCommand):
- name = 'stats'
- help = ('Overall usage statistics.')
- action = 'caladmin.stats.StatsAction'
-
-
-registerCommand(StatsOptions)
-
-from twisted.python import filepath
-
-class LogOptions(SubCommand):
- name = 'logs'
- help = ('Gather and report useful information from the logfiles.')
- action = 'caladmin.logs.LogAction'
-
- def __init__(self):
- SubCommand.__init__(self)
-
- self['logfile'] = None
-
- def opt_logfile(self, logfile):
- """Path to the log file to be analyzed.
- [default: /var/log/caldavd/server.log]
- """
-
- self['logfile'] = filepath.FilePath(logfile)
-
- opt_l = opt_logfile
-
- def postOptions(self):
- if not self['logfile']:
- self['logfile'] = filepath.FilePath(
- self.parent.config['ServerLogFile'])
-
- SubCommand.postOptions(self)
-
-registerCommand(LogOptions)
Copied: CalendarServer/branches/caladmin-tool/caladmin/options.py (from rev 549, CalendarServer/branches/caladmin-tool/caladmin/commands.py)
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/options.py (rev 0)
+++ CalendarServer/branches/caladmin-tool/caladmin/options.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -0,0 +1,175 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed 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.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+""" "pluggable" subcommands for the caladmin script
+"""
+
+from twisted.python import usage
+
+COMMANDS = {}
+
+def registerCommand(command):
+ COMMANDS[command.name] = command
+
+def listCommands():
+ return COMMANDS.keys()
+
+def genSubCommandsDef():
+ sc = listCommands()
+ sc.sort()
+
+ for name in sc:
+ command = COMMANDS[name]
+ yield [command.name, command.shortcut, command, command.help]
+
+
+from twisted.python import reflect
+
+class SubCommand(usage.Options):
+ name = None
+ shortcut = None
+ help = "FIXME"
+ action = None
+
+ params = ()
+
+ def parseArgs(self, *rest):
+ self.params += rest
+
+ def postOptions(self):
+ reflect.namedAny(self.action)(self).run()
+
+
+PARAM_HUMAN = ['human', 'h', 'Display byte values in a human readable form.']
+PARAM_MEGA = ['megabytes', 'm', 'Display byte values in megabytes']
+PARAM_KILO = ['kilobytes', 'k', 'Display byte values in kilobytes']
+PARAM_GIGA = ['gigabytes', 'g', 'Display byte values in gigabytes']
+
+
+class QuotaOptions(SubCommand):
+ name = 'quotas'
+ help = 'Retrieve quota information for principals'
+ action = 'caladmin.quotas.QuotaAction'
+
+ optFlags = [
+ PARAM_HUMAN,
+ PARAM_KILO,
+ PARAM_MEGA,
+ PARAM_GIGA,
+ ]
+
+ def __init__(self):
+ SubCommand.__init__(self)
+
+ self['types'] = []
+
+ def opt_users(self):
+ """Show Quotas for user calendars.
+ """
+
+ self['types'].append('users')
+ opt_u = opt_users
+
+ def opt_groups(self):
+ """Show Quotas for group calendars.
+ """
+
+ self['types'].append('groups')
+ opt_g = opt_groups
+
+ def opt_resources(self):
+ """Show Quotas for resource calendars.
+ """
+
+ self['types'].append('resources')
+ opt_r = opt_resources
+
+
+registerCommand(QuotaOptions)
+
+
+class UserOptions(SubCommand):
+ name = 'users'
+ help = 'Retrieve information about and perform actions on users.'
+ action = 'caladmin.users.UserAction'
+
+ optFlags = [
+ ['list', '1', 'List only usernames, one per line.'],
+ ['disabled', 'd', 'Limit display to disabled users.'],
+ ['detailed', None, 'Detailed statistics for each account.'],
+ ]
+
+registerCommand(UserOptions)
+
+
+class PurgeOptions(SubCommand):
+ name = 'purge'
+ help = ('Keep your store from becoming unnecessarily large by purging '
+ 'old events.')
+ action = 'caladmin.purge.PurgeAction'
+
+ optParameters = [
+ ['days', 'n', 30, 'Age threshold for purging events.'],
+ ]
+
+registerCommand(PurgeOptions)
+
+
+class StatsOptions(SubCommand):
+ name = 'stats'
+ help = ('Overall usage statistics.')
+ action = 'caladmin.stats.StatsAction'
+
+ optFlags = [
+ PARAM_HUMAN,
+ PARAM_KILO,
+ PARAM_MEGA,
+ PARAM_GIGA,
+ ]
+
+registerCommand(StatsOptions)
+
+from twisted.python import filepath
+
+class LogOptions(SubCommand):
+ name = 'logs'
+ help = ('Gather and report useful information from the logfiles.')
+ action = 'caladmin.logs.LogAction'
+
+ def __init__(self):
+ SubCommand.__init__(self)
+
+ self['logfile'] = None
+
+ def opt_logfile(self, logfile):
+ """Path to the log file to be analyzed.
+ [default: /var/log/caldavd/server.log]
+ """
+
+ self['logfile'] = filepath.FilePath(logfile)
+
+ opt_l = opt_logfile
+
+ def postOptions(self):
+ if not self['logfile']:
+ self['logfile'] = filepath.FilePath(
+ self.parent.config['ServerLogFile'])
+
+ SubCommand.postOptions(self)
+
+registerCommand(LogOptions)
Modified: CalendarServer/branches/caladmin-tool/caladmin/quotas.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/quotas.py 2006-11-22 17:37:40 UTC (rev 550)
+++ CalendarServer/branches/caladmin-tool/caladmin/quotas.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -21,6 +21,8 @@
from twisted.web2.dav.resource import TwistedQuotaRootProperty, TwistedQuotaUsedProperty
from twisted.web import microdom
+from caladmin.util import prepareByteValue
+
quotaRoot = "WebDAV:" + TwistedQuotaRootProperty.sname().replace("/", "%2F")
quotaUsed = "WebDAV:" + TwistedQuotaUsedProperty.sname().replace("/", "%2F")
@@ -56,29 +58,6 @@
self.principalCollection = config.parent.principalCollection
self.formatter = config.parent.formatter
- def prepareValue(self, value):
- if self.config['human']:
- h = value/1024.0
- if h < 1:
- return '%d' % (value,)
-
- h2 = h/1024.0
- if h2 < 1:
- return '%5.2fKB' % (h,)
-
- return '%5.2fMB' % (h2,)
-
- elif self.config['megabytes']:
- M = value/1024.0/1024.0
-
- return '%5.2fMB' % (M,)
-
- elif self.config['kilobytes']:
- K = value/1024.0
- return '%5.2fKB' % (K,)
-
- return value
-
def getQuotaStats(self):
defaultQuota = getQuotaRoot(self.calendarCollection)
@@ -116,9 +95,9 @@
yield (child.basename(),
type,
- self.prepareValue(childQuota),
- self.prepareValue(childUsed),
- self.prepareValue(childAvailable))
+ prepareByteValue(self.config, childQuota),
+ prepareByteValue(self.config, childUsed),
+ prepareByteValue(self.config, childAvailable))
def run(self):
if not self.config['types']:
Modified: CalendarServer/branches/caladmin-tool/caladmin/script.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/script.py 2006-11-22 17:37:40 UTC (rev 550)
+++ CalendarServer/branches/caladmin-tool/caladmin/script.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -35,7 +35,7 @@
from plistlib import readPlist
-from caladmin import commands
+from caladmin import options
from caladmin import formatters
from twistedcaldav.caldavd import caldavd_defaults, caldavd
@@ -63,7 +63,7 @@
options = ['--help']
if options == ['--help']:
- self.subCommands = commands.genSubCommandsDef()
+ self.subCommands = options.genSubCommandsDef()
usage.Options.parseOptions(self, options)
@@ -96,10 +96,10 @@
raise usage.UsageError("Please specify a valid formatter: %s" % (
', '.join(lf)))
- sc = commands.listCommands()
+ sc = options.listCommands()
sc.sort()
- self.subCommands = commands.genSubCommandsDef()
+ self.subCommands = options.genSubCommandsDef()
self.recursing = 1
Added: CalendarServer/branches/caladmin-tool/caladmin/stats.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/stats.py (rev 0)
+++ CalendarServer/branches/caladmin-tool/caladmin/stats.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -0,0 +1,140 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed 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.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+"""
+Statisitcs Types:
+
+ Account Stats:
+ # of calendars
+ # of events
+ # storage used (including things that don't count against quota?)
+ Last login?
+
+ Overall Stats:
+ # of accounts
+ # of calendars
+ # of events
+
+ Log Stats:
+ # Invitations sent per day/week/month
+ # bytes i/o
+ # requests
+ user agents
+
+"""
+import os
+import xattr
+import commands
+
+from twisted.web import microdom
+
+from caladmin.util import prepareByteValue
+
+def getResourceType(fp):
+ rt = 'WebDAV:{DAV:}resourcetype'
+ x = xattr.xattr(fp.path)
+ if not x.has_key(rt):
+ return None
+
+ collection = False
+
+ type = None
+
+ dom = microdom.parseString(x[rt])
+ rt = microdom.getElementsByTagName(dom, 'resourcetype')
+
+ for child in rt[0].childNodes:
+ if child.tagName == 'collection':
+ collection = True
+ else:
+ type = child.tagName
+
+ return (collection, type)
+
+
+class StatsAction(object):
+ def __init__(self, config):
+ self.config = config
+ self.formatter = self.config.parent.formatter
+ self.root = self.config.parent.root
+ self.calendarCollection = self.config.parent.calendarCollection
+ self.principalCollection = self.config.parent.principalCollection
+
+ self.gatherers = [
+ self.getAccountCount,
+ self.getGroupCount,
+ self.getResourceCount,
+ self.getCalendarCount,
+ self.getEventCount,
+ self.getDiskUsage]
+
+ def getDiskUsage(self):
+ output = commands.getoutput(' '.join(
+ ['/usr/bin/du', '-s', self.root.path]))
+
+ return ("Disk Usage", prepareByteValue(self.config,
+ int(output.split()[0])))
+
+ def _getPrincipalList(self, type):
+ typeRoot = self.principalCollection.child(type)
+ assert typeRoot.exists()
+
+ pl = []
+
+ for child in typeRoot.listdir():
+ if child not in ['.db.sqlite']:
+ pl.append(child)
+
+ return pl
+
+ def getAccountCount(self):
+ return ("# Accounts", len(self._getPrincipalList('users')))
+
+ def getGroupCount(self):
+ return ("# Groups", len(self._getPrincipalList('groups')))
+
+ def getResourceCount(self):
+ return ("# Resources", len(self._getPrincipalList('resources')))
+
+ def getEventCount(self):
+ return ("# Events", 0)
+
+ def getCalendarCount(self):
+ count = 0
+ for child in self.calendarCollection.walk():
+ if child.isdir():
+ if getResourceType(child) == (True, 'calendar'):
+ count += 1
+
+ return ("# Calendars", count)
+
+ def printStatistics(self, head, stats):
+ self.formatter.printRow([head], 16)
+
+ for stat in stats:
+ self.formatter.printRow(stat, 16)
+
+ def run(self):
+ assert self.root.exists()
+ stats = []
+
+ for gatherer in self.gatherers:
+ stats.append(gatherer())
+
+ self.printStatistics("Overall Statistics", stats)
+
Added: CalendarServer/branches/caladmin-tool/caladmin/util.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/util.py (rev 0)
+++ CalendarServer/branches/caladmin-tool/caladmin/util.py 2006-11-22 17:38:15 UTC (rev 551)
@@ -0,0 +1,49 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed 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.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+def prepareByteValue(config, value):
+ if config['human']:
+ KB = value/1024.0
+ if KB < 1:
+ return '%d' % (value,)
+
+ MB = KB/1024.0
+ if MB < 1:
+ return '%5.2fKB' % (KB,)
+
+ GB = MB/1024.0
+ if GB < 1:
+ return '%5.2fMB' % (MB,)
+
+ return '%5.2fGB' % (GB,)
+
+ elif config['gigabytes']:
+ G = value/1024.0/1024.0/1024.0
+
+ return '%5.2fGB' % (G,)
+
+ elif config['megabytes']:
+ M = value/1024.0/1024.0
+
+ return '%5.2fMB' % (M,)
+
+ elif config['kilobytes']:
+ K = value/1024.0
+ return '%5.2fKB' % (K,)
+
+ return value
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061122/80a13007/attachment.html
More information about the calendarserver-changes
mailing list