From 87d12b5c07e3174345d11b082604cab0f6164f44 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 24 Feb 2014 12:17:52 +0000 Subject: Add /1.0/lorry, make /1.0/give-me-job pick a job This is far from functional yet. give-me-job always gives the same job. --- lorry-controller-webapp | 86 +++++++++++++++++++++++++++++++++----- yarns.webapp/040-running-jobs.yarn | 10 +++++ 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/lorry-controller-webapp b/lorry-controller-webapp index 000ded3..cfc5534 100755 --- a/lorry-controller-webapp +++ b/lorry-controller-webapp @@ -52,6 +52,13 @@ STATUS_HTML_TEMPLATE = ''' ''' +class LorryNotFoundError(Exception): + + def __init__(self, path): + Exception.__init__( + self, 'Lorry with path %r not found in STATEDB' % path) + + class StateDB(object): '''A wrapper around raw Sqlite for STATEDB.''' @@ -73,7 +80,14 @@ class StateDB(object): c.execute('CREATE TABLE IF NOT EXISTS running_queue (running INT)') c.execute('INSERT INTO running_queue VALUES (0)') - c.execute('CREATE TABLE IF NOT EXISTS lorries (path TEXT PRIMARY KEY, text TEXT, generated INT)') + c.execute( + 'CREATE TABLE IF NOT EXISTS lorries (' + 'path TEXT PRIMARY KEY, ' + 'text TEXT, ' + 'generated INT, ' + 'due INT, ' + 'interval INT ' + ')') self._conn.commit() @@ -95,36 +109,65 @@ class StateDB(object): c.execute('UPDATE running_queue SET running = ?', str(new_value)) self._conn.commit() + def get_lorry_info(self, path): + logging.debug('StateDB.get_lorry_info called, path=%r', path) + self._open() + c = self._conn.cursor() + c.execute( + 'SELECT path, text, generated, due, interval ' + 'FROM lorries WHERE path IS ?', + (path,)) + row = c.fetchone() + if row is None: + raise LorryNotFoundError(path) + return { + 'path': row[0], + 'text': row[1], + 'generated': row[2], + 'due': row[3], + 'interval': row[4], + } + def get_lorries(self): logging.debug('StateDB.get_lorries called') self._open() c = self._conn.cursor() - return c.execute('SELECT path, text, generated FROM lorries') + return c.execute( + 'SELECT path, text, generated, due FROM lorries ORDER BY due') def get_lorries_paths(self): logging.debug('StateDB.get_lorries_paths called') self._open() c = self._conn.cursor() - return [row[0] for row in c.execute('SELECT path FROM lorries')] + return [ + row[0] + for row in c.execute('SELECT path FROM lorries ORDER BY due')] - def add_to_lorries(self, path=None, text=None, generated=None): + def add_to_lorries(self, path=None, text=None, generated=None, due=None, + interval=None): logging.debug( - 'StateDB.add_to_lorries(path=%r, text=%r, generated=%r called', + 'StateDB.add_to_lorries(' + 'path=%r, text=%r, generated=%r, due=%r, interval=%s called', path, text, - generated) + generated, + due, + interval) assert path is not None assert text is not None assert generated is not None + assert due is not None + assert interval is not None self._open() c = self._conn.cursor() c.execute('BEGIN TRANSACTION') c.execute( - 'INSERT OR REPLACE INTO lorries (path, text, generated) ' - 'VALUES (?, ?, ?)', - (path, text, generated)) + 'INSERT OR REPLACE INTO lorries ' + '(path, text, generated, due, interval) ' + 'VALUES (?, ?, ?, ?, ?)', + (path, text, generated, due, interval)) self._conn.commit() def remove_lorry(self, path): @@ -281,10 +324,14 @@ class ReadConfiguration(LorryControllerRoute): for lorry_spec in self.get_lorry_specs(filename): path = self.deduce_repo_path(section, lorry_spec) text = self.serialise_lorry_spec(lorry_spec) + due = 0 + interval = section['interval'] logging.debug( '%s %s: adding lorry spec %r: %r', self.http_method, self.path, path, text) - self.statedb.add_to_lorries(path=path, text=text, generated=0) + self.statedb.add_to_lorries( + path=path, text=text, generated=0, + due=due, interval=interval) added_paths.add(path) return added_paths @@ -328,6 +375,19 @@ class ListQueue(LorryControllerRoute): } +class ShowLorry(LorryControllerRoute): + + http_method = 'GET' + path = '/1.0/lorry/' + + def run(self, **kwargs): + logging.debug('%s %s called', self.http_method, self.path) + try: + return self.statedb.get_lorry_info(kwargs['path']) + except LorryNotFoundError as e: + bottle.abort(404, str(e)) + + class StartQueue(LorryControllerRoute): http_method = 'GET' @@ -357,7 +417,11 @@ class GiveMeJob(LorryControllerRoute): def run(self, **kwargs): logging.debug('%s %s called', self.http_method, self.path) - return { 'job-id': None } + paths = self.statedb.get_lorries_paths() + if paths: + return { 'job-id': paths[0] } + else: + return { 'job-id': None } class WEBAPP(cliapp.Application): diff --git a/yarns.webapp/040-running-jobs.yarn b/yarns.webapp/040-running-jobs.yarn index ad70d28..ea5b72e 100644 --- a/yarns.webapp/040-running-jobs.yarn +++ b/yarns.webapp/040-running-jobs.yarn @@ -12,8 +12,18 @@ To start with, with an empty run-queue, nothing should be scheduled. SCENARIO job scheduling GIVEN a new git repository in CONFGIT + AND an empty lorry-controller.conf in CONFGIT + AND lorry-controller.conf in CONFGIT adds lorries *.lorry using prefix upstream AND WEBAPP uses CONFGIT as its configuration directory AND a running WEBAPP WHEN admin makes request GET /1.0/give-me-job THEN response has job-id set to null + +Add a Lorry spec to the run-queue, and request a job. We should get +that job now. + + GIVEN Lorry file CONFGIT/foo.lorry with {"foo":{"type":"git","url":"git://foo"}} + WHEN admin makes request GET /1.0/read-configuration + AND admin makes request GET /1.0/give-me-job + THEN response has job-id set to "upstream/foo" -- cgit v1.2.1