diff --git a/notify_doc_impact.py b/notify_doc_impact.py
deleted file mode 100755
index 1d312ae..0000000
--- a/notify_doc_impact.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is designed to be called by a gerrit hook.  It searched new
-# patchsets for strings like "bug FOO" and updates corresponding Launchpad
-# bugs status.
-
-import argparse
-import re
-import subprocess
-import smtplib
-
-from email.mime.text import MIMEText
-
-BASE_DIR = '/home/gerrit2/review_site'
-EMAIL_TEMPLATE = """
-Hi, I'd like you to take a look at this patch for potential
-documentation impact.
-%s
-
-Log:
-%s
-"""
-DEST_ADDRESS = 'openstack-docs@lists.openstack.org'
-
-def process_impact(git_log, args):
-    """Notify doc team of doc impact"""
-    email_content = EMAIL_TEMPLATE % (args.change_url, git_log)
-    msg = MIMEText(email_content)
-    msg['Subject'] = '[%s] DocImpact review request' % args.project
-    msg['From'] = 'gerrit2@review.openstack.org'
-    msg['To'] = DEST_ADDRESS
-
-    s = smtplib.SMTP('localhost')
-    s.sendmail('gerrit2@review.openstack.org', DEST_ADDRESS, msg.as_string())
-    s.quit()
-
-def docs_impacted(git_log):
-    """Determine if a changes log indicates there is a doc impact"""
-    impact_regexp = r'DocImpact'
-    return re.search(impact_regexp, git_log, re.IGNORECASE)
-
-def extract_git_log(args):
-    """Extract git log of all merged commits"""
-    cmd = ['git',
-           '--git-dir=' + BASE_DIR + '/git/' + args.project + '.git',
-           'log', '--no-merges', args.commit + '^1..' + args.commit]
-    return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
-
-
-def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('hook')
-    #common
-    parser.add_argument('--change', default=None)
-    parser.add_argument('--change-url', default=None)
-    parser.add_argument('--project', default=None)
-    parser.add_argument('--branch', default=None)
-    parser.add_argument('--commit', default=None)
-    #change-merged
-    parser.add_argument('--submitter', default=None)
-    #patchset-created
-    parser.add_argument('--uploader', default=None)
-    parser.add_argument('--patchset', default=None)
-
-    args = parser.parse_args()
-
-    # Get git log
-    git_log = extract_git_log(args)
-
-    # Process doc_impacts found in git log
-    if docs_impacted(git_log):
-        process_impact(git_log, args)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/update_blueprint.py b/update_blueprint.py
deleted file mode 100755
index 9c18f1d..0000000
--- a/update_blueprint.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is designed to be called by a gerrit hook.  It searched new
-# patchsets for strings like "blueprint FOO" or "bp FOO" and updates
-# corresponding Launchpad blueprints with links back to the change.
-
-from launchpadlib.launchpad import Launchpad
-from launchpadlib.uris import LPNET_SERVICE_ROOT
-import os
-import argparse
-import re
-import subprocess
-
-import StringIO
-import ConfigParser
-import MySQLdb
-
-BASE_DIR = '/home/gerrit2/review_site'
-GERRIT_CACHE_DIR = os.path.expanduser(os.environ.get('GERRIT_CACHE_DIR',
-                                '~/.launchpadlib/cache'))
-GERRIT_CREDENTIALS = os.path.expanduser(os.environ.get('GERRIT_CREDENTIALS',
-                                '~/.launchpadlib/creds'))
-GERRIT_CONFIG = os.environ.get('GERRIT_CONFIG',
-                                 '/home/gerrit2/review_site/etc/gerrit.config')
-GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
-                                 '/home/gerrit2/review_site/etc/secure.config')
-SPEC_RE = re.compile(r'(blueprint|bp)\s*[#:]?\s*(\S+)', re.I)
-BODY_RE = re.compile(r'^\s+.*$')
-
-def get_broken_config(filename):
-    """ gerrit config ini files are broken and have leading tabs """
-    text = ""
-    with open(filename,"r") as conf:
-        for line in conf.readlines():
-            text = "%s%s" % (text, line.lstrip())
-
-    fp = StringIO.StringIO(text)
-    c=ConfigParser.ConfigParser()
-    c.readfp(fp)
-    return c
-
-GERRIT_CONFIG = get_broken_config(GERRIT_CONFIG)
-SECURE_CONFIG = get_broken_config(GERRIT_SECURE_CONFIG)
-DB_USER = GERRIT_CONFIG.get("database", "username")
-DB_PASS = SECURE_CONFIG.get("database","password")
-DB_DB = GERRIT_CONFIG.get("database","database")
-
-def update_spec(launchpad, project, name, subject, link, topic=None):
-    # For testing, if a project doesn't match openstack/foo, use
-    # the openstack-ci project instead.
-    group, project = project.split('/')
-    if group != 'openstack':
-        project = 'openstack-ci'
-
-    spec = launchpad.projects[project].getSpecification(name=name)
-    if not spec: return
-
-    if spec.whiteboard:
-        wb = spec.whiteboard.strip()
-    else:
-        wb = ''
-    changed = False
-    if topic:
-        topiclink = '%s/#q,topic:%s,n,z' % (link[:link.find('/',8)],
-                                            topic)
-        if topiclink not in wb:
-            wb += "\n\n\nGerrit topic: %(link)s" % dict(link=topiclink)
-            changed = True
-
-    if link not in wb:
-        wb += "\n\n\nAddressed by: %(link)s\n    %(subject)s\n" % dict(subject=subject,
-                                                                      link=link)
-        changed = True
-
-    if changed:
-        spec.whiteboard = wb
-        spec.lp_save()
-
-def find_specs(launchpad, dbconn, args):
-    git_log = subprocess.Popen(['git',
-                                '--git-dir=' + BASE_DIR + '/git/' + args.project + '.git',
-                                'log', '--no-merges',
-                                args.commit + '^1..' + args.commit],
-                               stdout=subprocess.PIPE).communicate()[0]
-
-    cur = dbconn.cursor()
-    cur.execute("select subject, topic from changes where change_key=%s", args.change)
-    subject, topic = cur.fetchone()
-    specs = set([m.group(2) for m in SPEC_RE.finditer(git_log)])
-
-    if topic:
-        topicspec = topic.split('/')[-1]
-        specs |= set([topicspec])
-
-    for spec in specs:
-        update_spec(launchpad, args.project, spec, subject,
-                    args.change_url, topic)
-
-def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('hook')
-    #common
-    parser.add_argument('--change', default=None)
-    parser.add_argument('--change-url', default=None)
-    parser.add_argument('--project', default=None)
-    parser.add_argument('--branch', default=None)
-    parser.add_argument('--commit', default=None)
-    #change-merged
-    parser.add_argument('--submitter', default=None)
-    # patchset-created
-    parser.add_argument('--uploader', default=None)
-    parser.add_argument('--patchset', default=None)
-
-    args = parser.parse_args()
-
-    launchpad = Launchpad.login_with('Gerrit User Sync', LPNET_SERVICE_ROOT,
-                                     GERRIT_CACHE_DIR,
-                                     credentials_file = GERRIT_CREDENTIALS,
-                                     version='devel')
-
-    conn = MySQLdb.connect(user = DB_USER, passwd = DB_PASS, db = DB_DB)
-
-    find_specs(launchpad, conn, args)
-
-if __name__ == '__main__':
-    main()
diff --git a/update_bug.py b/update_bug.py
deleted file mode 100755
index 72d1a46..0000000
--- a/update_bug.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This is designed to be called by a gerrit hook.  It searched new
-# patchsets for strings like "bug FOO" and updates corresponding Launchpad
-# bugs status.
-
-from launchpadlib.launchpad import Launchpad
-from launchpadlib.uris import LPNET_SERVICE_ROOT
-import os
-import argparse
-import re
-import subprocess
-
-
-BASE_DIR = '/home/gerrit2/review_site'
-GERRIT_CACHE_DIR = os.path.expanduser(os.environ.get('GERRIT_CACHE_DIR',
-                                '~/.launchpadlib/cache'))
-GERRIT_CREDENTIALS = os.path.expanduser(os.environ.get('GERRIT_CREDENTIALS',
-                                '~/.launchpadlib/creds'))
-
-
-def add_change_proposed_message(bugtask, change_url, project, branch):
-    subject = 'Fix proposed to %s (%s)' % (short_project(project), branch)
-    body = 'Fix proposed to branch: %s\nReview: %s' % (branch, change_url)
-    bugtask.bug.newMessage(subject=subject, content=body)
-
-
-def add_change_merged_message(bugtask, change_url, project, commit,
-                              submitter, branch, git_log):
-    subject = 'Fix merged to %s (%s)' % (short_project(project), branch)
-    git_url = 'http://github.com/%s/commit/%s' % (project, commit)
-    body = '''Reviewed:  %s
-Committed: %s
-Submitter: %s
-Branch:    %s\n''' % (change_url, git_url, submitter, branch)
-    body = body + '\n' + git_log
-    bugtask.bug.newMessage(subject=subject, content=body)
-
-
-def set_in_progress(bugtask, launchpad, uploader, change_url):
-    """Set bug In progress with assignee being the uploader"""
-
-    # Retrieve uploader from Launchpad. Use email as search key if
-    # provided, and only set if there is a clear match.
-    try:
-        searchkey = uploader[uploader.rindex("(") + 1:-1]
-    except ValueError:
-        searchkey = uploader
-    persons = launchpad.people.findPerson(text=searchkey)
-    if len(persons) == 1:
-        bugtask.assignee = persons[0]
-
-    bugtask.status = "In Progress"
-    bugtask.lp_save()
-
-
-def set_fix_committed(bugtask):
-    """Set bug fix committed"""
-
-    bugtask.status = "Fix Committed"
-    bugtask.lp_save()
-
-
-def set_fix_released(bugtask):
-    """Set bug fix released"""
-
-    bugtask.status = "Fix Released"
-    bugtask.lp_save()
-
-
-def release_fixcommitted(bugtask):
-    """Set bug FixReleased if it was FixCommitted"""
-
-    if bugtask.status == u'Fix Committed':
-        set_fix_released(bugtask)
-
-
-def tag_in_branchname(bugtask, branch):
-    """Tag bug with in-branch-name tag (if name is appropriate)"""
-
-    lp_bug = bugtask.bug
-    branch_name = branch.replace('/', '-')
-    if branch_name.replace('-', '').isalnum():
-        lp_bug.tags = lp_bug.tags + ["in-%s" % branch_name]
-        lp_bug.tags.append("in-%s" % branch_name)
-        lp_bug.lp_save()
-
-
-def short_project(full_project_name):
-    """Return the project part of the git repository name"""
-    return full_project_name.split('/')[-1]
-
-
-def git2lp(full_project_name):
-    """Convert Git repo name to Launchpad project"""
-    project_map = {
-        'openstack/openstack-ci-puppet': 'openstack-ci',
-        'openstack-ci/devstack-gate': 'openstack-ci',
-        'openstack-ci/gerrit': 'openstack-ci',
-        'openstack-ci/lodgeit': 'openstack-ci',
-        'openstack-ci/meetbot': 'openstack-ci',
-        }
-    return project_map.get(full_project_name, short_project(full_project_name))
-
-
-def is_direct_release(full_project_name):
-    """Test against a list of projects who directly release changes."""
-    return full_project_name in [
-        'openstack-ci/devstack-gate',
-        'openstack-ci/lodgeit',
-        'openstack-ci/meetbot',
-        'openstack-dev/devstack',
-        'openstack/openstack-ci',
-        'openstack/openstack-ci-puppet',
-        'openstack/openstack-manuals',
-        ]
-
-
-def process_bugtask(launchpad, bugtask, git_log, args):
-    """Apply changes to bugtask, based on hook / branch..."""
-
-    if args.hook == "change-merged":
-        if args.branch == 'master':
-            if is_direct_release(args.project):
-                set_fix_released(bugtask)
-            else:
-                set_fix_committed(bugtask)
-        elif args.branch == 'milestone-proposed':
-            release_fixcommitted(bugtask)
-        elif args.branch.startswith('stable/'):
-            series = args.branch[7:]
-            # Look for a related task matching the series
-            for reltask in bugtask.related_tasks:
-                if reltask.bug_target_name.endswith("/" + series):
-                    # Use fixcommitted if there is any
-                    set_fix_committed(reltask)
-                    break
-            else:
-                # Use tagging if there isn't any
-                tag_in_branchname(bugtask, args.branch)
-
-        add_change_merged_message(bugtask, args.change_url, args.project,
-                                  args.commit, args.submitter, args.branch,
-                                  git_log)
-
-    if args.hook == "patchset-created":
-        if args.branch == 'master':
-            set_in_progress(bugtask, launchpad, args.uploader, args.change_url)
-        elif args.branch.startswith('stable/'):
-            series = args.branch[7:]
-            for reltask in bugtask.related_tasks:
-                if reltask.bug_target_name.endswith("/" + series):
-                    set_in_progress(reltask, launchpad,
-                                    args.uploader, args.change_url)
-                    break
-
-        if args.patchset == '1':
-            add_change_proposed_message(bugtask, args.change_url,
-                                        args.project, args.branch)
-
-
-def find_bugs(launchpad, git_log, args):
-    """Find bugs referenced in the git log and return related bugtasks"""
-
-    bug_regexp = r'([Bb]ug|[Ll][Pp])[\s#:]*(\d+)'
-    tokens = re.split(bug_regexp, git_log)
-
-    # Extract unique bug tasks
-    bugtasks = {}
-    for token in tokens:
-        if re.match('^\d+$', token) and (token not in bugtasks):
-            try:
-                lp_bug = launchpad.bugs[token]
-                for lp_task in lp_bug.bug_tasks:
-                    if lp_task.bug_target_name == git2lp(args.project):
-                        bugtasks[token] = lp_task
-                        break
-            except KeyError:
-                # Unknown bug
-                pass
-
-    return bugtasks.values()
-
-
-def extract_git_log(args):
-    """Extract git log of all merged commits"""
-    cmd = ['git',
-           '--git-dir=' + BASE_DIR + '/git/' + args.project + '.git',
-           'log', '--no-merges', args.commit + '^1..' + args.commit]
-    return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
-
-
-def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument('hook')
-    #common
-    parser.add_argument('--change', default=None)
-    parser.add_argument('--change-url', default=None)
-    parser.add_argument('--project', default=None)
-    parser.add_argument('--branch', default=None)
-    parser.add_argument('--commit', default=None)
-    #change-merged
-    parser.add_argument('--submitter', default=None)
-    #patchset-created
-    parser.add_argument('--uploader', default=None)
-    parser.add_argument('--patchset', default=None)
-
-    args = parser.parse_args()
-
-    # Connect to Launchpad
-    launchpad = Launchpad.login_with('Gerrit User Sync', LPNET_SERVICE_ROOT,
-                                     GERRIT_CACHE_DIR,
-                                     credentials_file=GERRIT_CREDENTIALS,
-                                     version='devel')
-
-    # Get git log
-    git_log = extract_git_log(args)
-
-    # Process bugtasks found in git log
-    for bugtask in find_bugs(launchpad, git_log, args):
-        process_bugtask(launchpad, bugtask, git_log, args)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/update_cla_group.py b/update_cla_group.py
deleted file mode 100755
index d418cf0..0000000
--- a/update_cla_group.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /usr/bin/env python
-# Copyright (C) 2011 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# Add launchpad ids listed in the wiki CLA page to the CLA group in LP.
-
-import os
-import urllib
-import re
-
-from launchpadlib.launchpad import Launchpad
-from launchpadlib.uris import LPNET_SERVICE_ROOT
-
-DEBUG = False
-
-LP_CACHE_DIR = '~/.launchpadlib/cache'
-LP_CREDENTIALS = '~/.launchpadlib/creds'
-CONTRIBUTOR_RE = re.compile(r'.*?\|\|\s*(?P<name>.*?)\s*\|\|\s*(?P<login>.*?)\s*\|\|\s*(?P<trans>.*?)\s*\|\|.*?')
-LINK_RE = re.compile(r'\[\[.*\|\s*(?P<name>.*)\s*\]\]')
-
-for check_path in (os.path.dirname(LP_CACHE_DIR),
-                   os.path.dirname(LP_CREDENTIALS)):
-    if not os.path.exists(check_path):
-        os.makedirs(check_path)
-
-wiki_members = []
-for line in urllib.urlopen('http://wiki.openstack.org/Contributors?action=raw'):
-    m = CONTRIBUTOR_RE.match(line)
-    if m and m.group('login') and m.group('trans'):
-        login = m.group('login')
-        if login=="<#c0c0c0>'''Launchpad ID'''": continue
-        l = LINK_RE.match(login)
-        if l:
-            login = l.group('name')
-        wiki_members.append(login)
-
-launchpad = Launchpad.login_with('CLA Team Sync', LPNET_SERVICE_ROOT,
-                                 LP_CACHE_DIR,
-                                 credentials_file = LP_CREDENTIALS)
-
-lp_members = []
-
-team = launchpad.people['openstack-cla']
-for detail in team.members_details:
-    user = None
-    # detail.self_link ==
-    # 'https://api.launchpad.net/1.0/~team/+member/${username}'
-    login = detail.self_link.split('/')[-1]
-    status = detail.status
-    lp_members.append(login)
-
-for wm in wiki_members:
-    if wm not in lp_members:
-        print "Need to add %s to LP" % (wm)
-        try:
-            person = launchpad.people[wm]
-        except:
-            print 'Unable to find %s on LP'%wm
-            continue
-        status = team.addMember(person=person, status="Approved")
diff --git a/update_gerrit_users.py b/update_gerrit_users.py
deleted file mode 100755
index 15baaa9..0000000
--- a/update_gerrit_users.py
+++ /dev/null
@@ -1,409 +0,0 @@
-#! /usr/bin/env python
-# Copyright (C) 2011 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# Synchronize Gerrit users from Launchpad.
-
-import os
-import sys
-import fcntl
-import uuid
-import subprocess
-
-from datetime import datetime
-
-# There is a bug (810019) somewhere deep which causes pkg_resources
-# to bitch if it's imported after argparse. launchpadlib imports it,
-# so if we head it off at the pass, we can skip cronspam
-import pkg_resources
-
-import StringIO
-import ConfigParser
-import argparse
-import MySQLdb
-
-from launchpadlib.launchpad import Launchpad
-from launchpadlib.uris import LPNET_SERVICE_ROOT
-
-from openid.consumer import consumer
-from openid.cryptutil import randomString
-
-DEBUG = False
-
-# suppress pyflakes
-pkg_resources.get_supported_platform()
-
-pid_file = '/tmp/update_gerrit_users.pid'
-fp = open(pid_file, 'w')
-try:
-    fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
-except IOError:
-    # another instance is running
-    sys.exit(0)
-
-parser = argparse.ArgumentParser()
-parser.add_argument('user', help='The gerrit admin user')
-parser.add_argument('ssh_key', help='The gerrit admin SSH key file')
-parser.add_argument('site', help='The site in use (typically openstack or stackforge)')
-options = parser.parse_args()
-
-GERRIT_USER = options.user
-GERRIT_CONFIG = os.environ.get('GERRIT_CONFIG',
-                                 '/home/gerrit2/review_site/etc/gerrit.config')
-GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
-                                 '/home/gerrit2/review_site/etc/secure.config')
-GERRIT_SSH_KEY = options.ssh_key
-GERRIT_CACHE_DIR = os.path.expanduser(os.environ.get('GERRIT_CACHE_DIR',
-                                '~/.launchpadlib/cache'))
-GERRIT_CREDENTIALS = os.path.expanduser(os.environ.get('GERRIT_CREDENTIALS',
-                                '~/.launchpadlib/creds'))
-GERRIT_BACKUP_PATH = os.environ.get('GERRIT_BACKUP_PATH',
-                                '/home/gerrit2/dbupdates')
-
-for check_path in (os.path.dirname(GERRIT_CACHE_DIR),
-                   os.path.dirname(GERRIT_CREDENTIALS),
-                   GERRIT_BACKUP_PATH):
-  if not os.path.exists(check_path):
-    os.makedirs(check_path)
-
-def get_broken_config(filename):
-  """ gerrit config ini files are broken and have leading tabs """
-  text = ""
-  with open(filename,"r") as conf:
-    for line in conf.readlines():
-      text = "%s%s" % (text, line.lstrip())
-
-  fp = StringIO.StringIO(text)
-  c=ConfigParser.ConfigParser()
-  c.readfp(fp)
-  return c
-
-def get_type(in_type):
-  if in_type == "RSA":
-    return "ssh-rsa"
-  else:
-    return "ssh-dsa"
-
-gerrit_config = get_broken_config(GERRIT_CONFIG)
-secure_config = get_broken_config(GERRIT_SECURE_CONFIG)
-
-DB_USER = gerrit_config.get("database", "username")
-DB_PASS = secure_config.get("database","password")
-DB_DB = gerrit_config.get("database","database")
-
-db_backup_file = "%s.%s.sql" % (DB_DB, datetime.isoformat(datetime.now()))
-db_backup_path = os.path.join(GERRIT_BACKUP_PATH, db_backup_file)
-retval = os.system("mysqldump --opt -u%s -p%s %s | gzip -9 > %s.gz" %
-                     (DB_USER, DB_PASS, DB_DB, db_backup_path))
-if retval != 0:
-  print "Problem taking a db dump, aborting db update"
-  sys.exit(retval)
-
-conn = MySQLdb.connect(user = DB_USER, passwd = DB_PASS, db = DB_DB)
-cur = conn.cursor()
-
-
-launchpad = Launchpad.login_with('Gerrit User Sync', LPNET_SERVICE_ROOT,
-                                 GERRIT_CACHE_DIR,
-                                 credentials_file = GERRIT_CREDENTIALS)
-
-def get_sub_teams(team, have_teams):
-    for sub_team in launchpad.people[team].sub_teams:
-        if sub_team.name not in have_teams:
-           have_teams = get_sub_teams(sub_team.name, have_teams)
-    have_teams.append(team)
-    return have_teams
-
-
-teams_todo = get_sub_teams('openstack', [])
-
-users={}
-groups={}
-groups_in_groups={}
-group_implies_groups={}
-group_ids={}
-projects = subprocess.check_output(['/usr/bin/ssh', '-p', '29418',
-    '-i', GERRIT_SSH_KEY,
-    '-l', GERRIT_USER, 'localhost',
-    'gerrit', 'ls-projects']).split('\n')
-
-for team_todo in teams_todo:
-
-  team = launchpad.people[team_todo]
-  groups[team.name] = team.display_name
-
-  # Attempt to get nested group memberships. ~nova-core, for instance, is a
-  # member of ~nova, so membership in ~nova-core should imply membership in
-  # ~nova
-  group_in_group = groups_in_groups.get(team.name, {})
-  for subgroup in team.sub_teams:
-    group_in_group[subgroup.name] = 1
-  # We should now have a dictionary of the form {'nova': {'nova-core': 1}}
-  groups_in_groups[team.name] = group_in_group
-
-  for detail in team.members_details:
-
-    user = None
-
-    # detail.self_link ==
-    # 'https://api.launchpad.net/1.0/~team/+member/${username}'
-    login = detail.self_link.split('/')[-1]
-
-    if users.has_key(login):
-      user = users[login]
-    else:
-
-      user = dict(add_groups=[])
-
-    status = detail.status
-    if (status == "Approved" or status == "Administrator"):
-      user['add_groups'].append(team.name)
-    users[login] = user
-
-# If we picked up subgroups that were not in our original list of groups
-# make sure they get added
-for (supergroup, subgroups) in groups_in_groups.items():
-  for group in subgroups.keys():
-    if group not in groups.keys():
-      groups[group] = None
-
-# account_groups
-# groups is a dict of team name to team display name
-# here, for every group we have in that dict, we're building another dict of
-# group_name to group_id - and if the database doesn't already have the
-# group, we're adding it
-for (group_name, group_display_name) in groups.items():
-  if cur.execute("select group_id from account_groups where name = %s",
-                 group_name):
-    group_ids[group_name] = cur.fetchall()[0][0]
-  else:
-    cur.execute("""insert into account_group_id (s) values (NULL)""");
-    cur.execute("select max(s) from account_group_id")
-    group_id = cur.fetchall()[0][0]
-
-    # Match the 40-char 'uuid' that java is producing
-    group_uuid = uuid.uuid4()
-    second_uuid = uuid.uuid4()
-    full_uuid = "%s%s" % (group_uuid.hex, second_uuid.hex[:8])
-
-    cur.execute("""insert into account_groups
-                   (group_id, group_type, owner_group_id,
-                    name, description, group_uuid)
-                   values
-                   (%s, 'INTERNAL', 1, %s, %s, %s)""",
-                (group_id, group_name, group_display_name, full_uuid))
-    cur.execute("""insert into account_group_names (group_id, name) values
-    (%s, %s)""",
-    (group_id, group_name))
-
-    group_ids[group_name] = group_id
-
-# account_group_includes
-# groups_in_groups should be a dict of dicts, where the key is the larger
-# group and the inner dict is a list of groups that are members of the
-# larger group. So {'nova': {'nova-core': 1}}
-for (group_name, subgroups) in groups_in_groups.items():
-  for subgroup_name in subgroups.keys():
-    try:
-      cur.execute("""insert into account_group_includes
-                       (group_id, include_id)
-                      values (%s, %s)""",
-                  (group_ids[group_name], group_ids[subgroup_name]))
-    except MySQLdb.IntegrityError:
-      pass
-
-# Make a list of implied group membership
-# building a list which is the opposite of groups_in_group. Here
-# group_implies_groups is a dict keyed by group_id containing a list of
-# group_ids of implied membership. SO: if nova is 1 and nova-core is 2:
-# {'2': [1]}
-for group_id in group_ids.values():
-    total_groups = []
-    groups_todo = [group_id]
-    while len(groups_todo) > 0:
-        current_group = groups_todo.pop()
-        total_groups.append(current_group)
-        cur.execute("""select group_id from account_group_includes
-                        where include_id = %s""", (current_group))
-        for row in cur.fetchall():
-            if row[0] != 1 and row[0] not in total_groups:
-                groups_todo.append(row[0])
-    group_implies_groups[group_id] = total_groups
-
-if DEBUG:
-    def get_group_name(in_group_id):
-      for (group_name, group_id) in group_ids.items():
-        if group_id == in_group_id:
-          return group_name
-
-    print "groups in groups"
-    for (k,v) in groups_in_groups.items():
-      print k, v
-
-    print "group_imples_groups"
-    for (k, v) in group_implies_groups.items():
-      print get_group_name(k)
-      new_groups=[]
-      for val in v:
-        new_groups.append(get_group_name(val))
-      print "\t", new_groups
-
-for (username, user_details) in users.items():
-  member = launchpad.people[username]
-  # accounts
-  account_id = None
-  if cur.execute("""select account_id from account_external_ids where
-    external_id in (%s)""", ("username:%s" % username)):
-    account_id = cur.fetchall()[0][0]
-    # We have this bad boy - all we need to do is update his group membership
-
-  else:
-    # We need details
-    if not member.is_team:
-
-      openid_consumer = consumer.Consumer(dict(id=randomString(16, '0123456789abcdef')), None)
-      openid_request = openid_consumer.begin("https://launchpad.net/~%s" % member.name)
-      user_details['openid_external_id'] = openid_request.endpoint.getLocalID()
-
-      # Handle username change
-      if cur.execute("""select account_id from account_external_ids where
-        external_id in (%s)""", user_details['openid_external_id']):
-        account_id = cur.fetchall()[0][0]
-        cur.execute("""update account_external_ids
-                          set external_id=%s
-                        where external_id like 'username%%'
-                          and account_id = %s""",
-                     ('username:%s' % username, account_id))
-      else:
-        email = None
-        try:
-          email = member.preferred_email_address.email
-        except ValueError:
-          pass
-        user_details['email'] = email
-
-
-        cur.execute("""insert into account_id (s) values (NULL)""");
-        cur.execute("select max(s) from account_id")
-        account_id = cur.fetchall()[0][0]
-
-        cur.execute("""insert into accounts (account_id, full_name, preferred_email) values
-        (%s, %s, %s)""", (account_id, username, user_details['email']))
-
-        # account_external_ids
-        ## external_id
-        if not cur.execute("""select account_id from account_external_ids
-                              where account_id = %s and external_id = %s""",
-                           (account_id, user_details['openid_external_id'])):
-          cur.execute("""insert into account_external_ids
-                         (account_id, email_address, external_id)
-                         values (%s, %s, %s)""",
-                     (account_id, user_details['email'], user_details['openid_external_id']))
-        if not cur.execute("""select account_id from account_external_ids
-                              where account_id = %s and external_id = %s""",
-                           (account_id, "username:%s" % username)):
-          cur.execute("""insert into account_external_ids
-                         (account_id, external_id) values (%s, %s)""",
-                      (account_id, "username:%s" % username))
-
-        if user_details.get('email', None) is not None:
-          if not cur.execute("""select account_id from account_external_ids
-                                where account_id = %s and external_id = %s""",
-                             (account_id, "mailto:%s" % user_details['email'])):
-            cur.execute("""insert into account_external_ids
-                           (account_id, email_address, external_id)
-                           values (%s, %s, %s)""",
-                        (account_id, user_details['email'], "mailto:%s" %
-                        user_details['email']))
-
-  if account_id is not None:
-    # account_ssh_keys
-    user_details['ssh_keys'] = ["%s %s %s" % (get_type(key.keytype), key.keytext, key.comment) for key in member.sshkeys]
-
-    for key in user_details['ssh_keys']:
-
-      cur.execute("""select ssh_public_key from account_ssh_keys where
-        account_id = %s""", account_id)
-      db_keys = [r[0].strip() for r in cur.fetchall()]
-      if key.strip() not in db_keys:
-
-        cur.execute("""select max(seq)+1 from account_ssh_keys
-                              where account_id = %s""", account_id)
-        seq = cur.fetchall()[0][0]
-        if seq is None:
-          seq = 1
-        cur.execute("""insert into account_ssh_keys
-                        (ssh_public_key, valid, account_id, seq)
-                        values
-                        (%s, 'Y', %s, %s)""",
-                        (key.strip(), account_id, seq))
-
-    # account_group_members
-    # user_details['add_groups'] is a list of group names for which the
-    # user is either "Approved" or "Administrator"
-
-    groups_to_add = []
-    groups_to_watch = {}
-    groups_to_rm = {}
-
-    for group in user_details['add_groups']:
-      # if you are in the group nova-core, that should also put you in nova
-      add_groups = group_implies_groups[group_ids[group]]
-      add_groups.append(group_ids[group])
-      for add_group in add_groups:
-        if add_group not in groups_to_add:
-          groups_to_add.append(add_group)
-      # We only want to add watches for direct project membership groups
-      groups_to_watch[group_ids[group]] = group
-
-    # groups_to_add is now the full list of all groups we think the user
-    # should belong to. we want to limit the users groups to this list
-    for group in groups:
-      if group_ids[group] not in groups_to_add:
-        if group not in groups_to_rm.values():
-          groups_to_rm[group_ids[group]] = group
-
-    for group_id in groups_to_add:
-      if not cur.execute("""select account_id from account_group_members
-                            where account_id = %s and group_id = %s""",
-                         (account_id, group_id)):
-        # The current user does not exist in the group. Add it.
-        cur.execute("""insert into account_group_members
-                         (account_id, group_id)
-                       values (%s, %s)""", (account_id, group_id))
-        os_project_name = groups_to_watch.get(group_id, None)
-        if os_project_name is not None:
-          if os_project_name.endswith("-core"):
-              os_project_name = os_project_name[:-5]
-          os_project_name = "{site}/{project}".format(site=options.site, project=os_project_name)
-          if os_project_name in projects:
-            if not cur.execute("""select account_id
-                                   from account_project_watches
-                                  where account_id = %s
-                                    and project_name = %s""",
-                                 (account_id, os_project_name)):
-                cur.execute("""insert into account_project_watches
-                               VALUES
-                               ("Y", "N", "N", %s, %s, "*")""",
-                               (account_id, os_project_name))
-
-    for (group_id, group_name) in groups_to_rm.items():
-      cur.execute("""delete from account_group_members
-                     where account_id = %s and group_id = %s""",
-                  (account_id, group_id))
-
-os.system("ssh -i %s -p29418 %s@localhost gerrit flush-caches" %
-          (GERRIT_SSH_KEY, GERRIT_USER))
-
-conn.commit()
diff --git a/update_users.py b/update_users.py
deleted file mode 100644
index b40fbfd..0000000
--- a/update_users.py
+++ /dev/null
@@ -1,431 +0,0 @@
-#! /usr/bin/env python
-# Copyright (C) 2012 OpenStack, LLC.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# Synchronize Gerrit users from Launchpad.
-# TODO items:
-# 1. add a temporary (instance level) object store for the launchpad class
-# 2. split out the two classes into separate files to be used as a library
-
-import os
-import sys
-import ConfigParser
-import StringIO
-import paramiko
-import json
-import logging
-import uuid
-from launchpadlib.launchpad import Launchpad
-from launchpadlib.uris import LPNET_SERVICE_ROOT
-
-from datetime import datetime
-
-from openid.consumer import consumer
-from openid.cryptutil import randomString
-
-GERRIT_USER = os.environ.get('GERRIT_USER', 'launchpadsync')
-GERRIT_CONFIG = os.environ.get('GERRIT_CONFIG',
-                                 '/home/gerrit2/review_site/etc/gerrit.config')
-GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
-                                 '/home/gerrit2/review_site/etc/secure.config')
-GERRIT_SSH_KEY = os.environ.get('GERRIT_SSH_KEY',
-                                 '/home/gerrit2/.ssh/launchpadsync_rsa')
-GERRIT_CACHE_DIR = os.path.expanduser(os.environ.get('GERRIT_CACHE_DIR',
-                                '~/.launchpadlib/cache'))
-GERRIT_CREDENTIALS = os.path.expanduser(os.environ.get('GERRIT_CREDENTIALS',
-                                '~/.launchpadlib/creds'))
-GERRIT_BACKUP_PATH = os.environ.get('GERRIT_BACKUP_PATH',
-                                '/home/gerrit2/dbupdates')
-
-logging.basicConfig(format='%(asctime)-6s: %(name)s - %(levelname)s - %(message)s', filename='/var/log/gerrit/update_users.log')
-logger= logging.getLogger('update_users')
-logger.setLevel(logging.INFO)
-
-for check_path in (os.path.dirname(GERRIT_CACHE_DIR),
-                   os.path.dirname(GERRIT_CREDENTIALS),
-                   GERRIT_BACKUP_PATH):
-  if not os.path.exists(check_path):
-    os.makedirs(check_path)
-
-def get_broken_config(filename):
-  """ gerrit config ini files are broken and have leading tabs """
-  text = ""
-  with open(filename,"r") as conf:
-    for line in conf.readlines():
-      text = "%s%s" % (text, line.lstrip())
-
-  fp = StringIO.StringIO(text)
-  c=ConfigParser.ConfigParser()
-  c.readfp(fp)
-  return c
-
-gerrit_config = get_broken_config(GERRIT_CONFIG)
-secure_config = get_broken_config(GERRIT_SECURE_CONFIG)
-
-DB_USER = gerrit_config.get("database", "username")
-DB_PASS = secure_config.get("database","password")
-DB_DB = gerrit_config.get("database","database")
-
-def make_db_backup():
-  db_backup_file = "%s.%s.sql" % (DB_DB, datetime.isoformat(datetime.now()))
-  db_backup_path = os.path.join(GERRIT_BACKUP_PATH, db_backup_file)
-  retval = os.system("mysqldump --opt -u%s -p%s %s | gzip -9 > %s.gz" %
-                       (DB_USER, DB_PASS, DB_DB, db_backup_path))
-  if retval != 0:
-    logger.error("Problem taking a db dump, aborting db update")
-    sys.exit(retval)
-
-class LaunchpadAction(object):
-  def __init__(self):
-    logger.info('Connecting to Launchpad')
-    self.launchpad= Launchpad.login_with('Gerrit User Sync', LPNET_SERVICE_ROOT,
-                                 GERRIT_CACHE_DIR,
-                                 credentials_file = GERRIT_CREDENTIALS)
-
-    logger.info('Getting Launchpad teams')
-    self.lp_teams= self.get_all_sub_teams('openstack', [])
-
-  def get_all_sub_teams(self, team, have_teams):
-    for sub_team in self.launchpad.people[team].sub_teams:
-      if sub_team.name not in have_teams:
-         have_teams = self.get_all_sub_teams(sub_team.name, have_teams)
-    have_teams.append(team)
-    return have_teams
-
-  def get_sub_teams(self, team):
-    sub_teams= []
-    for sub_team in self.launchpad.people[team].sub_teams:
-      sub_teams.append(sub_team.name)
-    return sub_teams
-
-  def get_teams(self):
-    return self.lp_teams
-
-  def get_all_users(self):
-    logger.info('Getting Launchpad users')
-    users= []
-    for team in self.lp_teams:
-      for detail in self.launchpad.people[team].members_details:
-        if (detail.status == 'Approved' or detail.status == 'Administrator'):
-          name= detail.self_link.split('/')[-1]
-          if ((users.count(name) == 0) and (name not in self.lp_teams)):
-            users.append(name)
-    return users
-
-  def get_user_data(self, user):
-    return self.launchpad.people[user]
-
-  def get_team_members(self, team, gerrit):
-    users= []
-    for detail in self.launchpad.people[team].members_details:
-      if (detail.status == 'Approved' or detail.status == 'Administrator'):
-        name= detail.self_link.split('/')[-1]
-        # if we found a subteam
-        if name in self.lp_teams:
-          # check subteam for implied subteams
-          for implied_group in gerrit.get_implied_groups(name):
-            if implied_group in self.lp_teams:
-              users.extend(self.get_team_members(implied_group, gerrit))
-          users.extend(self.get_team_members(name, gerrit))
-          continue
-        users.append(name)
-    # check team for implied teams
-    for implied_group in gerrit.get_implied_groups(team):
-      if implied_group in self.lp_teams:
-        users.extend(self.get_team_members(implied_group, gerrit))
-    # filter out dupes
-    users= list(set(users))
-    return users
-
-  def get_team_watches(self, team):
-    users= []
-    for detail in self.launchpad.people[team].members_details:
-      if (detail.status == 'Approved' or detail.status == 'Administrator'):
-        name= detail.self_link.split('/')[-1]
-        if name in self.lp_teams:
-          continue
-        if users.count(name) == 0:
-          users.append(name)
-    return users
-
-  def get_team_display_name(self, team):
-    team_data = self.launchpad.people[team]
-    return team_data.display_name
-
-class GerritAction(object):
-  def __init__(self):
-    logger.info('Connecting to Gerrit')
-    self.ssh= paramiko.SSHClient()
-    self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-    self.ssh.connect('localhost', username=GERRIT_USER, port=29418, key_filename=GERRIT_SSH_KEY)
-
-  def cleanup(self):
-    logger.info('Closing connection to Gerrit')
-    self.ssh.close()
-
-  def run_query(self, query):
-    command= 'gerrit gsql --format JSON -c "{0}"'.format(query)
-    stdin, stdout, stderr= self.ssh.exec_command(command)
-#   trying to get stdout return code or stderr can hang with large result sets
-#    for line in stderr:
-#      logger.error(line)
-    return stdout
-
-  def get_groups(self):
-    logger.info('Getting Gerrit groups')
-    groups= []
-    query= "select name from account_groups"
-    stdout= self.run_query(query)
-    for line in stdout:
-      row= json.loads(line)
-      if row['type'] == 'row':
-        group= row['columns']['name']
-        groups.append(group)
-    return groups
-
-  def get_users(self):
-    logger.info('Getting Gerrit users')
-    users= []
-    query= "select external_id from account_external_ids"
-    stdout= self.run_query(query)
-    for line in stdout:
-      row= json.loads(line)
-      if row['type'] == 'row':
-        user= row['columns']['external_id'].replace('username:','')
-        users.append(user)
-    return users
-
-  def get_group_id(self, group_name):
-    query= "select group_id from account_groups where name='{0}'".format(group_name)
-    stdout= self.run_query(query)
-    line= stdout.readline()
-    row= json.loads(line)
-    if row['type'] == 'row':
-      return row['columns']['group_id']
-    else:
-      return 0
-
-  def get_user_id(self, user_name):
-    query= "select account_id from account_external_ids where external_id='username:{0}'".format(user_name)
-    stdout= self.run_query(query)
-    line= stdout.readline()
-    row= json.loads(line)
-    return row['columns']['account_id']
-
-  def get_users_from_group(self, group_name):
-    logger.info('Getting Gerrit users from group %s', group_name)
-    users= []
-    gid= self.get_group_id(group_name)
-
-    query= "select external_id from account_external_ids join account_group_members on account_group_members.account_id=account_external_ids.account_id where account_group_members.group_id={0} and external_id like 'username%%'".format(gid)
-    stdout= self.run_query(query)
-    for line in stdout:
-      row= json.loads(line)
-      if row['type'] == 'row':
-        user= row['columns']['external_id'].replace('username:','')
-        users.append(user)
-    return users
-
-  def get_users_from_watches(self, group_name):
-    logger.info('Getting Gerrit users from watch list %s', group_name)
-    users= []
-    if group_name.endswith("-core"):
-      group_name = group_name[:-5]
-    group_name = "openstack/{0}".format(group_name)
-
-    query= "select external_id from account_external_ids join account_project_watches on account_project_watches.account_id=account_external_ids.account_id where account_project_watches.project_name like '{0}' and external_id like 'username%%'".format(group_name)
-    stdout= self.run_query(query)
-    for line in stdout:
-      row= json.loads(line)
-      if row['type'] == 'row':
-        user= row['columns']['external_id'].replace('username:','')
-        users.append(user)
-    return users
-
-
-  def get_implied_groups(self, group_name):
-    gid= self.get_group_id(group_name)
-    groups= []
-    query= "select name from account_groups join account_group_includes on account_group_includes.include_id=account_groups.group_id where account_group_includes.group_id={0}".format(gid)
-    stdout= self.run_query(query)
-    for line in stdout:
-      row= json.loads(line)
-      if row['type'] == 'row':
-        group= row['columns']['name']
-        groups.append(group)
-    return groups
-
-  def add_group(self, group_name, group_display_name):
-    logger.info('New group %s (%s)', group_display_name, group)
-    query= "insert into account_group_id (s) values (NULL)"
-    stdout= self.run_query(query)
-    row= json.loads(stdout.readline())
-    if row['rowCount'] is not 1:
-      print "Could not get a new account group ID"
-      raise
-    query= "select max(s) from account_group_id"
-    stdout= self.run_query(query)
-    row= json.loads(stdout.readline())
-    gid= row['columns']['max(s)']
-    full_uuid= "{0}{1}".format(uuid.uuid4().hex, uuid.uuid4().hex[:8])
-    query= "insert into account_groups (group_id, group_type, owner_group_id, name, description, group_uuid) values ({0}, 'INTERNAL', 1, '{1}', '{2}', '{3}')". format(gid, group_name, group_display_name, full_uuid)
-    self.run_query(query)
-    query= "insert into account_group_names (group_id, name) values ({0}, '{1}')".format(gid, group_name)
-    self.run_query(query)
-
-  def add_user(self, user_name, user_data):
-    logger.info("Adding Gerrit user %s", user_name)
-    openid_consumer = consumer.Consumer(dict(id=randomString(16, '0123456789abcdef')), None)
-    openid_request = openid_consumer.begin("https://launchpad.net/~%s" % user_data.name)
-    user_openid_external_id = openid_request.endpoint.getLocalID()
-    query= "select account_id from account_external_ids where external_id in ('{0}')".format(user_openid_external_id)
-    stdout= self.run_query(query)
-    row= json.loads(stdout.readline())
-    if row['type'] == 'row':
-      # we have a result so this is an updated user name
-      account_id= row['columns']['account_id']
-      query= "update account_external_ids set external_id='{0}' where external_id like 'username%%' and account_id = {1}".format('username:%s' % user_name, account_id)
-      self.run_query(query)
-    else:
-      # we really do have a new user
-      user_ssh_keys= ["%s %s %s" % ('ssh-%s' % key.keytype.lower(), key.keytext, key.comment) for key in user_data.sshkeys]
-      user_email= None
-      try:
-        user_email = user_data.preferred_email_address.email
-      except ValueError:
-        pass
-      query= "insert into account_id (s) values (NULL)"
-      self.run_query(query)
-      query= "select max(s) from account_id"
-      stdout= self.run_query(query)
-      row= json.loads(stdout.readline())
-      uid= row['columns']['max(s)']
-      query= "insert into accounts (account_id, full_name, preferred_email) values ({0}, '{1}', '{2}')".format(uid, user_name, user_email)
-      self.run_query(query)
-      keyno= 1
-      for key in user_ssh_keys:
-        query= "insert into account_ssh_keys (ssh_public_key, valid, account_id, seq) values ('{0}', 'Y', {1}, {2})".format(key.strip(), uid, keyno)
-        self.run_query(query)
-        keyno = keyno + 1
-      query= "insert into account_external_ids (account_id, email_address, external_id) values ({0}, '{1}', '{2}')".format(uid, user_email, user_openid_external_id)
-      self.run_query(query)
-      query= "insert into account_external_ids (account_id, external_id) values ({0}, '{1}')".format(uid, "username:%s" % user_name)
-      self.run_query(query)
-      if user_email is not None:
-        query= "insert into account_external_ids (account_id, email_address, external_id) values ({0}. '{1}', '{2}')".format(uid, user_email, "mailto:%s" % user_email)
-    return None
-
-  def add_user_to_group(self, user_name, group_name):
-    logger.info("Adding Gerrit user %s to group %s", user_name, group_name)
-    uid= self.get_user_id(user_name)
-    gid= self.get_group_id(group_name)
-    if gid is 0:
-      print "Trying to add user {0} to non-existent group {1}".format(user_name, group_name)
-      raise
-    query= "insert into account_group_members (account_id, group_id) values ({0}, {1})".format(uid, gid)
-    self.run_query(query)
-
-  def add_user_to_watch(self, user_name, group_name):
-    logger.info("Adding Gerrit user %s to watch group %s", user_name, group_name)
-    uid= self.get_user_id(user_name)
-    if group_name.endswith("-core"):
-      group_name = group_name[:-5]
-    group_name = "openstack/{0}".format(group_name)
-    query= "insert into account_project_watches VALUES ('Y', 'N', 'N', {0}, '{1}', '*')". format(uid, group_name)
-    self.run_query(query)
-
-
-  def del_user_from_group(self, user_name, group_name):
-    logger.info("Deleting Gerrit user %s from group %s", user_name, group_name)
-    uid= self.get_user_id(user_name)
-    gid= self.get_group_id(group_name)
-    query= "delete from account_group_members where account_id = {0} and group_id = {1}".format(uid, gid)
-    self.run_query(query)
-    if group_name.endswith("-core"):
-      group_name = group_name[:-5]
-    group_name= "openstack/{0}".format(group_name)
-    query= "delete from account_project_watches where account_id = {0} and project_name= '{1}'".format(uid, group_name)
-    self.run_query(query)
-
-  def rebuild_sub_groups(self, group, sub_groups):
-    gid= self.get_group_id(group)
-    for sub_group in sub_groups:
-      sgid= self.get_group_id(sub_group)
-      query= "select group_id from account_group_includes where group_id={0} and include_id={1}".format(gid, sgid)
-      stdout= self.run_query(query)
-      row= json.loads(stdout.readline())
-      if row['type'] != 'row':
-        logger.info('Adding implied group %s to group %s', group, sub_group)
-        query= "insert into account_group_includes (group_id, include_id) values ({0}, {1})".format(gid, sgid)
-        self.run_query(query)
-
-
-# Actual work starts here!
-
-lp= LaunchpadAction()
-gerrit= GerritAction()
-
-logger.info('Making DB backup')
-make_db_backup()
-
-logger.info('Starting group reconcile')
-lp_groups= lp.get_teams()
-gerrit_groups= gerrit.get_groups()
-
-group_diff= filter(lambda a: a not in gerrit_groups, lp_groups)
-for group in group_diff:
-  group_display_name= lp.get_team_display_name(group)
-  gerrit.add_group(group, group_display_name)
-
-for group in lp_groups:
-  sub_group= lp.get_sub_teams(group)
-  if sub_group:
-    gerrit.rebuild_sub_groups(group, sub_group)
-
-logger.info('End group reconcile')
-
-logger.info('Starting user reconcile')
-lp_users= lp.get_all_users()
-gerrit_users= gerrit.get_users()
-
-user_diff= filter(lambda a: a not in gerrit_users, lp_users)
-for user in user_diff:
-  gerrit.add_user(user, lp.get_user_data(user))
-
-logger.info('End user reconcile')
-
-logger.info('Starting user to group reconcile')
-lp_groups= lp.get_teams()
-for group in lp_groups:
-  # First find users to attach to groups
-  gerrit_group_users= gerrit.get_users_from_group(group)
-  lp_group_users= lp.get_team_members(group, gerrit)
-
-  group_diff= filter(lambda a: a not in gerrit_group_users, lp_group_users)
-  for user in group_diff:
-    gerrit.add_user_to_group(user, group)
-  # Second find users to attach to watches
-  lp_group_watches= lp.get_team_watches(group)
-  gerrit_group_watches= gerrit.get_users_from_watches(group)
-  group_diff= filter(lambda a: a not in gerrit_group_watches, lp_group_watches)
-  for user in group_diff:
-    gerrit.add_user_to_watch(user, group)
-  # Third find users to remove from groups/watches
-  group_diff= filter(lambda a: a not in lp_group_users, gerrit_group_users)
-  for user in group_diff:
-    gerrit.del_user_from_group(user, group)
-
-logger.info('Ending user to group reconcile')
-
-gerrit.cleanup()
