summaryrefslogtreecommitdiff
path: root/morphlib/buildworker.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/buildworker.py')
-rw-r--r--morphlib/buildworker.py277
1 files changed, 0 insertions, 277 deletions
diff --git a/morphlib/buildworker.py b/morphlib/buildworker.py
deleted file mode 100644
index d839b09a..00000000
--- a/morphlib/buildworker.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# Copyright (C) 2012 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-import datetime
-from multiprocessing import Manager, Process
-
-import morphlib
-
-
-class BuildWorker(object):
-
- def __init__(self, name, ident, app):
- self.name = name
- self.ident = ident
- self.settings = app.settings
- self.real_msg = app.msg
- self.indent = 2
- self.idle_since = datetime.datetime.now()
- self.manager = Manager()
- self.reset()
-
- def indent_more(self): # pragma: no cover
- self.indent += 1
-
- def indent_less(self): # pragma: no cover
- self.indent -= 1
-
- def msg(self, text): # pragma: no cover
- spaces = ' ' * self.indent
- self.real_msg('%s%s' % (spaces, text))
-
- def reset(self):
- self.process = None
- self.blob = None
- self._output = self.manager.list()
- self._error = self.manager.dict()
-
- def build(self, blob):
- raise NotImplementedError
-
- def check_complete(self, timeout): # pragma: no cover
- if self.process:
- self.process.join(timeout)
- if self.process.is_alive():
- return False
- else:
- self.idle_since = datetime.datetime.now()
- return True
- else:
- return True
-
- @property
- def output(self):
- try:
- return self._output[0]
- except IndexError:
- return None
-
- @property
- def error(self):
- return self._error
-
- def options(self): # pragma: no cover
- '''Returns an array of command line options for the settings.
-
- NOTE: This is just a hack that uses internals of the cliapp.Settings
- class. We need to merge this kind of functionality into cliapp and
- remove this hack!
-
- '''
-
- # use the canonical names of the settings to generate cmdline options
- names = list(self.settings._canonical_names)
-
- # internal function to combine an option name and a value into string
- def combine(name, value):
- if name.startswith('--'):
- if isinstance(value, bool):
- if value:
- return '%s' % name
- else:
- return '%s=%s' % (name, value)
- else:
- if isinstance(value, bool):
- if value:
- return '%s' % name
- else:
- return '%s %s' % (name, value)
-
- # generate a list of (setting name, option name) pairs
- options_list = []
- options = self.settings._option_names(names)
- name_pairs = [(names[i], options[i]) for i in xrange(0, len(names))]
-
- # convert all settings into command line arguments; drop absent
- # settings and make sure to convert all values correctly
- for name, option in name_pairs:
- value = self.settings[name]
- if not value:
- continue
- if isinstance(value, list):
- for listval in value:
- if isinstance(listval, str):
- if len(listval) > 0:
- string = combine(option, listval)
- if string:
- options_list.append(string)
- else:
- string = combine(option, listval)
- if string:
- options_list.append(string)
- else:
- if isinstance(value, str):
- if len(value) > 0:
- string = combine(option, value)
- if string:
- options_list.append(string)
- else:
- string = combine(option, value)
- if string:
- options_list.append(string)
- return options_list
-
- def __str__(self):
- return self.name
-
-
-class LocalBuildWorker(BuildWorker):
-
- def __init__(self, name, ident, app):
- BuildWorker.__init__(self, name, ident, app)
-
- def run(self, first_tuple, second_tuple, sudo, output,
- error): # pragma: no cover
- ex = morphlib.execute.Execute('.', self.msg)
-
- # generate command line options
- args = self.options()
- cmdline = []
- if sudo:
- cmdline.extend(['sudo'])
- cmdline.extend(['morph', 'build-single'])
- cmdline.extend([first_tuple['repo'],
- first_tuple['ref'],
- first_tuple['filename']])
- if second_tuple:
- cmdline.extend([second_tuple['repo'],
- second_tuple['ref'],
- second_tuple['filename']])
- cmdline.extend(args)
-
- # run morph locally in a child process
- try:
- stdout = ex.runv(cmdline)
- output.append(stdout)
- except OSError, e:
- error['error'] = str(e)
- error['command'] = ' '.join(cmdline)
- except morphlib.execute.CommandFailure, e:
- error['error'] = str(e)
- error['command'] = ' '.join(cmdline)
-
- def build(self, blob): # pragma: no cover
- self.reset()
- self.blob = blob
-
- first_tuple = None
- if len(blob.parents) > 0:
- first_tuple = {
- 'repo': blob.parents[0].morph.treeish.original_repo,
- 'ref': blob.parents[0].morph.treeish.ref,
- 'filename': blob.parents[0].morph.filename,
- }
-
- blob_tuple = {
- 'repo': blob.morph.treeish.original_repo,
- 'ref': blob.morph.treeish.ref,
- 'filename': blob.morph.filename,
- }
-
- args = (first_tuple if first_tuple else blob_tuple,
- blob_tuple if first_tuple else None,
- blob.morph.kind == 'system',
- self._output,
- self._error)
- self.process = Process(group=None, target=self.run, args=args)
- self.process.start()
-
-
-class RemoteBuildWorker(BuildWorker):
-
- def __init__(self, name, ident, app):
- BuildWorker.__init__(self, name, ident, app)
- self.hostname = ident
-
- def run(self, first_tuple, second_tuple, sudo, output,
- error): # pragma: no cover
- ex = morphlib.execute.Execute('.', self.msg)
-
- # generate command line options
- args = self.options()
- cmdline = ['ssh', '-q', self.hostname]
- if sudo:
- cmdline.extend(['-t', '-t', '-t', 'sudo', '-S',
- 'bash', '--login', '-c'])
- cmdline.extend(['"'])
- cmdline.extend(['morph', 'build-single', repo, ref, filename])
- cmdline.extend([first_tuple['repo'],
- first_tuple['ref'],
- first_tuple['filename']])
- if second_tuple:
- cmdline.extend([second_tuple['repo'],
- second_tuple['ref'],
- second_tuple['filename']])
- cmdline.extend(args)
- cmdline.extend(['"'])
- else:
- cmdline.extend(['fakeroot'])
- cmdline.extend(['morph', 'build-single', repo, ref, filename])
- cmdline.extend([first_tuple['repo'],
- first_tuple['ref'],
- first_tuple['filename']])
- if second_tuple:
- cmdline.extend([second_tuple['repo'],
- second_tuple['ref'],
- second_tuple['filename']])
- cmdline.extend(args)
-
- # run morph on the other machine
- try:
- stdout = ex.runv(cmdline)
- output.append(stdout)
- except OSError, e:
- error['error'] = str(e)
- error['command'] = ' '.join(cmdline)
- except morphlib.execute.CommandFailure, e:
- error['error'] = str(e)
- error['command'] = ' '.join(cmdline)
-
- def build(self, blob): # pragma: no cover
- self.reset()
- self.blob = blob
-
- first_tuple = None
- if len(blob.parents) > 0:
- first_tuple = {
- 'repo': blob.parents[0].morph.treeish.original_repo,
- 'ref': blob.parents[0].morph.treeish.ref,
- 'filename': blob.parents[0].morph.filename,
- }
-
- blob_tuple = {
- 'repo': blob.morph.treeish.original_repo,
- 'ref': blob.morph.treeish.ref,
- 'filename': blob.morph.filename,
- }
-
- args = (first_tuple if first_tuple else blob_tuple,
- blob_tuple if first_tuple else None,
- blob.morph.kind == 'system',
- self._output,
- self._error)
- self.process = Process(group=None, target=self.run, args=args)
- self.process.start()