From 24efd83dfc0fd0fed90ed953bf4e0e7cde9824d0 Mon Sep 17 00:00:00 2001 From: Zack Cerza Date: Tue, 20 May 2014 19:42:29 -0500 Subject: [PATCH] Remove old lock server Signed-off-by: Zack Cerza --- teuthology/locker/__init__.py | 0 teuthology/locker/api.py | 200 ---------------------------------- teuthology/locker/config.py | 25 ----- teuthology/locker/locker.py | 19 ---- 4 files changed, 244 deletions(-) delete mode 100644 teuthology/locker/__init__.py delete mode 100644 teuthology/locker/api.py delete mode 100644 teuthology/locker/config.py delete mode 100755 teuthology/locker/locker.py diff --git a/teuthology/locker/__init__.py b/teuthology/locker/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/teuthology/locker/api.py b/teuthology/locker/api.py deleted file mode 100644 index 975a3a4440..0000000000 --- a/teuthology/locker/api.py +++ /dev/null @@ -1,200 +0,0 @@ -import json -import web -import subprocess - -from config import DB - -import logging -log = logging.getLogger(__name__) - -def load_machine(name): - results = list(DB.select('machine', what='*', - where='name = $name', - vars=dict(name=name))) - if not results: - raise web.NotFound() - return results[0] - -def get_sshkey(name): - if '@' in name: - _, name = name.rsplit('@') - args = ['ssh-keyscan'] - args.append(name) - p = subprocess.Popen( - args=args, - stdout=subprocess.PIPE, - ) - out, _ = p.communicate() - pubkey = None - for key_entry in out.splitlines(): - hostname, pubkey = key_entry.split(' ', 1) - if not pubkey: - status = 1 - else: - status = 0 - return (pubkey), status - -def update_sshkey(name, key, type): - if type == 'vps': - return - res = DB.update('machine', where='name = $name AND locked = false', - vars=dict(name=name), - sshpubkey=key,) - assert res == 1, 'Failed to update key of machine {name}'.format(name=name) - print 'Updated key on ', name - -class MachineLock: - def GET(self, name): - row = load_machine(name) - row.locked_since = row.locked_since.isoformat() - web.header('Content-type', 'text/json') - return json.dumps(row) - - def DELETE(self, name): - user = web.input('user')['user'] - machine = load_machine(name) - if not machine.locked: - raise web.BadRequest() - if machine.locked_by != user: - raise web.Forbidden() - - res = DB.update('machine', - where='locked = true AND name = $name AND locked_by = $user', - vars=dict(name=name, user=user), - locked=False, locked_by=None, description=None) - assert res == 1, 'Failed to unlock machine {name}'.format(name=name) - print user, 'unlocked', name - - def POST(self, name): - user = web.input('user')['user'] - desc = web.input(desc=None)['desc'] - machine = load_machine(name) - if machine.locked: - raise web.Forbidden() - - if machine.type == 'vps': - curkey = machine.sshpubkey - else: - curkey, getstatus = get_sshkey(name) - if getstatus != 0: - curkey = machine.sshpubkey - if machine.sshpubkey != curkey: - newkey = curkey - else: - newkey = machine.sshpubkey - res = DB.update('machine', where='name = $name AND locked = false', - vars=dict(name=name), - locked=True, - description=desc, - sshpubkey=newkey, - locked_by=user, - locked_since=web.db.SQLLiteral('NOW()')) - assert res == 1, 'Failed to lock machine {name}'.format(name=name) - print user, 'locked single machine', name, 'desc', desc - - def PUT(self, name): - desc = web.input(desc=None)['desc'] - status = web.input(status=None)['status'] - sshpubkey = web.input(sshpubkey=None)['sshpubkey'] - - updated = {} - if desc is not None: - updated['description'] = desc - if status is not None: - updated['up'] = (status == 'up') - if sshpubkey is not None: - updated['sshpubkey'] = sshpubkey - - if not updated: - raise web.BadRequest() - DB.update('machine', where='name = $name', - vars=dict(name=name), **updated) - print 'updated', name, 'with', updated, 'desc', desc - -class Lock: - def GET(self): - rows = list(DB.select('machine', what='*')) - if not rows: - raise web.NotFound() - for row in rows: - row.locked_since = row.locked_since.isoformat() - web.header('Content-type', 'text/json') - return json.dumps(rows) - - def POST(self): - user = web.input('user')['user'] - desc = web.input(desc=None)['desc'] - num = int(web.input('num')['num']) - machinetype = dict(machinetype=(web.input(machinetype='plana')['machinetype'])) - - if num < 1: - raise web.BadRequest() - - tries = 0 - check_existing = True - while True: - try: - # transaction will be rolled back if an exception is raised - with DB.transaction(): - if desc is not None and check_existing: - # if a description is provided, treat it as a - # key for locking in case the same run locked - # machines in the db successfully before, but - # the web server reported failure to it - # because the request took too long. Only try - # this once per request. - check_existing = False - results = list(DB.select('machine', - machinetype, desc, user, - what='name, sshpubkey', - where='locked = true AND up = true AND type = $machinetype AND description = $desc AND locked_by = $user', - limit=num)) - if len(results) == num: - name_keys = {} - for row in results: - name_keys[row.name] = row.sshpubkey - print 'reusing machines', name_keys.keys() - break - - results = list(DB.select('machine', machinetype, - what='name, sshpubkey, type', - where='locked = false AND up = true AND type = $machinetype', - limit=num)) - if len(results) < num: - raise web.HTTPError(status='503 Service Unavailable') - name_keys = {} - for row in results: - if row.type == 'vps': - curkey = row.sshpubkey - else: - curkey, getstatus = get_sshkey(row.name) - if getstatus != 0: - curkey = row.sshpubkey - if row.sshpubkey != curkey: - newkey = curkey - update_sshkey(row.name, curkey, row.type) - else: - newkey = row.sshpubkey - name_keys[row.name] = newkey - where_cond = web.db.sqlors('name = ', name_keys.keys()) \ - + ' AND locked = false AND up = true' - num_locked = DB.update('machine', - where=where_cond, - locked=True, - locked_by=user, - description=desc, - locked_since=web.db.SQLLiteral('NOW()')) - assert num_locked == num, 'Failed to lock machines' - except Exception: - log.exception("Saw exception") - tries += 1 - if tries < 10: - continue - raise - else: - break - - print user, 'locked', name_keys.keys(), 'desc', desc - - web.header('Content-type', 'text/json') - return json.dumps(name_keys) diff --git a/teuthology/locker/config.py b/teuthology/locker/config.py deleted file mode 100644 index c6ac36ffe5..0000000000 --- a/teuthology/locker/config.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -This file contains database configuration. - -The schema can be created with:: - - CREATE TABLE machine ( - name varchar(255), - type enum('burnupi','plana','vps') NOT NULL DEFAULT 'plana', - up boolean NOT NULL, - locked boolean NOT NULL, - locked_since timestamp NOT NULL DEFAULT '0000-00-00T00:00:00', - locked_by varchar(64), - description text, - sshpubkey text NOT NULL, - PRIMARY KEY (name), - INDEX (locked), - INDEX (up)); - -If using MySQL, be sure to use an engine that supports -transactions, like InnoDB. -""" -import web - -# Change these values to the connection info for your database. -DB = web.database(dbn='dbms', db='db', user='user', pw='password', host='host') diff --git a/teuthology/locker/locker.py b/teuthology/locker/locker.py deleted file mode 100755 index b017032b23..0000000000 --- a/teuthology/locker/locker.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -import web - -abspath = os.path.dirname(__file__) -if abspath not in sys.path: - sys.path.append(abspath) - -from api import Lock, MachineLock # noqa - -urls = ( - '/lock', 'Lock', - '/lock/(.*)', 'MachineLock', - ) - -app = web.application(urls, globals()) -application = app.wsgifunc() -- 2.39.5