Commit 8572f66b authored by Jondy Zhao's avatar Jondy Zhao

netreport: fix the problem that domain-user can't see net-drives

parent f53fc13f
...@@ -18,7 +18,7 @@ Here are example of src/Makefile: ...@@ -18,7 +18,7 @@ Here are example of src/Makefile:
PYTHON = /opt/slapos/bin/python PYTHON = /opt/slapos/bin/python
.PHONY : test .PHONY : test
build: netuse.c build: netuse.c
(cd ..; $(PYTHON) setup.py build) (cd ..; $(PYTHON) setup.py build)
...@@ -32,7 +32,7 @@ Then run test: ...@@ -32,7 +32,7 @@ Then run test:
$ cd src $ cd src
$ make test $ make test
Before test netreport.py, Before test netreport.py,
$ easy_install lxml $ easy_install lxml
$ ln -s /opt/git/slapos.core $ ln -s /opt/git/slapos.core
...@@ -43,6 +43,46 @@ Use Cases ...@@ -43,6 +43,46 @@ Use Cases
Slave Node Slave Node
---------- ----------
Copy file "slapos-monitor", "netuse.dll" to /usr/sbin, then add a startup item for the domain user:
* Logon as local administrator, run the following command in the cygwin terminal:
username="The domain user name, it could be seen in the C:/Documents and Seetings"
target=$(cygpath -w "/cygdrive/c/Documents and Settings/${username}/Start Menu/Programs/Startup/netdrive monitor.lnk")
cat <<EOF > create_shortcut.vbs
Set WshShell = WScript.CreateObject("WScript.Shell")
strStartup = WshShell.SpecialFolders("Startup")
Set oShellLink = WshShell.CreateShortcut("${target}")
oShellLink.TargetPath = "$(cygpath -w /bin/mintty.exe)"
oShellLink.Arguments = "-l /var/log/slap-monitor.log -w hide --exec /usr/sbin/slapos-monitor"
oShellLink.WindowStyle = 1
oShellLink.Description = "netdrive monitor"
oShellLink.WorkingDirectory = "$(cygpath -w /usr/sbin)"
oShellLink.Save
EOF
cscript //B create_shortcut.vbs
rm create_shortcut.vbs
If you don't want to add a shortcut, the second way is to add a startup item in the registry:
* Login as domain user, and run the following command in the cygwin terminal:
regtool set \\HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\slap-monitor \
"$(cygpath -w /bin/mintty.exe) -l /var/log/slap-monitor.log -w hide --exec /usr/sbin/slapos-monitor"
You want to remove the entry by
regtool unset \\HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\slap-monitor
* In case the domain user have no right to change registry, then get sid first:
mkpasswd -d
It will list all the users in the current domain, find the expected sid, suppose it is "S-1-5-21-117609710-920026266-725345543-500", login as local administrator:
regtool set \\HKU\\S-1-5-21-117609710-920026266-725345543-500\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\slap-monitor \
"$(cygpath -w /bin/mintty.exe) -l /var/log/slap-monitor.log -w hide --exec /usr/sbin/slapos-monitor"
Master Node Master Node
----------- -----------
...@@ -53,4 +93,3 @@ Issues ...@@ -53,4 +93,3 @@ Issues
====== ======
1. Some records may be lost if the computer is shutdown in unnormal way. 1. Some records may be lost if the computer is shutdown in unnormal way.
...@@ -27,13 +27,14 @@ ...@@ -27,13 +27,14 @@
# #
############################################################################## ##############################################################################
import argparse import argparse
from datetime import datetime, date
from lxml import etree
import netuse
import os.path import os.path
import slapos.slap.slap import slapos.slap.slap
import sqlite3 import sqlite3
import sys import sys
import xmlrpclib
from datetime import datetime, date
from lxml import etree
from time import sleep from time import sleep
def parseArgumentTuple(): def parseArgumentTuple():
...@@ -59,9 +60,13 @@ def parseArgumentTuple(): ...@@ -59,9 +60,13 @@ def parseArgumentTuple():
parser.add_argument("--data-file", parser.add_argument("--data-file",
help="File used to save report data.", help="File used to save report data.",
default="net_drive_usage_report.data") default="net_drive_usage_report.data")
parser.add_argument("--server-name", parser.add_argument("--port",
help="Interval in seconds to send report to master.", help="RPC Port of SlapMonitor.",
default="") default=8008)
parser.add_argument("--batch",
help="If True, send report per day at mid-night. "
"Otherwise send report instantly.",
default=False)
option = parser.parse_args() option = parser.parse_args()
# Build option_dict # Build option_dict
...@@ -85,7 +90,8 @@ class NetDriveUsageReporter(object): ...@@ -85,7 +90,8 @@ class NetDriveUsageReporter(object):
self._report_date = None self._report_date = None
self.report_interval = float(self.report_interval) self.report_interval = float(self.report_interval)
self.initializeDatabase(self.data_file) self.initializeDatabase(self.data_file)
self.slap_monitor_uri = 'http://localhost:%d' % option_dict['port']
def initializeConnection(self): def initializeConnection(self):
connection_dict = {} connection_dict = {}
connection_dict['key_file'] = self.key_file connection_dict['key_file'] = self.key_file
...@@ -96,8 +102,7 @@ class NetDriveUsageReporter(object): ...@@ -96,8 +102,7 @@ class NetDriveUsageReporter(object):
self._slap_computer = slap.registerComputer(self.computer_id) self._slap_computer = slap.registerComputer(self.computer_id)
def initializeConfigData(self): def initializeConfigData(self):
user_info = netuse.userInfo() self._domain_account = "SlapMonitor"
self._domain_account = "%s\\%s" % user_info[1:3]
q = self._db.execute q = self._db.execute
s = "SELECT _rowid_, report_date FROM config " \ s = "SELECT _rowid_, report_date FROM config " \
...@@ -119,13 +124,14 @@ class NetDriveUsageReporter(object): ...@@ -119,13 +124,14 @@ class NetDriveUsageReporter(object):
last_timestamp = datetime.now() last_timestamp = datetime.now()
interval = 30.0 if self.report_interval > 60 else (self.report_interval / 2) interval = 30.0 if self.report_interval > 60 else (self.report_interval / 2)
try: try:
monitor = xmlrpclib.ServerProxy(self.slap_monitor_uri)
while True: while True:
current_timestamp = datetime.now() current_timestamp = datetime.now()
d = current_timestamp - last_timestamp d = current_timestamp - last_timestamp
if d.seconds < self.report_interval: if d.seconds < self.report_interval:
sleep(interval) sleep(interval)
continue continue
self.insertUsageReport(last_timestamp.isoformat(), d.seconds) self.insertUsageReport(monitor, last_timestamp.isoformat(), d.seconds)
self.sendReport() self.sendReport()
last_timestamp = current_timestamp last_timestamp = current_timestamp
except KeyboardInterrupt: except KeyboardInterrupt:
...@@ -133,20 +139,20 @@ class NetDriveUsageReporter(object): ...@@ -133,20 +139,20 @@ class NetDriveUsageReporter(object):
finally: finally:
self._db.close() self._db.close()
def insertUsageReport(self, start, duration): def insertUsageReport(self, monitor, start, duration):
q = self._db.execute q = self._db.execute
for r in netuse.usageReport(self.server_name): for r in monitor.usageReport():
q( "INSERT INTO net_drive_usage " q( "INSERT INTO net_drive_usage "
"(config_id, drive_letter, remote_folder, " "(config_id, domain_user, drive_letter, remote_folder, "
" start, duration, usage_bytes )" " start, duration, usage_bytes )"
" VALUES (?, ?, ?, ?, ?, ?)", " VALUES (?, ?, ?, ?, ?, ?)",
(self._config_id, r[0], r[1], start, duration, r[3] - r[2])) (self._config_id, r[0], r[1], r[2], start, duration, r[4] - r[3]))
def sendAllReport(self): def sendAllReport(self):
"""Called at startup of this application, send all report """Called at startup of this application, send all report
in the config table.""" in the config table."""
q = self._db.execute q = self._db.execute
for r in q("SELECT _rowid_, domain_account, computer_id, report_date " for r in q("SELECT _rowid_, computer_id, report_date "
"FROM config " "FROM config "
"WHERE report_date < date('now')"): "WHERE report_date < date('now')"):
self._postData(self.generateDailyReport(*r)) self._postData(self.generateDailyReport(*r))
...@@ -160,10 +166,9 @@ class NetDriveUsageReporter(object): ...@@ -160,10 +166,9 @@ class NetDriveUsageReporter(object):
# Change report_date to today # Change report_date to today
# (Optional) Move all the reported data to histroy table # (Optional) Move all the reported data to histroy table
today = date.today().isoformat() today = date.today().isoformat()
if self._report_date < today: if (not self.batch) or self._report_date < today:
self._postData(self.generateDailyReport(self._config_id, self._postData(self.generateDailyReport(self._config_id,
self.computer_id, self.computer_id,
self._domain_account,
self._report_date)) self._report_date))
self._db.execute("UPDATE config SET report_date=? where _rowid_=?", self._db.execute("UPDATE config SET report_date=? where _rowid_=?",
(today, self._config_id)) (today, self._config_id))
...@@ -191,6 +196,7 @@ class NetDriveUsageReporter(object): ...@@ -191,6 +196,7 @@ class NetDriveUsageReporter(object):
config_id INTEGER REFERENCES config ( _rowid_ ), config_id INTEGER REFERENCES config ( _rowid_ ),
drive_letter TEXT NOT NULL, drive_letter TEXT NOT NULL,
remote_folder TEXT NOT NULL, remote_folder TEXT NOT NULL,
domain_user TEXT NOT NULL,
start TEXT DEFAULT CURRENT_TIMESTAMP, start TEXT DEFAULT CURRENT_TIMESTAMP,
duration FLOAT NOT NULL, duration FLOAT NOT NULL,
usage_bytes INTEGER, usage_bytes INTEGER,
...@@ -199,16 +205,17 @@ class NetDriveUsageReporter(object): ...@@ -199,16 +205,17 @@ class NetDriveUsageReporter(object):
config_id INTEGER REFERENCES config ( _rowid_ ), config_id INTEGER REFERENCES config ( _rowid_ ),
drive_letter TEXT NOT NULL, drive_letter TEXT NOT NULL,
remote_folder TEXT NOT NULL, remote_folder TEXT NOT NULL,
domain_user TEXT NOT NULL,
start TEXT NOT NULL, start TEXT NOT NULL,
duration FLOAT NOT NULL, duration FLOAT NOT NULL,
usage_bytes INTEGER, usage_bytes INTEGER,
remark TEXT)""") remark TEXT)""")
def generateDailyReport(self, config_id, computer_id, domain_account, def generateDailyReport(self, config_id, computer_id, report_date, remove=True):
report_date, remove=True):
q = self._db.execute q = self._db.execute
report = etree.Element("consumption") report = etree.Element("consumption")
for r in q("SELECT remote_folder, duration, usage_bytes FROM net_drive_usage " for r in q("SELECT domain_user, remote_folder, duration, usage_bytes "
"FROM net_drive_usage "
"WHERE config_id=? AND strftime('%Y-%m-%d', start)=?", "WHERE config_id=? AND strftime('%Y-%m-%d', start)=?",
(config_id, report_date)): (config_id, report_date)):
movement = etree.Element('movement') movement = etree.Element('movement')
...@@ -222,7 +229,7 @@ class NetDriveUsageReporter(object): ...@@ -222,7 +229,7 @@ class NetDriveUsageReporter(object):
movement.append(element) movement.append(element)
element = etree.Element("reference") element = etree.Element("reference")
element.text = domain_account element.text = etree.Element("domain_user"),
movement.append(element) movement.append(element)
element = etree.Element("reference") element = etree.Element("reference")
......
This diff is collapsed.
#!/usr/bin/python
import logging
import os
import sys
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
import netuse
# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)
class SlapNodeMonitor(object):
def __init__(self):
super(SlapNodeMonitor, self).__init__()
self.port = 8008
netuse.autoConnect()
self.drivelist = netuse.listNetDrive()
print 'Net drive list:'
print self.drivelist
def cleanup(self):
pass
def netdrive_usage(self):
'''Get net drive usage, return a list as
[ (user, drive, remote, free, total), ... ]
'''
result = []
for k in self.drivelist:
r = netuse.usageReport(k[0])
result.append((k[3], k[0], k[1], r[0], r[1]))
return repr(result)
def run(self):
# Create server
server = SimpleXMLRPCServer(('localhost', self.port),
requestHandler=RequestHandler)
server.register_introspection_functions()
server.register_function(self.netdrive_usage, 'netdrive_usage')
try:
# Run the server's main loop
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
self.cleanup()
if __name__ == '__main__':
SlapNodeMonitor().run()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment