Merge lp:~milo/linaro-patchmetrics/user-migration into lp:linaro-patchmetrics

Proposed by Milo Casagrande
Status: Merged
Merged at revision: 393
Proposed branch: lp:~milo/linaro-patchmetrics/user-migration
Merge into: lp:linaro-patchmetrics
Diff against target: 74 lines (+70/-0)
1 file modified
apps/patchmetrics/bin/migrate-linaro-users.py (+70/-0)
To merge this branch: bzr merge lp:~milo/linaro-patchmetrics/user-migration
Reviewer Review Type Date Requested Status
Paul Sokolovsky Approve
Linaro Automation & Validation Pending
Review via email: mp+192327@code.launchpad.net

Description of the change

A simple script to migrate users in the DB to the new Crowd authentication mechanism.
Users will be matched based on their email address.

There is a workaround at the moment in the code for emails longer than 30 chars: Django does not support that.

To post a comment you must log in.
Revision history for this message
Paul Sokolovsky (pfalcon) wrote :

One thing is that I thought this would be belong to django custom management commands, but I see that patchmetrics has that patterns of bin/ utils using _pythonpath module ok.

But the strategy looks pretty surprising. I always thought of something like: when we have both old (LP) and new (Crowd) user (so user would need to login via Crowd), and we migrate all objects from one user id to another. so, we retain both users in there (as backout strategy for example).

So, approach of this script with "destructive" migration of user's identity from Launchpad to Crowd feels almost like cheating. Well, if it works, I cannot really say something bad about it, because it's indeed nice automated en-masse solution. One thing I'd mention though is matter of how complete this "identity switching" is. For example, there's likely openid data linked to this account. I don't think this would interfere with something, but well, worth mentioning.

Otherwise, look good.

review: Approve
Revision history for this message
Milo Casagrande (milo) wrote :

On Wed, Oct 23, 2013 at 4:36 PM, Paul Sokolovsky
<email address hidden> wrote:
> Review: Approve
>
> One thing is that I thought this would be belong to django custom management commands, but I see that patchmetrics has that patterns of bin/ utils using _pythonpath module ok.

I personally do not like it either, but I do not like either the code
base to be honest.

> But the strategy looks pretty surprising. I always thought of something like: when we have both old (LP) and new (Crowd) user (so user would need to login via Crowd), and we migrate all objects from one user id to another. so, we retain both users in there (as backout strategy for example).
>
> So, approach of this script with "destructive" migration of user's identity from Launchpad to Crowd feels almost like cheating.

You are right, it is indeed like cheating.

But the more I looked at the DB though, the more I thought that this
was the most likely and easiest solution to migrate in just one batch.
If we ended up adding new users, as I was trying to do in the
beginning, we would have had to mass-update all the teams in
patchemtrics, and the user-teams membership (and still I was not sure
if we could have guaranteed the correct results).

> Well, if it works, I cannot really say something bad about it, because it's indeed nice automated en-masse solution. One thing I'd mention though is matter of how complete this "identity switching" is. For example, there's likely openid data linked to this account. I don't think this would interfere with something, but well, worth mentioning.

I tried to clean up also those, we will not need them anymore, but it
will take a little bit of cleaning because there are external keys
involved. We can do that, probably not as programmatically as this MP,
but it can be done with some SQL queries.

As far as we are concerned, the openid data does not pose a problem
for patchmetrics to work.
For how complete it is, you should be able to get everything you had
with the old authentication method.

--
Milo Casagrande | Automation Engineer
Linaro.org <www.linaro.org> │ Open source software for ARM SoCs

Revision history for this message
Paul Sokolovsky (pfalcon) wrote :

> As far as we are concerned, the openid data does not pose a problem for patchmetrics to work.

I agree, so should be good to go. Yet, we should keep this in contingency plan - if something pops up, we'll need to react quickly.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'apps/patchmetrics/bin/migrate-linaro-users.py'
2--- apps/patchmetrics/bin/migrate-linaro-users.py 1970-01-01 00:00:00 +0000
3+++ apps/patchmetrics/bin/migrate-linaro-users.py 2013-10-23 13:03:07 +0000
4@@ -0,0 +1,70 @@
5+#!/usr/bin/python
6+# Copyright (C) 2013 Linaro
7+#
8+# Author: Milo Casagrande <milo.casagrande@linaro.org>
9+# This file is part of the Patchmetrics package.
10+#
11+# Patchmetrics is free software; you can redistribute it and/or modify
12+# it under the terms of the GNU General Public License as published by
13+# the Free Software Foundation; either version 2 of the License, or
14+# (at your option) any later version.
15+#
16+# Patchmetrics is distributed in the hope that it will be useful,
17+# but WITHOUT ANY WARRANTY; without even the implied warranty of
18+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+# GNU General Public License for more details.
20+#
21+# You should have received a copy of the GNU General Public License
22+# along with Patchmetrics; if not, write to the Free Software
23+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24+
25+import _pythonpath
26+import sys
27+
28+from django.conf import settings
29+from django.contrib.auth.models import User
30+
31+from patchmetrics.crowd import (
32+ Crowd,
33+ CrowdException,
34+ CrowdNotFoundException,
35+)
36+
37+if __name__ == '__main__':
38+ if settings.AUTH_CROWD_APPLICATION_USER:
39+ crwd = Crowd(settings.AUTH_CROWD_APPLICATION_USER,
40+ settings.AUTH_CROWD_APPLICATION_PASSWORD,
41+ settings.AUTH_CROWD_SERVER_REST_URI)
42+
43+ users = User.objects.all().distinct()
44+ for user in users:
45+ if user and (user.is_active and user.email):
46+ crowd_usr = None
47+ try:
48+ crowd_usr = crwd.get_user(user.email)
49+ if crowd_usr.name != user.username:
50+ # Corner case, at least for now: Django has a limit
51+ # on the chars for username.
52+ if len(user.email) > 30:
53+ sys.stderr.write(
54+ "Impossible to save user, email is longer "
55+ "than 30 chars: {0}\n".format(user.email))
56+ continue
57+ else:
58+ split_name = crowd_usr.display_name.split()
59+ user.first_name = split_name[0]
60+ user.last_name = " ".join(split_name[1:])
61+ # Use the email from crowd, since some users looks
62+ # like have an email with capital letters that
63+ # shouldn't be.
64+ user.username = crowd_usr.emails[0]
65+ user.save()
66+ except CrowdNotFoundException:
67+ # Silently ignore, user is not in Crowd we can't really do
68+ # much here.
69+ pass
70+ except CrowdException, ex:
71+ sys.stderr.write("{0}\n".format(str(ex)))
72+ else:
73+ sys.stderr.write("No Crowd credentials found.\n")
74+ sys.exit(1)

Subscribers

People subscribed via source and target branches