Maintain launchpad id's in migration and manage autoincrement.

This patch extracts the launchpad ID during migration, and uses it
as the Story ID in StoryBoard. In order to make sure that we don't
end up in ID conflicts with StoryBoard's autoincrement, and MySQL
will not allow auto_increment to be set to anything lower than
the largest used ID, I've also provided a commandline mechanism
to set the auto-increment value directly during import. This allows
the user to "make room" for launchpad stories.

Change-Id: I36c542c7ecad7161cd1f3570b291c3500c4b2dff
This commit is contained in:
Michael Krotscheck 2014-09-24 11:24:41 -07:00
parent 8263abafe8
commit cfaebb4999
2 changed files with 33 additions and 6 deletions

View File

@ -14,6 +14,7 @@
from oslo.config import cfg
from storyboard.db.api import base as db_api
from storyboard.migrate.launchpad.loader import LaunchpadLoader
from storyboard.openstack.common import log
@ -26,7 +27,10 @@ IMPORT_OPTS = [
help="The local destination project for the remote stories."),
cfg.StrOpt("origin",
default="launchpad",
help="The origin system from which to import.")
help="The origin system from which to import."),
cfg.IntOpt("auto-increment",
default=None,
help="Optionally set the auto-increment on the stories table.")
]
CONF = cfg.CONF
@ -38,6 +42,17 @@ def main():
CONF.register_cli_opts(IMPORT_OPTS)
CONF(project='storyboard')
# If the user requested an autoincrement value, set that before we start
# importing things. Note that mysql will automatically set the
# autoincrement to the next-available id equal to or larger than the
# requested one.
auto_increment = CONF.auto_increment
if auto_increment:
print 'Setting stories.AUTO_INCREMENT to %d' % (auto_increment,)
session = db_api.get_session()
session.execute('ALTER TABLE stories AUTO_INCREMENT = %d;'
% (auto_increment,))
if CONF.origin is 'launchpad':
loader = LaunchpadLoader(CONF.from_project, CONF.to_project)
loader.run()

View File

@ -13,6 +13,7 @@
# under the License.
import json
import re
import sys
from openid.consumer import consumer
@ -157,7 +158,17 @@ class LaunchpadWriter(object):
else:
updated_at = None
print "Importing %s" % (bug.self_link)
# Extract the launchpad ID from the self link.
# example url: https://api.launchpad.net/1.0/bugs/1057477
url_match = re.search("([0-9]+)$", str(bug.self_link))
if not url_match:
print 'ERROR: Unable to extract launchpad ID from %s.' \
% (bug.self_link,)
print 'ERROR: Please file a ticket.'
return
launchpad_id = int(url_match.groups()[0])
print "Importing %s" % (bug.self_link,)
# If the title is too long, prepend it to the description and
# truncate it.
@ -169,6 +180,7 @@ class LaunchpadWriter(object):
description = bug.title + '\n\n' + description
story = db_api.entity_create(Story, {
'id': launchpad_id,
'description': description,
'created_at': created_at,
'creator': owner,
@ -182,7 +194,7 @@ class LaunchpadWriter(object):
'title': title,
'assignee_id': assignee.id if assignee else None,
'project_id': self.project.id,
'story_id': story.id,
'story_id': launchpad_id,
'created_at': created_at,
'updated_at': updated_at,
'priority': priority,
@ -192,7 +204,7 @@ class LaunchpadWriter(object):
# Create the creation event for the story manually, so we don't trigger
# event notifications.
db_api.entity_create(TimeLineEvent, {
'story_id': story.id,
'story_id': launchpad_id,
'author_id': owner.id,
'event_type': event_types.STORY_CREATED,
'created_at': created_at
@ -200,7 +212,7 @@ class LaunchpadWriter(object):
# Create the creation event for the task.
db_api.entity_create(TimeLineEvent, {
'story_id': story.id,
'story_id': launchpad_id,
'author_id': owner.id,
'event_type': event_types.TASK_CREATED,
'created_at': created_at,
@ -223,7 +235,7 @@ class LaunchpadWriter(object):
})
db_api.entity_create(TimeLineEvent, {
'story_id': story.id,
'story_id': launchpad_id,
'author_id': message_owner.id,
'event_type': event_types.USER_COMMENT,
'comment_id': comment.id,