blob: 108f08107b9dcf2efc5cfd7ca46fae0337f9e20a [file] [log] [blame]
# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script for administering the Continuous Integration Database."""
import logging
import os
from chromite.lib import cidb
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import git
MIGRATE = "migrate"
WIPE = "wipe"
COMMANDS = [MIGRATE, WIPE]
def GetParser():
"""Creates the argparse parser."""
parser = commandline.ArgumentParser(description=__doc__)
# Put options that control the mode of script into mutually exclusive group.
parser.add_argument(
"command",
action="store",
choices=COMMANDS,
help="The action to execute.",
)
parser.add_argument(
"cred_dir",
action="store",
metavar="CIDB_CREDENTIALS_DIR",
help="Database credentials directory with certificates "
"and other connection information.",
)
parser.add_argument(
"--migrate-version",
action="store",
default=None,
help="Maximum schema version to migrate to.",
)
return parser
def main(argv):
parser = GetParser()
options = parser.parse_args(argv)
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
# Check that we have no uncommitted files, and that our checkout's HEAD is
# contained in a remote branch. This is to ensure that we don't accidentally
# run uncommitted migrations.
uncommitted_files = git.RunGit(os.getcwd(), ["status", "-s"]).stdout
if uncommitted_files:
cros_build_lib.Die("You appear to have uncommitted files. Aborting!")
remote_branches = git.RunGit(
os.getcwd(), ["branch", "-r", "--contains"]
).stdout
if not remote_branches:
cros_build_lib.Die(
"You appear to be on a local branch of chromite. Aborting!"
)
if options.command == MIGRATE:
positive_confirmation = "please modify my database"
warn = (
"This option will apply schema changes to your existing database. "
"You should not run this against the production database unless "
"your changes are thoroughly tested, and those tests included "
"in cidb_integration_test.py (including tests that old data is "
"sanely migrated forward). Database corruption could otherwise "
'result. Are you sure you want to proceed? If so, type "%s" '
"now.\n"
) % positive_confirmation
elif options.command == WIPE:
positive_confirmation = "please delete my data"
warn = (
"This operation will wipe (i.e. DELETE!) the entire contents of "
"the database pointed at by %s. Are you sure you want to proceed? "
'If so, type "%s" now.\n'
) % (os.path.join(options.cred_dir, "host.txt"), positive_confirmation)
else:
cros_build_lib.Die("No command or unsupported command. Exiting.")
print(warn)
conf_string = input("(%s)?: " % positive_confirmation)
if conf_string != positive_confirmation:
cros_build_lib.Die("You changed your mind. Aborting.")
if options.command == MIGRATE:
print("OK, applying migrations...")
db = cidb.CIDBConnection(options.cred_dir)
db.ApplySchemaMigrations(maxVersion=options.migrate_version)
elif options.command == WIPE:
print("OK, wiping database...")
db = cidb.CIDBConnection(options.cred_dir)
db.DropDatabase()
print("Done.")