2013-10-10 03:52:28 +00:00
|
|
|
import logging
|
|
|
|
import string
|
2013-10-18 20:36:11 +00:00
|
|
|
import shutil
|
|
|
|
import os
|
|
|
|
import hashlib
|
2014-01-03 21:32:00 +00:00
|
|
|
import random
|
2013-10-10 03:52:28 +00:00
|
|
|
|
2013-10-18 22:28:37 +00:00
|
|
|
from datetime import datetime, timedelta
|
2013-10-25 19:47:34 +00:00
|
|
|
from flask import url_for
|
2013-11-06 22:09:22 +00:00
|
|
|
from peewee import SqliteDatabase, create_model_tables, drop_model_tables
|
2013-10-10 03:52:28 +00:00
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
from data.database import *
|
2013-10-10 03:52:28 +00:00
|
|
|
from data import model
|
|
|
|
from app import app
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2013-11-07 04:21:12 +00:00
|
|
|
store = app.config['STORAGE']
|
2013-10-10 03:52:28 +00:00
|
|
|
|
2013-10-19 00:18:23 +00:00
|
|
|
SAMPLE_DIFFS = ['test/data/sample/diffs/diffs%s.json' % i
|
|
|
|
for i in range(1, 10)]
|
2013-10-18 20:36:11 +00:00
|
|
|
|
2013-10-18 22:28:37 +00:00
|
|
|
REFERENCE_DATE = datetime(2013, 6, 23)
|
2013-11-08 03:43:43 +00:00
|
|
|
TEST_STRIPE_ID = 'cus_2tmnh3PkXQS8NG'
|
2013-10-18 22:28:37 +00:00
|
|
|
|
2013-10-18 20:36:11 +00:00
|
|
|
|
|
|
|
def __gen_checksum(image_id):
|
|
|
|
h = hashlib.md5(image_id)
|
2013-10-19 00:35:14 +00:00
|
|
|
return 'tarsum+sha256:' + h.hexdigest() + h.hexdigest()
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
|
2013-10-18 22:28:37 +00:00
|
|
|
def __gen_image_id(repo, image_num):
|
|
|
|
str_to_hash = "%s/%s/%s" % (repo.namespace, repo.name, image_num)
|
2013-10-18 20:36:11 +00:00
|
|
|
|
|
|
|
h = hashlib.md5(str_to_hash)
|
2013-10-19 00:35:14 +00:00
|
|
|
return h.hexdigest() + h.hexdigest()
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
|
2013-10-18 22:28:37 +00:00
|
|
|
global_image_num = [0]
|
2013-11-06 22:09:22 +00:00
|
|
|
def __create_subtree(repo, structure, parent):
|
2013-10-10 04:40:07 +00:00
|
|
|
num_nodes, subtrees, last_node_tags = structure
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
# create the nodes
|
|
|
|
for i in range(num_nodes):
|
2013-10-18 22:28:37 +00:00
|
|
|
image_num = global_image_num[0]
|
|
|
|
global_image_num[0] += 1
|
|
|
|
docker_image_id = __gen_image_id(repo, image_num)
|
2013-10-18 20:36:11 +00:00
|
|
|
logger.debug('new docker id: %s' % docker_image_id)
|
|
|
|
checksum = __gen_checksum(docker_image_id)
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
new_image = model.create_image(docker_image_id, repo)
|
|
|
|
model.set_image_checksum(docker_image_id, repo, checksum)
|
|
|
|
|
2013-10-18 22:28:37 +00:00
|
|
|
creation_time = REFERENCE_DATE + timedelta(days=image_num)
|
2013-10-10 03:52:28 +00:00
|
|
|
new_image = model.set_image_metadata(docker_image_id, repo.namespace,
|
2013-10-18 22:28:37 +00:00
|
|
|
repo.name, str(creation_time),
|
2013-10-10 03:52:28 +00:00
|
|
|
'no comment', parent)
|
|
|
|
|
2014-01-03 21:32:00 +00:00
|
|
|
model.set_image_size(docker_image_id, repo.namespace, repo.name, random.randrange(1, 1024 * 1024 * 1024))
|
|
|
|
|
2013-10-18 20:36:11 +00:00
|
|
|
# Populate the diff file
|
|
|
|
diff_path = store.image_file_diffs_path(repo.namespace, repo.name,
|
2013-10-18 22:28:37 +00:00
|
|
|
docker_image_id)
|
|
|
|
source_diff = SAMPLE_DIFFS[image_num % len(SAMPLE_DIFFS)]
|
2013-10-18 20:36:11 +00:00
|
|
|
|
|
|
|
with open(source_diff, 'r') as source_file:
|
|
|
|
store.stream_write(diff_path, source_file)
|
|
|
|
|
2013-10-10 03:52:28 +00:00
|
|
|
parent = new_image
|
|
|
|
|
2013-10-10 04:40:07 +00:00
|
|
|
if last_node_tags:
|
|
|
|
if not isinstance(last_node_tags, list):
|
|
|
|
last_node_tags = [last_node_tags]
|
|
|
|
|
|
|
|
for tag_name in last_node_tags:
|
|
|
|
model.create_or_update_tag(repo.namespace, repo.name, tag_name,
|
|
|
|
new_image.docker_image_id)
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
for subtree in subtrees:
|
2013-11-06 22:09:22 +00:00
|
|
|
__create_subtree(repo, subtree, new_image)
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
|
2013-10-17 02:37:29 +00:00
|
|
|
def __generate_repository(user, name, description, is_public, permissions,
|
|
|
|
structure):
|
2013-10-10 03:52:28 +00:00
|
|
|
repo = model.create_repository(user.username, name, user)
|
|
|
|
|
|
|
|
if is_public:
|
|
|
|
model.set_repository_visibility(repo, 'public')
|
|
|
|
|
2013-10-12 01:28:02 +00:00
|
|
|
if description:
|
|
|
|
repo.description = description
|
|
|
|
repo.save()
|
|
|
|
|
2013-10-10 03:52:28 +00:00
|
|
|
for delegate, role in permissions:
|
|
|
|
model.set_user_repo_permission(delegate.username, user.username, name,
|
|
|
|
role)
|
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
__create_subtree(repo, structure, None)
|
2013-10-10 03:52:28 +00:00
|
|
|
|
2013-10-25 19:47:34 +00:00
|
|
|
return repo
|
|
|
|
|
2013-10-01 18:14:39 +00:00
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
def initialize_database():
|
|
|
|
create_model_tables(all_models)
|
|
|
|
|
|
|
|
Role.create(name='admin')
|
|
|
|
Role.create(name='write')
|
|
|
|
Role.create(name='read')
|
|
|
|
TeamRole.create(name='admin')
|
|
|
|
TeamRole.create(name='creator')
|
|
|
|
TeamRole.create(name='member')
|
|
|
|
Visibility.create(name='public')
|
|
|
|
Visibility.create(name='private')
|
|
|
|
LoginService.create(name='github')
|
2013-11-20 21:13:03 +00:00
|
|
|
LoginService.create(name='quayrobot')
|
2013-11-27 07:29:31 +00:00
|
|
|
|
|
|
|
LogEntryKind.create(name='account_change_plan')
|
|
|
|
LogEntryKind.create(name='account_change_cc')
|
|
|
|
LogEntryKind.create(name='account_change_password')
|
|
|
|
LogEntryKind.create(name='account_convert')
|
|
|
|
|
|
|
|
LogEntryKind.create(name='create_robot')
|
|
|
|
LogEntryKind.create(name='delete_robot')
|
|
|
|
|
|
|
|
LogEntryKind.create(name='create_repo')
|
|
|
|
LogEntryKind.create(name='push_repo')
|
|
|
|
LogEntryKind.create(name='pull_repo')
|
|
|
|
LogEntryKind.create(name='delete_repo')
|
2014-01-06 20:20:58 +00:00
|
|
|
LogEntryKind.create(name='delete_tag')
|
2013-11-27 07:29:31 +00:00
|
|
|
LogEntryKind.create(name='add_repo_permission')
|
|
|
|
LogEntryKind.create(name='change_repo_permission')
|
|
|
|
LogEntryKind.create(name='delete_repo_permission')
|
|
|
|
LogEntryKind.create(name='change_repo_visibility')
|
|
|
|
LogEntryKind.create(name='add_repo_accesstoken')
|
|
|
|
LogEntryKind.create(name='delete_repo_accesstoken')
|
|
|
|
LogEntryKind.create(name='add_repo_webhook')
|
|
|
|
LogEntryKind.create(name='delete_repo_webhook')
|
|
|
|
LogEntryKind.create(name='set_repo_description')
|
|
|
|
LogEntryKind.create(name='build_dockerfile')
|
|
|
|
|
|
|
|
LogEntryKind.create(name='org_create_team')
|
|
|
|
LogEntryKind.create(name='org_delete_team')
|
|
|
|
LogEntryKind.create(name='org_add_team_member')
|
|
|
|
LogEntryKind.create(name='org_remove_team_member')
|
|
|
|
LogEntryKind.create(name='org_set_team_description')
|
|
|
|
LogEntryKind.create(name='org_set_team_role')
|
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
|
|
|
|
def wipe_database():
|
|
|
|
logger.debug('Wiping all data from the DB.')
|
|
|
|
|
|
|
|
# Sanity check to make sure we're not killing our prod db
|
|
|
|
db = model.db
|
|
|
|
if (not isinstance(model.db, SqliteDatabase) or
|
|
|
|
app.config['DB_DRIVER'] is not SqliteDatabase):
|
|
|
|
raise RuntimeError('Attempted to wipe production database!')
|
|
|
|
|
|
|
|
drop_model_tables(all_models, fail_silently=True)
|
|
|
|
|
|
|
|
|
|
|
|
def populate_database():
|
|
|
|
logger.debug('Populating the DB with test data.')
|
|
|
|
|
|
|
|
new_user_1 = model.create_user('devtable', 'password',
|
|
|
|
'jschorr@devtable.com')
|
|
|
|
new_user_1.verified = True
|
|
|
|
new_user_1.save()
|
|
|
|
|
2013-11-20 23:23:59 +00:00
|
|
|
model.create_robot('dtrobot', new_user_1)
|
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
new_user_2 = model.create_user('public', 'password',
|
|
|
|
'jacob.moshenko@gmail.com')
|
|
|
|
new_user_2.verified = True
|
|
|
|
new_user_2.save()
|
|
|
|
|
|
|
|
new_user_3 = model.create_user('freshuser', 'password', 'no@thanks.com')
|
|
|
|
new_user_3.verified = True
|
|
|
|
new_user_3.save()
|
|
|
|
|
2013-11-07 04:21:12 +00:00
|
|
|
reader = model.create_user('reader', 'password', 'no1@thanks.com')
|
|
|
|
reader.verified = True
|
|
|
|
reader.save()
|
|
|
|
|
2013-11-08 04:29:58 +00:00
|
|
|
outside_org = model.create_user('outsideorg', 'password', 'no2@thanks.com')
|
|
|
|
outside_org.verified = True
|
|
|
|
outside_org.save()
|
|
|
|
|
2013-11-06 22:09:22 +00:00
|
|
|
__generate_repository(new_user_1, 'simple', 'Simple repository.', False,
|
|
|
|
[], (4, [], ['latest', 'prod']))
|
|
|
|
|
|
|
|
__generate_repository(new_user_1, 'complex',
|
|
|
|
'Complex repository with many branches and tags.',
|
|
|
|
False, [(new_user_2, 'read')],
|
|
|
|
(2, [(3, [], 'v2.0'),
|
|
|
|
(1, [(1, [(1, [], ['prod'])],
|
|
|
|
'staging'),
|
|
|
|
(1, [], None)], None)], None))
|
|
|
|
|
|
|
|
__generate_repository(new_user_1, 'gargantuan', None, False, [],
|
|
|
|
(2, [(3, [], 'v2.0'),
|
|
|
|
(1, [(1, [(1, [], ['latest', 'prod'])],
|
|
|
|
'staging'),
|
|
|
|
(1, [], None)], None),
|
|
|
|
(20, [], 'v3.0'),
|
|
|
|
(5, [], 'v4.0'),
|
|
|
|
(1, [(1, [], 'v5.0'), (1, [], 'v6.0')], None)],
|
|
|
|
None))
|
|
|
|
|
|
|
|
__generate_repository(new_user_2, 'publicrepo',
|
|
|
|
'Public repository pullable by the world.', True,
|
|
|
|
[], (10, [], 'latest'))
|
|
|
|
|
|
|
|
__generate_repository(new_user_1, 'shared',
|
|
|
|
'Shared repository, another user can write.', False,
|
2013-11-07 04:21:12 +00:00
|
|
|
[(new_user_2, 'write'), (reader, 'read')],
|
|
|
|
(5, [], 'latest'))
|
2013-11-06 22:09:22 +00:00
|
|
|
|
|
|
|
building = __generate_repository(new_user_1, 'building',
|
|
|
|
'Empty repository which is building.',
|
|
|
|
False, [], (0, [], None))
|
|
|
|
|
2013-11-08 03:43:43 +00:00
|
|
|
org = model.create_organization('buynlarge', 'quay@devtable.com',
|
2013-11-06 22:09:22 +00:00
|
|
|
new_user_1)
|
2013-11-08 03:43:43 +00:00
|
|
|
org.stripe_id = TEST_STRIPE_ID
|
|
|
|
org.save()
|
|
|
|
|
2013-11-20 23:23:59 +00:00
|
|
|
model.create_robot('neworgrobot', org)
|
|
|
|
|
2013-11-08 03:43:43 +00:00
|
|
|
owners = model.get_organization_team('buynlarge', 'owners')
|
|
|
|
owners.description = 'Owners have unfetterd access across the entire org.'
|
|
|
|
owners.save()
|
2013-11-06 22:09:22 +00:00
|
|
|
|
|
|
|
org_repo = __generate_repository(org, 'orgrepo',
|
|
|
|
'Repository owned by an org.', False,
|
2013-11-08 04:29:58 +00:00
|
|
|
[(outside_org, 'read')],
|
|
|
|
(4, [], ['latest', 'prod']))
|
2013-11-06 22:09:22 +00:00
|
|
|
|
|
|
|
reader_team = model.create_team('readers', org, 'member',
|
|
|
|
'Readers of orgrepo.')
|
|
|
|
model.set_team_repo_permission(reader_team.name, org_repo.namespace,
|
|
|
|
org_repo.name, 'read')
|
|
|
|
model.add_user_to_team(new_user_2, reader_team)
|
2013-11-07 04:21:12 +00:00
|
|
|
model.add_user_to_team(reader, reader_team)
|
2013-11-06 22:09:22 +00:00
|
|
|
|
|
|
|
token = model.create_access_token(building, 'write')
|
|
|
|
tag = 'ci.devtable.com:5000/%s/%s' % (building.namespace, building.name)
|
|
|
|
build = model.create_repository_build(building, token, '123-45-6789', tag)
|
|
|
|
|
|
|
|
build.build_node_id = 1
|
|
|
|
build.phase = 'building'
|
|
|
|
build.status_url = 'http://localhost:5000/test/build/status'
|
|
|
|
build.save()
|
|
|
|
|
2013-12-03 00:07:14 +00:00
|
|
|
today = datetime.today()
|
|
|
|
week_ago = today - timedelta(6)
|
|
|
|
six_ago = today - timedelta(5)
|
|
|
|
four_ago = today - timedelta(4)
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('org_create_team', org.username, performer=new_user_1, timestamp=week_ago,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'team': 'readers'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('org_set_team_role', org.username, performer=new_user_1, timestamp=week_ago,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'team': 'readers', 'role': 'read'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('create_repo', org.username, performer=new_user_1, repository=org_repo, timestamp=week_ago,
|
2013-12-03 03:29:54 +00:00
|
|
|
metadata={'namespace': org.username, 'repo': 'orgrepo'})
|
2013-12-03 00:07:14 +00:00
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('change_repo_permission', org.username, performer=new_user_2, repository=org_repo, timestamp=six_ago,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'username': new_user_1.username, 'repo': 'orgrepo', 'role': 'admin'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('change_repo_permission', org.username, performer=new_user_1, repository=org_repo, timestamp=six_ago,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'username': new_user_2.username, 'repo': 'orgrepo', 'role': 'read'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('add_repo_accesstoken', org.username, performer=new_user_1, repository=org_repo, timestamp=four_ago,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'repo': 'orgrepo', 'token': 'deploytoken'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('push_repo', org.username, performer=new_user_2, repository=org_repo, timestamp=today,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'username': new_user_2.username, 'repo': 'orgrepo'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('pull_repo', org.username, performer=new_user_2, repository=org_repo, timestamp=today,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'username': new_user_2.username, 'repo': 'orgrepo'})
|
|
|
|
|
2013-12-03 21:48:44 +00:00
|
|
|
model.log_action('pull_repo', org.username, repository=org_repo, timestamp=today,
|
2013-12-03 00:07:14 +00:00
|
|
|
metadata={'token': 'sometoken', 'token_code': 'somecode', 'repo': 'orgrepo'})
|
2013-11-06 22:09:22 +00:00
|
|
|
|
2014-01-06 20:20:58 +00:00
|
|
|
model.log_action('delete_tag', org.username, performer=new_user_2, repository=org_repo, timestamp=today,
|
|
|
|
metadata={'username': new_user_2.username, 'repo': 'orgrepo', 'tag': 'sometag'})
|
|
|
|
|
2014-01-08 23:44:50 +00:00
|
|
|
model.log_action('pull_repo', org.username, repository=org_repo, timestamp=today,
|
|
|
|
metadata={'token_code': 'somecode', 'repo': 'orgrepo'})
|
|
|
|
|
2013-10-01 18:14:39 +00:00
|
|
|
if __name__ == '__main__':
|
2013-11-06 22:09:22 +00:00
|
|
|
logging.basicConfig(**app.config['LOGGING_CONFIG'])
|
|
|
|
initialize_database()
|
2013-10-10 03:52:28 +00:00
|
|
|
|
|
|
|
if app.config.get('POPULATE_DB_TEST_DATA', False):
|
2013-11-06 22:09:22 +00:00
|
|
|
populate_database()
|