Merge lp:~therve/landscape-client/sysinfo-network-disks into lp:~landscape/landscape-client/trunk

Proposed by Thomas Herve
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 217
Merge reported by: Thomas Herve
Merged at revision: not available
Proposed branch: lp:~therve/landscape-client/sysinfo-network-disks
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 249 lines (+86/-24)
5 files modified
landscape/lib/disk.py (+10/-3)
landscape/lib/tests/test_disk.py (+9/-0)
landscape/sysinfo/deployment.py (+4/-1)
landscape/sysinfo/disk.py (+21/-16)
landscape/sysinfo/tests/test_disk.py (+42/-4)
To merge this branch: bzr merge lp:~therve/landscape-client/sysinfo-network-disks
Reviewer Review Type Date Requested Status
Free Ekanayaka (community) Approve
Kevin McDermott (community) Approve
Review via email: mp+22037@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Kevin McDermott (bigkevmcd) wrote :

Fairly trivial change, I'd still have preferred to see a config option that allowed users to add further FS types, but if needed that can go in a separate branch.

+1

review: Approve
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Looks good to me, +1!

[1]

+ def test_whitelist(self):

This test has no docstring.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/lib/disk.py'
2--- landscape/lib/disk.py 2008-08-20 22:23:23 +0000
3+++ landscape/lib/disk.py 2010-03-24 15:30:35 +0000
4@@ -4,11 +4,14 @@
5 import statvfs
6
7
8-def get_mount_info(mounts_file, statvfs_):
9+def get_mount_info(mounts_file, statvfs_, filesystems_whitelist=None):
10 """
11 Given a mounts file (e.g., /proc/mounts), generate dicts with the following
12 keys:
13
14+ @param filesystems_whitelist: if provided, the list of file systems which
15+ we're allowed to stat.
16+
17 - device: The device file which is mounted.
18 - mount-point: The path at which the filesystem is mounted.
19 - filesystem: The filesystem type.
20@@ -21,6 +24,9 @@
21 mount_point = mount_point.decode("string-escape")
22 except ValueError:
23 continue
24+ if (filesystems_whitelist is not None and
25+ filesystem not in filesystems_whitelist):
26+ continue
27 megabytes = 1024 * 1024
28 stats = statvfs_(mount_point)
29 block_size = stats[statvfs.F_BSIZE]
30@@ -31,11 +37,12 @@
31 "free-space": free_space}
32
33
34-def get_filesystem_for_path(path, mounts_file, statvfs_):
35+def get_filesystem_for_path(path, mounts_file, statvfs_,
36+ filesystems_whitelist=None):
37 candidate = None
38 path = os.path.realpath(path)
39 path_segments = path.split("/")
40- for info in get_mount_info(mounts_file, statvfs_):
41+ for info in get_mount_info(mounts_file, statvfs_, filesystems_whitelist):
42 mount_segments = info["mount-point"].split("/")
43 if path.startswith(info["mount-point"]):
44 if ((not candidate)
45
46=== modified file 'landscape/lib/tests/test_disk.py'
47--- landscape/lib/tests/test_disk.py 2009-11-06 13:41:30 +0000
48+++ landscape/lib/tests/test_disk.py 2010-03-24 15:30:35 +0000
49@@ -50,3 +50,12 @@
50 info = get_filesystem_for_path(symlink_path,
51 self.mount_file, self.statvfs)
52 self.assertEquals(info["mount-point"], "/foo")
53+
54+ def test_whitelist(self):
55+ self.set_mount_points(["/"])
56+ info = get_filesystem_for_path(
57+ "/", self.mount_file, self.statvfs, ["ext3"])
58+ self.assertIdentical(info, None)
59+ info = get_filesystem_for_path(
60+ "/", self.mount_file, self.statvfs, ["ext3", "fsfs"])
61+ self.assertNotIdentical(info, None)
62
63=== modified file 'landscape/sysinfo/deployment.py'
64--- landscape/sysinfo/deployment.py 2010-02-05 14:55:32 +0000
65+++ landscape/sysinfo/deployment.py 2010-03-24 15:30:35 +0000
66@@ -60,6 +60,7 @@
67 % (plugin_name.lower(), plugin_name))()
68 for plugin_name in plugins]
69
70+
71 def get_landscape_log_directory(landscape_dir=None):
72 """
73 Work out the correct path to store logs in depending on the effective
74@@ -79,7 +80,7 @@
75 logger.propagate = False
76 if not os.path.isdir(landscape_dir):
77 os.mkdir(landscape_dir)
78- log_filename = os.path.join(landscape_dir, "sysinfo.log")
79+ log_filename = os.path.join(landscape_dir, "sysinfo.log")
80 handler = RotatingFileHandler(log_filename,
81 maxBytes=500 * 1024, backupCount=1)
82 logger.addHandler(handler)
83@@ -113,11 +114,13 @@
84 done = Deferred()
85 reactor.callWhenRunning(
86 lambda: maybeDeferred(run_sysinfo).chainDeferred(done))
87+
88 def stop_reactor(result):
89 # We won't need to use callLater here once we use Twisted >8.
90 # tm:3011
91 reactor.callLater(0, reactor.stop)
92 return result
93+
94 done.addBoth(stop_reactor)
95 reactor.run()
96 else:
97
98=== modified file 'landscape/sysinfo/disk.py'
99--- landscape/sysinfo/disk.py 2009-07-17 00:15:44 +0000
100+++ landscape/sysinfo/disk.py 2010-03-24 15:30:35 +0000
101@@ -7,9 +7,10 @@
102 from landscape.lib.disk import get_mount_info, get_filesystem_for_path
103
104
105-# List of filesystem types to exclude when generating disk use statistics.
106-BORING_FILESYSTEMS = set(["udf", "iso9660", "fuse.gvfs-fuse-daemon",
107- "squashfs", "ecryptfs"])
108+# List of filesystem types authorized when generating disk use statistics.
109+STABLE_FILESYSTEMS = set(
110+ ["ext", "ext2", "ext3", "ext4", "reiserfs", "ntfs", "msdos", "dos", "vfat",
111+ "xfs", "hpfs", "jfs", "ufs", "hfs", "hfsplus"])
112
113
114 def format_megabytes(megabytes):
115@@ -38,22 +39,28 @@
116
117 def run(self):
118 main_info = get_filesystem_for_path("/home", self._mounts_file,
119- self._statvfs)
120- total = main_info["total-space"]
121- if total <= 0:
122- main_info = get_filesystem_for_path("/", self._mounts_file,
123- self._statvfs)
124+ self._statvfs, STABLE_FILESYSTEMS)
125+ if main_info is not None:
126 total = main_info["total-space"]
127- if total <= 0:
128- main_usage = "unknown"
129+ if total <= 0:
130+ root_main_info = get_filesystem_for_path(
131+ "/", self._mounts_file, self._statvfs, STABLE_FILESYSTEMS)
132+ if root_main_info is not None:
133+ total = root_main_info["total-space"]
134+ main_info = root_main_info
135+ if total <= 0:
136+ main_usage = "unknown"
137+ else:
138+ main_usage = usage(main_info)
139+ self._sysinfo.add_header("Usage of " + main_info["mount-point"],
140+ main_usage)
141 else:
142- main_usage = usage(main_info)
143- self._sysinfo.add_header("Usage of " + main_info["mount-point"],
144- main_usage)
145+ self._sysinfo.add_header("Usage of /home", "unknown")
146
147 seen_mounts = set()
148 seen_devices = set()
149- infos = list(get_mount_info(self._mounts_file, self._statvfs))
150+ infos = list(get_mount_info(self._mounts_file, self._statvfs,
151+ STABLE_FILESYSTEMS))
152 infos.sort(key=lambda i: len(i["mount-point"]))
153 for info in infos:
154 total = info["total-space"]
155@@ -64,8 +71,6 @@
156 if mount_seen or device_seen:
157 continue
158
159- if info["filesystem"] in BORING_FILESYSTEMS:
160- continue
161 if total <= 0:
162 # Some "virtual" filesystems have 0 total space. ignore them.
163 continue
164
165=== modified file 'landscape/sysinfo/tests/test_disk.py'
166--- landscape/sysinfo/tests/test_disk.py 2009-08-07 22:36:33 +0000
167+++ landscape/sysinfo/tests/test_disk.py 2010-03-24 15:30:35 +0000
168@@ -4,6 +4,7 @@
169 from landscape.sysinfo.disk import Disk, format_megabytes
170 from landscape.tests.helpers import LandscapeTest
171
172+
173 class DiskTest(LandscapeTest):
174
175 def setUp(self):
176@@ -31,8 +32,10 @@
177 result = self.disk.run()
178 self.assertTrue(isinstance(result, Deferred))
179 called = []
180+
181 def callback(result):
182 called.append(True)
183+
184 result.addCallback(callback)
185 self.assertTrue(called)
186
187@@ -93,11 +96,14 @@
188
189 def test_multiple_notes(self):
190 """
191- A note will be displayed for each filesystem using 85% or more capacity.
192+ A note will be displayed for each filesystem using 85% or more
193+ capacity.
194 """
195 self.add_mount("/", block_size=1024, capacity=1000000, unused=150000)
196- self.add_mount("/use", block_size=2048, capacity=2000000, unused=200000)
197- self.add_mount("/emp", block_size=4096, capacity=3000000, unused=460000)
198+ self.add_mount(
199+ "/use", block_size=2048, capacity=2000000, unused=200000)
200+ self.add_mount(
201+ "/emp", block_size=4096, capacity=3000000, unused=460000)
202 self.disk.run()
203 self.assertEquals(self.sysinfo.get_notes(),
204 ["/ is using 85.0% of 976MB",
205@@ -151,7 +157,7 @@
206 self.assertEquals(self.sysinfo.get_notes(), [])
207
208 def test_no_duplicate_roots(self):
209- self.add_mount("/", capacity=0, unused=0, fs="rootfs")
210+ self.add_mount("/", capacity=0, unused=0, fs="ext4")
211 self.add_mount("/", capacity=1000, unused=1, fs="ext3")
212 self.disk.run()
213 self.assertEquals(self.sysinfo.get_notes(),
214@@ -206,3 +212,35 @@
215 self.disk.run()
216 self.assertEquals(self.sysinfo.get_notes(),
217 ["/ is using 100.0% of 3MB"])
218+
219+ def test_ignore_filesystems(self):
220+ """
221+ Network filesystems like nfs are ignored, because they can stall
222+ randomly in stat.
223+ """
224+ self.add_mount("/", capacity=1000, unused=1000, fs="ext3")
225+ self.add_mount("/mnt/disk1", capacity=1000, unused=0, fs="nfs")
226+ self.disk.run()
227+ self.assertEquals(self.sysinfo.get_notes(), [])
228+
229+ def test_nfs_as_root(self):
230+ """
231+ If / is not a whitelist filesystem, we don't report the usage of /home.
232+ """
233+ self.add_mount("/", capacity=1000, unused=1000, fs="nfs")
234+ self.disk.run()
235+ self.assertEquals(self.sysinfo.get_notes(), [])
236+ self.assertEquals(self.sysinfo.get_headers(),
237+ [("Usage of /home", "unknown")])
238+
239+ def test_nfs_as_root_but_not_home(self):
240+ """
241+ If / is not a whitelist filesystem, but that /home is with a weird stat
242+ value, we don't report the usage of /home.
243+ """
244+ self.add_mount("/", capacity=1000, unused=1000, fs="nfs")
245+ self.add_mount("/home", capacity=0, unused=0, fs="ext3")
246+ self.disk.run()
247+ self.assertEquals(self.sysinfo.get_notes(), [])
248+ self.assertEquals(self.sysinfo.get_headers(),
249+ [("Usage of /home", "unknown")])

Subscribers

People subscribed via source and target branches

to all changes: