1
--- a/landscape/__init__.py
2
+++ b/landscape/__init__.py
5
-UPSTREAM_VERSION = "13.10+bzr73"
6
+UPSTREAM_VERSION = "14.01"
7
VERSION = "%s%s" % (UPSTREAM_VERSION, DEBIAN_REVISION)
9
# The "server-api" field of outgoing messages will be set to this value, and
10
--- a/landscape/broker/config.py
11
+++ b/landscape/broker/config.py
13
"""Get the path to the message store."""
14
return os.path.join(self.data_path, "messages")
16
- def load(self, args, accept_nonexistent_config=False):
17
+ def load(self, args):
19
Load options from command line arguments and a config file.
22
C{http_proxy} and C{https_proxy} environment variables based on
25
- super(BrokerConfiguration, self).load(
26
- args, accept_nonexistent_config=accept_nonexistent_config)
27
+ super(BrokerConfiguration, self).load(args)
29
os.environ["http_proxy"] = self.http_proxy
30
elif self._original_http_proxy:
31
--- a/landscape/deployment.py
32
+++ b/landscape/deployment.py
35
self.load(self._command_line_args)
37
- def load(self, args, accept_nonexistent_config=False):
38
+ def load(self, args, accept_nonexistent_default_config=False):
40
Load configuration data from command line arguments and a config file.
42
+ @param accept_nonexistent_default_config: If True, don't complain if
43
+ default configuration files aren't found
45
@raise: A SystemExit if the arguments are bad.
48
self.load_command_line(args)
51
config_filenames = [self.config]
52
+ allow_missing = False
54
config_filenames = self.default_config_filenames
55
+ allow_missing = accept_nonexistent_default_config
56
# Parse configuration file, if found.
57
for config_filename in config_filenames:
58
if (os.path.isfile(config_filename)
63
- if not accept_nonexistent_config:
64
+ if not allow_missing:
65
if len(config_filenames) == 1:
67
"error: config file %s can't be read" %
72
- def load(self, args, accept_nonexistent_config=False):
73
+ def load(self, args):
75
Load configuration data from command line arguments and a config file.
77
- super(Configuration, self).load(
78
- args, accept_nonexistent_config=accept_nonexistent_config)
79
+ super(Configuration, self).load(args)
81
if not isinstance(self.server_autodiscover, bool):
82
autodiscover = str(self.server_autodiscover).lower()
83
--- a/landscape/sysinfo/deployment.py
84
+++ b/landscape/sysinfo/deployment.py
87
sysinfo = SysInfoPluginRegistry()
88
config = SysInfoConfiguration()
90
+ # landscape-sysinfo needs to work where there's no
91
+ # /etc/landscape/client.conf See lp:1293990
92
+ config.load(args, accept_nonexistent_default_config=True)
93
for plugin in config.get_plugins():
96
--- a/landscape/sysinfo/tests/test_deployment.py
97
+++ b/landscape/sysinfo/tests/test_deployment.py
100
from twisted.internet.defer import Deferred
102
+from landscape.lib.fs import create_file
104
from landscape.sysinfo.deployment import (
105
SysInfoConfiguration, ALL_PLUGINS, run, setup_logging,
106
get_landscape_log_directory)
109
def test_config_file(self):
110
filename = self.makeFile()
111
- f = open(filename, "w")
112
- f.write("[sysinfo]\nsysinfo_plugins = TestPlugin\n")
114
+ create_file(filename, "[sysinfo]\nsysinfo_plugins = TestPlugin\n")
115
self.configuration.load(["--config", filename, "-d", self.makeDir()])
116
plugins = self.configuration.get_plugins()
117
self.assertEqual(len(plugins), 1)
120
return result.addCallback(check_result)
122
+ def test_missing_config_file(self):
123
+ """The process doesn't fail if there is no config file."""
124
+ # Existing revert in tearDown will handle undoing this
125
+ SysInfoConfiguration.default_config_filenames = []
128
+ def check_result(result):
129
+ self.assertIn("System load", self.stdout.getvalue())
131
+ return result.addCallback(check_result)
133
def test_plugins_called_after_reactor_starts(self):
135
Plugins are invoked after the reactor has started, so that they can
136
--- a/landscape/tests/test_deployment.py
137
+++ b/landscape/tests/test_deployment.py
139
from StringIO import StringIO
140
from textwrap import dedent
142
-from landscape.deployment import Configuration, get_versioned_persist
143
+from landscape.lib.fs import read_file, create_file
145
+from landscape.deployment import (
146
+ BaseConfiguration, Configuration, get_versioned_persist)
147
from landscape.manager.config import ManagerConfiguration
149
from landscape.tests.helpers import LandscapeTest, LogKeeperHelper
154
+class BaseConfigurationTest(LandscapeTest):
156
+ def test_load_not_found_default_accept_missing(self):
158
+ C{config.load} doesn't exit the process if the default config file
159
+ is not found and C{accept_nonexistent_default_config} is C{True}.
161
+ class MyConfiguration(BaseConfiguration):
162
+ default_config_filenames = ["/not/here"]
164
+ config = MyConfiguration()
165
+ result = config.load([], accept_nonexistent_default_config=True)
166
+ self.assertIs(result, None)
168
+ def test_load_not_found_accept_missing(self):
170
+ C{config.load} exits the process if the specified config file
171
+ is not found and C{accept_nonexistent_default_config} is C{True}.
173
+ class MyConfiguration(BaseConfiguration):
174
+ default_config_filenames = []
176
+ config = MyConfiguration()
177
+ filename = "/not/here"
178
+ error = self.assertRaises(
179
+ SystemExit, config.load, ["--config", filename],
180
+ accept_nonexistent_default_config=True)
182
+ "error: config file %s can't be read" % filename, str(error))
185
class ConfigurationTest(LandscapeTest):
187
helpers = [LogKeeperHelper]
189
self.write_config_file(log_level="debug")
190
self.config.log_level = "warning"
192
- data = open(self.config_filename).read()
193
+ data = read_file(self.config_filename)
194
self.assertConfigEqual(data, "[client]\nlog_level = warning")
196
def test_write_configuration_with_section(self):
198
self.write_config_file(section_name="babble", whatever="yay")
199
self.config.whatever = "boo"
201
- data = open(self.config_filename).read()
202
+ data = read_file(self.config_filename)
203
self.assertConfigEqual(data, "[babble]\nwhatever = boo")
205
def test_write_unrelated_configuration_back(self):
207
self.config.load_configuration_file(config_filename)
208
self.config.whatever = "boo"
210
- data = open(config_filename).read()
211
+ data = read_file(config_filename)
212
self.assertConfigEqual(
214
"[babble]\nwhatever = boo\n\n[goojy]\nunrelated = yes")
217
self.config.log_level = "warning"
219
- data = open(self.config_filename).read()
220
- self.assertConfigEqual(data,
221
- "[client]\nlog_level = warning\n")
222
+ data = read_file(self.config_filename)
223
+ self.assertConfigEqual(data, "[client]\nlog_level = warning\n")
225
def test_write_empty_list_values_instead_of_double_quotes(self):
229
self.config.include_manager_plugins = ""
231
- data = open(self.config_filename).read()
232
+ data = read_file(self.config_filename)
233
self.assertConfigEqual(data, "[client]\ninclude_manager_plugins = \n")
235
def test_dont_write_config_specified_default_options(self):
237
self.write_config_file(log_level="debug")
238
self.config.log_level = "info"
240
- data = open(self.config_filename).read()
241
+ data = read_file(self.config_filename)
242
self.assertConfigEqual(data, "[client]")
244
def test_dont_write_unspecified_default_options(self):
246
self.write_config_file()
247
self.config.log_level = "info"
249
- data = open(self.config_filename).read()
250
+ data = read_file(self.config_filename)
251
self.assertConfigEqual(data, "[client]")
253
def test_dont_write_client_section_default_options(self):
255
self.write_config_file(log_level="debug")
256
self.config.log_level = "info"
258
- data = open(self.config_filename).read()
259
+ data = read_file(self.config_filename)
260
self.assertConfigEqual(data, "[client]")
262
def test_do_write_preexisting_default_options(self):
264
self.config.load_configuration_file(config_filename)
265
self.config.log_level = "info"
267
- data = open(config_filename).read()
268
+ data = read_file(config_filename)
269
self.assertConfigEqual(data, "[client]\nlog_level = info\n")
271
def test_dont_delete_explicitly_set_default_options(self):
272
@@ -266,21 +299,21 @@
274
self.write_config_file(log_level="info")
276
- data = open(self.config_filename).read()
277
+ data = read_file(self.config_filename)
278
self.assertConfigEqual(data, "[client]\nlog_level = info")
280
def test_dont_write_config_option(self):
281
self.write_config_file()
282
self.config.config = self.config_filename
284
- data = open(self.config_filename).read()
285
+ data = read_file(self.config_filename)
286
self.assertConfigEqual(data, "[client]")
288
def test_write_command_line_options(self):
289
self.write_config_file()
290
self.config.load(["--log-level", "warning"])
292
- data = open(self.config_filename).read()
293
+ data = read_file(self.config_filename)
294
self.assertConfigEqual(data, "[client]\nlog_level = warning\n")
296
def test_write_command_line_precedence(self):
298
self.write_config_file(log_level="debug")
299
self.config.load(["--log-level", "warning"])
301
- data = open(self.config_filename).read()
302
+ data = read_file(self.config_filename)
303
self.assertConfigEqual(data, "[client]\nlog_level = warning\n")
305
def test_write_manually_set_precedence(self):
306
@@ -299,17 +332,16 @@
307
self.config.load(["--log-level", "warning"])
308
self.config.log_level = "error"
310
- data = open(self.config_filename).read()
311
+ data = read_file(self.config_filename)
312
self.assertConfigEqual(data, "[client]\nlog_level = error\n")
314
def test_write_to_given_config_file(self):
315
- filename = self.makeFile()
316
+ filename = self.makeFile(content="")
318
- ["--log-level", "warning", "--config", filename],
319
- accept_nonexistent_config=True)
320
+ ["--log-level", "warning", "--config", filename])
321
self.config.log_level = "error"
323
- data = open(filename).read()
324
+ data = read_file(filename)
325
self.assertConfigEqual(data, "[client]\nlog_level = error\n")
327
def test_comments_are_maintained(self):
329
self.config.load_configuration_file(filename)
330
self.config.log_level = "error"
332
- new_config = open(filename).read()
333
+ new_config = read_file(filename)
334
self.assertConfigEqual(
336
"[client]\n# Comment 1\nlog_level = error\n#Comment 2\n")
339
filename = self.makeFile("[client]\nhello = world1\n")
340
self.config.load(["--config", filename])
341
- open(filename, "w").write("[client]\nhello = world2\n")
342
+ create_file(filename, "[client]\nhello = world2\n")
344
self.assertEqual(self.config.hello, "world2")
348
def test_url_option(self):
349
"""Ensure options.url option can be read by parse_args."""
350
- options = self.parser.parse_args(["--url",
351
- "http://mylandscape/message-system"])[0]
352
+ options = self.parser.parse_args(
353
+ ["--url", "http://mylandscape/message-system"])[0]
354
self.assertEqual(options.url, "http://mylandscape/message-system")
356
def test_url_default(self):
359
def test_ping_url_option(self):
360
"""Ensure options.ping_url option can be read by parse_args."""
361
- options = self.parser.parse_args(["--ping-url",
362
- "http://mylandscape/ping"])[0]
363
+ options = self.parser.parse_args(
364
+ ["--ping-url", "http://mylandscape/ping"])[0]
365
self.assertEqual(options.ping_url, "http://mylandscape/ping")
367
def test_ping_url_default(self):
370
def test_ssl_public_key_option(self):
371
"""Ensure options.ssl_public_key option can be read by parse_args."""
372
- options = self.parser.parse_args(["--ssl-public-key",
373
- "/tmp/somekeyfile.ssl"])[0]
374
+ options = self.parser.parse_args(
375
+ ["--ssl-public-key", "/tmp/somekeyfile.ssl"])[0]
376
self.assertEqual(options.ssl_public_key, "/tmp/somekeyfile.ssl")
378
def test_ssl_public_key_default(self):
380
Ensure options.autodiscover_srv_query_string option can be read by
383
- options = self.parser.parse_args(["--autodiscover-srv-query-string",
384
- "_tcp._landscape.someotherdomain"])[0]
385
+ options = self.parser.parse_args(
386
+ ["--autodiscover-srv-query-string",
387
+ "_tcp._landscape.someotherdomain"])[0]
388
self.assertEqual(options.autodiscover_srv_query_string,
389
"_tcp._landscape.someotherdomain")
392
Ensure options.autodiscover_a_query_string option can be read by
395
- options = self.parser.parse_args(["--autodiscover-a-query-string",
396
- "customname.mydomain"])[0]
397
+ options = self.parser.parse_args(
398
+ ["--autodiscover-a-query-string", "customname.mydomain"])[0]
399
self.assertEqual(options.autodiscover_a_query_string,
400
"customname.mydomain")
404
def test_log_file_option(self):
405
"""Ensure options.log_dir option can be read by parse_args."""
406
- options = self.parser.parse_args(["--log-dir",
407
- "/var/log/my-awesome-log"])[0]
408
+ options = self.parser.parse_args(
409
+ ["--log-dir", "/var/log/my-awesome-log"])[0]
410
self.assertEqual(options.log_dir, "/var/log/my-awesome-log")
412
def test_log_level_default(self):