Probably not I huge deal, but I suspect that the key file is not removed if the process fails?
[2]
+ if not line.strip() or line.startswith("#"):
I think comments can start also after some blanks, so maybe:
+ if not line.strip() or line.strip().startswith("#"):
[3]
+class SourcesList(ManagerPlugin):
and
+ "repositories", self._wrap_handle_repositories)
It would be nice for the plugin and message name to match a bit more (that's often the cases for other plugins/messages). I'd suggest "class AptSources" and "apt-sources-replace" or something. The name "reposiories" sounds a bit generic, in case we want to add other operations later. This not blocking though.
[4]
+class ProcessError(Exception):
+ """Exception raised when running a process fails."""
and
+ def run_process(self, command, args):
This seems generic enough that it could be made a function under landscape.lib.process, like:
class ProcessError(Exception):
"""Exception raised when running a process fails."""
def run_process(self, command, args):
"""Run the process in an asynchronous fashion."""
def handle_process_error(result):
"""
Turn a failed process command (code != 0) to a C{ProcessError}.
"""
out, err, code = result
if code:
raise ProcessError(out, err)
else:
return result
def handle_process_failure(failure):
"""
Turn a signaled process command to a C{ProcessError}.
"""
out, err, signal = failure.value
raise ProcessError(out, err)
Nice work, nothing really blocking so feel free to address what you think is worth. +1
[1]
+ deferred. addCallback( self._handle_ process_ error) addCallback( lambda ignore, path=path: os.unlink(path))
+ deferred.
Probably not I huge deal, but I suspect that the key file is not removed if the process fails?
[2]
+ if not line.strip() or line.startswith ("#"):
I think comments can start also after some blanks, so maybe:
+ if not line.strip() or line.strip( ).startswith( "#"):
[3]
+class SourcesList( ManagerPlugin) :
and
+ "repositories", self._wrap_ handle_ repositories)
It would be nice for the plugin and message name to match a bit more (that's often the cases for other plugins/messages). I'd suggest "class AptSources" and "apt-sources- replace" or something. The name "reposiories" sounds a bit generic, in case we want to add other operations later. This not blocking though.
[4]
+class ProcessError( Exception) :
+ """Exception raised when running a process fails."""
and
+ def run_process(self, command, args):
This seems generic enough that it could be made a function under landscape. lib.process, like:
class ProcessError( Exception) :
"""Exception raised when running a process fails."""
def __init__(self, out, err):
super( ProcessError, self)._ _init__ ("%s\n% s" % (out, err))
def run_process(self, command, args):
"""Run the process in an asynchronous fashion."""
def handle_ process_ error(result) :
"""
Turn a failed process command (code != 0) to a C{ProcessError}.
"""
out, err, code = result
if code:
raise ProcessError(out, err)
else:
return result
def handle_ process_ failure( failure) :
"""
Turn a signaled process command to a C{ProcessError}.
"""
out, err, signal = failure.value
raise ProcessError(out, err)
deferred = getProcessOutpu tAndValue( command, args) addCallback( handle_ process_ error) addErrback( handle_ process_ failure)
deferred.
deferred.
return deferred
You could test run_process separately, and have the tests for SourcesList simply shows that ProcessError failures are handled correctly:
def test_failed_ import_ no_changes( self):
repositories aren't changed.
"""
If the C{apt-key} command failed for some reasons, the current
"""
def run_process( command, args): or("nok" , "some error"))
return fail(ProcessErr
sources = file(self. sourceslist. SOURCES_ LIST, "w")
sources. write(" oki\n\ndoki\ n#comment\ n")
sources. close()
service = self.broker_service
self.assertMes sages(service. message_ store.get_ pending_ messages( ),
[{"type" : "operation-result",
'result- text': u"ProcessError: nok\nsome error",
"status" : FAILED, "operation-id": 1}])