Strip whitespace from ALL the things.
2
Bobfile
|
@ -19,4 +19,4 @@ version = 1
|
||||||
project = "builder"
|
project = "builder"
|
||||||
tags = ["git:short"]
|
tags = ["git:short"]
|
||||||
|
|
||||||
# vim:ft=toml
|
# vim:ft=toml
|
||||||
|
|
2
app.py
|
@ -29,7 +29,7 @@ from data.userevent import UserEventsBuilderModule
|
||||||
|
|
||||||
class Config(BaseConfig):
|
class Config(BaseConfig):
|
||||||
""" Flask config enhanced with a `from_yamlfile` method """
|
""" Flask config enhanced with a `from_yamlfile` method """
|
||||||
|
|
||||||
def from_yamlfile(self, config_file):
|
def from_yamlfile(self, config_file):
|
||||||
with open(config_file) as f:
|
with open(config_file) as f:
|
||||||
c = yaml.load(f)
|
c = yaml.load(f)
|
||||||
|
|
|
@ -77,7 +77,7 @@ IMPLIED_SCOPES = {
|
||||||
def scopes_from_scope_string(scopes):
|
def scopes_from_scope_string(scopes):
|
||||||
if not scopes:
|
if not scopes:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
return {ALL_SCOPES.get(scope, None) for scope in scopes.split(',')}
|
return {ALL_SCOPES.get(scope, None) for scope in scopes.split(',')}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="146" height="18" fill="#555"/><rect rx="4" x="92" width="54" height="18" fill="#dfb317"/><path fill="#dfb317" d="M92 0h4v18h-4z"/><rect rx="4" width="146" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="118" y="13" fill="#010101" fill-opacity=".3">building</text><text x="118" y="12">building</text></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="146" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="146" height="18" fill="#555"/><rect rx="4" x="92" width="54" height="18" fill="#dfb317"/><path fill="#dfb317" d="M92 0h4v18h-4z"/><rect rx="4" width="146" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="118" y="13" fill="#010101" fill-opacity=".3">building</text><text x="118" y="12">building</text></g></svg>
|
Before Width: | Height: | Size: 835 B After Width: | Height: | Size: 836 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="164" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="164" height="18" fill="#555"/><rect rx="4" x="92" width="72" height="18" fill="#e05d44"/><path fill="#e05d44" d="M92 0h4v18h-4z"/><rect rx="4" width="164" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="127" y="13" fill="#010101" fill-opacity=".3">build failed</text><text x="127" y="12">build failed</text></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="164" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="164" height="18" fill="#555"/><rect rx="4" x="92" width="72" height="18" fill="#e05d44"/><path fill="#e05d44" d="M92 0h4v18h-4z"/><rect rx="4" width="164" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="127" y="13" fill="#010101" fill-opacity=".3">build failed</text><text x="127" y="12">build failed</text></g></svg>
|
Before Width: | Height: | Size: 843 B After Width: | Height: | Size: 844 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="130" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="130" height="18" fill="#555"/><rect rx="4" x="92" width="38" height="18" fill="#9f9f9f"/><path fill="#9f9f9f" d="M92 0h4v18h-4z"/><rect rx="4" width="130" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="110" y="13" fill="#010101" fill-opacity=".3">none</text><text x="110" y="12">none</text></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="130" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="130" height="18" fill="#555"/><rect rx="4" x="92" width="38" height="18" fill="#9f9f9f"/><path fill="#9f9f9f" d="M92 0h4v18h-4z"/><rect rx="4" width="130" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="110" y="13" fill="#010101" fill-opacity=".3">none</text><text x="110" y="12">none</text></g></svg>
|
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 828 B |
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="135" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="135" height="18" fill="#555"/><rect rx="4" x="92" width="43" height="18" fill="#4c1"/><path fill="#4c1" d="M92 0h4v18h-4z"/><rect rx="4" width="135" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="112.5" y="13" fill="#010101" fill-opacity=".3">ready</text><text x="112.5" y="12">ready</text></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="135" height="18"><linearGradient id="a" x2="0" y2="100%"><stop offset="0" stop-color="#fff" stop-opacity=".7"/><stop offset=".1" stop-color="#aaa" stop-opacity=".1"/><stop offset=".9" stop-opacity=".3"/><stop offset="1" stop-opacity=".5"/></linearGradient><rect rx="4" width="135" height="18" fill="#555"/><rect rx="4" x="92" width="43" height="18" fill="#4c1"/><path fill="#4c1" d="M92 0h4v18h-4z"/><rect rx="4" width="135" height="18" fill="url(#a)"/><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="47" y="13" fill="#010101" fill-opacity=".3">Docker Image</text><text x="47" y="12">Docker Image</text><text x="112.5" y="13" fill="#010101" fill-opacity=".3">ready</text><text x="112.5" y="12">ready</text></g></svg>
|
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 828 B |
|
@ -4,4 +4,4 @@ worker_class = 'gevent'
|
||||||
timeout = 2000
|
timeout = 2000
|
||||||
daemon = False
|
daemon = False
|
||||||
logconfig = 'conf/logging.conf'
|
logconfig = 'conf/logging.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
|
|
|
@ -4,4 +4,4 @@ worker_class = 'gevent'
|
||||||
timeout = 2000
|
timeout = 2000
|
||||||
logconfig = 'conf/logging.conf'
|
logconfig = 'conf/logging.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
preload_app = True
|
preload_app = True
|
||||||
|
|
|
@ -3,4 +3,4 @@ workers = 4
|
||||||
timeout = 2000
|
timeout = 2000
|
||||||
logconfig = 'conf/logging.conf'
|
logconfig = 'conf/logging.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
preload_app = True
|
preload_app = True
|
||||||
|
|
|
@ -4,4 +4,4 @@ worker_class = 'gevent'
|
||||||
timeout = 30
|
timeout = 30
|
||||||
logconfig = 'conf/logging.conf'
|
logconfig = 'conf/logging.conf'
|
||||||
pythonpath = '.'
|
pythonpath = '.'
|
||||||
preload_app = True
|
preload_app = True
|
||||||
|
|
|
@ -4,4 +4,4 @@ error_log /var/log/nginx/nginx.error.log;
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
accept_mutex off;
|
accept_mutex off;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ location / {
|
||||||
location /realtime {
|
location /realtime {
|
||||||
proxy_pass http://web_app_server;
|
proxy_pass http://web_app_server;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_request_buffering off;
|
proxy_request_buffering off;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /v1/ {
|
location /v1/ {
|
||||||
|
@ -59,4 +59,4 @@ location /v1/_ping {
|
||||||
add_header X-Docker-Registry-Version 0.6.0;
|
add_header X-Docker-Registry-Version 0.6.0;
|
||||||
add_header X-Docker-Registry-Standalone 0;
|
add_header X-Docker-Registry-Standalone 0;
|
||||||
return 200 'true';
|
return 200 'true';
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,9 @@ class DefaultConfig(object):
|
||||||
REGISTRY_TITLE = 'Quay.io'
|
REGISTRY_TITLE = 'Quay.io'
|
||||||
REGISTRY_TITLE_SHORT = 'Quay.io'
|
REGISTRY_TITLE_SHORT = 'Quay.io'
|
||||||
CONTACT_INFO = [
|
CONTACT_INFO = [
|
||||||
'mailto:support@quay.io',
|
'mailto:support@quay.io',
|
||||||
'irc://chat.freenode.net:6665/quayio',
|
'irc://chat.freenode.net:6665/quayio',
|
||||||
'tel:+1-888-930-3475',
|
'tel:+1-888-930-3475',
|
||||||
'https://twitter.com/quayio',
|
'https://twitter.com/quayio',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ class RedisBuildLogs(object):
|
||||||
return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj)) - 1
|
return self._redis.rpush(self._logs_key(build_id), json.dumps(log_obj)) - 1
|
||||||
|
|
||||||
def get_log_entries(self, build_id, start_index):
|
def get_log_entries(self, build_id, start_index):
|
||||||
"""
|
"""
|
||||||
Returns a tuple of the current length of the list and an iterable of the
|
Returns a tuple of the current length of the list and an iterable of the
|
||||||
requested log entries.
|
requested log entries.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -25,4 +25,4 @@ def downgrade(tables):
|
||||||
(tables.logentrykind.delete()
|
(tables.logentrykind.delete()
|
||||||
.where(tables.logentrykind.c.name == op.inline_literal('repo_verb')))
|
.where(tables.logentrykind.c.name == op.inline_literal('repo_verb')))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -71,7 +71,7 @@ def upgrade(tables):
|
||||||
op.create_index('repositorynotification_repository_id', 'repositorynotification', ['repository_id'], unique=False)
|
op.create_index('repositorynotification_repository_id', 'repositorynotification', ['repository_id'], unique=False)
|
||||||
op.create_index('repositorynotification_uuid', 'repositorynotification', ['uuid'], unique=False)
|
op.create_index('repositorynotification_uuid', 'repositorynotification', ['uuid'], unique=False)
|
||||||
op.add_column(u'notification', sa.Column('dismissed', sa.Boolean(), nullable=False))
|
op.add_column(u'notification', sa.Column('dismissed', sa.Boolean(), nullable=False))
|
||||||
|
|
||||||
# Manually add the new notificationkind types
|
# Manually add the new notificationkind types
|
||||||
op.bulk_insert(tables.notificationkind,
|
op.bulk_insert(tables.notificationkind,
|
||||||
[
|
[
|
||||||
|
|
|
@ -114,7 +114,7 @@ def upgrade(tables):
|
||||||
{'id':30, 'name':'create_prototype_permission'},
|
{'id':30, 'name':'create_prototype_permission'},
|
||||||
{'id':31, 'name':'modify_prototype_permission'},
|
{'id':31, 'name':'modify_prototype_permission'},
|
||||||
{'id':32, 'name':'delete_prototype_permission'},
|
{'id':32, 'name':'delete_prototype_permission'},
|
||||||
|
|
||||||
{'id':33, 'name':'setup_repo_trigger'},
|
{'id':33, 'name':'setup_repo_trigger'},
|
||||||
{'id':34, 'name':'delete_repo_trigger'},
|
{'id':34, 'name':'delete_repo_trigger'},
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
from data.model.legacy import *
|
from data.model.legacy import *
|
|
@ -102,7 +102,7 @@ class DatabaseAuthorizationProvider(AuthorizationProvider):
|
||||||
.get())
|
.get())
|
||||||
return found.data
|
return found.data
|
||||||
except OAuthAccessToken.DoesNotExist:
|
except OAuthAccessToken.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def persist_authorization_code(self, client_id, code, scope):
|
def persist_authorization_code(self, client_id, code, scope):
|
||||||
app = OAuthApplication.get(client_id=client_id)
|
app = OAuthApplication.get(client_id=client_id)
|
||||||
|
@ -261,7 +261,7 @@ def list_access_tokens_for_user(user):
|
||||||
.join(User)
|
.join(User)
|
||||||
.where(OAuthAccessToken.authorized_user == user))
|
.where(OAuthAccessToken.authorized_user == user))
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
def list_applications_for_org(org):
|
def list_applications_for_org(org):
|
||||||
|
|
|
@ -44,7 +44,7 @@ class WorkQueue(object):
|
||||||
def update_metrics(self):
|
def update_metrics(self):
|
||||||
if self._reporter is None:
|
if self._reporter is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
with self._transaction_factory(db):
|
with self._transaction_factory(db):
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
name_match_query = self._name_match_query()
|
name_match_query = self._name_match_query()
|
||||||
|
|
|
@ -102,13 +102,13 @@ class UserEventListener(object):
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.loads(item['data'] or '{}')
|
data = json.loads(item['data'] or '{}')
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
yield event_id, data
|
yield event_id, data
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Unsubscribes from the channel(s). Should be called once the connection
|
Unsubscribes from the channel(s). Should be called once the connection
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
<!-- HEADER -->
|
<!-- HEADER -->
|
||||||
<table class="head-wrap" bgcolor="#FFFFFF" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
<table class="head-wrap" bgcolor="#FFFFFF" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||||
<td class="header container" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 100% !important; clear: both !important; margin: 0; padding: 0;">
|
<td class="header container" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; display: block !important; max-width: 100% !important; clear: both !important; margin: 0; padding: 0;">
|
||||||
|
|
||||||
<div class="content" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; display: block; margin: 0; padding: 15px;">
|
<div class="content" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; display: block; margin: 0; padding: 15px;">
|
||||||
<table bgcolor="#FFFFFF" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><img src="{{ app_logo }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; margin: 0; padding: 0;" alt="{{ app_title }}" title="{{ app_title }}"/></td>
|
<table bgcolor="#FFFFFF" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><img src="{{ app_logo }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; max-width: 100%; margin: 0; padding: 0;" alt="{{ app_title }}" title="{{ app_title }}"/></td>
|
||||||
</tr></table></div>
|
</tr></table></div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||||
</tr></table><!-- /HEADER --><!-- BODY --><table class="body-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
</tr></table><!-- /HEADER --><!-- BODY --><table class="body-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;"><tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"><td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</td>
|
</td>
|
||||||
</tr></table></div><!-- /content -->
|
</tr></table></div><!-- /content -->
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;"></td>
|
||||||
</tr></table><!-- /BODY -->
|
</tr></table><!-- /BODY -->
|
||||||
|
|
|
@ -289,7 +289,7 @@ def require_fresh_login(func):
|
||||||
|
|
||||||
if not user.password_hash or last_login >= valid_span:
|
if not user.password_hash or last_login >= valid_span:
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
raise FreshLoginRequired()
|
raise FreshLoginRequired()
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ def get_invoices(customer_id):
|
||||||
'total': i.total,
|
'total': i.total,
|
||||||
'plan': i.lines.data[0].plan.id if i.lines.data[0].plan else None
|
'plan': i.lines.data[0].plan.id if i.lines.data[0].plan else None
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
invoices = billing.Invoice.all(customer=customer_id, count=12)
|
invoices = billing.Invoice.all(customer=customer_id, count=12)
|
||||||
except stripe.APIConnectionError as e:
|
except stripe.APIConnectionError as e:
|
||||||
|
@ -247,7 +247,7 @@ class UserPlan(ApiResource):
|
||||||
except stripe.APIConnectionError as e:
|
except stripe.APIConnectionError as e:
|
||||||
abort(503, message='Cannot contact Stripe')
|
abort(503, message='Cannot contact Stripe')
|
||||||
|
|
||||||
if cus.subscription:
|
if cus.subscription:
|
||||||
return subscription_view(cus.subscription, private_repos)
|
return subscription_view(cus.subscription, private_repos)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -313,7 +313,7 @@ class OrganizationPlan(ApiResource):
|
||||||
except stripe.APIConnectionError as e:
|
except stripe.APIConnectionError as e:
|
||||||
abort(503, message='Cannot contact Stripe')
|
abort(503, message='Cannot contact Stripe')
|
||||||
|
|
||||||
if cus.subscription:
|
if cus.subscription:
|
||||||
return subscription_view(cus.subscription, private_repos)
|
return subscription_view(cus.subscription, private_repos)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -338,7 +338,7 @@ class UserInvoiceList(ApiResource):
|
||||||
user = get_authenticated_user()
|
user = get_authenticated_user()
|
||||||
if not user.stripe_id:
|
if not user.stripe_id:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
return get_invoices(user.stripe_id)
|
return get_invoices(user.stripe_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ class OrgnaizationInvoiceList(ApiResource):
|
||||||
organization = model.get_organization(orgname)
|
organization = model.get_organization(orgname)
|
||||||
if not organization.stripe_id:
|
if not organization.stripe_id:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
return get_invoices(organization.stripe_id)
|
return get_invoices(organization.stripe_id)
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
|
@ -42,7 +42,7 @@ def user_view(user):
|
||||||
|
|
||||||
def trigger_view(trigger):
|
def trigger_view(trigger):
|
||||||
|
|
||||||
if trigger and trigger.uuid:
|
if trigger and trigger.uuid:
|
||||||
config_dict = get_trigger_config(trigger)
|
config_dict = get_trigger_config(trigger)
|
||||||
build_trigger = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
build_trigger = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
||||||
return {
|
return {
|
||||||
|
@ -200,7 +200,7 @@ class RepositoryBuildStatus(RepositoryParamResource):
|
||||||
if (not build or build.repository.name != repository or
|
if (not build or build.repository.name != repository or
|
||||||
build.repository.namespace_user.username != namespace):
|
build.repository.namespace_user.username != namespace):
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
can_write = ModifyRepositoryPermission(namespace, repository).can()
|
can_write = ModifyRepositoryPermission(namespace, repository).can()
|
||||||
return build_status_view(build, can_write)
|
return build_status_view(build, can_write)
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ def swagger_route_data(include_internal=False, compact=False):
|
||||||
|
|
||||||
if 'view_class' in dir(endpoint_method):
|
if 'view_class' in dir(endpoint_method):
|
||||||
view_class = endpoint_method.view_class
|
view_class = endpoint_method.view_class
|
||||||
|
|
||||||
param_data_map = {}
|
param_data_map = {}
|
||||||
if '__api_path_params' in dir(view_class):
|
if '__api_path_params' in dir(view_class):
|
||||||
param_data_map = view_class.__api_path_params
|
param_data_map = view_class.__api_path_params
|
||||||
|
@ -126,7 +126,7 @@ def swagger_route_data(include_internal=False, compact=False):
|
||||||
|
|
||||||
if not internal or (internal and include_internal):
|
if not internal or (internal and include_internal):
|
||||||
# Swagger requires valid nicknames on all operations.
|
# Swagger requires valid nicknames on all operations.
|
||||||
if new_operation.get('nickname'):
|
if new_operation.get('nickname'):
|
||||||
operations.append(new_operation)
|
operations.append(new_operation)
|
||||||
else:
|
else:
|
||||||
logger.debug('Operation missing nickname: %s' % method)
|
logger.debug('Operation missing nickname: %s' % method)
|
||||||
|
@ -149,7 +149,7 @@ def swagger_route_data(include_internal=False, compact=False):
|
||||||
|
|
||||||
if not internal or (internal and include_internal):
|
if not internal or (internal and include_internal):
|
||||||
apis.append(new_resource)
|
apis.append(new_resource)
|
||||||
|
|
||||||
# If compact form was requested, simply return the APIs.
|
# If compact form was requested, simply return the APIs.
|
||||||
if compact:
|
if compact:
|
||||||
return {'apis': apis}
|
return {'apis': apis}
|
||||||
|
|
|
@ -15,7 +15,7 @@ def log_view(log):
|
||||||
view = {
|
view = {
|
||||||
'kind': log.kind.name,
|
'kind': log.kind.name,
|
||||||
'metadata': json.loads(log.metadata_json),
|
'metadata': json.loads(log.metadata_json),
|
||||||
'ip': log.ip,
|
'ip': log.ip,
|
||||||
'datetime': format_date(log.datetime),
|
'datetime': format_date(log.datetime),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ def get_logs(start_time, end_time, performer_name=None, repository=None, namespa
|
||||||
except ValueError:
|
except ValueError:
|
||||||
start_time = None
|
start_time = None
|
||||||
|
|
||||||
if not start_time:
|
if not start_time:
|
||||||
start_time = datetime.today() - timedelta(7) # One week
|
start_time = datetime.today() - timedelta(7) # One week
|
||||||
|
|
||||||
if end_time:
|
if end_time:
|
||||||
|
@ -49,8 +49,8 @@ def get_logs(start_time, end_time, performer_name=None, repository=None, namespa
|
||||||
end_time = end_time + timedelta(days=1)
|
end_time = end_time + timedelta(days=1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
end_time = None
|
end_time = None
|
||||||
|
|
||||||
if not end_time:
|
if not end_time:
|
||||||
end_time = datetime.today()
|
end_time = datetime.today()
|
||||||
|
|
||||||
logs = model.list_logs(start_time, end_time, performer=performer, repository=repository,
|
logs = model.list_logs(start_time, end_time, performer=performer, repository=repository,
|
||||||
|
|
|
@ -143,7 +143,7 @@ class Organization(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
org_data = request.get_json()
|
org_data = request.get_json()
|
||||||
if 'invoice_email' in org_data:
|
if 'invoice_email' in org_data:
|
||||||
logger.debug('Changing invoice_email for organization: %s', org.username)
|
logger.debug('Changing invoice_email for organization: %s', org.username)
|
||||||
|
@ -153,10 +153,10 @@ class Organization(ApiResource):
|
||||||
new_email = org_data['email']
|
new_email = org_data['email']
|
||||||
if model.find_user_by_email(new_email):
|
if model.find_user_by_email(new_email):
|
||||||
raise request_error(message='E-mail address already used')
|
raise request_error(message='E-mail address already used')
|
||||||
|
|
||||||
logger.debug('Changing email address for organization: %s', org.username)
|
logger.debug('Changing email address for organization: %s', org.username)
|
||||||
model.update_email(org, new_email)
|
model.update_email(org, new_email)
|
||||||
|
|
||||||
teams = model.get_teams_within_org(org)
|
teams = model.get_teams_within_org(org)
|
||||||
return org_view(org, teams)
|
return org_view(org, teams)
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
@ -186,13 +186,13 @@ class OrgPrivateRepositories(ApiResource):
|
||||||
plan = get_plan(cus.subscription.plan.id)
|
plan = get_plan(cus.subscription.plan.id)
|
||||||
if plan:
|
if plan:
|
||||||
repos_allowed = plan['privateRepos']
|
repos_allowed = plan['privateRepos']
|
||||||
|
|
||||||
data['privateAllowed'] = (private_repos < repos_allowed)
|
data['privateAllowed'] = (private_repos < repos_allowed)
|
||||||
|
|
||||||
|
|
||||||
if AdministerOrganizationPermission(orgname).can():
|
if AdministerOrganizationPermission(orgname).can():
|
||||||
data['privateCount'] = private_repos
|
data['privateCount'] = private_repos
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
@ -211,19 +211,19 @@ class OrgnaizationMemberList(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
# Loop to create the members dictionary. Note that the members collection
|
# Loop to create the members dictionary. Note that the members collection
|
||||||
# will return an entry for *every team* a member is on, so we will have
|
# will return an entry for *every team* a member is on, so we will have
|
||||||
# duplicate keys (which is why we pre-build the dictionary).
|
# duplicate keys (which is why we pre-build the dictionary).
|
||||||
members_dict = {}
|
members_dict = {}
|
||||||
members = model.get_organization_members_with_teams(org)
|
members = model.get_organization_members_with_teams(org)
|
||||||
for member in members:
|
for member in members:
|
||||||
if not member.user.username in members_dict:
|
if not member.user.username in members_dict:
|
||||||
members_dict[member.user.username] = {'name': member.user.username,
|
members_dict[member.user.username] = {'name': member.user.username,
|
||||||
'kind': 'user',
|
'kind': 'user',
|
||||||
'is_robot': member.user.robot,
|
'is_robot': member.user.robot,
|
||||||
'teams': []}
|
'teams': []}
|
||||||
|
|
||||||
members_dict[member.user.username]['teams'].append(member.team.name)
|
members_dict[member.user.username]['teams'].append(member.team.name)
|
||||||
|
|
||||||
return {'members': members_dict}
|
return {'members': members_dict}
|
||||||
|
@ -244,7 +244,7 @@ class OrganizationMember(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
member_dict = None
|
member_dict = None
|
||||||
member_teams = model.get_organization_members_with_teams(org, membername=membername)
|
member_teams = model.get_organization_members_with_teams(org, membername=membername)
|
||||||
for member in member_teams:
|
for member in member_teams:
|
||||||
|
@ -253,7 +253,7 @@ class OrganizationMember(ApiResource):
|
||||||
'kind': 'user',
|
'kind': 'user',
|
||||||
'is_robot': member.user.robot,
|
'is_robot': member.user.robot,
|
||||||
'teams': []}
|
'teams': []}
|
||||||
|
|
||||||
member_dict['teams'].append(member.team.name)
|
member_dict['teams'].append(member.team.name)
|
||||||
|
|
||||||
if not member_dict:
|
if not member_dict:
|
||||||
|
@ -364,7 +364,7 @@ class OrganizationApplications(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
app_data = request.get_json()
|
app_data = request.get_json()
|
||||||
application = model.oauth.create_application(
|
application = model.oauth.create_application(
|
||||||
org, app_data['name'],
|
org, app_data['name'],
|
||||||
|
@ -397,7 +397,7 @@ class OrganizationApplicationResource(ApiResource):
|
||||||
'required': [
|
'required': [
|
||||||
'name',
|
'name',
|
||||||
'redirect_uri',
|
'redirect_uri',
|
||||||
'application_uri'
|
'application_uri'
|
||||||
],
|
],
|
||||||
'properties': {
|
'properties': {
|
||||||
'name': {
|
'name': {
|
||||||
|
@ -452,7 +452,7 @@ class OrganizationApplicationResource(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
application = model.oauth.lookup_application(org, client_id)
|
application = model.oauth.lookup_application(org, client_id)
|
||||||
if not application:
|
if not application:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
@ -485,7 +485,7 @@ class OrganizationApplicationResource(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
application = model.oauth.delete_application(org, client_id)
|
application = model.oauth.delete_application(org, client_id)
|
||||||
if not application:
|
if not application:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
@ -510,7 +510,7 @@ class OrganizationApplicationResetClientSecret(ApiResource):
|
||||||
org = model.get_organization(orgname)
|
org = model.get_organization(orgname)
|
||||||
except model.InvalidOrganizationException:
|
except model.InvalidOrganizationException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
application = model.oauth.lookup_application(org, client_id)
|
application = model.oauth.lookup_application(org, client_id)
|
||||||
if not application:
|
if not application:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
|
@ -70,7 +70,7 @@ class RepositoryUserPermissionList(RepositoryParamResource):
|
||||||
org_members)
|
org_members)
|
||||||
|
|
||||||
role_view_func = wrapped_role_org_view
|
role_view_func = wrapped_role_org_view
|
||||||
|
|
||||||
# Load and return the permissions.
|
# Load and return the permissions.
|
||||||
repo_perms = model.get_all_repo_users(namespace, repository)
|
repo_perms = model.get_all_repo_users(namespace, repository)
|
||||||
return {
|
return {
|
||||||
|
@ -150,7 +150,7 @@ class RepositoryUserPermission(RepositoryParamResource):
|
||||||
pass
|
pass
|
||||||
except model.DataModelException as ex:
|
except model.DataModelException as ex:
|
||||||
raise request_error(exception=ex)
|
raise request_error(exception=ex)
|
||||||
|
|
||||||
log_action('change_repo_permission', namespace,
|
log_action('change_repo_permission', namespace,
|
||||||
{'username': username, 'repo': repository,
|
{'username': username, 'repo': repository,
|
||||||
'role': new_permission['role']},
|
'role': new_permission['role']},
|
||||||
|
@ -170,7 +170,7 @@ class RepositoryUserPermission(RepositoryParamResource):
|
||||||
log_action('delete_repo_permission', namespace,
|
log_action('delete_repo_permission', namespace,
|
||||||
{'username': username, 'repo': repository},
|
{'username': username, 'repo': repository},
|
||||||
repo=model.get_repository(namespace, repository))
|
repo=model.get_repository(namespace, repository))
|
||||||
|
|
||||||
return 'Deleted', 204
|
return 'Deleted', 204
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ def log_prototype_action(action_kind, orgname, prototype, **kwargs):
|
||||||
log_params['delegate_user'] = prototype.delegate_user.username
|
log_params['delegate_user'] = prototype.delegate_user.username
|
||||||
elif prototype.delegate_team:
|
elif prototype.delegate_team:
|
||||||
log_params['delegate_team'] = prototype.delegate_team.name
|
log_params['delegate_team'] = prototype.delegate_team.name
|
||||||
|
|
||||||
log_action(action_kind, orgname, log_params)
|
log_action(action_kind, orgname, log_params)
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ class PermissionPrototypeList(ApiResource):
|
||||||
'name': {
|
'name': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'description': 'The name for the delegate team or user',
|
'description': 'The name for the delegate team or user',
|
||||||
},
|
},
|
||||||
'kind': {
|
'kind': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'description': 'Whether the delegate is a user or a team',
|
'description': 'Whether the delegate is a user or a team',
|
||||||
|
@ -108,7 +108,7 @@ class PermissionPrototypeList(ApiResource):
|
||||||
'user',
|
'user',
|
||||||
'team',
|
'team',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -128,7 +128,7 @@ class PermissionPrototypeList(ApiResource):
|
||||||
permissions = model.get_prototype_permissions(org)
|
permissions = model.get_prototype_permissions(org)
|
||||||
org_members = model.get_organization_member_set(orgname)
|
org_members = model.get_organization_member_set(orgname)
|
||||||
return {'prototypes': [prototype_view(p, org_members) for p in permissions]}
|
return {'prototypes': [prototype_view(p, org_members) for p in permissions]}
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
@nickname('createOrganizationPrototypePermission')
|
@nickname('createOrganizationPrototypePermission')
|
||||||
|
@ -148,7 +148,7 @@ class PermissionPrototypeList(ApiResource):
|
||||||
if ('activating_user' in details and details['activating_user'] and
|
if ('activating_user' in details and details['activating_user'] and
|
||||||
'name' in details['activating_user']):
|
'name' in details['activating_user']):
|
||||||
activating_username = details['activating_user']['name']
|
activating_username = details['activating_user']['name']
|
||||||
|
|
||||||
delegate = details['delegate'] if 'delegate' in details else {}
|
delegate = details['delegate'] if 'delegate' in details else {}
|
||||||
delegate_kind = delegate.get('kind', None)
|
delegate_kind = delegate.get('kind', None)
|
||||||
delegate_name = delegate.get('name', None)
|
delegate_name = delegate.get('name', None)
|
||||||
|
@ -174,7 +174,7 @@ class PermissionPrototypeList(ApiResource):
|
||||||
log_prototype_action('create_prototype_permission', orgname, prototype)
|
log_prototype_action('create_prototype_permission', orgname, prototype)
|
||||||
org_members = model.get_organization_member_set(orgname)
|
org_members = model.get_organization_member_set(orgname)
|
||||||
return prototype_view(prototype, org_members)
|
return prototype_view(prototype, org_members)
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ class PermissionPrototype(ApiResource):
|
||||||
log_prototype_action('delete_prototype_permission', orgname, prototype)
|
log_prototype_action('delete_prototype_permission', orgname, prototype)
|
||||||
|
|
||||||
return 'Deleted', 204
|
return 'Deleted', 204
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
@nickname('updateOrganizationPrototypePermission')
|
@nickname('updateOrganizationPrototypePermission')
|
||||||
|
@ -249,5 +249,5 @@ class PermissionPrototype(ApiResource):
|
||||||
original_role=existing.role.name)
|
original_role=existing.role.name)
|
||||||
org_members = model.get_organization_member_set(orgname)
|
org_members = model.get_organization_member_set(orgname)
|
||||||
return prototype_view(prototype, org_members)
|
return prototype_view(prototype, org_members)
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
|
@ -45,7 +45,7 @@ class RepositoryAuthorizedEmail(RepositoryParamResource):
|
||||||
@nickname('sendAuthorizeRepoEmail')
|
@nickname('sendAuthorizeRepoEmail')
|
||||||
def post(self, namespace, repository, email):
|
def post(self, namespace, repository, email):
|
||||||
""" Starts the authorization process for an e-mail address on a repository. """
|
""" Starts the authorization process for an e-mail address on a repository. """
|
||||||
|
|
||||||
with tf(db):
|
with tf(db):
|
||||||
record = model.get_email_authorized_for_repo(namespace, repository, email)
|
record = model.get_email_authorized_for_repo(namespace, repository, email)
|
||||||
if record and record.confirmed:
|
if record and record.confirmed:
|
||||||
|
|
|
@ -201,7 +201,7 @@ class Repository(RepositoryParamResource):
|
||||||
}
|
}
|
||||||
|
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
@require_repo_write
|
@require_repo_write
|
||||||
@nickname('updateRepo')
|
@nickname('updateRepo')
|
||||||
@validate_json_request('RepoUpdate')
|
@validate_json_request('RepoUpdate')
|
||||||
|
@ -212,7 +212,7 @@ class Repository(RepositoryParamResource):
|
||||||
values = request.get_json()
|
values = request.get_json()
|
||||||
repo.description = values['description']
|
repo.description = values['description']
|
||||||
repo.save()
|
repo.save()
|
||||||
|
|
||||||
log_action('set_repo_description', namespace,
|
log_action('set_repo_description', namespace,
|
||||||
{'repo': repository, 'description': values['description']},
|
{'repo': repository, 'description': values['description']},
|
||||||
repo=repo)
|
repo=repo)
|
||||||
|
|
|
@ -78,7 +78,7 @@ class RepositoryNotificationList(RepositoryParamResource):
|
||||||
json['config'])
|
json['config'])
|
||||||
|
|
||||||
resp = notification_view(notification)
|
resp = notification_view(notification)
|
||||||
log_action('add_repo_notification', namespace,
|
log_action('add_repo_notification', namespace,
|
||||||
{'repo': repository, 'notification_id': notification.uuid,
|
{'repo': repository, 'notification_id': notification.uuid,
|
||||||
'event': json['event'], 'method': json['method']},
|
'event': json['event'], 'method': json['method']},
|
||||||
repo=repo)
|
repo=repo)
|
||||||
|
@ -117,7 +117,7 @@ class RepositoryNotification(RepositoryParamResource):
|
||||||
def delete(self, namespace, repository, uuid):
|
def delete(self, namespace, repository, uuid):
|
||||||
""" Deletes the specified notification. """
|
""" Deletes the specified notification. """
|
||||||
notification = model.delete_repo_notification(namespace, repository, uuid)
|
notification = model.delete_repo_notification(namespace, repository, uuid)
|
||||||
log_action('delete_repo_notification', namespace,
|
log_action('delete_repo_notification', namespace,
|
||||||
{'repo': repository, 'notification_id': uuid,
|
{'repo': repository, 'notification_id': uuid,
|
||||||
'event': notification.event.name, 'method': notification.method.name},
|
'event': notification.event.name, 'method': notification.method.name},
|
||||||
repo=model.get_repository(namespace, repository))
|
repo=model.get_repository(namespace, repository))
|
||||||
|
|
|
@ -96,7 +96,7 @@ class OrgRobot(ApiResource):
|
||||||
parent = model.get_organization(orgname)
|
parent = model.get_organization(orgname)
|
||||||
robot, password = model.get_robot(robot_shortname, parent)
|
robot, password = model.get_robot(robot_shortname, parent)
|
||||||
return robot_view(robot.username, password)
|
return robot_view(robot.username, password)
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
@require_scope(scopes.ORG_ADMIN)
|
@require_scope(scopes.ORG_ADMIN)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class EntitySearch(ApiResource):
|
||||||
robot_namespace = namespace_name
|
robot_namespace = namespace_name
|
||||||
|
|
||||||
if args['includeTeams']:
|
if args['includeTeams']:
|
||||||
teams = model.get_matching_teams(prefix, organization)
|
teams = model.get_matching_teams(prefix, organization)
|
||||||
|
|
||||||
if args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) \
|
if args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) \
|
||||||
and namespace_name.startswith(prefix):
|
and namespace_name.startswith(prefix):
|
||||||
|
@ -124,6 +124,6 @@ class FindRepositories(ApiResource):
|
||||||
matching = model.get_matching_repositories(prefix, username)
|
matching = model.get_matching_repositories(prefix, username)
|
||||||
return {
|
return {
|
||||||
'repositories': [repo_view(repo) for repo in matching
|
'repositories': [repo_view(repo) for repo in matching
|
||||||
if (repo.visibility.name == 'public' or
|
if (repo.visibility.name == 'public' or
|
||||||
ReadRepositoryPermission(repo.namespace_user.username, repo.name).can())]
|
ReadRepositoryPermission(repo.namespace_user.username, repo.name).can())]
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
# They want a real paying plan, create the customer and plan
|
# They want a real paying plan, create the customer and plan
|
||||||
# simultaneously
|
# simultaneously
|
||||||
card = token
|
card = token
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cus = billing.Customer.create(email=user.email, plan=plan, card=card)
|
cus = billing.Customer.create(email=user.email, plan=plan, card=card)
|
||||||
user.stripe_id = cus.id
|
user.stripe_id = cus.id
|
||||||
|
@ -116,7 +116,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
return carderror_response(e)
|
return carderror_response(e)
|
||||||
except stripe.APIConnectionError as e:
|
except stripe.APIConnectionError as e:
|
||||||
return connection_response(e)
|
return connection_response(e)
|
||||||
|
|
||||||
response_json = subscription_view(cus.subscription, private_repos)
|
response_json = subscription_view(cus.subscription, private_repos)
|
||||||
check_repository_usage(user, plan_found)
|
check_repository_usage(user, plan_found)
|
||||||
log_action('account_change_plan', user.username, {'plan': plan})
|
log_action('account_change_plan', user.username, {'plan': plan})
|
||||||
|
|
|
@ -38,7 +38,7 @@ class SuperUserLogs(ApiResource):
|
||||||
performer_name = args['performer']
|
performer_name = args['performer']
|
||||||
start_time = args['starttime']
|
start_time = args['starttime']
|
||||||
end_time = args['endtime']
|
end_time = args['endtime']
|
||||||
|
|
||||||
return get_logs(start_time, end_time)
|
return get_logs(start_time, end_time)
|
||||||
|
|
||||||
abort(403)
|
abort(403)
|
||||||
|
@ -196,7 +196,7 @@ class SuperUserManagement(ApiResource):
|
||||||
user = model.get_user(username)
|
user = model.get_user(username)
|
||||||
if not user or user.organization or user.robot:
|
if not user or user.organization or user.robot:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
return user_view(user)
|
return user_view(user)
|
||||||
|
|
||||||
abort(403)
|
abort(403)
|
||||||
|
@ -237,7 +237,7 @@ class SuperUserManagement(ApiResource):
|
||||||
|
|
||||||
if 'email' in user_data:
|
if 'email' in user_data:
|
||||||
model.update_email(user, user_data['email'])
|
model.update_email(user, user_data['email'])
|
||||||
|
|
||||||
return user_view(user)
|
return user_view(user)
|
||||||
|
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class RepositoryTag(RepositoryParamResource):
|
||||||
image = model.get_repo_image(namespace, repository, image_id)
|
image = model.get_repo_image(namespace, repository, image_id)
|
||||||
if not image:
|
if not image:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
original_image_id = None
|
original_image_id = None
|
||||||
try:
|
try:
|
||||||
original_tag_image = model.get_tag_image(namespace, repository, tag)
|
original_tag_image = model.get_tag_image(namespace, repository, tag)
|
||||||
|
|
|
@ -28,7 +28,7 @@ def try_accept_invite(code, user):
|
||||||
|
|
||||||
|
|
||||||
def handle_addinvite_team(inviter, team, user=None, email=None):
|
def handle_addinvite_team(inviter, team, user=None, email=None):
|
||||||
invite = model.add_or_invite_to_team(inviter, team, user, email,
|
invite = model.add_or_invite_to_team(inviter, team, user, email,
|
||||||
requires_invite = features.MAILING)
|
requires_invite = features.MAILING)
|
||||||
if not invite:
|
if not invite:
|
||||||
# User was added to the team directly.
|
# User was added to the team directly.
|
||||||
|
@ -146,7 +146,7 @@ class OrganizationTeam(ApiResource):
|
||||||
team = model.set_team_org_permission(team, details['role'],
|
team = model.set_team_org_permission(team, details['role'],
|
||||||
get_authenticated_user().username)
|
get_authenticated_user().username)
|
||||||
log_action('org_set_team_role', orgname, {'team': teamname, 'role': details['role']})
|
log_action('org_set_team_role', orgname, {'team': teamname, 'role': details['role']})
|
||||||
|
|
||||||
return team_view(orgname, team), 200
|
return team_view(orgname, team), 200
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
@ -181,7 +181,7 @@ class TeamMemberList(ApiResource):
|
||||||
team = model.get_organization_team(orgname, teamname)
|
team = model.get_organization_team(orgname, teamname)
|
||||||
except model.InvalidTeamException:
|
except model.InvalidTeamException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
members = model.get_organization_team_members(team.id)
|
members = model.get_organization_team_members(team.id)
|
||||||
invites = []
|
invites = []
|
||||||
|
|
||||||
|
@ -220,14 +220,14 @@ class TeamMember(ApiResource):
|
||||||
user = model.get_user(membername)
|
user = model.get_user(membername)
|
||||||
if not user:
|
if not user:
|
||||||
raise request_error(message='Unknown user')
|
raise request_error(message='Unknown user')
|
||||||
|
|
||||||
# Add or invite the user to the team.
|
# Add or invite the user to the team.
|
||||||
inviter = get_authenticated_user()
|
inviter = get_authenticated_user()
|
||||||
invite = handle_addinvite_team(inviter, team, user=user)
|
invite = handle_addinvite_team(inviter, team, user=user)
|
||||||
if not invite:
|
if not invite:
|
||||||
log_action('org_add_team_member', orgname, {'member': membername, 'team': teamname})
|
log_action('org_add_team_member', orgname, {'member': membername, 'team': teamname})
|
||||||
return member_view(user, invited=False)
|
return member_view(user, invited=False)
|
||||||
|
|
||||||
# User was invited.
|
# User was invited.
|
||||||
log_action('org_invite_team_member', orgname, {
|
log_action('org_invite_team_member', orgname, {
|
||||||
'user': membername,
|
'user': membername,
|
||||||
|
@ -254,7 +254,7 @@ class TeamMember(ApiResource):
|
||||||
team = model.get_organization_team(orgname, teamname)
|
team = model.get_organization_team(orgname, teamname)
|
||||||
except model.InvalidTeamException:
|
except model.InvalidTeamException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
# Find the member.
|
# Find the member.
|
||||||
member = model.get_user(membername)
|
member = model.get_user(membername)
|
||||||
if not member:
|
if not member:
|
||||||
|
@ -294,7 +294,7 @@ class InviteTeamMember(ApiResource):
|
||||||
team = model.get_organization_team(orgname, teamname)
|
team = model.get_organization_team(orgname, teamname)
|
||||||
except model.InvalidTeamException:
|
except model.InvalidTeamException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
# Invite the email to the team.
|
# Invite the email to the team.
|
||||||
inviter = get_authenticated_user()
|
inviter = get_authenticated_user()
|
||||||
invite = handle_addinvite_team(inviter, team, email=email)
|
invite = handle_addinvite_team(inviter, team, email=email)
|
||||||
|
@ -320,7 +320,7 @@ class InviteTeamMember(ApiResource):
|
||||||
team = model.get_organization_team(orgname, teamname)
|
team = model.get_organization_team(orgname, teamname)
|
||||||
except model.InvalidTeamException:
|
except model.InvalidTeamException:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
# Delete the invite.
|
# Delete the invite.
|
||||||
model.delete_team_email_invite(team, email)
|
model.delete_team_email_invite(team, email)
|
||||||
log_action('org_delete_team_member_invite', orgname, {
|
log_action('org_delete_team_member_invite', orgname, {
|
||||||
|
@ -345,7 +345,7 @@ class TeamMemberInvite(ApiResource):
|
||||||
# Accept the invite for the current user.
|
# Accept the invite for the current user.
|
||||||
team = try_accept_invite(code, get_authenticated_user())
|
team = try_accept_invite(code, get_authenticated_user())
|
||||||
if not team:
|
if not team:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
orgname = team.organization.username
|
orgname = team.organization.username
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -76,7 +76,7 @@ class BuildTrigger(RepositoryParamResource):
|
||||||
# We are just going to eat this error
|
# We are just going to eat this error
|
||||||
logger.warning('Trigger deactivation problem: %s', ex)
|
logger.warning('Trigger deactivation problem: %s', ex)
|
||||||
|
|
||||||
log_action('delete_repo_trigger', namespace,
|
log_action('delete_repo_trigger', namespace,
|
||||||
{'repo': repository, 'trigger_id': trigger_uuid,
|
{'repo': repository, 'trigger_id': trigger_uuid,
|
||||||
'service': trigger.service.name, 'config': config_dict},
|
'service': trigger.service.name, 'config': config_dict},
|
||||||
repo=model.get_repository(namespace, repository))
|
repo=model.get_repository(namespace, repository))
|
||||||
|
@ -192,7 +192,7 @@ class BuildTriggerActivate(RepositoryParamResource):
|
||||||
|
|
||||||
# Make sure the namespace matches that of the trigger.
|
# Make sure the namespace matches that of the trigger.
|
||||||
if robot_namespace != namespace:
|
if robot_namespace != namespace:
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
# Set the pull robot.
|
# Set the pull robot.
|
||||||
trigger.pull_robot = pull_robot
|
trigger.pull_robot = pull_robot
|
||||||
|
@ -224,7 +224,7 @@ class BuildTriggerActivate(RepositoryParamResource):
|
||||||
repo = model.get_repository(namespace, repository)
|
repo = model.get_repository(namespace, repository)
|
||||||
log_action('setup_repo_trigger', namespace,
|
log_action('setup_repo_trigger', namespace,
|
||||||
{'repo': repository, 'namespace': namespace,
|
{'repo': repository, 'namespace': namespace,
|
||||||
'trigger_id': trigger.uuid, 'service': trigger.service.name,
|
'trigger_id': trigger.uuid, 'service': trigger.service.name,
|
||||||
'pull_robot': trigger.pull_robot.username if trigger.pull_robot else None,
|
'pull_robot': trigger.pull_robot.username if trigger.pull_robot else None,
|
||||||
'config': final_config}, repo=repo)
|
'config': final_config}, repo=repo)
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ class BuildTriggerAnalyze(RepositoryParamResource):
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'message': 'Could not parse the Dockerfile specified'
|
'message': 'Could not parse the Dockerfile specified'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine the base image (i.e. the FROM) for the Dockerfile.
|
# Determine the base image (i.e. the FROM) for the Dockerfile.
|
||||||
base_image = parsed.get_base_image()
|
base_image = parsed.get_base_image()
|
||||||
if not base_image:
|
if not base_image:
|
||||||
|
@ -346,7 +346,7 @@ class BuildTriggerAnalyze(RepositoryParamResource):
|
||||||
# Make sure the current user can see/administer the robot.
|
# Make sure the current user can see/administer the robot.
|
||||||
(robot_namespace, shortname) = parse_robot_username(user.username)
|
(robot_namespace, shortname) = parse_robot_username(user.username)
|
||||||
return AdministerOrganizationPermission(robot_namespace).can()
|
return AdministerOrganizationPermission(robot_namespace).can()
|
||||||
|
|
||||||
repo_users = list(model.get_all_repo_users_transitive(base_namespace, base_repository))
|
repo_users = list(model.get_all_repo_users_transitive(base_namespace, base_repository))
|
||||||
read_robots = [robot_view(user) for user in repo_users if is_valid_robot(user)]
|
read_robots = [robot_view(user) for user in repo_users if is_valid_robot(user)]
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ class BuildTriggerAnalyze(RepositoryParamResource):
|
||||||
}
|
}
|
||||||
|
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
|
|
||||||
@resource('/v1/repository/<repopath:repository>/trigger/<trigger_uuid>/start')
|
@resource('/v1/repository/<repopath:repository>/trigger/<trigger_uuid>/start')
|
||||||
class ActivateBuildTrigger(RepositoryParamResource):
|
class ActivateBuildTrigger(RepositoryParamResource):
|
||||||
|
@ -462,7 +462,7 @@ class BuildTriggerFieldValues(RepositoryParamResource):
|
||||||
|
|
||||||
if values is None:
|
if values is None:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'values': values
|
'values': values
|
||||||
}
|
}
|
||||||
|
@ -486,7 +486,7 @@ class BuildTriggerSources(RepositoryParamResource):
|
||||||
user_permission = UserAdminPermission(trigger.connected_user.username)
|
user_permission = UserAdminPermission(trigger.connected_user.username)
|
||||||
if user_permission.can():
|
if user_permission.can():
|
||||||
trigger_handler = BuildTriggerBase.get_trigger_for_service(trigger.service.name)
|
trigger_handler = BuildTriggerBase.get_trigger_for_service(trigger.service.name)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'sources': trigger_handler.list_build_sources(trigger.auth_token)
|
'sources': trigger_handler.list_build_sources(trigger.auth_token)
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ class User(ApiResource):
|
||||||
user = get_authenticated_user()
|
user = get_authenticated_user()
|
||||||
user_data = request.get_json()
|
user_data = request.get_json()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if 'password' in user_data:
|
if 'password' in user_data:
|
||||||
logger.debug('Changing password for user: %s', user.username)
|
logger.debug('Changing password for user: %s', user.username)
|
||||||
log_action('account_change_password', user.username)
|
log_action('account_change_password', user.username)
|
||||||
|
@ -189,8 +189,8 @@ class User(ApiResource):
|
||||||
if model.find_user_by_email(new_email):
|
if model.find_user_by_email(new_email):
|
||||||
# Email already used.
|
# Email already used.
|
||||||
raise request_error(message='E-mail address already used')
|
raise request_error(message='E-mail address already used')
|
||||||
|
|
||||||
if features.MAILING:
|
if features.MAILING:
|
||||||
logger.debug('Sending email to change email address for user: %s',
|
logger.debug('Sending email to change email address for user: %s',
|
||||||
user.username)
|
user.username)
|
||||||
code = model.create_confirm_email_code(user, new_email=new_email)
|
code = model.create_confirm_email_code(user, new_email=new_email)
|
||||||
|
@ -206,7 +206,7 @@ class User(ApiResource):
|
||||||
raise request_error(message='Username is already in use')
|
raise request_error(message='Username is already in use')
|
||||||
|
|
||||||
model.change_username(user, new_username)
|
model.change_username(user, new_username)
|
||||||
|
|
||||||
except model.InvalidPasswordException, ex:
|
except model.InvalidPasswordException, ex:
|
||||||
raise request_error(exception=ex)
|
raise request_error(exception=ex)
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ class PrivateRepositories(ApiResource):
|
||||||
plan = get_plan(cus.subscription.plan.id)
|
plan = get_plan(cus.subscription.plan.id)
|
||||||
if plan:
|
if plan:
|
||||||
repos_allowed = plan['privateRepos']
|
repos_allowed = plan['privateRepos']
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'privateCount': private_repos,
|
'privateCount': private_repos,
|
||||||
'privateAllowed': (private_repos < repos_allowed)
|
'privateAllowed': (private_repos < repos_allowed)
|
||||||
|
|
|
@ -37,4 +37,4 @@ def csrf_protect(func):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
app.jinja_env.globals['csrf_token'] = generate_csrf_token
|
app.jinja_env.globals['csrf_token'] = generate_csrf_token
|
||||||
|
|
|
@ -146,7 +146,7 @@ def get_user():
|
||||||
'username': '$oauthtoken',
|
'username': '$oauthtoken',
|
||||||
'email': None,
|
'email': None,
|
||||||
})
|
})
|
||||||
elif get_authenticated_user():
|
elif get_authenticated_user():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'username': get_authenticated_user().username,
|
'username': get_authenticated_user().username,
|
||||||
'email': get_authenticated_user().email,
|
'email': get_authenticated_user().email,
|
||||||
|
@ -205,7 +205,7 @@ def create_repository(namespace, repository):
|
||||||
elif repo:
|
elif repo:
|
||||||
permission = ModifyRepositoryPermission(namespace, repository)
|
permission = ModifyRepositoryPermission(namespace, repository)
|
||||||
if not permission.can():
|
if not permission.can():
|
||||||
abort(403,
|
abort(403,
|
||||||
message='You do not have permission to modify repository %(namespace)s/%(repository)s',
|
message='You do not have permission to modify repository %(namespace)s/%(repository)s',
|
||||||
issue='no-repo-write-permission',
|
issue='no-repo-write-permission',
|
||||||
namespace=namespace, repository=repository)
|
namespace=namespace, repository=repository)
|
||||||
|
@ -214,7 +214,7 @@ def create_repository(namespace, repository):
|
||||||
permission = CreateRepositoryPermission(namespace)
|
permission = CreateRepositoryPermission(namespace)
|
||||||
if not permission.can():
|
if not permission.can():
|
||||||
logger.info('Attempt to create a new repo with insufficient perms.')
|
logger.info('Attempt to create a new repo with insufficient perms.')
|
||||||
abort(403,
|
abort(403,
|
||||||
message='You do not have permission to create repositories in namespace "%(namespace)s"',
|
message='You do not have permission to create repositories in namespace "%(namespace)s"',
|
||||||
issue='no-create-permission',
|
issue='no-create-permission',
|
||||||
namespace=namespace)
|
namespace=namespace)
|
||||||
|
@ -369,7 +369,7 @@ def get_search():
|
||||||
matching = []
|
matching = []
|
||||||
|
|
||||||
results = [result_view(repo) for repo in matching
|
results = [result_view(repo) for repo in matching
|
||||||
if (repo.visibility.name == 'public' or
|
if (repo.visibility.name == 'public' or
|
||||||
ReadRepositoryPermission(repo.namespace_user.username, repo.name).can())]
|
ReadRepositoryPermission(repo.namespace_user.username, repo.name).can())]
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
|
|
|
@ -83,7 +83,7 @@ class BuildQueueEvent(NotificationEvent):
|
||||||
|
|
||||||
def get_level(self, event_data, notification_data):
|
def get_level(self, event_data, notification_data):
|
||||||
return 'info'
|
return 'info'
|
||||||
|
|
||||||
def get_sample_data(self, repository):
|
def get_sample_data(self, repository):
|
||||||
build_uuid = 'fake-build-id'
|
build_uuid = 'fake-build-id'
|
||||||
|
|
||||||
|
@ -94,9 +94,9 @@ class BuildQueueEvent(NotificationEvent):
|
||||||
'docker_tags': ['latest', 'foo', 'bar'],
|
'docker_tags': ['latest', 'foo', 'bar'],
|
||||||
'trigger_kind': 'GitHub'
|
'trigger_kind': 'GitHub'
|
||||||
}, subpage='/build?current=%s' % build_uuid)
|
}, subpage='/build?current=%s' % build_uuid)
|
||||||
|
|
||||||
def get_summary(self, event_data, notification_data):
|
def get_summary(self, event_data, notification_data):
|
||||||
return 'Build queued for repository %s' % (event_data['repository'])
|
return 'Build queued for repository %s' % (event_data['repository'])
|
||||||
|
|
||||||
|
|
||||||
class BuildStartEvent(NotificationEvent):
|
class BuildStartEvent(NotificationEvent):
|
||||||
|
@ -116,7 +116,7 @@ class BuildStartEvent(NotificationEvent):
|
||||||
'docker_tags': ['latest', 'foo', 'bar'],
|
'docker_tags': ['latest', 'foo', 'bar'],
|
||||||
'trigger_kind': 'GitHub'
|
'trigger_kind': 'GitHub'
|
||||||
}, subpage='/build?current=%s' % build_uuid)
|
}, subpage='/build?current=%s' % build_uuid)
|
||||||
|
|
||||||
def get_summary(self, event_data, notification_data):
|
def get_summary(self, event_data, notification_data):
|
||||||
return 'Build started for repository %s' % (event_data['repository'])
|
return 'Build started for repository %s' % (event_data['repository'])
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class BuildFailureEvent(NotificationEvent):
|
||||||
'trigger_kind': 'GitHub',
|
'trigger_kind': 'GitHub',
|
||||||
'error_message': 'This is a fake error message'
|
'error_message': 'This is a fake error message'
|
||||||
}, subpage='/build?current=%s' % build_uuid)
|
}, subpage='/build?current=%s' % build_uuid)
|
||||||
|
|
||||||
def get_summary(self, event_data, notification_data):
|
def get_summary(self, event_data, notification_data):
|
||||||
return 'Build failure for repository %s' % (event_data['repository'])
|
return 'Build failure for repository %s' % (event_data['repository'])
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import json
|
||||||
|
|
||||||
def build_event_data(repo, extra_data={}, subpage=None):
|
def build_event_data(repo, extra_data={}, subpage=None):
|
||||||
repo_string = '%s/%s' % (repo.namespace_user.username, repo.name)
|
repo_string = '%s/%s' % (repo.namespace_user.username, repo.name)
|
||||||
homepage = '%s://%s/repository/%s' % (app.config['PREFERRED_URL_SCHEME'],
|
homepage = '%s://%s/repository/%s' % (app.config['PREFERRED_URL_SCHEME'],
|
||||||
app.config['SERVER_HOSTNAME'],
|
app.config['SERVER_HOSTNAME'],
|
||||||
repo_string)
|
repo_string)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class NotificationMethod(object):
|
||||||
Validates that the notification can be created with the given data. Throws
|
Validates that the notification can be created with the given data. Throws
|
||||||
a CannotValidateNotificationMethodException on failure.
|
a CannotValidateNotificationMethodException on failure.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def perform(self, notification, event_handler, notification_data):
|
def perform(self, notification, event_handler, notification_data):
|
||||||
"""
|
"""
|
||||||
|
@ -70,7 +70,7 @@ class QuayNotificationMethod(NotificationMethod):
|
||||||
status, err_message, target_users = self.find_targets(repository, config_data)
|
status, err_message, target_users = self.find_targets(repository, config_data)
|
||||||
if err_message:
|
if err_message:
|
||||||
raise CannotValidateNotificationMethodException(err_message)
|
raise CannotValidateNotificationMethodException(err_message)
|
||||||
|
|
||||||
def find_targets(self, repository, config_data):
|
def find_targets(self, repository, config_data):
|
||||||
target_info = config_data['target']
|
target_info = config_data['target']
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ class QuayNotificationMethod(NotificationMethod):
|
||||||
except model.InvalidTeamException:
|
except model.InvalidTeamException:
|
||||||
# Probably deleted.
|
# Probably deleted.
|
||||||
return (True, 'Unknown team %s' % target_info['name'], None)
|
return (True, 'Unknown team %s' % target_info['name'], None)
|
||||||
|
|
||||||
# Lookup the team's members
|
# Lookup the team's members
|
||||||
return (True, None, model.get_organization_team_members(team.id))
|
return (True, None, model.get_organization_team_members(team.id))
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ class WebhookMethod(NotificationMethod):
|
||||||
|
|
||||||
class FlowdockMethod(NotificationMethod):
|
class FlowdockMethod(NotificationMethod):
|
||||||
""" Method for sending notifications to Flowdock via the Team Inbox API:
|
""" Method for sending notifications to Flowdock via the Team Inbox API:
|
||||||
https://www.flowdock.com/api/team-inbox
|
https://www.flowdock.com/api/team-inbox
|
||||||
"""
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def method_name(cls):
|
def method_name(cls):
|
||||||
|
@ -288,7 +288,7 @@ class HipchatMethod(NotificationMethod):
|
||||||
'color': color,
|
'color': color,
|
||||||
'message': event_handler.get_message(notification_data['event_data'], notification_data),
|
'message': event_handler.get_message(notification_data['event_data'], notification_data),
|
||||||
'notify': level == 'error',
|
'notify': level == 'error',
|
||||||
'message_format': 'html',
|
'message_format': 'html',
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -59,4 +59,4 @@ def track_and_log(event_name, repo, **kwargs):
|
||||||
model.log_action(event_name, namespace,
|
model.log_action(event_name, namespace,
|
||||||
performer=get_authenticated_user(),
|
performer=get_authenticated_user(),
|
||||||
ip=request.remote_addr, metadata=metadata,
|
ip=request.remote_addr, metadata=metadata,
|
||||||
repository=repo)
|
repository=repo)
|
||||||
|
|
|
@ -100,7 +100,7 @@ class BuildTrigger(object):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def activate(self, trigger_uuid, standard_webhook_url, auth_token, config):
|
def activate(self, trigger_uuid, standard_webhook_url, auth_token, config):
|
||||||
"""
|
"""
|
||||||
Activates the trigger for the service, with the given new configuration.
|
Activates the trigger for the service, with the given new configuration.
|
||||||
Returns new configuration that should be stored if successful.
|
Returns new configuration that should be stored if successful.
|
||||||
"""
|
"""
|
||||||
|
@ -246,7 +246,7 @@ class GithubBuildTrigger(BuildTrigger):
|
||||||
gh_client = self._get_client(auth_token)
|
gh_client = self._get_client(auth_token)
|
||||||
source = config['build_source']
|
source = config['build_source']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo = gh_client.get_repo(source)
|
repo = gh_client.get_repo(source)
|
||||||
|
|
||||||
# Find the first matching branch.
|
# Find the first matching branch.
|
||||||
|
@ -381,7 +381,7 @@ class GithubBuildTrigger(BuildTrigger):
|
||||||
raise SkipRequestException()
|
raise SkipRequestException()
|
||||||
|
|
||||||
if should_skip_commit(commit_message):
|
if should_skip_commit(commit_message):
|
||||||
raise SkipRequestException()
|
raise SkipRequestException()
|
||||||
|
|
||||||
short_sha = GithubBuildTrigger.get_display_name(commit_sha)
|
short_sha = GithubBuildTrigger.get_display_name(commit_sha)
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ class GithubBuildTrigger(BuildTrigger):
|
||||||
branches = self.list_field_values(auth_token, config, 'branch_name')
|
branches = self.list_field_values(auth_token, config, 'branch_name')
|
||||||
tags = self.list_field_values(auth_token, config, 'tag_name')
|
tags = self.list_field_values(auth_token, config, 'tag_name')
|
||||||
|
|
||||||
return ([{'kind': 'branch', 'name': b} for b in branches] +
|
return ([{'kind': 'branch', 'name': b} for b in branches] +
|
||||||
[{'kind': 'tag', 'name': tag} for tag in tags])
|
[{'kind': 'tag', 'name': tag} for tag in tags])
|
||||||
|
|
||||||
if field_name == 'tag_name':
|
if field_name == 'tag_name':
|
||||||
|
|
|
@ -40,7 +40,7 @@ def _open_stream(namespace, repository, tag, synthetic_image_id, image_json, ima
|
||||||
current_image_path = store.image_layer_path(current_image_entry.storage.uuid)
|
current_image_path = store.image_layer_path(current_image_entry.storage.uuid)
|
||||||
current_image_stream = store.stream_read_file(current_image_entry.storage.locations,
|
current_image_stream = store.stream_read_file(current_image_entry.storage.locations,
|
||||||
current_image_path)
|
current_image_path)
|
||||||
|
|
||||||
current_image_id = current_image_entry.id
|
current_image_id = current_image_entry.id
|
||||||
logger.debug('Returning image layer %s: %s' % (current_image_id, current_image_path))
|
logger.debug('Returning image layer %s: %s' % (current_image_id, current_image_path))
|
||||||
yield current_image_stream
|
yield current_image_stream
|
||||||
|
@ -56,7 +56,7 @@ def _write_synthetic_image_to_storage(linked_storage_uuid, linked_locations, que
|
||||||
|
|
||||||
def handle_exception(ex):
|
def handle_exception(ex):
|
||||||
logger.debug('Exception when building squashed image %s: %s', linked_storage_uuid, ex)
|
logger.debug('Exception when building squashed image %s: %s', linked_storage_uuid, ex)
|
||||||
|
|
||||||
with database.UseThenDisconnect(app.config):
|
with database.UseThenDisconnect(app.config):
|
||||||
model.delete_derived_storage_by_uuid(linked_storage_uuid)
|
model.delete_derived_storage_by_uuid(linked_storage_uuid)
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ def receipt():
|
||||||
invoice = stripe.Invoice.retrieve(invoice_id)
|
invoice = stripe.Invoice.retrieve(invoice_id)
|
||||||
if invoice:
|
if invoice:
|
||||||
user_or_org = model.get_user_or_org_by_customer_id(invoice.customer)
|
user_or_org = model.get_user_or_org_by_customer_id(invoice.customer)
|
||||||
|
|
||||||
if user_or_org:
|
if user_or_org:
|
||||||
if user_or_org.organization:
|
if user_or_org.organization:
|
||||||
admin_org = AdministerOrganizationPermission(user_or_org.username)
|
admin_org = AdministerOrganizationPermission(user_or_org.username)
|
||||||
|
@ -244,9 +244,9 @@ def receipt():
|
||||||
else:
|
else:
|
||||||
if not user_or_org.username == current_user.db_user().username:
|
if not user_or_org.username == current_user.db_user().username:
|
||||||
abort(404)
|
abort(404)
|
||||||
return
|
return
|
||||||
|
|
||||||
file_data = renderInvoiceToPdf(invoice, user_or_org)
|
file_data = renderInvoiceToPdf(invoice, user_or_org)
|
||||||
return Response(file_data,
|
return Response(file_data,
|
||||||
mimetype="application/pdf",
|
mimetype="application/pdf",
|
||||||
headers={"Content-Disposition": "attachment;filename=receipt.pdf"})
|
headers={"Content-Disposition": "attachment;filename=receipt.pdf"})
|
||||||
|
@ -263,7 +263,7 @@ def confirm_repo_email():
|
||||||
record = model.confirm_email_authorization_for_repo(code)
|
record = model.confirm_email_authorization_for_repo(code)
|
||||||
except model.DataModelException as ex:
|
except model.DataModelException as ex:
|
||||||
return render_page_template('confirmerror.html', error_message=ex.message)
|
return render_page_template('confirmerror.html', error_message=ex.message)
|
||||||
|
|
||||||
message = """
|
message = """
|
||||||
Your E-mail address has been authorized to receive notifications for repository
|
Your E-mail address has been authorized to receive notifications for repository
|
||||||
<a href="%s://%s/repository/%s/%s">%s/%s</a>.
|
<a href="%s://%s/repository/%s/%s">%s/%s</a>.
|
||||||
|
@ -285,13 +285,13 @@ def confirm_email():
|
||||||
user, new_email, old_email = model.confirm_user_email(code)
|
user, new_email, old_email = model.confirm_user_email(code)
|
||||||
except model.DataModelException as ex:
|
except model.DataModelException as ex:
|
||||||
return render_page_template('confirmerror.html', error_message=ex.message)
|
return render_page_template('confirmerror.html', error_message=ex.message)
|
||||||
|
|
||||||
if new_email:
|
if new_email:
|
||||||
send_email_changed(user.username, old_email, new_email)
|
send_email_changed(user.username, old_email, new_email)
|
||||||
|
|
||||||
common_login(user)
|
common_login(user)
|
||||||
|
|
||||||
return redirect(url_for('web.user', tab='email')
|
return redirect(url_for('web.user', tab='email')
|
||||||
if new_email else url_for('web.index'))
|
if new_email else url_for('web.index'))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ def stripe_webhook():
|
||||||
@process_auth
|
@process_auth
|
||||||
def build_trigger_webhook(trigger_uuid, **kwargs):
|
def build_trigger_webhook(trigger_uuid, **kwargs):
|
||||||
logger.debug('Webhook received with uuid %s', trigger_uuid)
|
logger.debug('Webhook received with uuid %s', trigger_uuid)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
trigger = model.get_build_trigger(trigger_uuid)
|
trigger = model.get_build_trigger(trigger_uuid)
|
||||||
except model.InvalidBuildTriggerException:
|
except model.InvalidBuildTriggerException:
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<a href="{{ event_data.homepage }}">Build</a> failed for repository
|
<a href="{{ event_data.homepage }}">Build</a> failed for repository
|
||||||
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }}): {{ event_data.error_message }}
|
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }}): {{ event_data.error_message }}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<a href="{{ event_data.homepage }}">Build</a> started for repository
|
<a href="{{ event_data.homepage }}">Build</a> started for repository
|
||||||
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }})
|
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }})
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<a href="{{ event_data.homepage }}">Build</a> completed for repository
|
<a href="{{ event_data.homepage }}">Build</a> completed for repository
|
||||||
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }})
|
{{ event_data.repository | repository_reference }} ({{ event_data.build_id }})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% if notification_data.performer_data.entity_name %}
|
{% if notification_data.performer_data.entity_name %}
|
||||||
{{ notification_data.performer_data.entity_name | user_reference }} pushed
|
{{ notification_data.performer_data.entity_name | user_reference }} pushed
|
||||||
{% else %}
|
{% else %}
|
||||||
Push of
|
Push of
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if event_data.updated_tags %}
|
{% if event_data.updated_tags %}
|
||||||
|
@ -9,4 +9,4 @@ Push of
|
||||||
{% for tag in event_data.updated_tags %}{%if loop.index > 1 %}, {% endif %}{{ (event_data.repository, tag) | repository_tag_reference }}{% endfor %} in
|
{% for tag in event_data.updated_tags %}{%if loop.index > 1 %}, {% endif %}{{ (event_data.repository, tag) | repository_tag_reference }}{% endfor %} in
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
repository {{ event_data.repository | repository_reference }}
|
repository {{ event_data.repository | repository_reference }}
|
||||||
|
|
|
@ -52,7 +52,7 @@ def format_local_name(url):
|
||||||
filename = filename + '.css'
|
filename = filename + '.css'
|
||||||
else:
|
else:
|
||||||
filename = filename + '.js'
|
filename = filename + '.js'
|
||||||
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ if __name__ == '__main__':
|
||||||
for url in EXTERNAL_FONTS:
|
for url in EXTERNAL_FONTS:
|
||||||
print 'Downloading %s' % url
|
print 'Downloading %s' % url
|
||||||
response = urllib2.urlopen('https://' + url)
|
response = urllib2.urlopen('https://' + url)
|
||||||
|
|
||||||
filename = os.path.basename(url).split('?')[0]
|
filename = os.path.basename(url).split('?')[0]
|
||||||
with open('static/fonts/' + filename, "wb") as local_file:
|
with open('static/fonts/' + filename, "wb") as local_file:
|
||||||
local_file.write(response.read())
|
local_file.write(response.read())
|
||||||
|
|
|
@ -28,4 +28,4 @@ class FeatureNameValue(object):
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
return self.value.__nonzero__()
|
return self.value.__nonzero__()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = function(grunt) {
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
sourceMapName: '../static/dist/<%= pkg.name %>.min.map'
|
sourceMapName: '../static/dist/<%= pkg.name %>.min.map'
|
||||||
},
|
},
|
||||||
js_min: {
|
js_min: {
|
||||||
files: {
|
files: {
|
||||||
'../static/dist/<%= pkg.name %>.min.js': ['../static/dist/<%= pkg.name %>.js']
|
'../static/dist/<%= pkg.name %>.min.js': ['../static/dist/<%= pkg.name %>.js']
|
||||||
}
|
}
|
||||||
|
@ -78,4 +78,4 @@ module.exports = function(grunt) {
|
||||||
|
|
||||||
// Default task(s).
|
// Default task(s).
|
||||||
grunt.registerTask('default', ['ngtemplates', 'concat', 'cssmin', 'uglify']);
|
grunt.registerTask('default', ['ngtemplates', 'concat', 'cssmin', 'uglify']);
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ class HealthCheck(object):
|
||||||
Conducts any custom healthcheck work, returning a dict representing the HealthCheck
|
Conducts any custom healthcheck work, returning a dict representing the HealthCheck
|
||||||
output and a boolean indicating whether the instance is healthy.
|
output and a boolean indicating whether the instance is healthy.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_check(cls, name, parameters):
|
def get_check(cls, name, parameters):
|
||||||
|
@ -44,12 +44,12 @@ class ProductionHealthCheck(HealthCheck):
|
||||||
def __init__(self, access_key, secret_key):
|
def __init__(self, access_key, secret_key):
|
||||||
self.access_key = access_key
|
self.access_key = access_key
|
||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def check_name(cls):
|
def check_name(cls):
|
||||||
return 'ProductionHealthCheck'
|
return 'ProductionHealthCheck'
|
||||||
|
|
||||||
def conduct_healthcheck(self, db_healthy, buildlogs_healthy):
|
def conduct_healthcheck(self, db_healthy, buildlogs_healthy):
|
||||||
data = {
|
data = {
|
||||||
'db_healthy': db_healthy,
|
'db_healthy': db_healthy,
|
||||||
'buildlogs_healthy': buildlogs_healthy
|
'buildlogs_healthy': buildlogs_healthy
|
||||||
|
@ -81,4 +81,4 @@ class ProductionHealthCheck(HealthCheck):
|
||||||
# requests once RDS comes back up.
|
# requests once RDS comes back up.
|
||||||
return (data, not is_rds_working)
|
return (data, not is_rds_working)
|
||||||
|
|
||||||
return (data, db_healthy)
|
return (data, db_healthy)
|
||||||
|
|
10
initdb.py
|
@ -28,7 +28,7 @@ SAMPLE_CMDS = [["/bin/bash"],
|
||||||
["/bin/sh", "-c",
|
["/bin/sh", "-c",
|
||||||
"sed -i 's/#\\(force_color_prompt\\)/\\1/' /etc/skel/.bashrc"],
|
"sed -i 's/#\\(force_color_prompt\\)/\\1/' /etc/skel/.bashrc"],
|
||||||
["/bin/sh", "-c", "#(nop) EXPOSE [8080]"],
|
["/bin/sh", "-c", "#(nop) EXPOSE [8080]"],
|
||||||
["/bin/sh", "-c",
|
["/bin/sh", "-c",
|
||||||
"#(nop) MAINTAINER Jake Moshenko <jake@devtable.com>"],
|
"#(nop) MAINTAINER Jake Moshenko <jake@devtable.com>"],
|
||||||
None]
|
None]
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ def setup_database_for_testing(testcase):
|
||||||
|
|
||||||
global db_initialized_for_testing
|
global db_initialized_for_testing
|
||||||
if not db_initialized_for_testing:
|
if not db_initialized_for_testing:
|
||||||
logger.debug('Setting up DB for testing.')
|
logger.debug('Setting up DB for testing.')
|
||||||
|
|
||||||
# Setup the database.
|
# Setup the database.
|
||||||
wipe_database()
|
wipe_database()
|
||||||
|
@ -191,7 +191,7 @@ def initialize_database():
|
||||||
LoginService.create(name='ldap')
|
LoginService.create(name='ldap')
|
||||||
|
|
||||||
BuildTriggerService.create(name='github')
|
BuildTriggerService.create(name='github')
|
||||||
|
|
||||||
LogEntryKind.create(name='account_change_plan')
|
LogEntryKind.create(name='account_change_plan')
|
||||||
LogEntryKind.create(name='account_change_cc')
|
LogEntryKind.create(name='account_change_cc')
|
||||||
LogEntryKind.create(name='account_change_password')
|
LogEntryKind.create(name='account_change_password')
|
||||||
|
@ -231,7 +231,7 @@ def initialize_database():
|
||||||
LogEntryKind.create(name='create_prototype_permission')
|
LogEntryKind.create(name='create_prototype_permission')
|
||||||
LogEntryKind.create(name='modify_prototype_permission')
|
LogEntryKind.create(name='modify_prototype_permission')
|
||||||
LogEntryKind.create(name='delete_prototype_permission')
|
LogEntryKind.create(name='delete_prototype_permission')
|
||||||
|
|
||||||
LogEntryKind.create(name='setup_repo_trigger')
|
LogEntryKind.create(name='setup_repo_trigger')
|
||||||
LogEntryKind.create(name='delete_repo_trigger')
|
LogEntryKind.create(name='delete_repo_trigger')
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ def populate_database():
|
||||||
week_ago = today - timedelta(6)
|
week_ago = today - timedelta(6)
|
||||||
six_ago = today - timedelta(5)
|
six_ago = today - timedelta(5)
|
||||||
four_ago = today - timedelta(4)
|
four_ago = today - timedelta(4)
|
||||||
|
|
||||||
model.log_action('org_create_team', org.username, performer=new_user_1,
|
model.log_action('org_create_team', org.username, performer=new_user_1,
|
||||||
timestamp=week_ago, metadata={'team': 'readers'})
|
timestamp=week_ago, metadata={'team': 'readers'})
|
||||||
|
|
||||||
|
|
|
@ -36,4 +36,4 @@ psycopg2
|
||||||
pyyaml
|
pyyaml
|
||||||
git+https://github.com/DevTable/aniso8601-fake.git
|
git+https://github.com/DevTable/aniso8601-fake.git
|
||||||
git+https://github.com/DevTable/anunidecode.git
|
git+https://github.com/DevTable/anunidecode.git
|
||||||
gipc
|
gipc
|
||||||
|
|
|
@ -8,4 +8,4 @@ debug run (i.e. hit localhost):
|
||||||
|
|
||||||
```
|
```
|
||||||
casperjs screenshots.js --d
|
casperjs screenshots.js --d
|
||||||
```
|
```
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
.co-m-navbar {
|
.co-m-navbar {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.co-fx-box-shadow {
|
.co-fx-box-shadow {
|
||||||
|
@ -185,7 +185,7 @@ nav.navbar-default .navbar-nav>li>a.active {
|
||||||
top: 14px;
|
top: 14px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
@ -619,7 +619,7 @@ i.toggle-icon:hover {
|
||||||
|
|
||||||
.logs-view-element .log .log-description code {
|
.logs-view-element .log .log-description code {
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -636,7 +636,7 @@ i.toggle-icon:hover {
|
||||||
|
|
||||||
|
|
||||||
.billing-options-element .current-card .no-card-outline {
|
.billing-options-element .current-card .no-card-outline {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 73px;
|
width: 73px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -789,17 +789,17 @@ i.toggle-icon:hover {
|
||||||
-webkit-animation-fill-mode: forwards;
|
-webkit-animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-moz-keyframes scaleup {
|
@-moz-keyframes scaleup {
|
||||||
0% { -moz-transform: scale(0); }
|
0% { -moz-transform: scale(0); }
|
||||||
100% { -moz-transform: scale(1); }
|
100% { -moz-transform: scale(1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes scaleup {
|
@-webkit-keyframes scaleup {
|
||||||
0% { -webkit-transform: scale(0); }
|
0% { -webkit-transform: scale(0); }
|
||||||
100% { -webkit-transform: scale(1); }
|
100% { -webkit-transform: scale(1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes scaleup {
|
@keyframes scaleup {
|
||||||
0% { transform: scale(0); }
|
0% { transform: scale(0); }
|
||||||
100% { transform: scale(1); }
|
100% { transform: scale(1); }
|
||||||
}
|
}
|
||||||
|
@ -997,7 +997,7 @@ i.toggle-icon:hover {
|
||||||
float: right;
|
float: right;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-toggle {
|
.accordion-toggle {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -1340,7 +1340,7 @@ i.toggle-icon:hover {
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plans-list .plan .count {
|
.plans-list .plan .count {
|
||||||
|
@ -2379,7 +2379,7 @@ p.editable:hover i {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.clipboard-copied-message {
|
.clipboard-copied-message {
|
||||||
-webkit-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
-webkit-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
||||||
-moz-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
-moz-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
||||||
-ms-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
-ms-animation: fadeOut 4s ease-in-out 0s 1 forwards;
|
||||||
|
@ -3167,7 +3167,7 @@ p.editable:hover i {
|
||||||
}
|
}
|
||||||
|
|
||||||
.usage-caption {
|
.usage-caption {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
@ -3257,7 +3257,7 @@ p.editable:hover i {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-view .highlight .team-title {
|
.org-view .highlight .team-title {
|
||||||
animation: highlighttemp 1s 2;
|
animation: highlighttemp 1s 2;
|
||||||
animation-timing-function: ease-in-out;
|
animation-timing-function: ease-in-out;
|
||||||
animation-direction: alternate;
|
animation-direction: alternate;
|
||||||
|
@ -3271,22 +3271,22 @@ p.editable:hover i {
|
||||||
-webkit-animation-direction: alternate;
|
-webkit-animation-direction: alternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-moz-keyframes highlighttemp {
|
@-moz-keyframes highlighttemp {
|
||||||
0% { background-color: white; }
|
0% { background-color: white; }
|
||||||
100% { background-color: rgba(92, 184, 92, 0.36); }
|
100% { background-color: rgba(92, 184, 92, 0.36); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes highlighttemp {
|
@-webkit-keyframes highlighttemp {
|
||||||
0% { background-color: white; }
|
0% { background-color: white; }
|
||||||
100% { background-color: rgba(92, 184, 92, 0.36); }
|
100% { background-color: rgba(92, 184, 92, 0.36); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes highlighttemp {
|
@keyframes highlighttemp {
|
||||||
0% { background-color: white; }
|
0% { background-color: white; }
|
||||||
100% { background-color: rgba(92, 184, 92, 0.36); }
|
100% { background-color: rgba(92, 184, 92, 0.36); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-view .team-title {
|
.org-view .team-title {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
@ -4626,7 +4626,7 @@ have a fixed width and height (but it's not required).
|
||||||
.tour-section.tour-header {
|
.tour-section.tour-header {
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-section.tour-header .tour-section-title {
|
.tour-section.tour-header .tour-section-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -4735,13 +4735,13 @@ have a fixed width and height (but it's not required).
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.testimonial .speaker-info .speaker-title a {
|
.testimonial .speaker-info .speaker-title a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.learn-more {
|
.learn-more {
|
||||||
float: right;
|
float: right;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4775,7 +4775,7 @@ i.slack-icon {
|
||||||
|
|
||||||
.external-notification-view-element {
|
.external-notification-view-element {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
@ -4871,4 +4871,4 @@ i.slack-icon {
|
||||||
#startTriggerDialog #runForm .field-title {
|
#startTriggerDialog #runForm .field-title {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="angular-tour-ui-element"
|
<div class="angular-tour-ui-element"
|
||||||
ng-class="[tour ? 'touring' : 'nottouring', inline ? 'inline' : 'overlay']">
|
ng-class="[tour ? 'touring' : 'nottouring', inline ? 'inline' : 'overlay']">
|
||||||
|
|
||||||
<div class="tour-title">
|
<div class="tour-title">
|
||||||
<h4><i class="fa fa-dot-circle-o"></i> {{ tour.title }}</h4>
|
<h4><i class="fa fa-dot-circle-o"></i> {{ tour.title }}</h4>
|
||||||
<button type="button" class="close" ng-click="stop()" aria-hidden="true">×</button>
|
<button type="button" class="close" ng-click="stop()" aria-hidden="true">×</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<th>Application Name</th>
|
<th>Application Name</th>
|
||||||
<th>Application URI</th>
|
<th>Application URI</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr ng-repeat="app in applications">
|
<tr ng-repeat="app in applications">
|
||||||
<td><a href="/organization/{{ organization.name }}/application/{{ app.client_id }}">{{ app.name }}</a></td>
|
<td><a href="/organization/{{ organization.name }}/application/{{ app.client_id }}">{{ app.name }}</a></td>
|
||||||
<td><a href="{{ app.application_uri }}" ng-if="app.application_uri" target="_blank">{{ app.application_uri }}</a></td>
|
<td><a href="{{ app.application_uri }}" ng-if="app.application_uri" target="_blank">{{ app.application_uri }}</a></td>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody class="invoice" ng-repeat="invoice in invoices">
|
<tbody class="invoice" ng-repeat="invoice in invoices">
|
||||||
<tr class="invoice-title">
|
<tr class="invoice-title">
|
||||||
<td ng-click="toggleInvoice(invoice.id)"><span class="invoice-datetime">{{ invoice.date * 1000 | date:'medium' }}</span></td>
|
<td ng-click="toggleInvoice(invoice.id)"><span class="invoice-datetime">{{ invoice.date * 1000 | date:'medium' }}</span></td>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="billing-options-element">
|
<div class="billing-options-element">
|
||||||
<!-- Credit Card -->
|
<!-- Credit Card -->
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-title">
|
<div class="panel-title">
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
<div class="alert alert-danger" ng-if="error.message == 'HTTP code: 403' && getLocalPullInfo().isLocal">
|
<div class="alert alert-danger" ng-if="error.message == 'HTTP code: 403' && getLocalPullInfo().isLocal">
|
||||||
<div ng-if="getLocalPullInfo().login">
|
<div ng-if="getLocalPullInfo().login">
|
||||||
Note: The credentials <b>{{ getLocalPullInfo().login.username }}</b> for registry <b>{{ getLocalPullInfo().login.registry }}</b> cannot
|
Note: The credentials <b>{{ getLocalPullInfo().login.username }}</b> for registry <b>{{ getLocalPullInfo().login.registry }}</b> cannot
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
handle-item-selected="handleEventSelected(datum)" clear-value="clearCounter">
|
handle-item-selected="handleEventSelected(datum)" clear-value="clearCounter">
|
||||||
<!-- Icons -->
|
<!-- Icons -->
|
||||||
<i class="dropdown-select-icon fa fa-lg" ng-class="currentEvent.icon"></i>
|
<i class="dropdown-select-icon fa fa-lg" ng-class="currentEvent.icon"></i>
|
||||||
|
|
||||||
<!-- Dropdown menu -->
|
<!-- Dropdown menu -->
|
||||||
<ul class="dropdown-select-menu pull-right" role="menu">
|
<ul class="dropdown-select-menu pull-right" role="menu">
|
||||||
<li ng-repeat="event in events">
|
<li ng-repeat="event in events">
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
handle-item-selected="handleMethodSelected(datum)" clear-value="clearCounter">
|
handle-item-selected="handleMethodSelected(datum)" clear-value="clearCounter">
|
||||||
<!-- Icons -->
|
<!-- Icons -->
|
||||||
<i class="dropdown-select-icon fa fa-lg" ng-class="currentMethod.icon"></i>
|
<i class="dropdown-select-icon fa fa-lg" ng-class="currentMethod.icon"></i>
|
||||||
|
|
||||||
<!-- Dropdown menu -->
|
<!-- Dropdown menu -->
|
||||||
<ul class="dropdown-select-menu pull-right" role="menu">
|
<ul class="dropdown-select-menu pull-right" role="menu">
|
||||||
<li ng-repeat="method in methods">
|
<li ng-repeat="method in methods">
|
||||||
|
@ -91,16 +91,16 @@
|
||||||
<div ng-if="getHelpUrl(field, currentConfig)" style="margin-top: 10px">
|
<div ng-if="getHelpUrl(field, currentConfig)" style="margin-top: 10px">
|
||||||
See: <a href="{{ getHelpUrl(field, currentConfig) }}" target="_blank">{{ getHelpUrl(field, currentConfig) }}</a>
|
See: <a href="{{ getHelpUrl(field, currentConfig) }}" target="_blank">{{ getHelpUrl(field, currentConfig) }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr ng-if="currentMethod.id == 'webhook'">
|
<tr ng-if="currentMethod.id == 'webhook'">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="alert alert-info" style="margin-top: 20px; margin-bottom: 0px">
|
<div class="alert alert-info" style="margin-top: 20px; margin-bottom: 0px">
|
||||||
JSON metadata representing the event will be <b>POST</b>ed to the URL.
|
JSON metadata representing the event will be <b>POST</b>ed to the URL.
|
||||||
<br><br>
|
<br><br>
|
||||||
The contents for each event can be found in the user guide:
|
The contents for each event can be found in the user guide:
|
||||||
<a href="http://docs.quay.io/guides/notifications.html#webhook{{ currentEvent.id ? '_' + currentEvent.id : '' }}"
|
<a href="http://docs.quay.io/guides/notifications.html#webhook{{ currentEvent.id ? '_' + currentEvent.id : '' }}"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
http://docs.quay.io/guides/notifications.html
|
http://docs.quay.io/guides/notifications.html
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="creating">Cancel</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="creating">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Normal button bar -->
|
<!-- Normal button bar -->
|
||||||
<div class="modal-footer" ng-if="status == '' || status == 'creating'">
|
<div class="modal-footer" ng-if="status == '' || status == 'creating'">
|
||||||
<button type="submit" class="btn btn-primary"
|
<button type="submit" class="btn btn-primary"
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
Regenerating Token...
|
Regenerating Token...
|
||||||
<i class="fa fa-refresh fa-spin"></i>
|
<i class="fa fa-refresh fa-spin"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="well well-sm" ng-show="!regenerating">
|
<div class="well well-sm" ng-show="!regenerating">
|
||||||
<input id="token-view" class="token-view" type="text" value="{{ token }}" onClick="this.select();" readonly>
|
<input id="token-view" class="token-view" type="text" value="{{ token }}" onClick="this.select();" readonly>
|
||||||
<i class="fa fa-refresh" ng-show="supportsRegenerate" ng-click="askRegenerate()"
|
<i class="fa fa-refresh" ng-show="supportsRegenerate" ng-click="askRegenerate()"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-select-menu-transclude"></div>
|
<div class="dropdown-select-menu-transclude"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="transcluded" ng-transclude>
|
<div class="transcluded" ng-transclude>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<span class="entity-reference-element">
|
<span class="entity-reference-element">
|
||||||
<span ng-if="entity.kind == 'team'">
|
<span ng-if="entity.kind == 'team'">
|
||||||
<i class="fa fa-group" data-title="Team" bs-tooltip="tooltip.title" data-container="body"></i>
|
<i class="fa fa-group" data-title="Team" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||||
<span class="entity-name">
|
<span class="entity-name">
|
||||||
<span ng-if="!getIsAdmin(namespace)">{{entity.name}}</span>
|
<span ng-if="!getIsAdmin(namespace)">{{entity.name}}</span>
|
||||||
<span ng-if="getIsAdmin(namespace)"><a href="/organization/{{ namespace }}/teams/{{ entity.name }}">{{entity.name}}</a></span>
|
<span ng-if="getIsAdmin(namespace)"><a href="/organization/{{ namespace }}/teams/{{ entity.name }}">{{entity.name}}</a></span>
|
||||||
|
|
|
@ -34,22 +34,22 @@
|
||||||
Robot accounts are not permitted
|
Robot accounts are not permitted
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li role="presentation" ng-repeat="team in teams" ng-show="!lazyLoading"
|
<li role="presentation" ng-repeat="team in teams" ng-show="!lazyLoading"
|
||||||
ng-click="setEntity(team.name, 'team', false)">
|
ng-click="setEntity(team.name, 'team', false)">
|
||||||
<a role="menuitem" tabindex="-1" href="javascript:void(0)">
|
<a role="menuitem" tabindex="-1" href="javascript:void(0)">
|
||||||
<i class="fa fa-group"></i> <span>{{ team.name }}</span>
|
<i class="fa fa-group"></i> <span>{{ team.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li role="presentation" class="divider" ng-show="!lazyLoading && teams && (isAdmin || robots)"></li>
|
<li role="presentation" class="divider" ng-show="!lazyLoading && teams && (isAdmin || robots)"></li>
|
||||||
|
|
||||||
<li role="presentation" ng-repeat="robot in robots" ng-show="!lazyLoading">
|
<li role="presentation" ng-repeat="robot in robots" ng-show="!lazyLoading">
|
||||||
<a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-click="setEntity(robot.name, 'user', true)">
|
<a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-click="setEntity(robot.name, 'user', true)">
|
||||||
<i class="fa fa-wrench"></i> <span>{{ robot.name }}</span>
|
<i class="fa fa-wrench"></i> <span>{{ robot.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li role="presentation" class="divider" ng-show="!lazyLoading && robots && isAdmin"></li>
|
<li role="presentation" class="divider" ng-show="!lazyLoading && robots && isAdmin"></li>
|
||||||
|
|
||||||
<li role="presentation" ng-show="includeTeams && isOrganization && !lazyLoading && isAdmin">
|
<li role="presentation" ng-show="includeTeams && isOrganization && !lazyLoading && isAdmin">
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
<span class="external-login-button-element">
|
<span class="external-login-button-element">
|
||||||
<span ng-if="provider == 'github'">
|
<span ng-if="provider == 'github'">
|
||||||
<a href="javascript:void(0)" class="btn btn-primary btn-block" quay-require="['GITHUB_LOGIN']" ng-click="startSignin('github')" style="margin-bottom: 10px" ng-disabled="signingIn">
|
<a href="javascript:void(0)" class="btn btn-primary btn-block" quay-require="['GITHUB_LOGIN']" ng-click="startSignin('github')" style="margin-bottom: 10px" ng-disabled="signingIn">
|
||||||
<i class="fa fa-github fa-lg"></i>
|
<i class="fa fa-github fa-lg"></i>
|
||||||
<span ng-if="action != 'attach'">
|
<span ng-if="action != 'attach'">
|
||||||
Sign In with GitHub
|
Sign In with GitHub
|
||||||
<span ng-if="isEnterprise('github')">Enterprise</span>
|
<span ng-if="isEnterprise('github')">Enterprise</span>
|
||||||
</span>
|
</span>
|
||||||
<span ng-if="action == 'attach'">
|
<span ng-if="action == 'attach'">
|
||||||
Attach to GitHub
|
Attach to GitHub
|
||||||
<span ng-if="isEnterprise('github')">Enterprise</span>
|
<span ng-if="isEnterprise('github')">Enterprise</span>
|
||||||
Account
|
Account
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span ng-if="provider == 'google'">
|
<span ng-if="provider == 'google'">
|
||||||
<a href="javascript:void(0)" class="btn btn-primary btn-block" quay-require="['GOOGLE_LOGIN']" ng-click="startSignin('google')" ng-disabled="signingIn">
|
<a href="javascript:void(0)" class="btn btn-primary btn-block" quay-require="['GOOGLE_LOGIN']" ng-click="startSignin('google')" ng-disabled="signingIn">
|
||||||
<i class="fa fa-google fa-lg"></i>
|
<i class="fa fa-google fa-lg"></i>
|
||||||
<span ng-if="action != 'attach'">Sign In with Google</span>
|
<span ng-if="action != 'attach'">Sign In with Google</span>
|
||||||
<span ng-if="action == 'attach'">Attach to Google Account</span>
|
<span ng-if="action == 'attach'">Attach to Google Account</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
{{ eventInfo.title }}
|
{{ eventInfo.title }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="view-row">
|
<div class="view-row">
|
||||||
<span class="flow-text">Issue A</span>
|
<span class="flow-text">Issue A</span>
|
||||||
<span class="notification-method">
|
<span class="notification-method">
|
||||||
|
|
|
@ -19,15 +19,15 @@
|
||||||
<li><a ng-href="{{ user.organizations.length ? '/organizations/' : '/tour/organizations/' }}" target="{{ appLinkTarget() }}" quay-section="organization">Organizations</a></li>
|
<li><a ng-href="{{ user.organizations.length ? '/organizations/' : '/tour/organizations/' }}" target="{{ appLinkTarget() }}" quay-section="organization">Organizations</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<ul class="nav navbar-nav navbar-right" ng-switch on="user.anonymous">
|
<ul class="nav navbar-nav navbar-right" ng-switch on="user.anonymous">
|
||||||
<li>
|
<li>
|
||||||
<form class="navbar-form navbar-left" role="search">
|
<form class="navbar-form navbar-left" role="search">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="repo-search"></span>
|
<span class="repo-search"></span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<span class="navbar-left user-tools" ng-show="!user.anonymous">
|
<span class="navbar-left user-tools" ng-show="!user.anonymous">
|
||||||
<a href="/new/"><i class="fa fa-upload user-tool" bs-tooltip="tooltip.title" data-placement="bottom" data-title="Create new repository" data-container="body"></i></a>
|
<a href="/new/"><i class="fa fa-upload user-tool" bs-tooltip="tooltip.title" data-placement="bottom" data-title="Create new repository" data-container="body"></i></a>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<img ng-src="{{ '/static/img/flags/' + getLocationImage(location) }}">
|
<img ng-src="{{ '/static/img/flags/' + getLocationImage(location) }}">
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="ping-tower" ng-class="locationPingClass">
|
<span class="ping-tower" ng-class="locationPingClass">
|
||||||
<div class="ping-sliver"></div>
|
<div class="ping-sliver"></div>
|
||||||
<div class="ping-sliver"></div>
|
<div class="ping-sliver"></div>
|
||||||
<div class="ping-sliver"></div>
|
<div class="ping-sliver"></div>
|
||||||
|
|
|
@ -19,25 +19,25 @@
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="loading">
|
<div ng-show="loading">
|
||||||
<div class="quay-spinner 3x"></div>
|
<div class="quay-spinner 3x"></div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="!loading">
|
<div ng-show="!loading">
|
||||||
<div id="bar-chart" style="width: 800px; height: 500px;" ng-show="chartVisible">
|
<div id="bar-chart" style="width: 800px; height: 500px;" ng-show="chartVisible">
|
||||||
<svg style="width: 800px; height: 500px;"></svg>
|
<svg style="width: 800px; height: 500px;"></svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="side-controls">
|
<div class="side-controls">
|
||||||
<div class="result-count">
|
<div class="result-count">
|
||||||
Showing {{(logs | visibleLogFilter:kindsAllowed | filter:search | limitTo:150).length}} of
|
Showing {{(logs | visibleLogFilter:kindsAllowed | filter:search | limitTo:150).length}} of
|
||||||
{{(logs | visibleLogFilter:kindsAllowed | filter:search).length}} matching logs
|
{{(logs | visibleLogFilter:kindsAllowed | filter:search).length}} matching logs
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-input">
|
<div class="filter-input">
|
||||||
<input id="log-filter" class="form-control" placeholder="Filter Logs" type="text" ng-model="search.$">
|
<input id="log-filter" class="form-control" placeholder="Filter Logs" type="text" ng-model="search.$">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
<th style="min-width: 226px">Date/Time</th>
|
<th style="min-width: 226px">Date/Time</th>
|
||||||
<th>User/Token/App</th>
|
<th>User/Token/App</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="log" ng-repeat="log in (logs | visibleLogFilter:kindsAllowed | filter:search | limitTo:150)">
|
<tr class="log" ng-repeat="log in (logs | visibleLogFilter:kindsAllowed | filter:search | limitTo:150)">
|
||||||
<td>
|
<td>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>{{ log.datetime }}</td>
|
<td>{{ log.datetime }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="log-performer" ng-if="log.metadata.oauth_token_application">
|
<span class="log-performer" ng-if="log.metadata.oauth_token_application">
|
||||||
<div>
|
<div>
|
||||||
<span class="application-reference" data-title="log.metadata.oauth_token_application"
|
<span class="application-reference" data-title="log.metadata.oauth_token_application"
|
||||||
client-id="log.metadata.oauth_token_application_id"></span>
|
client-id="log.metadata.oauth_token_application_id"></span>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="log-performer" ng-if="!log.metadata.oauth_token_application && log.performer">
|
<span class="log-performer" ng-if="!log.metadata.oauth_token_application && log.performer">
|
||||||
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="log-performer" ng-if="!log.performer && log.metadata.token">
|
<span class="log-performer" ng-if="!log.performer && log.metadata.token">
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="trigger-description" trigger="trigger"></div>
|
<div class="trigger-description" trigger="trigger"></div>
|
||||||
|
|
||||||
<form name="runForm" id="runForm">
|
<form name="runForm" id="runForm">
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr ng-repeat="field in runParameters">
|
<tr ng-repeat="field in runParameters">
|
||||||
|
@ -35,4 +35,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /.modal-content -->
|
</div><!-- /.modal-content -->
|
||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
</div><!-- /.modal -->
|
</div><!-- /.modal -->
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="wmd-panel">
|
<div class="wmd-panel">
|
||||||
<div id="wmd-button-bar-description-{{id}}"></div>
|
<div id="wmd-button-bar-description-{{id}}"></div>
|
||||||
<textarea class="wmd-input" id="wmd-input-description-{{id}}" placeholder="Enter {{ fieldTitle }}">{{ content }}</textarea>
|
<textarea class="wmd-input" id="wmd-input-description-{{id}}" placeholder="Enter {{ fieldTitle }}">{{ content }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="wmd-preview-description-{{id}}" class="wmd-panel wmd-preview"></div>
|
<div id="wmd-preview-description-{{id}}" class="wmd-panel wmd-preview"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
ng-class="(requireCreate && !namespaces[org.name].can_create_repo) ? 'disabled' : ''">
|
ng-class="(requireCreate && !namespaces[org.name].can_create_repo) ? 'disabled' : ''">
|
||||||
<a class="namespace" href="javascript:void(0)" ng-click="setNamespace(org)">
|
<a class="namespace" href="javascript:void(0)" ng-click="setNamespace(org)">
|
||||||
<img src="//www.gravatar.com/avatar/{{ org.gravatar }}?s=24&d=identicon" />
|
<img src="//www.gravatar.com/avatar/{{ org.gravatar }}?s=24&d=identicon" />
|
||||||
<span class="namespace-name">{{ org.name }}</span>
|
<span class="namespace-name">{{ org.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<i class="fa fa-exclamation-triangle" ng-show="requireCreate && !namespaces[org.name].can_create_repo"
|
<i class="fa fa-exclamation-triangle" ng-show="requireCreate && !namespaces[org.name].can_create_repo"
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<div ng-repeat="notification in notificationService.notifications">
|
<div ng-repeat="notification in notificationService.notifications">
|
||||||
<div class="notification-view" notification="notification" parent="this"></div>
|
<div class="notification-view" notification="notification" parent="this"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
You are using more private repositories than your plan allows. Please
|
You are using more private repositories than your plan allows. Please
|
||||||
upgrade your subscription to avoid disruptions in your <span ng-show="organization">organization's</span> service.
|
upgrade your subscription to avoid disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning" ng-show="limit == 'at' && !planLoading">
|
<div class="alert alert-warning" ng-show="limit == 'at' && !planLoading">
|
||||||
You are at your current plan's number of allowed private repositories. It might be time to think about
|
You are at your current plan's number of allowed private repositories. It might be time to think about
|
||||||
upgrading your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
upgrading your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
<div class="alert alert-success" ng-show="limit == 'near' && !planLoading">
|
<div class="alert alert-success" ng-show="limit == 'near' && !planLoading">
|
||||||
You are nearing the number of allowed private repositories. It might be time to think about
|
You are nearing the number of allowed private repositories. It might be time to think about
|
||||||
upgrading your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
upgrading your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Trial info -->
|
<!-- Trial info -->
|
||||||
<div class="alert alert-success" ng-show="subscription.trialEnd != null" style="font-size: 125%">
|
<div class="alert alert-success" ng-show="subscription.trialEnd != null" style="font-size: 125%">
|
||||||
Free trial until <strong>{{ parseDate(subscription.trialEnd) | date }}</strong>
|
Free trial until <strong>{{ parseDate(subscription.trialEnd) | date }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Chart -->
|
<!-- Chart -->
|
||||||
<div class="usage-chart" total="subscribedPlan.privateRepos || 0"
|
<div class="usage-chart" total="subscribedPlan.privateRepos || 0"
|
||||||
current="subscription.usedPrivateRepos || 0"
|
current="subscription.usedPrivateRepos || 0"
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<td style="min-width: 64px">Price</td>
|
<td style="min-width: 64px">Price</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr ng-repeat="plan in plans" ng-show="isPlanVisible(plan, subscribedPlan)"
|
<tr ng-repeat="plan in plans" ng-show="isPlanVisible(plan, subscribedPlan)"
|
||||||
ng-class="{'active':(subscribedPlan.stripeId === plan.stripeId), 'deprecated-plan':plan.deprecated}">
|
ng-class="{'active':(subscribedPlan.stripeId === plan.stripeId), 'deprecated-plan':plan.deprecated}">
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<th style="min-width: 85px">Price</th>
|
<th style="min-width: 85px">Price</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr ng-repeat="plan in plans" ng-class="currentPlan == plan ? 'active' : ''">
|
<tr ng-repeat="plan in plans" ng-class="currentPlan == plan ? 'active' : ''">
|
||||||
<td>{{ plan.title }}</td>
|
<td>{{ plan.title }}</td>
|
||||||
<td>{{ plan.privateRepos }}</td>
|
<td>{{ plan.privateRepos }}</td>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<button class="btn btn-success" data-trigger="click"
|
<button class="btn btn-success" data-trigger="click"
|
||||||
data-content-template="/static/directives/popup-input-dialog.html"
|
data-content-template="/static/directives/popup-input-dialog.html"
|
||||||
data-placement="bottom" ng-click="popupShown()" bs-popover>
|
data-placement="bottom" ng-click="popupShown()" bs-popover>
|
||||||
<span ng-transclude></span>
|
<span ng-transclude></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
Default permissions provide a means of specifying <span class="context-tooltip" data-title="By default, all repositories have the creating user added as an 'Admin'" bs-tooltip="tooltip.title">additional</span> permissions that should be granted automatically to a repository <strong>when it is created</strong>.
|
Default permissions provide a means of specifying <span class="context-tooltip" data-title="By default, all repositories have the creating user added as an 'Admin'" bs-tooltip="tooltip.title">additional</span> permissions that should be granted automatically to a repository <strong>when it is created</strong>.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="side-controls">
|
<div class="side-controls">
|
||||||
<button class="btn btn-success" ng-click="showAddDialog()">
|
<button class="btn btn-success" ng-click="showAddDialog()">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<th>
|
<th>
|
||||||
<span class="context-tooltip"
|
<span class="context-tooltip"
|
||||||
data-title="The user or robot that is creating a repository. If '(Organization Default)', then any repository created in this organization will be granted the permission."
|
data-title="The user or robot that is creating a repository. If '(Organization Default)', then any repository created in this organization will be granted the permission."
|
||||||
bs-tooltip="tooltip.title" data-container="body">
|
bs-tooltip="tooltip.title" data-container="body">
|
||||||
Repository Creator
|
Repository Creator
|
||||||
</span>
|
</span>
|
||||||
|
@ -31,9 +31,9 @@
|
||||||
<th>Permission</th>
|
<th>Permission</th>
|
||||||
<th style="width: 150px"></th>
|
<th style="width: 150px"></th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr ng-repeat="prototype in prototypes | orderBy:comparePrototypes">
|
<tr ng-repeat="prototype in prototypes | orderBy:comparePrototypes">
|
||||||
<td>
|
<td>
|
||||||
<span class="entity-reference block-reference" entity="prototype.activating_user"
|
<span class="entity-reference block-reference" entity="prototype.activating_user"
|
||||||
namespace="organization.name" ng-show="prototype.activating_user"></span>
|
namespace="organization.name" ng-show="prototype.activating_user"></span>
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
<button type="button" class="btn btn-default"
|
<button type="button" class="btn btn-default"
|
||||||
ng-class="newForWholeOrg ? '' : 'active btn-info'" ng-click="setNewForWholeOrg(false)">A specific user</button>
|
ng-class="newForWholeOrg ? '' : 'active btn-info'" ng-click="setNewForWholeOrg(false)">A specific user</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button ype="button" class="btn btn-primary" ng-disabled="!(newForWholeOrg || activatingForNew) || !delegateForNew" ng-click="createPrototype()">
|
<button ype="button" class="btn btn-primary" ng-disabled="!(newForWholeOrg || activatingForNew) || !delegateForNew" ng-click="createPrototype()">
|
||||||
Create Permission
|
Create Permission
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="crumb"><a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}">{{repo.name}}</a></span>
|
<span class="crumb"><a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}">{{repo.name}}</a></span>
|
||||||
<span class="current">
|
<span class="current">
|
||||||
<i class="fa fa-archive" style="margin-left: 2px; margin-right: 2px;"></i>
|
<i class="fa fa-archive" style="margin-left: 2px; margin-right: 2px;"></i>
|
||||||
{{image.id.substr(0, 12)}}
|
{{image.id.substr(0, 12)}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<span class="crumb">
|
<span class="crumb">
|
||||||
<a href="{{ '/repository/?namespace=' + repo.namespace }}">{{repo.namespace}}</a>
|
<a href="{{ '/repository/?namespace=' + repo.namespace }}">{{repo.namespace}}</a>
|
||||||
</span>
|
</span>
|
||||||
<span class="crumb"><a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}">{{repo.name}}</a></span>
|
<span class="crumb"><a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}">{{repo.name}}</a></span>
|
||||||
<span class="current"><i class="fa" ng-class="subsectionIcon" style="margin-left: 4px; margin-right: 8px;"></i>{{subsection}}</span>
|
<span class="current"><i class="fa" ng-class="subsectionIcon" style="margin-left: 4px; margin-right: 8px;"></i>{{subsection}}</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
<th>Robot Account Name</th>
|
<th>Robot Account Name</th>
|
||||||
<th style="width: 150px"></th>
|
<th style="width: 150px"></th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr ng-repeat="robotInfo in robots">
|
<tr ng-repeat="robotInfo in robots">
|
||||||
<td class="robot">
|
<td class="robot">
|
||||||
<i class="fa fa-wrench"></i>
|
<i class="fa fa-wrench"></i>
|
||||||
<a ng-click="showRobot(robotInfo)">
|
<a ng-click="showRobot(robotInfo)">
|
||||||
<span class="prefix">{{ getPrefix(robotInfo.name) }}+</span>{{ getShortenedName(robotInfo.name) }}
|
<span class="prefix">{{ getPrefix(robotInfo.name) }}+</span>{{ getShortenedName(robotInfo.name) }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="delete-ui" delete-title="'Delete Robot Account'" perform-delete="deleteRobot(robotInfo)"></span>
|
<span class="delete-ui" delete-title="'Delete Robot Account'" perform-delete="deleteRobot(robotInfo)"></span>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
<div class="modal-body" ng-show="currentView == 'activating'">
|
<div class="modal-body" ng-show="currentView == 'activating'">
|
||||||
<span class="quay-spinner"></span> Setting up trigger...
|
<span class="quay-spinner"></span> Setting up trigger...
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" ng-show="currentView != 'activating'">
|
<div class="modal-body" ng-show="currentView != 'activating'">
|
||||||
<!-- Trigger-specific setup -->
|
<!-- Trigger-specific setup -->
|
||||||
<div class="trigger-description-element trigger-option-section" ng-switch on="trigger.service">
|
<div class="trigger-description-element trigger-option-section" ng-switch on="trigger.service">
|
||||||
<div ng-switch-when="github">
|
<div ng-switch-when="github">
|
||||||
<div class="trigger-setup-github" repository="repository" trigger="trigger"
|
<div class="trigger-setup-github" repository="repository" trigger="trigger"
|
||||||
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
next-step-counter="nextStepCounter" current-step-valid="state.stepValid"
|
||||||
analyze="checkAnalyze(isValid)"></div>
|
analyze="checkAnalyze(isValid)"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<div class="dockerfile-found-content">
|
<div class="dockerfile-found-content">
|
||||||
A robot account is <strong>required</strong> for this build trigger because
|
A robot account is <strong>required</strong> for this build trigger because
|
||||||
|
|
||||||
the
|
the
|
||||||
<a href="{{ pullInfo.analysis.dockerfile_url }}" ng-if="pullInfo.analysis.dockerfile_url" target="_blank">
|
<a href="{{ pullInfo.analysis.dockerfile_url }}" ng-if="pullInfo.analysis.dockerfile_url" target="_blank">
|
||||||
Dockerfile found
|
Dockerfile found
|
||||||
</a>
|
</a>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
<div style="margin-bottom: 12px">Please select the credentials to use when pulling the base image:</div>
|
<div style="margin-bottom: 12px">Please select the credentials to use when pulling the base image:</div>
|
||||||
<div ng-if="!isNamespaceAdmin(repository.namespace)" style="color: #aaa;">
|
<div ng-if="!isNamespaceAdmin(repository.namespace)" style="color: #aaa;">
|
||||||
<strong>Note:</strong> In order to set pull credentials for a build trigger, you must be an
|
<strong>Note:</strong> In order to set pull credentials for a build trigger, you must be an
|
||||||
Administrator of the namespace <strong>{{ repository.namespace }}</strong>
|
Administrator of the namespace <strong>{{ repository.namespace }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -79,14 +79,14 @@
|
||||||
|
|
||||||
<!-- Robot Select -->
|
<!-- Robot Select -->
|
||||||
<div ng-show="!pullInfo.is_public" style="margin-top: 10px">
|
<div ng-show="!pullInfo.is_public" style="margin-top: 10px">
|
||||||
<div class="entity-search" namespace="repository.namespace"
|
<div class="entity-search" namespace="repository.namespace"
|
||||||
placeholder="'Select robot account for pulling...'"
|
placeholder="'Select robot account for pulling...'"
|
||||||
current-entity="pullInfo.pull_entity"
|
current-entity="pullInfo.pull_entity"
|
||||||
allowed-entities="['robot']"></div>
|
allowed-entities="['robot']"></div>
|
||||||
|
|
||||||
<div ng-if="pullInfo.analysis.robots.length" style="margin-top: 20px; margin-bottom: 0px;">
|
<div ng-if="pullInfo.analysis.robots.length" style="margin-top: 20px; margin-bottom: 0px;">
|
||||||
<strong>Note</strong>: We've automatically selected robot account
|
<strong>Note</strong>: We've automatically selected robot account
|
||||||
<span class="entity-reference" entity="pullInfo.analysis.robots[0]"></span>,
|
<span class="entity-reference" entity="pullInfo.analysis.robots[0]"></span>,
|
||||||
since it has access to the private repository.
|
since it has access to the private repository.
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="!pullInfo.analysis.robots.length && pullInfo.analysis.name"
|
<div ng-if="!pullInfo.analysis.robots.length && pullInfo.analysis.name"
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span ng-show="tryAgainSoon == 0">
|
<span ng-show="tryAgainSoon == 0">
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
|
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
|
||||||
|
|
||||||
<span class="social-alternate" quay-show="Features.GITHUB_LOGIN || Features.GOOGLE_LOGIN">
|
<span class="social-alternate" quay-show="Features.GITHUB_LOGIN || Features.GOOGLE_LOGIN">
|
||||||
<i class="fa fa-circle"></i>
|
<i class="fa fa-circle"></i>
|
||||||
<span class="inner-text">OR</span>
|
<span class="inner-text">OR</span>
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
<span class="quay-spinner"></span>
|
<span class="quay-spinner"></span>
|
||||||
{{ loadMessage }}
|
{{ loadMessage }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
<div class="step-view-element">
|
<div class="step-view-element">
|
||||||
<div class="transcluded" ng-transclude>
|
<div class="transcluded" ng-transclude>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,9 +38,9 @@
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<div class="tour-section-title">Dockerfile build in the cloud</div>
|
<div class="tour-section-title">Dockerfile build in the cloud</div>
|
||||||
<div class="tour-section-description">
|
<div class="tour-section-description">
|
||||||
Like to use <b>Dockerfiles</b> to build your images? Simply upload your Dockerfile (and any additional files it needs) and we'll build your Dockerfile into an image and push it to your repository.
|
Like to use <b>Dockerfiles</b> to build your images? Simply upload your Dockerfile (and any additional files it needs) and we'll build your Dockerfile into an image and push it to your repository.
|
||||||
</div>
|
</div>
|
||||||
<div class="tour-section-description">
|
<div class="tour-section-description">
|
||||||
If you store your Dockerfile in <i class="fa fa-github fa-lg" style="margin: 6px;"></i><b>GitHub</b>, add a <b>Build Trigger</b> to your repository and we'll start a Dockerfile build for every change you make.
|
If you store your Dockerfile in <i class="fa fa-github fa-lg" style="margin: 6px;"></i><b>GitHub</b>, add a <b>Build Trigger</b> to your repository and we'll start a Dockerfile build for every change you make.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tour-section row">
|
<div class="tour-section row">
|
||||||
<div class="col-md-7"><img src="/static/img/org-repo-list.png" data-title="Repositories" data-screenshot-url="https://quay.io/repository/" class="img-responsive"></div>
|
<div class="col-md-7"><img src="/static/img/org-repo-list.png" data-title="Repositories" data-screenshot-url="https://quay.io/repository/" class="img-responsive"></div>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
|
@ -405,7 +405,7 @@
|
||||||
c0,0.596-0.208,1.102-0.625,1.518c-0.416,0.417-0.923,0.625-1.518,0.625h-21.429c-0.596,0-1.102-0.208-1.518-0.625
|
c0,0.596-0.208,1.102-0.625,1.518c-0.416,0.417-0.923,0.625-1.518,0.625h-21.429c-0.596,0-1.102-0.208-1.518-0.625
|
||||||
C103.708,124.459,103.5,123.953,103.5,123.357z M110.643,108.357h11.429v-4.286c0-1.577-0.558-2.924-1.674-4.04
|
C103.708,124.459,103.5,123.953,103.5,123.357z M110.643,108.357h11.429v-4.286c0-1.577-0.558-2.924-1.674-4.04
|
||||||
s-2.463-1.674-4.04-1.674c-1.578,0-2.924,0.558-4.041,1.674c-1.115,1.116-1.674,2.463-1.674,4.04V108.357z"/>
|
s-2.463-1.674-4.04-1.674c-1.578,0-2.924,0.558-4.041,1.674c-1.115,1.116-1.674,2.463-1.674,4.04V108.357z"/>
|
||||||
<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="99.889,122.5 21.5,122.5 21.5,20.5
|
<polyline fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" points="99.889,122.5 21.5,122.5 21.5,20.5
|
||||||
123.5,20.5 123.5,92.469 "/>
|
123.5,20.5 123.5,92.469 "/>
|
||||||
<rect x="32.214" y="61.422" fill="#4CA0D8" width="20.156" height="20.156"/>
|
<rect x="32.214" y="61.422" fill="#4CA0D8" width="20.156" height="20.156"/>
|
||||||
<rect x="92.63" y="61.422" fill="#4CA0D8" width="20.156" height="20.156"/>
|
<rect x="92.63" y="61.422" fill="#4CA0D8" width="20.156" height="20.156"/>
|
||||||
|
@ -429,5 +429,5 @@
|
||||||
<div class="row" style="text-align: center; margin-bottom: 20px;">
|
<div class="row" style="text-align: center; margin-bottom: 20px;">
|
||||||
<a href="https://coreos.com/products/enterprise-registry" class="btn btn-primary">Learn more about Enterprise Registry</a>
|
<a href="https://coreos.com/products/enterprise-registry" class="btn btn-primary">Learn more about Enterprise Registry</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="dockerfile-location">
|
<div class="dockerfile-location">
|
||||||
<i class="fa fa-folder fa-lg"></i> {{ state.currentLocation || '(Repository Root)' }}
|
<i class="fa fa-folder fa-lg"></i> {{ state.currentLocation || '(Repository Root)' }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<a href="javascript:void(0)" ng-click="selectRepo(repo, org)"><i class="fa fa-github fa-lg"></i> {{ repo }}</a>
|
<a href="javascript:void(0)" ng-click="selectRepo(repo, org)"><i class="fa fa-github fa-lg"></i> {{ repo }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation" class="divider" ng-repeat-end ng-show="$index < orgs.length - 1"></li>
|
<li role="presentation" class="divider" ng-repeat-end ng-show="$index < orgs.length - 1"></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -91,11 +91,11 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input class="form-control" type="text" ng-model="state.branchTagFilter"
|
<input class="form-control" type="text" ng-model="state.branchTagFilter"
|
||||||
placeholder="(Regular expression. Examples: heads/branchname, tags/tagname)" required>
|
placeholder="(Regular expression. Examples: heads/branchname, tags/tagname)" required>
|
||||||
<div class="dropdown input-group-addon">
|
<div class="dropdown input-group-addon">
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu pull-right">
|
<ul class="dropdown-menu pull-right">
|
||||||
<li><a href="javascript:void(0)" ng-click="state.branchTagFilter = 'heads/.+'">
|
<li><a href="javascript:void(0)" ng-click="state.branchTagFilter = 'heads/.+'">
|
||||||
<i class="fa fa-code-fork"></i>All Branches</a>
|
<i class="fa fa-code-fork"></i>All Branches</a>
|
||||||
|
@ -116,11 +116,11 @@
|
||||||
<ul class="matching-refs branches">
|
<ul class="matching-refs branches">
|
||||||
<li ng-repeat="branchName in branchNames | limitTo:20"
|
<li ng-repeat="branchName in branchNames | limitTo:20"
|
||||||
class="ref-reference"
|
class="ref-reference"
|
||||||
ng-class="isMatching('heads', branchName, state.branchTagFilter) ? 'match' : 'not-match'">
|
ng-class="isMatching('heads', branchName, state.branchTagFilter) ? 'match' : 'not-match'">
|
||||||
<span ng-click="addRef('heads', branchName)" target="_blank">
|
<span ng-click="addRef('heads', branchName)" target="_blank">
|
||||||
{{ branchName }}
|
{{ branchName }}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<span ng-if="branchNames.length > 20">...</span>
|
<span ng-if="branchNames.length > 20">...</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -129,14 +129,14 @@
|
||||||
<ul class="matching-refs tags">
|
<ul class="matching-refs tags">
|
||||||
<li ng-repeat="tagName in tagNames | limitTo:20"
|
<li ng-repeat="tagName in tagNames | limitTo:20"
|
||||||
class="ref-reference"
|
class="ref-reference"
|
||||||
ng-class="isMatching('tags', tagName, state.branchTagFilter) ? 'match' : 'not-match'">
|
ng-class="isMatching('tags', tagName, state.branchTagFilter) ? 'match' : 'not-match'">
|
||||||
<span ng-click="addRef('tags', tagName)" target="_blank">
|
<span ng-click="addRef('tags', tagName)" target="_blank">
|
||||||
{{ tagName }}
|
{{ tagName }}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<span ng-if="tagNames.length > 20">...</span>
|
<span ng-if="tagNames.length > 20">...</span>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="state.branchTagFilter && !branchNames.length"
|
<div ng-if="state.branchTagFilter && !branchNames.length"
|
||||||
style="margin-top: 10px">
|
style="margin-top: 10px">
|
||||||
<strong>Warning:</strong> No branches found
|
<strong>Warning:</strong> No branches found
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dockerfile folder select -->
|
<!-- Dockerfile folder select -->
|
||||||
<div class="step-view-step" complete-condition="trigger.$ready" load-callback="loadLocations(callback)"
|
<div class="step-view-step" complete-condition="trigger.$ready" load-callback="loadLocations(callback)"
|
||||||
load-message="Loading Folders">
|
load-message="Loading Folders">
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
<i class="dropdown-select-icon none-icon fa fa-folder-o fa-lg" ng-show="state.isInvalidLocation"></i>
|
<i class="dropdown-select-icon none-icon fa fa-folder-o fa-lg" ng-show="state.isInvalidLocation"></i>
|
||||||
<i class="dropdown-select-icon none-icon fa fa-folder fa-lg" style="color: black;" ng-show="!state.isInvalidLocation"></i>
|
<i class="dropdown-select-icon none-icon fa fa-folder fa-lg" style="color: black;" ng-show="!state.isInvalidLocation"></i>
|
||||||
<i class="dropdown-select-icon fa fa-folder fa-lg"></i>
|
<i class="dropdown-select-icon fa fa-folder fa-lg"></i>
|
||||||
|
|
||||||
<!-- Dropdown menu -->
|
<!-- Dropdown menu -->
|
||||||
<ul class="dropdown-select-menu" role="menu">
|
<ul class="dropdown-select-menu" role="menu">
|
||||||
<li ng-repeat="location in locations">
|
<li ng-repeat="location in locations">
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown-header" role="presentation" ng-show="!locations.length">
|
<li class="dropdown-header" role="presentation" ng-show="!locations.length">
|
||||||
No Dockerfiles found in repository
|
No Dockerfiles found in repository
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@
|
||||||
<input type="text" class="form-control input-lg" placeholder="Email" ng-model="recovery.email">
|
<input type="text" class="form-control input-lg" placeholder="Email" ng-model="recovery.email">
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Send Recovery Email</button>
|
<button class="btn btn-lg btn-primary btn-block" type="submit">Send Recovery Email</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="alert alert-danger" ng-show="invalidRecovery">{{errorMessage}}</div>
|
<div class="alert alert-danger" ng-show="invalidRecovery">{{errorMessage}}</div>
|
||||||
|
|
||||||
<div class="alert alert-success" ng-show="sent">Account recovery email was sent.</div>
|
<div class="alert alert-success" ng-show="sent">Account recovery email was sent.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<stop offset="0" style="stop-color:#FFFFFF"/>
|
<stop offset="0" style="stop-color:#FFFFFF"/>
|
||||||
<stop offset="1" style="stop-color:#000000"/>
|
<stop offset="1" style="stop-color:#000000"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<polygon fill="url(#SVGID_3_)" points="125.383,38.316 154.156,107.085 206.812,107.085 198.899,63.493 178.039,86.368
|
<polygon fill="url(#SVGID_3_)" points="125.383,38.316 154.156,107.085 206.812,107.085 198.899,63.493 178.039,86.368
|
||||||
169.695,80.9 155.883,59.896 136.029,42.632 "/>
|
169.695,80.9 155.883,59.896 136.029,42.632 "/>
|
||||||
</g>
|
</g>
|
||||||
<path fill="#CAD5DA" d="M50.447,81.587L59.739,77l2.667,8.333L69.573,95.5l6.667,41.5c0,0-20,18.333-20.667,18.5s-19.167-5-19.167-5
|
<path fill="#CAD5DA" d="M50.447,81.587L59.739,77l2.667,8.333L69.573,95.5l6.667,41.5c0,0-20,18.333-20.667,18.5s-19.167-5-19.167-5
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -7,13 +7,13 @@
|
||||||
<rect x="79.797" y="74.656" fill="#231F20" width="0.561" height="1.094"/>
|
<rect x="79.797" y="74.656" fill="#231F20" width="0.561" height="1.094"/>
|
||||||
<rect x="80.756" y="74.656" fill="#231F20" width="0.561" height="1.094"/>
|
<rect x="80.756" y="74.656" fill="#231F20" width="0.561" height="1.094"/>
|
||||||
<g>
|
<g>
|
||||||
<polygon fill="#4B5059" points="79.16,77.125 79.16,76.188 81.723,76.188 81.723,75.25 79.098,75.25 77.848,80.812 81.723,80.812
|
<polygon fill="#4B5059" points="79.16,77.125 79.16,76.188 81.723,76.188 81.723,75.25 79.098,75.25 77.848,80.812 81.723,80.812
|
||||||
81.723,78.5 79.16,78.5 79.16,77.562 81.723,77.562 81.723,77.125 "/>
|
81.723,78.5 79.16,78.5 79.16,77.562 81.723,77.562 81.723,77.125 "/>
|
||||||
<rect x="79.16" y="76.188" fill="#A73D37" width="2.562" height="0.938"/>
|
<rect x="79.16" y="76.188" fill="#A73D37" width="2.562" height="0.938"/>
|
||||||
<rect x="79.16" y="77.562" fill="#A73D37" width="2.562" height="0.938"/>
|
<rect x="79.16" y="77.562" fill="#A73D37" width="2.562" height="0.938"/>
|
||||||
</g>
|
</g>
|
||||||
<rect x="72.41" y="79.625" fill="#9BA9B2" width="10.5" height="7.75"/>
|
<rect x="72.41" y="79.625" fill="#9BA9B2" width="10.5" height="7.75"/>
|
||||||
<polygon fill="#E8E5D1" points="80.598,86.062 78.41,81.125 71.098,81.125 71.098,81.844 69.504,81.844 69.504,84.156
|
<polygon fill="#E8E5D1" points="80.598,86.062 78.41,81.125 71.098,81.125 71.098,81.844 69.504,81.844 69.504,84.156
|
||||||
71.098,84.156 71.098,93.711 84.598,94.25 84.598,86.062 "/>
|
71.098,84.156 71.098,93.711 84.598,94.25 84.598,86.062 "/>
|
||||||
<polyline fill="#E8E5D1" points="2.41,90.819 2.41,85.562 2.973,85.562 3.66,90.819 "/>
|
<polyline fill="#E8E5D1" points="2.41,90.819 2.41,85.562 2.973,85.562 3.66,90.819 "/>
|
||||||
<g>
|
<g>
|
||||||
|
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
306
static/js/app.js
|
@ -59,13 +59,13 @@ function PlansCtrl($scope, $location, UserService, PlanService, $routeParams) {
|
||||||
|
|
||||||
$scope.signedIn = function() {
|
$scope.signedIn = function() {
|
||||||
$('#signinModal').modal('hide');
|
$('#signinModal').modal('hide');
|
||||||
PlanService.handleNotedPlan();
|
PlanService.handleNotedPlan();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.buyNow = function(plan) {
|
$scope.buyNow = function(plan) {
|
||||||
PlanService.notePlan(plan);
|
PlanService.notePlan(plan);
|
||||||
if ($scope.user && !$scope.user.anonymous) {
|
if ($scope.user && !$scope.user.anonymous) {
|
||||||
PlanService.handleNotedPlan();
|
PlanService.handleNotedPlan();
|
||||||
} else {
|
} else {
|
||||||
$('#signinModal').modal({});
|
$('#signinModal').modal({});
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ function PlansCtrl($scope, $location, UserService, PlanService, $routeParams) {
|
||||||
|
|
||||||
if ($scope && $routeParams['trial-plan']) {
|
if ($scope && $routeParams['trial-plan']) {
|
||||||
$scope.buyNow($routeParams['trial-plan']);
|
$scope.buyNow($routeParams['trial-plan']);
|
||||||
}
|
}
|
||||||
}, /* include the personal plan */ true);
|
}, /* include the personal plan */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ function TutorialCtrl($scope, AngularTour, AngularTourSignals, UserService, Conf
|
||||||
'steps': [
|
'steps': [
|
||||||
{
|
{
|
||||||
'title': 'Welcome to the ' + Config.REGISTRY_TITLE_SHORT + ' tutorial!',
|
'title': 'Welcome to the ' + Config.REGISTRY_TITLE_SHORT + ' tutorial!',
|
||||||
'templateUrl': '/static/tutorial/welcome.html'
|
'templateUrl': '/static/tutorial/welcome.html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Sign in to get started',
|
'title': 'Sign in to get started',
|
||||||
|
@ -235,7 +235,7 @@ function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
|
||||||
$scope.namespace = null;
|
$scope.namespace = null;
|
||||||
$scope.page = 1;
|
$scope.page = 1;
|
||||||
$scope.publicPageCount = null;
|
$scope.publicPageCount = null;
|
||||||
|
|
||||||
// Monitor changes in the user.
|
// Monitor changes in the user.
|
||||||
UserService.updateUserIn($scope, function() {
|
UserService.updateUserIn($scope, function() {
|
||||||
loadMyRepos($scope.namespace);
|
loadMyRepos($scope.namespace);
|
||||||
|
@ -269,7 +269,7 @@ function RepoListCtrl($scope, $sanitize, Restangular, UserService, ApiService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {'public': false, 'sort': true, 'namespace': namespace};
|
var options = {'public': false, 'sort': true, 'namespace': namespace};
|
||||||
|
|
||||||
$scope.user_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
$scope.user_repositories = ApiService.listReposAsResource().withOptions(options).get(function(resp) {
|
||||||
return resp.repositories;
|
return resp.repositories;
|
||||||
});
|
});
|
||||||
|
@ -318,7 +318,7 @@ function LandingCtrl($scope, UserService, ApiService, Features, Config) {
|
||||||
if (namespace == $scope.user.username) {
|
if (namespace == $scope.user.username) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.user.organizations) {
|
if ($scope.user.organizations) {
|
||||||
for (var i = 0; i < $scope.user.organizations.length; ++i) {
|
for (var i = 0; i < $scope.user.organizations.length; ++i) {
|
||||||
var org = $scope.user.organizations[i];
|
var org = $scope.user.organizations[i];
|
||||||
|
@ -483,7 +483,7 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
|
||||||
|
|
||||||
$scope.currentPullCommand = $scope.pullCommands[0];
|
$scope.currentPullCommand = $scope.pullCommands[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.showNewBuildDialog = function() {
|
$scope.showNewBuildDialog = function() {
|
||||||
$scope.buildDialogShowCounter++;
|
$scope.buildDialogShowCounter++;
|
||||||
};
|
};
|
||||||
|
@ -655,7 +655,7 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
|
||||||
|
|
||||||
$scope.setImage = function(imageId, opt_updateURL) {
|
$scope.setImage = function(imageId, opt_updateURL) {
|
||||||
if (!$scope.images) { return; }
|
if (!$scope.images) { return; }
|
||||||
|
|
||||||
var image = null;
|
var image = null;
|
||||||
for (var i = 0; i < $scope.images.length; ++i) {
|
for (var i = 0; i < $scope.images.length; ++i) {
|
||||||
var currentImage = $scope.images[i];
|
var currentImage = $scope.images[i];
|
||||||
|
@ -691,7 +691,7 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
|
||||||
// We must find a good default.
|
// We must find a good default.
|
||||||
for (tagName in repo.tags) {
|
for (tagName in repo.tags) {
|
||||||
if (!proposedTag || tagName == 'latest') {
|
if (!proposedTag || tagName == 'latest') {
|
||||||
proposedTag = repo.tags[tagName];
|
proposedTag = repo.tags[tagName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,7 +702,7 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
|
||||||
|
|
||||||
if ($scope.tree) {
|
if ($scope.tree) {
|
||||||
$scope.tree.setTag(proposedTag.name);
|
$scope.tree.setTag(proposedTag.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_updateURL) {
|
if (opt_updateURL) {
|
||||||
$location.search('image', null);
|
$location.search('image', null);
|
||||||
|
@ -871,7 +871,7 @@ function RepoCtrl($scope, $sanitize, Restangular, ImageMetadataService, ApiServi
|
||||||
};
|
};
|
||||||
|
|
||||||
var listImages = function() {
|
var listImages = function() {
|
||||||
var params = {'repository': namespace + '/' + name};
|
var params = {'repository': namespace + '/' + name};
|
||||||
$scope.imageHistory = ApiService.listRepositoryImagesAsResource(params).get(function(resp) {
|
$scope.imageHistory = ApiService.listRepositoryImagesAsResource(params).get(function(resp) {
|
||||||
$scope.images = resp.images;
|
$scope.images = resp.images;
|
||||||
$scope.specificImages = [];
|
$scope.specificImages = [];
|
||||||
|
@ -971,7 +971,7 @@ function BuildPackageCtrl($scope, Restangular, ApiService, DataFileService, $rou
|
||||||
return dockerfilePath;
|
return dockerfilePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
var processBuildPack = function(uint8array) {
|
var processBuildPack = function(uint8array) {
|
||||||
var archiveread = function(files) {
|
var archiveread = function(files) {
|
||||||
var getpath = function(file) {
|
var getpath = function(file) {
|
||||||
return file.path;
|
return file.path;
|
||||||
|
@ -1056,7 +1056,7 @@ function BuildPackageCtrl($scope, Restangular, ApiService, DataFileService, $rou
|
||||||
$scope.accessDenied = true;
|
$scope.accessDenied = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.title = 'Repository Build Pack - ' + resp['display_name'];
|
$rootScope.title = 'Repository Build Pack - ' + resp['display_name'];
|
||||||
$scope.repobuild = resp;
|
$scope.repobuild = resp;
|
||||||
$scope.repo = {
|
$scope.repo = {
|
||||||
|
@ -1115,7 +1115,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
$('#confirmRestartBuildModal').modal('hide');
|
$('#confirmRestartBuildModal').modal('hide');
|
||||||
|
|
||||||
var subdirectory = '';
|
var subdirectory = '';
|
||||||
if (build['job_config']) {
|
if (build['job_config']) {
|
||||||
subdirectory = build['job_config']['build_subdir'] || '';
|
subdirectory = build['job_config']['build_subdir'] || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,7 +1159,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
|
|
||||||
$scope.processANSI = function(message, container) {
|
$scope.processANSI = function(message, container) {
|
||||||
var filter = container.logs._filter = (container.logs._filter || ansi2html.create());
|
var filter = container.logs._filter = (container.logs._filter || ansi2html.create());
|
||||||
|
|
||||||
// Note: order is important here.
|
// Note: order is important here.
|
||||||
var setup = filter.getSetupHtml();
|
var setup = filter.getSetupHtml();
|
||||||
var stream = filter.addInputToStream(message);
|
var stream = filter.addInputToStream(message);
|
||||||
|
@ -1194,7 +1194,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
if ($scope.pollChannel) {
|
if ($scope.pollChannel) {
|
||||||
$scope.pollChannel.stop();
|
$scope.pollChannel.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new channel for polling the build status and logs.
|
// Create a new channel for polling the build status and logs.
|
||||||
var conductStatusAndLogRequest = function(callback) {
|
var conductStatusAndLogRequest = function(callback) {
|
||||||
getBuildStatusAndLogs(build, callback);
|
getBuildStatusAndLogs(build, callback);
|
||||||
|
@ -1230,7 +1230,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
return endIndex;
|
return endIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
var getBuildStatusAndLogs = function(build, callback) {
|
var getBuildStatusAndLogs = function(build, callback) {
|
||||||
var params = {
|
var params = {
|
||||||
'repository': namespace + '/' + name,
|
'repository': namespace + '/' + name,
|
||||||
'build_uuid': build.id
|
'build_uuid': build.id
|
||||||
|
@ -1238,7 +1238,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
|
|
||||||
ApiService.getRepoBuildStatus(null, params, true).then(function(resp) {
|
ApiService.getRepoBuildStatus(null, params, true).then(function(resp) {
|
||||||
if (build != $scope.currentBuild) { callback(false); return; }
|
if (build != $scope.currentBuild) { callback(false); return; }
|
||||||
|
|
||||||
// Note: We use extend here rather than replacing as Angular is depending on the
|
// Note: We use extend here rather than replacing as Angular is depending on the
|
||||||
// root build object to remain the same object.
|
// root build object to remain the same object.
|
||||||
var matchingBuilds = $.grep($scope.builds, function(elem) {
|
var matchingBuilds = $.grep($scope.builds, function(elem) {
|
||||||
|
@ -1258,9 +1258,9 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
'start': $scope.logStartIndex
|
'start': $scope.logStartIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
ApiService.getRepoBuildLogsAsResource(params, true).withOptions(options).get(function(resp) {
|
ApiService.getRepoBuildLogsAsResource(params, true).withOptions(options).get(function(resp) {
|
||||||
if (build != $scope.currentBuild) { callback(false); return; }
|
if (build != $scope.currentBuild) { callback(false); return; }
|
||||||
|
|
||||||
// Process the logs we've received.
|
// Process the logs we've received.
|
||||||
$scope.logStartIndex = processLogs(resp['logs'], resp['start'], resp['total']);
|
$scope.logStartIndex = processLogs(resp['logs'], resp['start'], resp['total']);
|
||||||
|
|
||||||
|
@ -1323,7 +1323,7 @@ function RepoBuildCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
|
||||||
fetchRepository();
|
fetchRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerService, $routeParams,
|
function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerService, $routeParams,
|
||||||
$rootScope, $location, UserService, Config, Features, ExternalNotificationData) {
|
$rootScope, $location, UserService, Config, Features, ExternalNotificationData) {
|
||||||
|
|
||||||
var namespace = $routeParams.namespace;
|
var namespace = $routeParams.namespace;
|
||||||
|
@ -1335,7 +1335,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
||||||
$scope.permissions = {'team': [], 'user': [], 'loading': 2};
|
$scope.permissions = {'team': [], 'user': [], 'loading': 2};
|
||||||
$scope.logsShown = 0;
|
$scope.logsShown = 0;
|
||||||
$scope.deleting = false;
|
$scope.deleting = false;
|
||||||
|
|
||||||
$scope.permissionCache = {};
|
$scope.permissionCache = {};
|
||||||
$scope.showTriggerSetupCounter = 0;
|
$scope.showTriggerSetupCounter = 0;
|
||||||
|
|
||||||
|
@ -1436,7 +1436,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
||||||
var permission = $scope.permissions[kind][entityName];
|
var permission = $scope.permissions[kind][entityName];
|
||||||
var currentRole = permission.role;
|
var currentRole = permission.role;
|
||||||
permission.role = role;
|
permission.role = role;
|
||||||
|
|
||||||
var permissionPut = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
var permissionPut = Restangular.one(getRestUrl('repository', namespace, name, 'permissions', kind, entityName));
|
||||||
permissionPut.customPUT(permission).then(function() {}, function(resp) {
|
permissionPut.customPUT(permission).then(function() {}, function(resp) {
|
||||||
$scope.permissions[kind][entityName] = {'role': currentRole};
|
$scope.permissions[kind][entityName] = {'role': currentRole};
|
||||||
|
@ -1534,7 +1534,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
||||||
$scope.deleting = true;
|
$scope.deleting = true;
|
||||||
ApiService.deleteRepository(null, params).then(function() {
|
ApiService.deleteRepository(null, params).then(function() {
|
||||||
$scope.repo = null;
|
$scope.repo = null;
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
document.location = '/repository/';
|
document.location = '/repository/';
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -1545,7 +1545,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.showNewNotificationCounter = 0;
|
$scope.showNewNotificationCounter = 0;
|
||||||
|
|
||||||
$scope.showNewNotificationDialog = function() {
|
$scope.showNewNotificationDialog = function() {
|
||||||
$scope.showNewNotificationCounter++;
|
$scope.showNewNotificationCounter++;
|
||||||
};
|
};
|
||||||
|
@ -1629,7 +1629,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, KeyService, TriggerServi
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.showManualBuildDialog = 0;
|
$scope.showManualBuildDialog = 0;
|
||||||
|
|
||||||
$scope.startTrigger = function(trigger, opt_custom) {
|
$scope.startTrigger = function(trigger, opt_custom) {
|
||||||
var parameters = TriggerService.getRunParameters(trigger.service);
|
var parameters = TriggerService.getRunParameters(trigger.service);
|
||||||
if (parameters.length && !opt_custom) {
|
if (parameters.length && !opt_custom) {
|
||||||
|
@ -1767,7 +1767,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
||||||
$scope.invoicesShown = 0;
|
$scope.invoicesShown = 0;
|
||||||
|
|
||||||
$scope.USER_PATTERN = USER_PATTERN;
|
$scope.USER_PATTERN = USER_PATTERN;
|
||||||
|
|
||||||
$scope.loadAuthedApps = function() {
|
$scope.loadAuthedApps = function() {
|
||||||
if ($scope.authorizedApps) { return; }
|
if ($scope.authorizedApps) { return; }
|
||||||
|
|
||||||
|
@ -1810,7 +1810,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
||||||
$scope.orgPlans = plans;
|
$scope.orgPlans = plans;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.convertStep = 1;
|
$scope.convertStep = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1858,7 +1858,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
$scope.updatingUser = false;
|
$scope.updatingUser = false;
|
||||||
UIService.showFormError('#changeUsernameForm', result);
|
UIService.showFormError('#changeUsernameForm', result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeEmail = function() {
|
$scope.changeEmail = function() {
|
||||||
|
@ -1903,7 +1903,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
||||||
UserService.load();
|
UserService.load();
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
$scope.updatingUser = false;
|
$scope.updatingUser = false;
|
||||||
UIService.showFormError('#changePasswordForm', result);
|
UIService.showFormError('#changePasswordForm', result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1920,7 +1920,7 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, ImageMetadataService) {
|
function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, ImageMetadataService) {
|
||||||
var namespace = $routeParams.namespace;
|
var namespace = $routeParams.namespace;
|
||||||
var name = $routeParams.name;
|
var name = $routeParams.name;
|
||||||
var imageid = $routeParams.image;
|
var imageid = $routeParams.image;
|
||||||
|
@ -1944,7 +1944,7 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.substr(0, index).split('/');
|
return filepath.substr(0, index).split('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1967,10 +1967,10 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
|
||||||
$scope.search['$'] = filter;
|
$scope.search['$'] = filter;
|
||||||
document.getElementById('change-filter').value = filter;
|
document.getElementById('change-filter').value = filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.initializeTree = function() {
|
$scope.initializeTree = function() {
|
||||||
if ($scope.tree) { return; }
|
if ($scope.tree) { return; }
|
||||||
|
|
||||||
$scope.tree = new ImageFileChangeTree($scope.image, $scope.combinedChanges);
|
$scope.tree = new ImageFileChangeTree($scope.image, $scope.combinedChanges);
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.tree.draw('changes-tree-container');
|
$scope.tree.draw('changes-tree-container');
|
||||||
|
@ -1990,7 +1990,7 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
|
||||||
var fetchImage = function() {
|
var fetchImage = function() {
|
||||||
var params = {
|
var params = {
|
||||||
'repository': namespace + '/' + name,
|
'repository': namespace + '/' + name,
|
||||||
'image_id': imageid
|
'image_id': imageid
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.image = ApiService.getImageAsResource(params).get(function(image) {
|
$scope.image = ApiService.getImageAsResource(params).get(function(image) {
|
||||||
|
@ -2015,14 +2015,14 @@ function ImageViewCtrl($scope, $routeParams, $rootScope, $timeout, ApiService, I
|
||||||
var fetchChanges = function() {
|
var fetchChanges = function() {
|
||||||
var params = {
|
var params = {
|
||||||
'repository': namespace + '/' + name,
|
'repository': namespace + '/' + name,
|
||||||
'image_id': imageid
|
'image_id': imageid
|
||||||
};
|
};
|
||||||
|
|
||||||
ApiService.getImageChanges(null, params).then(function(changes) {
|
ApiService.getImageChanges(null, params).then(function(changes) {
|
||||||
var combinedChanges = [];
|
var combinedChanges = [];
|
||||||
var addCombinedChanges = function(c, kind) {
|
var addCombinedChanges = function(c, kind) {
|
||||||
for (var i = 0; i < c.length; ++i) {
|
for (var i = 0; i < c.length; ++i) {
|
||||||
combinedChanges.push({
|
combinedChanges.push({
|
||||||
'kind': kind,
|
'kind': kind,
|
||||||
'file': c[i]
|
'file': c[i]
|
||||||
});
|
});
|
||||||
|
@ -2066,7 +2066,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
|
||||||
$scope.$watch('repo.namespace', function(namespace) {
|
$scope.$watch('repo.namespace', function(namespace) {
|
||||||
// Note: Can initially be undefined.
|
// Note: Can initially be undefined.
|
||||||
if (!namespace) { return; }
|
if (!namespace) { return; }
|
||||||
|
|
||||||
var isUserNamespace = (namespace == $scope.user.username);
|
var isUserNamespace = (namespace == $scope.user.username);
|
||||||
|
|
||||||
$scope.planRequired = null;
|
$scope.planRequired = null;
|
||||||
|
@ -2103,7 +2103,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2176,7 +2176,7 @@ function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService
|
||||||
var isUserNamespace = $scope.isUserNamespace;
|
var isUserNamespace = $scope.isUserNamespace;
|
||||||
ApiService.getPrivateAllowed(isUserNamespace ? null : $scope.repo.namespace).then(function(resp) {
|
ApiService.getPrivateAllowed(isUserNamespace ? null : $scope.repo.namespace).then(function(resp) {
|
||||||
$scope.checkingPlan = false;
|
$scope.checkingPlan = false;
|
||||||
|
|
||||||
if (resp['privateAllowed']) {
|
if (resp['privateAllowed']) {
|
||||||
$scope.planRequired = null;
|
$scope.planRequired = null;
|
||||||
return;
|
return;
|
||||||
|
@ -2218,8 +2218,8 @@ function OrgViewCtrl($rootScope, $scope, ApiService, $routeParams) {
|
||||||
{ 'id': 'creator', 'title': 'Creator', 'kind': 'success' },
|
{ 'id': 'creator', 'title': 'Creator', 'kind': 'success' },
|
||||||
{ 'id': 'admin', 'title': 'Admin', 'kind': 'primary' }
|
{ 'id': 'admin', 'title': 'Admin', 'kind': 'primary' }
|
||||||
];
|
];
|
||||||
|
|
||||||
$scope.setRole = function(role, teamname) {
|
$scope.setRole = function(role, teamname) {
|
||||||
var previousRole = $scope.organization.teams[teamname].role;
|
var previousRole = $scope.organization.teams[teamname].role;
|
||||||
$scope.organization.teams[teamname].role = role;
|
$scope.organization.teams[teamname].role = role;
|
||||||
|
|
||||||
|
@ -2231,7 +2231,7 @@ function OrgViewCtrl($rootScope, $scope, ApiService, $routeParams) {
|
||||||
var data = $scope.organization.teams[teamname];
|
var data = $scope.organization.teams[teamname];
|
||||||
|
|
||||||
ApiService.updateOrganizationTeam(data, params).then(function(resp) {
|
ApiService.updateOrganizationTeam(data, params).then(function(resp) {
|
||||||
}, function(resp) {
|
}, function(resp) {
|
||||||
$scope.organization.teams[teamname].role = previousRole;
|
$scope.organization.teams[teamname].role = previousRole;
|
||||||
$scope.roleError = resp.data || '';
|
$scope.roleError = resp.data || '';
|
||||||
$('#cannotChangeTeamModal').modal({});
|
$('#cannotChangeTeamModal').modal({});
|
||||||
|
@ -2306,7 +2306,7 @@ function OrgAdminCtrl($rootScope, $scope, $timeout, Restangular, $routeParams, U
|
||||||
PlanService.getPlans(function(plans) {
|
PlanService.getPlans(function(plans) {
|
||||||
$scope.plans = plans;
|
$scope.plans = plans;
|
||||||
$scope.plan_map = {};
|
$scope.plan_map = {};
|
||||||
|
|
||||||
for (var i = 0; i < plans.length; ++i) {
|
for (var i = 0; i < plans.length; ++i) {
|
||||||
$scope.plan_map[plans[i].stripeId] = plans[i];
|
$scope.plan_map[plans[i].stripeId] = plans[i];
|
||||||
}
|
}
|
||||||
|
@ -2321,7 +2321,7 @@ function OrgAdminCtrl($rootScope, $scope, $timeout, Restangular, $routeParams, U
|
||||||
$scope.invoicesShown = 0;
|
$scope.invoicesShown = 0;
|
||||||
$scope.applicationsShown = 0;
|
$scope.applicationsShown = 0;
|
||||||
$scope.changingOrganization = false;
|
$scope.changingOrganization = false;
|
||||||
|
|
||||||
$scope.loadLogs = function() {
|
$scope.loadLogs = function() {
|
||||||
$scope.logsShown++;
|
$scope.logsShown++;
|
||||||
};
|
};
|
||||||
|
@ -2444,7 +2444,7 @@ function TeamViewCtrl($rootScope, $scope, $timeout, Features, Restangular, ApiSe
|
||||||
|
|
||||||
$scope.addNewMember = function(member) {
|
$scope.addNewMember = function(member) {
|
||||||
if (!member || $scope.memberMap[member.name]) { return; }
|
if (!member || $scope.memberMap[member.name]) { return; }
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
'orgname': orgname,
|
'orgname': orgname,
|
||||||
'teamname': teamname,
|
'teamname': teamname,
|
||||||
|
@ -2539,7 +2539,7 @@ function TeamViewCtrl($rootScope, $scope, $timeout, Features, Restangular, ApiSe
|
||||||
$scope.membersResource = ApiService.getOrganizationTeamMembersAsResource(params).get(function(resp) {
|
$scope.membersResource = ApiService.getOrganizationTeamMembersAsResource(params).get(function(resp) {
|
||||||
$scope.members = resp.members;
|
$scope.members = resp.members;
|
||||||
$scope.canEditMembers = resp.can_edit;
|
$scope.canEditMembers = resp.can_edit;
|
||||||
|
|
||||||
$('.info-icon').popover({
|
$('.info-icon').popover({
|
||||||
'trigger': 'hover',
|
'trigger': 'hover',
|
||||||
'html': true
|
'html': true
|
||||||
|
@ -2687,7 +2687,7 @@ function OrgMemberLogsCtrl($scope, $routeParams, $rootScope, $timeout, Restangul
|
||||||
});
|
});
|
||||||
|
|
||||||
return resp.member;
|
return resp.member;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load the org info and the member info.
|
// Load the org info and the member info.
|
||||||
|
@ -2783,7 +2783,7 @@ function ManageApplicationCtrl($scope, $routeParams, $rootScope, $location, $tim
|
||||||
' under organization ' + $scope.orgname;
|
' under organization ' + $scope.orgname;
|
||||||
|
|
||||||
return resp;
|
return resp;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|