Merge lp:~free.ekanayaka/landscape-client/drop-config-bus into lp:~landscape/landscape-client/trunk

Proposed by Free Ekanayaka
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 255
Merged at revision: 256
Proposed branch: lp:~free.ekanayaka/landscape-client/drop-config-bus
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 268 lines (+52/-33)
4 files modified
landscape/deployment.py (+0/-7)
landscape/tests/test_deployment.py (+20/-10)
landscape/tests/test_watchdog.py (+23/-8)
landscape/watchdog.py (+9/-8)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-client/drop-config-bus
Reviewer Review Type Date Requested Status
Thomas Herve (community) Approve
Jamu Kakar (community) Approve
Review via email: mp+27197@code.launchpad.net

Description of the change

This branch drops the Configuration.bus option, which was used to select the DBus bus to connect to.

To post a comment you must log in.
Revision history for this message
Thomas Herve (therve) wrote :

[1]
+ if not (os.getuid() == 0 or
+ pwd.getpwnam("landscape").pw_uid == os.getuid()):
         sys.exit("When using the system bus, landscape-client must be run as "
                  "root.")

It seems that we can remove this check completely?

review: Needs Fixing
Revision history for this message
Jamu Kakar (jkakar) wrote :

[1]

+ info("Watchdog watching for daemons")

Please add a period to the end of this sentence.

[2]

+ if not (os.getuid() == 0 or
+ pwd.getpwnam("landscape").pw_uid == os.getuid()):
         sys.exit("When using the system bus, landscape-client must be run as "
                  "root.")

If the 'landscape' user doesn't exist a KeyError will be raised by
pwd.getpwnam. The user will get a message like:

KeyError: 'getpwnam(): name not found: landscape'

I recommend making this a bit more friendly by displaying a more
easily understandable message if the 'landscape' user isn't present:

    try:
        landscape_uid = pwd.getpwnam("landscape").pw_uid
    except KeyError:
        sys.exit("The 'landscape' user doesn't exist!")
    else:
        if os.getuid() not in (0, landscape_uid):
             sys.exit("landscape-client can only be run as 'root' "
                      "or 'landscape'.")

[3]

The docstring for the 'run' function needs to be updated.

+1 with these issues fixed.

review: Approve
255. By Free Ekanayaka

Fix Thomas' [1] and Jamu's [1] to [3]

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

Thanks Thomas and Jamu, I think it's all fixed!

Revision history for this message
Thomas Herve (therve) wrote :

+1!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/deployment.py'
2--- landscape/deployment.py 2010-05-07 10:51:41 +0000
3+++ landscape/deployment.py 2010-06-10 08:55:43 +0000
4@@ -153,9 +153,6 @@
5 "or the '%s' directive in the config file."
6 % (option.replace('_', '-'), option))
7
8- if self.bus not in ("session", "system"):
9- sys.exit("error: bus must be one of 'session' or 'system'")
10-
11 def _load_external_options(self):
12 """Hook for loading options from elsewhere (e.g. for --import)."""
13
14@@ -223,16 +220,12 @@
15 @return: An L{OptionParser} preset with options that all
16 landscape-related programs accept. These include
17 - C{config} (C{None})
18- - C{bus} (C{system})
19 """
20 parser = OptionParser(version=VERSION)
21 parser.add_option("-c", "--config", metavar="FILE",
22 help="Use config from this file (any command line "
23 "options override settings from the file) "
24 "(default: '/etc/landscape/client.conf').")
25- parser.add_option("--bus", default="system",
26- help="Which DBUS bus to use. One of 'session' "
27- "or 'system' (default: 'system').")
28 return parser
29
30 def get_config_filename(self):
31
32=== modified file 'landscape/tests/test_deployment.py'
33--- landscape/tests/test_deployment.py 2010-05-03 13:08:02 +0000
34+++ landscape/tests/test_deployment.py 2010-06-10 08:55:43 +0000
35@@ -11,6 +11,7 @@
36 class BabbleConfiguration(Configuration):
37 config_section = "babble"
38 default_config_filenames = []
39+
40 def make_parser(self):
41 parser = super(BabbleConfiguration, self).make_parser()
42 parser.add_option("--whatever", metavar="STUFF")
43@@ -25,9 +26,11 @@
44
45 def reset_config(self, configuration_class=None):
46 if not configuration_class:
47+
48 class MyConfiguration(Configuration):
49 default_config_filenames = []
50 configuration_class = MyConfiguration
51+
52 self.config_class = configuration_class
53 self.config = configuration_class()
54 self.parser = self.config.make_parser()
55@@ -51,18 +54,23 @@
56 self.assertEquals(self.config.log_level, "command line")
57
58 def test_command_line_option_without_default(self):
59+
60 class MyConfiguration(Configuration):
61+
62 def make_parser(self):
63 parser = OptionParser()
64 # Keep the dash in the option name to ensure it works.
65 parser.add_option("--foo-bar")
66 return parser
67+
68 self.assertEquals(MyConfiguration().foo_bar, None)
69
70 def test_command_line_with_required_options(self):
71+
72 class MyConfiguration(Configuration):
73 required_options = ("foo_bar",)
74 config = None
75+
76 def make_parser(self):
77 parser = super(MyConfiguration, self).make_parser()
78 # Keep the dash in the option name to ensure it works.
79@@ -81,14 +89,17 @@
80 self.assertEquals(self.config.foo_bar, "ooga")
81
82 def test_command_line_with_unsaved_options(self):
83+
84 class MyConfiguration(Configuration):
85 unsaved_options = ("foo_bar",)
86 config = None
87+
88 def make_parser(self):
89 parser = super(MyConfiguration, self).make_parser()
90 # Keep the dash in the option name to ensure it works.
91 parser.add_option("--foo-bar", metavar="NAME")
92 return parser
93+
94 self.reset_config(configuration_class=MyConfiguration)
95 self.write_config_file()
96
97@@ -112,9 +123,11 @@
98
99 def test_no_section_available(self):
100 config_filename = self.makeFile("")
101+
102 class MyConfiguration(Configuration):
103 config_section = "nonexistent"
104 default_config_filenames = (config_filename,)
105+
106 self.reset_config(configuration_class=MyConfiguration)
107 self.config.load([])
108
109@@ -220,16 +233,6 @@
110 data = open(filename).read()
111 self.assertEquals(data.strip(), "[client]\nlog_level = error")
112
113- def test_bus_option(self):
114- """The bus option must be specified as 'system' or 'session'."""
115- self.assertRaises(SystemExit,
116- self.config.load,
117- ["--bus", "foobar"])
118- self.config.load(["--bus", "session"])
119- self.assertEquals(self.config.bus, "session")
120- self.config.load(["--bus", "system"])
121- self.assertEquals(self.config.bus, "system")
122-
123 def test_config_option(self):
124 opts = self.parser.parse_args(["--config", "hello.cfg"])[0]
125 self.assertEquals(opts.config, "hello.cfg")
126@@ -240,22 +243,28 @@
127 self.assertEquals(self.config.hello, "world")
128
129 def test_load_typed_option_from_file(self):
130+
131 class MyConfiguration(self.config_class):
132+
133 def make_parser(self):
134 parser = super(MyConfiguration, self).make_parser()
135 parser.add_option("--year", default=1, type="int")
136 return parser
137+
138 filename = self.makeFile("[client]\nyear = 2008\n")
139 config = MyConfiguration()
140 config.load(["--config", filename])
141 self.assertEquals(config.year, 2008)
142
143 def test_load_typed_option_from_command_line(self):
144+
145 class MyConfiguration(self.config_class):
146+
147 def make_parser(self):
148 parser = super(MyConfiguration, self).make_parser()
149 parser.add_option("--year", default=1, type="int")
150 return parser
151+
152 config = MyConfiguration()
153 config.load(["--year", "2008"])
154 self.assertEquals(config.year, 2008)
155@@ -346,6 +355,7 @@
156 class GetVersionedPersistTest(LandscapeTest):
157
158 def test_upgrade_service(self):
159+
160 class FakeService(object):
161 persist_filename = self.makePersistFile(content="")
162 service_name = "monitor"
163
164=== modified file 'landscape/tests/test_watchdog.py'
165--- landscape/tests/test_watchdog.py 2010-05-03 13:08:02 +0000
166+++ landscape/tests/test_watchdog.py 2010-06-10 08:55:43 +0000
167@@ -963,8 +963,7 @@
168 self.configuration = WatchDogConfiguration()
169 self.data_path = self.makeDir()
170 self.log_dir = self.makeDir()
171- self.configuration.load(["--bus", "system",
172- "--data-path", self.data_path,
173+ self.configuration.load(["--data-path", self.data_path,
174 "--log-dir", self.log_dir])
175
176 def test_daemonize(self):
177@@ -1316,8 +1315,9 @@
178 getpwnam("landscape").pw_uid
179 self.mocker.result(1001)
180 self.mocker.replay()
181- sys_exit = self.assertRaises(SystemExit, run, ["--bus", "system"])
182- self.assertIn("landscape-client must be run as root", str(sys_exit))
183+ sys_exit = self.assertRaises(SystemExit, run)
184+ self.assertIn("landscape-client can only be run"
185+ " as 'root' or 'landscape'.", str(sys_exit))
186
187 def test_landscape_user(self):
188 """
189@@ -1328,11 +1328,27 @@
190 self.mocker.result(os.getuid())
191 self.mocker.replay()
192 reactor = FakeReactor()
193- run(["--bus", "system", "--log-dir", self.makeFile()],
194- reactor=reactor)
195+ run(["--log-dir", self.makeFile()], reactor=reactor)
196 self.assertTrue(reactor.running)
197
198+ def test_non_root(self):
199+ """
200+ The watchdog should print an error message and exit if the
201+ 'landscape' user doesn't exist.
202+ """
203+ getpwnam = self.mocker.replace("pwd.getpwnam")
204+ getpwnam("landscape")
205+ self.mocker.throw(KeyError())
206+ self.mocker.replay()
207+ sys_exit = self.assertRaises(SystemExit, run)
208+ self.assertIn("The 'landscape' user doesn't exist!", str(sys_exit))
209+
210 def test_clean_environment(self):
211+ getpwnam = self.mocker.replace("pwd.getpwnam")
212+ getpwnam("landscape").pw_uid
213+ self.mocker.result(os.getuid())
214+ self.mocker.replay()
215+
216 os.environ["DEBIAN_YO"] = "yo"
217 os.environ["DEBCONF_YO"] = "yo"
218 os.environ["LANDSCAPE_ATTACHMENTS"] = "some attachments"
219@@ -1340,8 +1356,7 @@
220 os.environ["UNRELATED"] = "unrelated"
221
222 reactor = FakeReactor()
223- run(["--bus", "session", "--log-dir", self.makeFile()],
224- reactor=reactor)
225+ run(["--log-dir", self.makeFile()], reactor=reactor)
226 self.assertNotIn("DEBIAN_YO", os.environ)
227 self.assertNotIn("DEBCONF_YO", os.environ)
228 self.assertNotIn("LANDSCAPE_ATTACHMENTS", os.environ)
229
230=== modified file 'landscape/watchdog.py'
231--- landscape/watchdog.py 2010-05-03 13:08:02 +0000
232+++ landscape/watchdog.py 2010-06-10 08:55:43 +0000
233@@ -496,7 +496,7 @@
234 reactor.crash() # so stopService isn't called.
235 return
236 self._daemonize()
237- info("Watchdog watching for daemons on %r bus." % self._config.bus)
238+ info("Watchdog watching for daemons.")
239 return self.watchdog.start()
240
241 def die(failure):
242@@ -582,19 +582,20 @@
243 @param reactor: The reactor to use. If none is specified, the global
244 reactor is used.
245 @raise SystemExit: if command line arguments are bad, or when landscape-
246- client is running as non-root and the configuration indicates use of
247- the system bus.
248+ client is not running as 'root' or 'landscape'.
249 """
250 clean_environment()
251
252 config = WatchDogConfiguration()
253 config.load(args)
254
255- if (config.bus == "system"
256- and not (os.getuid() == 0
257- or pwd.getpwnam("landscape").pw_uid == os.getuid())):
258- sys.exit("When using the system bus, landscape-client must be run as "
259- "root.")
260+ try:
261+ landscape_uid = pwd.getpwnam("landscape").pw_uid
262+ except KeyError:
263+ sys.exit("The 'landscape' user doesn't exist!")
264+
265+ if os.getuid() not in (0, landscape_uid):
266+ sys.exit("landscape-client can only be run as 'root' or 'landscape'.")
267
268 init_logging(config, "watchdog")
269

Subscribers

People subscribed via source and target branches

to all changes: