Temporarily put user rename behind a feature flag. Switch queue names back to using the username for namespace while we figure out a real migration strategy.
This commit is contained in:
parent
768a60b414
commit
2b8c246476
9 changed files with 44 additions and 67 deletions
|
@ -160,6 +160,9 @@ class DefaultConfig(object):
|
||||||
# Feature Flag: Whether users can be created (by non-super users).
|
# Feature Flag: Whether users can be created (by non-super users).
|
||||||
FEATURE_USER_CREATION = True
|
FEATURE_USER_CREATION = True
|
||||||
|
|
||||||
|
# Feature Flag: Whether users can be renamed
|
||||||
|
FEATURE_USER_RENAME = False
|
||||||
|
|
||||||
DISTRIBUTED_STORAGE_CONFIG = {
|
DISTRIBUTED_STORAGE_CONFIG = {
|
||||||
'local_eu': ['LocalStorage', {'storage_path': 'test/data/registry/eu'}],
|
'local_eu': ['LocalStorage', {'storage_path': 'test/data/registry/eu'}],
|
||||||
'local_us': ['LocalStorage', {'storage_path': 'test/data/registry/us'}],
|
'local_us': ['LocalStorage', {'storage_path': 'test/data/registry/us'}],
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""remove the namespace column.
|
||||||
|
|
||||||
|
Revision ID: 2430f55c41d5
|
||||||
|
Revises: 17f11e265e13
|
||||||
|
Create Date: 2014-09-30 17:31:33.308490
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2fb36d4be80d'
|
||||||
|
down_revision = '17f11e265e13'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
import re
|
||||||
|
from app import app
|
||||||
|
|
||||||
|
|
||||||
|
NAMESPACE_EXTRACTOR = re.compile(r'^([a-z]+/)([a-z0-9_]+)(/.*$)')
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(tables):
|
||||||
|
op.create_index('repository_namespace_user_id', 'repository', ['namespace_user_id'], unique=False)
|
||||||
|
op.drop_column('repository', 'namespace')
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(tables):
|
||||||
|
op.add_column('repository', sa.Column('namespace', sa.String(length=255)))
|
||||||
|
op.drop_index('repository_namespace_user_id', table_name='repository')
|
|
@ -1,59 +0,0 @@
|
||||||
"""Translate the queue names to reference namespace by id, remove the namespace column.
|
|
||||||
|
|
||||||
Revision ID: 2430f55c41d5
|
|
||||||
Revises: 17f11e265e13
|
|
||||||
Create Date: 2014-09-30 17:31:33.308490
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '2fb36d4be80d'
|
|
||||||
down_revision = '17f11e265e13'
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
import re
|
|
||||||
from app import app
|
|
||||||
from data.database import QueueItem, User, db
|
|
||||||
|
|
||||||
|
|
||||||
NAMESPACE_EXTRACTOR = re.compile(r'^([a-z]+/)([a-z0-9_]+)(/.*$)')
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(tables):
|
|
||||||
# Rename the namespace component of the existing queue items to reference user ids
|
|
||||||
with app.config['DB_TRANSACTION_FACTORY'](db):
|
|
||||||
for item in QueueItem.select():
|
|
||||||
namespace_match = NAMESPACE_EXTRACTOR.match(item.queue_name)
|
|
||||||
if namespace_match is not None:
|
|
||||||
namespace_name = namespace_match.group(2)
|
|
||||||
namespace_user = User.get(User.username == namespace_name)
|
|
||||||
item.queue_name = '%s%s%s' % (namespace_match.group(1), str(namespace_user.id),
|
|
||||||
namespace_match.group(3))
|
|
||||||
item.save()
|
|
||||||
else:
|
|
||||||
raise RuntimeError('Invalid queue name: %s' % item.queue_name)
|
|
||||||
|
|
||||||
op.create_index('repository_namespace_user_id', 'repository', ['namespace_user_id'], unique=False)
|
|
||||||
op.drop_column('repository', 'namespace')
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(tables):
|
|
||||||
# Add the namespace column back in and fill it in
|
|
||||||
op.add_column('repository', sa.Column('namespace', sa.String(length=255)))
|
|
||||||
op.drop_index('repository_namespace_user_id', table_name='repository')
|
|
||||||
|
|
||||||
# Rename the namespace component of existing queue items to reference namespace strings
|
|
||||||
with app.config['DB_TRANSACTION_FACTORY'](db):
|
|
||||||
for item in QueueItem.select():
|
|
||||||
namespace_match = NAMESPACE_EXTRACTOR.match(item.queue_name)
|
|
||||||
if namespace_match is not None:
|
|
||||||
namespace_id = namespace_match.group(2)
|
|
||||||
namespace_user = User.get(User.id == namespace_id)
|
|
||||||
item.queue_name = '%s%s%s' % (namespace_match.group(1),
|
|
||||||
str(namespace_user.username),
|
|
||||||
namespace_match.group(3))
|
|
||||||
item.save()
|
|
||||||
else:
|
|
||||||
raise RuntimeError('Invalid queue name: %s' % item.queue_name)
|
|
|
@ -144,7 +144,7 @@ class TestRepositoryNotification(RepositoryParamResource):
|
||||||
event_info = NotificationEvent.get_event(notification.event.name)
|
event_info = NotificationEvent.get_event(notification.event.name)
|
||||||
sample_data = event_info.get_sample_data(repository=notification.repository)
|
sample_data = event_info.get_sample_data(repository=notification.repository)
|
||||||
notification_data = build_notification_data(notification, sample_data)
|
notification_data = build_notification_data(notification, sample_data)
|
||||||
notification_queue.put([str(notification.repository.namespace_user.id), repository,
|
notification_queue.put([notification.repository.namespace_user.username, repository,
|
||||||
notification.event.name], json.dumps(notification_data))
|
notification.event.name], json.dumps(notification_data))
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
|
@ -198,7 +198,8 @@ class User(ApiResource):
|
||||||
else:
|
else:
|
||||||
model.update_email(user, new_email, auto_verify=not features.MAILING)
|
model.update_email(user, new_email, auto_verify=not features.MAILING)
|
||||||
|
|
||||||
if 'username' in user_data and user_data['username'] != user.username:
|
if ('username' in user_data and user_data['username'] != user.username and
|
||||||
|
features.USER_RENAME):
|
||||||
new_username = user_data['username']
|
new_username = user_data['username']
|
||||||
if model.get_user_or_org(new_username) is not None:
|
if model.get_user_or_org(new_username) is not None:
|
||||||
# Username already used
|
# Username already used
|
||||||
|
|
|
@ -238,7 +238,7 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
||||||
dockerfile_id, build_name,
|
dockerfile_id, build_name,
|
||||||
trigger, pull_robot_name=pull_robot_name)
|
trigger, pull_robot_name=pull_robot_name)
|
||||||
|
|
||||||
dockerfile_build_queue.put([str(repository.namespace_user.id), repository.name], json.dumps({
|
dockerfile_build_queue.put([repository.namespace_user.username, repository.name], json.dumps({
|
||||||
'build_uuid': build_request.uuid,
|
'build_uuid': build_request.uuid,
|
||||||
'pull_credentials': model.get_pull_credentials(pull_robot_name) if pull_robot_name else None
|
'pull_credentials': model.get_pull_credentials(pull_robot_name) if pull_robot_name else None
|
||||||
}), retries_remaining=1)
|
}), retries_remaining=1)
|
||||||
|
|
|
@ -58,5 +58,5 @@ def spawn_notification(repo, event_name, extra_data={}, subpage=None, pathargs=[
|
||||||
event_name=event_name)
|
event_name=event_name)
|
||||||
for notification in list(notifications):
|
for notification in list(notifications):
|
||||||
notification_data = build_notification_data(notification, event_data, performer_data)
|
notification_data = build_notification_data(notification, event_data, performer_data)
|
||||||
path = [str(repo.namespace_user.id), repo.name, event_name] + pathargs
|
path = [repo.namespace_user.username, repo.name, event_name] + pathargs
|
||||||
notification_queue.put(path, json.dumps(notification_data))
|
notification_queue.put(path, json.dumps(notification_data))
|
||||||
|
|
|
@ -259,7 +259,7 @@ def put_image_layer(namespace, repository, image_id):
|
||||||
# process it.
|
# process it.
|
||||||
profile.debug('Adding layer to diff queue')
|
profile.debug('Adding layer to diff queue')
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
image_diff_queue.put([str(repo.namespace_user.id), repository, image_id], json.dumps({
|
image_diff_queue.put([repo.namespace_user.username, repository, image_id], json.dumps({
|
||||||
'namespace_user_id': repo.namespace_user.id,
|
'namespace_user_id': repo.namespace_user.id,
|
||||||
'repository': repository,
|
'repository': repository,
|
||||||
'image_id': image_id,
|
'image_id': image_id,
|
||||||
|
@ -333,7 +333,7 @@ def put_image_checksum(namespace, repository, image_id):
|
||||||
# process it.
|
# process it.
|
||||||
profile.debug('Adding layer to diff queue')
|
profile.debug('Adding layer to diff queue')
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
image_diff_queue.put([str(repo.namespace_user.id), repository, image_id], json.dumps({
|
image_diff_queue.put([repo.namespace_user.username, repository, image_id], json.dumps({
|
||||||
'namespace_user_id': repo.namespace_user.id,
|
'namespace_user_id': repo.namespace_user.id,
|
||||||
'repository': repository,
|
'repository': repository,
|
||||||
'image_id': image_id,
|
'image_id': image_id,
|
||||||
|
|
|
@ -38,7 +38,9 @@
|
||||||
<li quay-show="Features.USER_LOG_ACCESS || hasPaidBusinessPlan">
|
<li quay-show="Features.USER_LOG_ACCESS || hasPaidBusinessPlan">
|
||||||
<a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">Usage Logs</a>
|
<a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">Usage Logs</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#username">Change Username</a></li>
|
<li quay-require="['USER_RENAME']">
|
||||||
|
<a href="javascript:void(0)" data-toggle="tab" data-target="#username">Change Username</a>
|
||||||
|
</li>
|
||||||
<li quay-show="Config.AUTHENTICATION_TYPE == 'Database'">
|
<li quay-show="Config.AUTHENTICATION_TYPE == 'Database'">
|
||||||
<a href="javascript:void(0)" data-toggle="tab" data-target="#migrate" id="migrateTab">Convert to Organization</a>
|
<a href="javascript:void(0)" data-toggle="tab" data-target="#migrate" id="migrateTab">Convert to Organization</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -236,7 +238,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Change username tab -->
|
<!-- Change username tab -->
|
||||||
<div id="username" class="tab-pane">
|
<div id="username" class="tab-pane" quay-show="Features.USER_RENAME">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-title">Change Username</div>
|
<div class="panel-title">Change Username</div>
|
||||||
|
|
Reference in a new issue