Merge branch 'dockerbuild' of https://bitbucket.org/yackob03/quay into dockerbuild
This commit is contained in:
commit
2113fcf54f
25 changed files with 274 additions and 92 deletions
|
@ -195,4 +195,4 @@ def get_all_status():
|
|||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
|
||||
app.run(host='0.0.0.0', port=5002, debug=True)
|
||||
app.run(host='0.0.0.0', port=5002, debug=True)
|
||||
|
|
27
certs/digital_ocean
Normal file
27
certs/digital_ocean
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAwjlIK0HodmDNrZAmaALtr9RLriRSeeLh76gV8KHmjRweeT7v
|
||||
dmhKeGP1nOAs17caZkcwsW0tiDbCeIv2MisV405sScjPOxFivWpY8tL72sgVuOAl
|
||||
ReZauOGZ4M1ZcSa/YbT7tnFCIayYE9pde4ih5LmYZqKsBsaNq3ErcMnAzqG77D95
|
||||
8swuVwhz/INioBWwe4FjO76/0DqS357hT5yHDWthJD6UUH12VajPKBtXEvGNUtNL
|
||||
vdq+drm9omt2y0seMn47fZXiNIulLv7ojsWKwtRMTsGcjnv6VMZAVAuX11u4cJd+
|
||||
oPTbDl0D+02B7XYcxABqdMZcOc1/7VTUlFFd4wIDAQABAoIBAAs4V+z3z8AW84rV
|
||||
SwKzOJvxvbV/r6wO6VJ4+Vt/XtxEBZanhhnnCHZP//5iDPUhRMsnza5SSlEWKMHi
|
||||
BAT97DPHcgYJLb+Rz4x1ulG80oPfDzIw8LZLCm6nycXs1v/sZx3z4J63iER9vgNX
|
||||
mBLs371g42b6esmhasm+re3EGflV0LeY1IX0MY40pqGndmW8Fly1QH179TrMzVUJ
|
||||
btu3i2JrwWmKk5zO5YGm0SYY5QQGCdjPj6SL+idDniAefEvbjJYz2qOaPOF3wj/7
|
||||
r8dAnmyaP10Q3JojT01Et5ltMfr0oF2/pic9tWYGrgn/aIuoXUXj0SF3Pfgrb/4L
|
||||
Et1kzFECgYEA8Tb/9bYzQgtaQTQfzFU/KnsIKKnrxh73rZwnIxG59WvN0Ws41Byf
|
||||
rv8fEbXWU8Yj0drxRSud9fADr99lZGWFxle8rSW5+qqoUxG8n/fkktzHxyPE/9Mh
|
||||
pZW7un7a5/glKgUpHpjaOCZj9rhdF1AwdUXLSo1sFc7VBsKvKiKJAT0CgYEAziDt
|
||||
A9h5lOgiLGf1xdBq3qmLIlARz7fivAcZ5acSGN5k6MFFxjHNqhcXRusqs7g+hvCN
|
||||
eRupdwfgSdLwrTfvxuY4pCcddfYIZO3uUZYs/glvYRtIxaP2kMBkZTs9KzI02Bjv
|
||||
zT3NPReR/46SqW0zvYTlRFSY7VZ0eRED/5xnjZ8CgYAZdlrSjyceA6DFXUE2CpGe
|
||||
ZFpaIIW45i/y7ZbcBtUAaR7SymS3T0Yz7M5UykMTmMjTMC9jw9Tqzyk0eXp0fJsA
|
||||
cuaByIe3RCh8jFTC9iH0tsWH6eizsI/OsN2eNCHbdsBFjUHn7u6qGrNWqeN5wIc8
|
||||
+d8ZwY/1RV4LVqWy5u5baQKBgHLFvJMWluQFuPl2zU9etBLU3ma1pKU/I11EqvPH
|
||||
afk044UCEKLBml1pzAkt6jH1lcM2798OOvbPCOCyNlaMvdLG36TvLqU+3/+qx7bf
|
||||
4p90i3LLaWK64BBLP9tp9640n13vzJ5AGiY5GI7uSNVTu6p789hvLlOAfwvmII7T
|
||||
/IjLAoGBAO6iU8i6pAOaKa7+/uExXx6xwk3vqQtovxByo1/m7NpyUtT+ElDSq+t9
|
||||
7f+3TzzPB6ggdMl8d+PSyHR3o7KjVPgOSe7zld7eePhUrLjwZ4lh5ohcvhvYfaRL
|
||||
0EgRTaTb+zLtCAvJS/ilNnJoIcxUmD8u5uSXpY7vAleSOiQTJRTh
|
||||
-----END RSA PRIVATE KEY-----
|
1
certs/digital_ocean.pub
Normal file
1
certs/digital_ocean.pub
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCOUgrQeh2YM2tkCZoAu2v1EuuJFJ54uHvqBXwoeaNHB55Pu92aEp4Y/Wc4CzXtxpmRzCxbS2INsJ4i/YyKxXjTmxJyM87EWK9aljy0vvayBW44CVF5lq44ZngzVlxJr9htPu2cUIhrJgT2l17iKHkuZhmoqwGxo2rcStwycDOobvsP3nyzC5XCHP8g2KgFbB7gWM7vr/QOpLfnuFPnIcNa2EkPpRQfXZVqM8oG1cS8Y1S00u92r52ub2ia3bLSx4yfjt9leI0i6Uu/uiOxYrC1ExOwZyOe/pUxkBUC5fXW7hwl36g9NsOXQP7TYHtdhzEAGp0xlw5zX/tVNSUUV3j jake@coreserver
|
13
config.py
13
config.py
|
@ -85,8 +85,15 @@ class GitHubProdConfig(GitHubTestConfig):
|
|||
GITHUB_CLIENT_SECRET = 'f89d8bb28ea3bd4e1c68808500d185a816be53b1'
|
||||
|
||||
|
||||
class DigitalOceanConfig():
|
||||
DO_CLIENT_ID = 'LJ44y2wwYj1MD0BRxS6qHA'
|
||||
DO_CLIENT_SECRET = 'b9357a6f6ff45a33bb03f6dbbad135f9'
|
||||
DO_SSH_KEY_ID = '46986'
|
||||
|
||||
|
||||
class DebugConfig(FlaskConfig, MailConfig, LocalStorage, SQLiteDB,
|
||||
StripeTestConfig, MixpanelTestConfig, GitHubTestConfig):
|
||||
StripeTestConfig, MixpanelTestConfig, GitHubTestConfig,
|
||||
DigitalOceanConfig):
|
||||
REGISTRY_SERVER = 'localhost:5000'
|
||||
LOGGING_CONFIG = {
|
||||
'level': logging.DEBUG,
|
||||
|
@ -98,7 +105,7 @@ class DebugConfig(FlaskConfig, MailConfig, LocalStorage, SQLiteDB,
|
|||
|
||||
class LocalHostedConfig(FlaskConfig, MailConfig, S3Storage, RDSMySQL,
|
||||
StripeLiveConfig, MixpanelTestConfig,
|
||||
GitHubProdConfig):
|
||||
GitHubProdConfig, DigitalOceanConfig):
|
||||
REGISTRY_SERVER = 'localhost:5000'
|
||||
LOGGING_CONFIG = {
|
||||
'level': logging.DEBUG,
|
||||
|
@ -109,7 +116,7 @@ class LocalHostedConfig(FlaskConfig, MailConfig, S3Storage, RDSMySQL,
|
|||
|
||||
class ProductionConfig(FlaskConfig, MailConfig, S3Storage, RDSMySQL,
|
||||
StripeLiveConfig, MixpanelProdConfig,
|
||||
GitHubProdConfig):
|
||||
GitHubProdConfig, DigitalOceanConfig):
|
||||
REGISTRY_SERVER = 'quay.io'
|
||||
LOGGING_CONFIG = {
|
||||
'stream': sys.stderr,
|
||||
|
|
|
@ -150,6 +150,13 @@ class RepositoryTag(BaseModel):
|
|||
)
|
||||
|
||||
|
||||
class RepositoryBuild(BaseModel):
|
||||
digitalocean_build_node_id = IntegerField(null=True)
|
||||
phase = CharField(default='waiting')
|
||||
status_url = CharField(null=True)
|
||||
repository = ForeignKeyField(Repository)
|
||||
|
||||
|
||||
class QueueItem(BaseModel):
|
||||
queue_name = CharField(index=True)
|
||||
body = TextField()
|
||||
|
@ -162,7 +169,7 @@ def initialize_db():
|
|||
create_model_tables([User, Repository, Image, AccessToken, Role,
|
||||
RepositoryPermission, Visibility, RepositoryTag,
|
||||
EmailConfirmation, FederatedLogin, LoginService,
|
||||
QueueItem])
|
||||
QueueItem, RepositoryBuild])
|
||||
Role.create(name='admin')
|
||||
Role.create(name='write')
|
||||
Role.create(name='read')
|
||||
|
|
|
@ -30,6 +30,10 @@ class InvalidTokenException(DataModelException):
|
|||
pass
|
||||
|
||||
|
||||
class InvalidRepositoryBuildException(DataModelException):
|
||||
pass
|
||||
|
||||
|
||||
def create_user(username, password, email):
|
||||
if not validate_email(email):
|
||||
raise InvalidEmailAddressException('Invalid email address: %s' % email)
|
||||
|
@ -548,3 +552,11 @@ def load_token_data(code):
|
|||
return fetched[0]
|
||||
else:
|
||||
raise InvalidTokenException('Invalid delegate token code: %s' % code)
|
||||
|
||||
|
||||
def get_repository_build(request_dbid):
|
||||
try:
|
||||
return RepositoryBuild.get(RepositoryBuild == request_dbid)
|
||||
except RepositoryBuild.DoesNotExist:
|
||||
msg = 'Unable to locate a build by id: %s' % request_dbid
|
||||
raise InvalidRepositoryBuildException(msg)
|
||||
|
|
|
@ -56,3 +56,4 @@ class WorkQueue(object):
|
|||
|
||||
|
||||
image_diff_queue = WorkQueue('imagediff')
|
||||
dockerfile_build_queue = WorkQueue('dockerfilebuild')
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
width: 40px;
|
||||
}
|
||||
|
||||
.repo-circle .icon-lock {
|
||||
font-size: 50%;
|
||||
.repo-circle .fa-lock {
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
right: 0px;
|
||||
|
@ -31,11 +30,11 @@
|
|||
text-align: center;
|
||||
height: 20px;
|
||||
line-height: 21px;
|
||||
font-size: 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.repo-circle.no-background .icon-lock {
|
||||
bottom: -4px;
|
||||
.repo-circle.no-background .fa-lock {
|
||||
bottom: 2px;
|
||||
right: -6px;
|
||||
color: #444;
|
||||
}
|
||||
|
@ -711,7 +710,7 @@ p.editable:hover i {
|
|||
}
|
||||
|
||||
.repo-listing i {
|
||||
font-size: 1.5em;
|
||||
font-size: 2em;
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
|
@ -802,15 +801,15 @@ p.editable:hover i {
|
|||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.repo .changes-container i.icon-plus-sign-alt {
|
||||
.repo .changes-container i.fa-plus-square {
|
||||
color: rgb(73, 209, 73);
|
||||
}
|
||||
|
||||
.repo .changes-container i.icon-minus-sign-alt {
|
||||
.repo .changes-container i.fa-minus-square {
|
||||
color: rgb(209, 73, 73);
|
||||
}
|
||||
|
||||
.repo .changes-container i.icon-edit-sign {
|
||||
.repo .changes-container i.fa-pencil-square {
|
||||
color: rgb(73, 100, 209);
|
||||
}
|
||||
|
||||
|
@ -926,11 +925,11 @@ p.editable:hover i {
|
|||
width: 580px;
|
||||
}
|
||||
|
||||
.repo-admin .repo-access-state .state-icon i.icon-lock {
|
||||
.repo-admin .repo-access-state .state-icon i.fa-lock {
|
||||
background: rgb(253, 191, 191);
|
||||
}
|
||||
|
||||
.repo-admin .repo-access-state .state-icon i.icon-unlock-alt {
|
||||
.repo-admin .repo-access-state .state-icon i.fa-unlock-alt {
|
||||
background: rgb(170, 236, 170);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<i class="icon-lock icon-large" style="{{ !!(repo.is_public) ? 'visibility: hidden' : 'visibility: visible' }}" title="Private Repository"></i>
|
||||
<i class="icon-hdd icon-large"></i>
|
||||
<i class="fa fa-lock fa-lg" style="{{ repo.is_public ? 'visibility: hidden' : 'visibility: visible' }}" title="Private Repository"></i>
|
||||
<i class="fa fa-hdd fa-lg"></i>
|
||||
|
|
|
@ -85,7 +85,7 @@ function HeaderCtrl($scope, $location, UserService, Restangular) {
|
|||
},
|
||||
template: function (datum) {
|
||||
template = '<div class="repo-mini-listing">';
|
||||
template += '<i class="icon-hdd icon-large"></i>'
|
||||
template += '<i class="fa fa-hdd fa-lg"></i>'
|
||||
template += '<span class="name">' + datum.repo.namespace +'/' + datum.repo.name + '</span>'
|
||||
if (datum.repo.description) {
|
||||
template += '<span class="description">' + getFirstTextLine(datum.repo.description) + '</span>'
|
||||
|
@ -485,7 +485,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
},
|
||||
template: function (datum) {
|
||||
template = '<div class="user-mini-listing">';
|
||||
template += '<i class="icon-user icon-large"></i>'
|
||||
template += '<i class="fa fa-user fa-lg"></i>'
|
||||
template += '<span class="name">' + datum.username + '</span>'
|
||||
template += '</div>'
|
||||
return template;
|
||||
|
|
|
@ -1039,17 +1039,17 @@ ImageFileChangeTree.prototype.update_ = function(source) {
|
|||
node.select('.node-icon')
|
||||
.html(function(d) {
|
||||
if (!d.kind) {
|
||||
var folder = d._children ? 'icon-folder-close' : 'icon-folder-open';
|
||||
var folder = d._children ? 'fa fa-folder' : 'fa fa-folder-open';
|
||||
return '<i class="' + folder + '"></i>';
|
||||
}
|
||||
|
||||
var icon = {
|
||||
'added': 'plus-sign-alt',
|
||||
'removed': 'minus-sign-alt',
|
||||
'changed': 'edit-sign'
|
||||
'added': 'plus-square',
|
||||
'removed': 'minus-square',
|
||||
'changed': 'pencil-square'
|
||||
};
|
||||
|
||||
return '<i class="change-icon icon-' + icon[d.kind] + '"></i>';
|
||||
return '<i class="change-icon fa fa-' + icon[d.kind] + '"></i>';
|
||||
});
|
||||
|
||||
// Transition exiting nodes to the parent's new position.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(function(browserchrome, $) {
|
||||
var htmlTemplate = '<div class="browser-chrome-container"><div class="browser-chrome-header"><i class="icon-remove-sign"></i> <i class="icon-minus-sign"></i> <i class="icon-plus-sign"></i><div class="browser-chrome-tab"><div class="browser-chrome-tab-wrapper"><div class="browser-chrome-tab-content"><i class="icon-file-alt icon-large"></i> <span class="tab-title">Tab Title</span></div></div></div><div class="user-icon-container"><i class="icon-user icon-2x"></i></div></div><div class="browser-chrome-url-bar"><div class="left-controls"><i class="icon-arrow-left icon-large"></i> <i class="icon-arrow-right icon-large"></i> <i class="icon-rotate-right icon-large"></i> </div><div class="right-controls"> <i class="icon-reorder icon-large"></i></div><div class="browser-chrome-url"><span class="protocol-https" style="display: none"><i class="icon-lock"></i>https</span><span class="protocol-http"><i class="icon-file-alt"></i>http</span><span class="url-text">://google.com/</span></div></div></div>'
|
||||
var htmlTemplate = '<div class="browser-chrome-container"><div class="browser-chrome-header"><i class="fa fa-times-circle"></i> <i class="fa fa-minus-circle"></i> <i class="fa fa-plus-circle"></i><div class="browser-chrome-tab"><div class="browser-chrome-tab-wrapper"><div class="browser-chrome-tab-content"><i class="fa fa-file-alt fa-lg"></i> <span class="tab-title">Tab Title</span></div></div></div><div class="user-icon-container"><i class="fa fa-user fa-2x"></i></div></div><div class="browser-chrome-url-bar"><div class="left-controls"><i class="fa fa-arrow-left fa-lg"></i> <i class="fa fa-arrow-right fa-lg"></i> <i class="fa fa-rotate-right fa-lg"></i> </div><div class="right-controls"> <i class="fa fa-reorder fa-lg"></i></div><div class="browser-chrome-url"><span class="protocol-https" style="display: none"><i class="fa fa-lock"></i>https</span><span class="protocol-http"><i class="fa fa-file-alt"></i>http</span><span class="url-text">://google.com/</span></div></div></div>'
|
||||
|
||||
browserchrome.update = function() {
|
||||
$('[data-screenshot-url]').each(function(index, element) {
|
||||
|
|
|
@ -1359,42 +1359,42 @@
|
|||
}
|
||||
|
||||
group1 = makeGroup(1);
|
||||
buttons.bold = makeButton("wmd-bold-button", "Bold - Ctrl+B", "icon-bold", bindCommand("doBold"), group1);
|
||||
buttons.italic = makeButton("wmd-italic-button", "Italic - Ctrl+I", "icon-italic", bindCommand("doItalic"), group1);
|
||||
buttons.bold = makeButton("wmd-bold-button", "Bold - Ctrl+B", "fa fa-bold", bindCommand("doBold"), group1);
|
||||
buttons.italic = makeButton("wmd-italic-button", "Italic - Ctrl+I", "fa fa-italic", bindCommand("doItalic"), group1);
|
||||
|
||||
group2 = makeGroup(2);
|
||||
/*
|
||||
buttons.link = makeButton("wmd-link-button", "Link - Ctrl+L", "icon-link", bindCommand(function (chunk, postProcessing) {
|
||||
buttons.link = makeButton("wmd-link-button", "Link - Ctrl+L", "fa fa-link", bindCommand(function (chunk, postProcessing) {
|
||||
return this.doLinkOrImage(chunk, postProcessing, false);
|
||||
}), group2);
|
||||
*/
|
||||
buttons.quote = makeButton("wmd-quote-button", "Blockquote - Ctrl+Q", "icon-quote-left", bindCommand("doBlockquote"), group2);
|
||||
buttons.code = makeButton("wmd-code-button", "Code Sample - Ctrl+K", "icon-code", bindCommand("doCode"), group2);
|
||||
buttons.quote = makeButton("wmd-quote-button", "Blockquote - Ctrl+Q", "fa fa-quote-left", bindCommand("doBlockquote"), group2);
|
||||
buttons.code = makeButton("wmd-code-button", "Code Sample - Ctrl+K", "fa fa-code", bindCommand("doCode"), group2);
|
||||
/*
|
||||
buttons.image = makeButton("wmd-image-button", "Image - Ctrl+G", "icon-picture", bindCommand(function (chunk, postProcessing) {
|
||||
buttons.image = makeButton("wmd-image-button", "Image - Ctrl+G", "fa fa-picture", bindCommand(function (chunk, postProcessing) {
|
||||
return this.doLinkOrImage(chunk, postProcessing, true);
|
||||
}), group2);
|
||||
*/
|
||||
|
||||
group3 = makeGroup(3);
|
||||
buttons.olist = makeButton("wmd-olist-button", "Numbered List - Ctrl+O", "icon-list", bindCommand(function (chunk, postProcessing) {
|
||||
buttons.olist = makeButton("wmd-olist-button", "Numbered List - Ctrl+O", "fa fa-list", bindCommand(function (chunk, postProcessing) {
|
||||
this.doList(chunk, postProcessing, true);
|
||||
}), group3);
|
||||
buttons.ulist = makeButton("wmd-ulist-button", "Bulleted List - Ctrl+U", "icon-list-ul", bindCommand(function (chunk, postProcessing) {
|
||||
buttons.ulist = makeButton("wmd-ulist-button", "Bulleted List - Ctrl+U", "fa fa-list-ul", bindCommand(function (chunk, postProcessing) {
|
||||
this.doList(chunk, postProcessing, false);
|
||||
}), group3);
|
||||
buttons.heading = makeButton("wmd-heading-button", "Heading - Ctrl+H", "icon-tasks", bindCommand("doHeading"), group3);
|
||||
buttons.hr = makeButton("wmd-hr-button", "Horizontal Rule - Ctrl+R", "icon-minus", bindCommand("doHorizontalRule"), group3);
|
||||
buttons.heading = makeButton("wmd-heading-button", "Heading - Ctrl+H", "fa fa-tasks", bindCommand("doHeading"), group3);
|
||||
buttons.hr = makeButton("wmd-hr-button", "Horizontal Rule - Ctrl+R", "fa fa-minus", bindCommand("doHorizontalRule"), group3);
|
||||
|
||||
group4 = makeGroup(4);
|
||||
buttons.undo = makeButton("wmd-undo-button", "Undo - Ctrl+Z", "icon-undo", null, group4);
|
||||
buttons.undo = makeButton("wmd-undo-button", "Undo - Ctrl+Z", "fa fa-undo", null, group4);
|
||||
buttons.undo.execute = function (manager) { if (manager) manager.undo(); };
|
||||
|
||||
var redoTitle = /win/.test(nav.platform.toLowerCase()) ?
|
||||
"Redo - Ctrl+Y" :
|
||||
"Redo - Ctrl+Shift+Z"; // mac and other non-Windows platforms
|
||||
|
||||
buttons.redo = makeButton("wmd-redo-button", redoTitle, "icon-share-alt", null, group4);
|
||||
buttons.redo = makeButton("wmd-redo-button", redoTitle, "fa fa-share", null, group4);
|
||||
buttons.redo.execute = function (manager) { if (manager) manager.redo(); };
|
||||
|
||||
if (helpOptions) {
|
||||
|
@ -1402,7 +1402,7 @@
|
|||
group5.className = group5.className + " pull-right";
|
||||
var helpButton = document.createElement("button");
|
||||
var helpButtonImage = document.createElement("i");
|
||||
helpButtonImage.className = "icon-question-sign";
|
||||
helpButtonImage.className = "fa fa-question-sign";
|
||||
helpButton.appendChild(helpButtonImage);
|
||||
helpButton.className = "btn";
|
||||
helpButton.id = "wmd-help-button" + postfix;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="fa-bar"></span>
|
||||
<span class="fa-bar"></span>
|
||||
<span class="fa-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/static/img/quay-logo.png">
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
</div>
|
||||
|
||||
<div class="loading" ng-show="loading">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="container repo repo-image-view" ng-show="!loading && image">
|
||||
<div class="header">
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}" class="back"><i class="icon-chevron-left"></i></a>
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}" class="back"><i class="fa fa-chevron-left"></i></a>
|
||||
<h3>
|
||||
<i class="icon-archive icon-large" style="color: #aaa; margin-right: 10px;"></i>
|
||||
<i class="fa fa-archive fa-lg" style="color: #aaa; margin-right: 10px;"></i>
|
||||
<span style="color: #aaa;"> {{repo.namespace}}</span>
|
||||
<span style="color: #ccc">/</span>
|
||||
<span style="color: #666;">{{repo.name}}</span>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<div class="input-group">
|
||||
<input id="full-id" type="text" class="form-control" value="{{ image.id }}" readonly>
|
||||
<span id="copyClipboard" class="input-group-addon" title="Copy to Clipboard" data-clipboard-target="full-id">
|
||||
<i class="icon-copy"></i>
|
||||
<i class="fa fa-copy"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -75,7 +75,7 @@
|
|||
No matching changes
|
||||
</div>
|
||||
<div class="change" ng-repeat="change in combinedChanges | filter:search | limitTo:50">
|
||||
<i ng-class="{'added': 'icon-plus-sign-alt', 'removed': 'icon-minus-sign-alt', 'changed': 'icon-edit-sign'}[change.kind]"></i>
|
||||
<i ng-class="{'added': 'fa fa-plus-square', 'removed': 'fa fa-minus-square', 'changed': 'fa fa-pencil-square'}[change.kind]"></i>
|
||||
<span title="{{change.file}}">
|
||||
<span style="color: #888;">
|
||||
<span ng-repeat="folder in getFolders(change.file)"><a href="javascript:void(0)" ng-click="setFolderFilter(getFolder(change.file), $index)">{{folder}}</a>/</span></span><span>{{getFilename(change.file)}}</span>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<div ng-show="!user.anonymous">
|
||||
<div ng-show="loadingmyrepos">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<div ng-show="!loadingmyrepos && myrepos.length > 0">
|
||||
<h2>Your Top Repositories</h2>
|
||||
|
@ -44,10 +44,10 @@
|
|||
<div class="form-group signin-buttons">
|
||||
<button class="btn btn-primary btn-block landing-signup-button" ng-disabled="signupForm.$invalid" type="submit" analytics-on analytics-event="register">Sign Up for Free!</button>
|
||||
<span class="landing-social-alternate">
|
||||
<i class="icon-circle"></i>
|
||||
<i class="fa fa-circle"></i>
|
||||
<span class="inner-text">OR</span>
|
||||
</span>
|
||||
<a href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ github_state_clause }}" class="btn btn-primary btn-block"><i class="icon-github icon-large"></i> Sign In with GitHub</a>
|
||||
<a href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ github_state_clause }}" class="btn btn-primary btn-block"><i class="fa fa-github fa-lg"></i> Sign In with GitHub</a>
|
||||
<p class="help-block">No credit card required.</p>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -68,7 +68,7 @@
|
|||
|
||||
<div class="row" ng-show="user.anonymous">
|
||||
<div class="col-md-4 shoutout">
|
||||
<i class="icon-lock"></i>
|
||||
<i class="fa fa-lock"></i>
|
||||
<b>Secure</b>
|
||||
<span class="shoutout-expand">
|
||||
Store your private docker containers where only you and your team
|
||||
|
@ -77,7 +77,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-md-4 shoutout">
|
||||
<i class="icon-user"></i>
|
||||
<i class="fa fa-user"></i>
|
||||
<b>Shareable</b>
|
||||
<span class="shoutout-expand">
|
||||
Have to share a repository? No problem! Share with anyone you choose
|
||||
|
@ -85,7 +85,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-md-4 shoutout">
|
||||
<i class="icon-cloud"></i>
|
||||
<i class="fa fa-cloud"></i>
|
||||
<b>Cloud Hosted</b>
|
||||
<span class="shoutout-expand">
|
||||
Accessible from anywhere, anytime
|
||||
|
@ -97,7 +97,7 @@
|
|||
|
||||
<div class="product-tour container" ng-show="user.anonymous">
|
||||
<div class="tour-header row">
|
||||
<div class="tour-shoutout-header"><i class="icon-chevron-sign-down"></i></div>
|
||||
<div class="tour-shoutout-header"><i class="fa fa-chevron-circle-down"></i></div>
|
||||
<div class="tour-shoutout">Take a tour of Quay</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="loading" ng-show="loading">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="container" ng-show="!loading && (!repo || !permissions)">
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="container repo repo-admin" ng-show="!loading && repo && permissions">
|
||||
<div class="header">
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}" class="back"><i class="icon-chevron-left"></i></a>
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name }}" class="back"><i class="fa fa-chevron-left"></i></a>
|
||||
<h3>
|
||||
<span class="repo-circle no-background" repo="repo"></span> <span style="color: #aaa;"> {{repo.namespace}}</span> <span style="color: #ccc">/</span> {{repo.name}}
|
||||
</h3>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">User Access Permissions
|
||||
|
||||
<i class="info-icon icon-info-sign" data-placement="left" data-content="Allow any number of users to read, write or administer this repository"></i>
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Allow any number of users to read, write or administer this repository"></i>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
<tr ng-repeat="(username, permission) in permissions">
|
||||
<td class="user">
|
||||
<i class="icon-user"></i>
|
||||
<i class="fa fa-user"></i>
|
||||
<span>{{username}}</span>
|
||||
</td>
|
||||
<td class="user-permissions">
|
||||
|
@ -46,7 +46,7 @@
|
|||
<td>
|
||||
<span class="delete-ui" tabindex="0" title="Delete Permission">
|
||||
<span class="delete-ui-button" ng-click="deleteRole(username)"><button class="btn btn-danger">Delete</button></span>
|
||||
<i class="icon-remove"></i>
|
||||
<i class="fa fa-remove"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -64,7 +64,7 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Access Token Permissions
|
||||
|
||||
<i class="info-icon icon-info-sign" data-placement="left" data-content="Grant permissions to this repository by creating unique tokens that can be used without entering account passwords<br><br>To use in docker:<br><dl class='dl-horizontal'><dt>Username</dt><dd>$token</dd><dt>Password</dt><dd>(token value)</dd><dt>Email</dt><dd>(any value)</dd></dl>"></i>
|
||||
<i class="info-icon fa fa-info-circle" data-placement="left" data-content="Grant permissions to this repository by creating unique tokens that can be used without entering account passwords<br><br>To use in docker:<br><dl class='dl-horizontal'><dt>Username</dt><dd>$token</dd><dt>Password</dt><dd>(token value)</dd><dt>Email</dt><dd>(any value)</dd></dl>"></i>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form name="createTokenForm" ng-submit="createToken()">
|
||||
|
@ -79,7 +79,7 @@
|
|||
|
||||
<tr ng-repeat="(code, token) in tokens">
|
||||
<td class="user token">
|
||||
<i class="icon-key"></i>
|
||||
<i class="fa fa-key"></i>
|
||||
<a ng-click="showToken(token.code)">{{ token.friendlyName }}</a>
|
||||
</td>
|
||||
<td class="user-permissions">
|
||||
|
@ -91,7 +91,7 @@
|
|||
<td>
|
||||
<span class="delete-ui" tabindex="0" title="Delete Token">
|
||||
<span class="delete-ui-button" ng-click="deleteToken(token.code)"><button class="btn btn-danger" type="button">Delete</button></span>
|
||||
<i class="icon-remove"></i>
|
||||
<i class="fa fa-remove"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -114,7 +114,7 @@
|
|||
<div class="panel-heading">Repository Settings</div>
|
||||
<div class="panel-body">
|
||||
<div class="repo-access-state" ng-show="!repo.is_public">
|
||||
<div class="state-icon"><i class="icon-lock"></i></div>
|
||||
<div class="state-icon"><i class="fa fa-lock"></i></div>
|
||||
|
||||
This repository is currently <b>private</b>. Only users on the above access list may view and interact with it.
|
||||
|
||||
|
@ -124,7 +124,7 @@
|
|||
</div>
|
||||
|
||||
<div class="repo-access-state" ng-show="repo.is_public">
|
||||
<div class="state-icon"><i class="icon-unlock-alt"></i></div>
|
||||
<div class="state-icon"><i class="fa fa-unlock-alt"></i></div>
|
||||
|
||||
This repository is currently <b>public</b> and is visible to all users, and may be pulled by all users.
|
||||
|
||||
|
@ -171,7 +171,7 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title"><i class="icon-key"></i> {{ shownToken.friendlyName }}</h4>
|
||||
<h4 class="modal-title"><i class="fa fa-key"></i> {{ shownToken.friendlyName }}</h4>
|
||||
</div>
|
||||
<div class="modal-body token-dialog-body">
|
||||
<div class="alert alert-info">The docker <u>username</u> is <b>$token</b> and the <u>password</u> is the token. You may use any value for email.</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="loading" ng-show="loading">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="container ready-indicator" ng-show="!loading" data-status="{{ loading ? '' : 'ready' }}">
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
|
||||
|
||||
<span class="social-alternate">
|
||||
<i class="icon-circle"></i>
|
||||
<i class="fa fa-circle"></i>
|
||||
<span class="inner-text">OR</span>
|
||||
</span>
|
||||
|
||||
<a id='github-signin-link' href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ mixpanelDistinctIdClause }}" class="btn btn-primary btn-lg btn-block"><i class="icon-github icon-large"></i> Sign In with GitHub</a>
|
||||
<a id='github-signin-link' href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ mixpanelDistinctIdClause }}" class="btn btn-primary btn-lg btn-block"><i class="fa fa-github fa-lg"></i> Sign In with GitHub</a>
|
||||
</form>
|
||||
|
||||
<div class="alert alert-danger" ng-show="invalidCredentials">Invalid username or password.</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="container user-admin">
|
||||
<div class="loading" ng-show="planLoading || planChanging">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<div class="row" ng-show="errorMessage">
|
||||
<div class="col-md-12">
|
||||
|
@ -18,7 +18,7 @@
|
|||
<div class="panel-heading">
|
||||
{{ plan.title }}
|
||||
<span class="pull-right" ng-show="subscription.plan == plan.stripeId">
|
||||
<i class="icon-ok"></i>
|
||||
<i class="fa fa-ok"></i>
|
||||
Subscribed
|
||||
</span>
|
||||
</div>
|
||||
|
@ -59,7 +59,7 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="loading" ng-show="updatingUser">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="panel panel-default">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
</div>
|
||||
|
||||
<div class="loading" ng-show="loading">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="container repo" ng-show="!loading && repo">
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
<span class="settings-cog" ng-show="repo.can_admin" title="Repository Settings">
|
||||
<a href="{{ '/repository/' + repo.namespace + '/' + repo.name + '/admin' }}">
|
||||
<i class="icon-cog icon-large"></i>
|
||||
<i class="fa fa-cog fa-lg"></i>
|
||||
</a>
|
||||
</span>
|
||||
</h3>
|
||||
|
@ -29,7 +29,7 @@
|
|||
<div class="input-group">
|
||||
<input id="pull-text" type="text" class="form-control" value="{{ 'docker pull quay.io/' + repo.namespace + '/' + repo.name }}" readonly>
|
||||
<span id="copyClipboard" class="input-group-addon" title="Copy to Clipboard" data-clipboard-target="pull-text">
|
||||
<i class="icon-copy"></i>
|
||||
<i class="fa fa-copy"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
|||
<!-- Description -->
|
||||
<p ng-class="'description lead ' + (repo.can_write ? 'editable' : 'noteditable')" ng-click="editDescription()">
|
||||
<span class="content" ng-bind-html-unsafe="getMarkedDown(repo.description)"></span>
|
||||
<i class="icon-edit"></i>
|
||||
<i class="fa fa-edit"></i>
|
||||
</p>
|
||||
|
||||
<div class="repo-content" ng-show="!currentTag.image">
|
||||
|
@ -62,7 +62,7 @@
|
|||
<div class="panel-heading">
|
||||
<!-- Tag dropdown -->
|
||||
<span class="tag-dropdown dropdown" title="Tags">
|
||||
<i class="icon-tag"><span class="tag-count">{{getTagCount(repo)}}</span></i>
|
||||
<i class="fa fa-tag"><span class="tag-count">{{getTagCount(repo)}}</span></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{currentTag.name}} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="tag in repo.tags">
|
||||
|
@ -76,7 +76,7 @@
|
|||
|
||||
<!-- Image history loading -->
|
||||
<div ng-hide="imageHistory" style="padding: 10px; text-align: center;">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<!-- Tree View itself -->
|
||||
|
@ -90,7 +90,7 @@
|
|||
<div class="panel-heading">
|
||||
<!-- Image dropdown -->
|
||||
<span class="tag-dropdown dropdown" title="Images">
|
||||
<i class="icon-archive"><span class="tag-count">{{imageHistory.length}}</span></i>
|
||||
<i class="fa fa-archive"><span class="tag-count">{{imageHistory.length}}</span></i>
|
||||
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{currentImage.id.substr(0, 12)}} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="image in imageHistory">
|
||||
|
@ -117,22 +117,22 @@
|
|||
|
||||
<!-- Image changes loading -->
|
||||
<div ng-hide="currentImageChanges">
|
||||
<i class="icon-spinner icon-spin icon-3x"></i>
|
||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||
</div>
|
||||
|
||||
<div class="changes-container small-changes-container"
|
||||
ng-show="currentImageChanges.changed.length || currentImageChanges.added.length || currentImageChanges.removed.length">
|
||||
<div class="changes-count-container accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseChanges">
|
||||
<span class="change-count added" ng-show="currentImageChanges.added.length > 0" title="Files Added">
|
||||
<i class="icon-plus-sign-alt"></i>
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<b>{{currentImageChanges.added.length}}</b>
|
||||
</span>
|
||||
<span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" title="Files Removed">
|
||||
<i class="icon-minus-sign-alt"></i>
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<b>{{currentImageChanges.removed.length}}</b>
|
||||
</span>
|
||||
<span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" title="Files Changed">
|
||||
<i class="icon-edit-sign"></i>
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<b>{{currentImageChanges.changed.length}}</b>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -140,15 +140,15 @@
|
|||
<div id="collapseChanges" class="panel-collapse collapse in">
|
||||
<div class="well well-sm">
|
||||
<div class="change added" ng-repeat="file in currentImageChanges.added | limitTo:5">
|
||||
<i class="icon-plus-sign-alt"></i>
|
||||
<i class="fa fa-plus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change removed" ng-repeat="file in currentImageChanges.removed | limitTo:5">
|
||||
<i class="icon-minus-sign-alt"></i>
|
||||
<i class="fa fa-minus-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
<div class="change changed" ng-repeat="file in currentImageChanges.changed | limitTo:5">
|
||||
<i class="icon-edit-sign"></i>
|
||||
<i class="fa fa-pencil-square"></i>
|
||||
<span title="{{file}}">{{file}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Hosted private docker repositories. Includes full user management and history. Free for public repositories.">
|
||||
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css">
|
||||
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'>
|
||||
|
|
Binary file not shown.
|
@ -10,7 +10,6 @@ from data.queue import image_diff_queue
|
|||
from endpoints.registry import process_image_changes
|
||||
|
||||
|
||||
|
||||
root_logger = logging.getLogger('')
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
@ -59,11 +58,6 @@ parser.add_argument('--log', default='diffsworker.log',
|
|||
args = parser.parse_args()
|
||||
|
||||
|
||||
# if not args.D:
|
||||
# else:
|
||||
# logging.basicConfig(format=FORMAT, level=logging.DEBUG)
|
||||
# start_worker(args)
|
||||
|
||||
if args.D:
|
||||
handler = logging.FileHandler(args.log)
|
||||
handler.setFormatter(formatter)
|
||||
|
|
134
workers/dockerfilebuild.py
Normal file
134
workers/dockerfilebuild.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
import logging
|
||||
import json
|
||||
import daemon
|
||||
import time
|
||||
import argparse
|
||||
import digitalocean
|
||||
|
||||
from apscheduler.scheduler import Scheduler
|
||||
from multiprocessing.pool import ThreadPool
|
||||
|
||||
from data.queue import dockerfile_build_queue
|
||||
from data import model
|
||||
from app import app
|
||||
|
||||
|
||||
root_logger = logging.getLogger('')
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
|
||||
FORMAT = '%(asctime)-15s - %(levelname)s - %(pathname)s - %(funcName)s - %(message)s'
|
||||
formatter = logging.Formatter(FORMAT)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def babysit_builder(request):
|
||||
manager = digitalocean.Manager(client_id=app.config['DO_CLIENT_ID'],
|
||||
api_key=app.config['DO_CLIENT_SECRET'])
|
||||
repository_build = model.get_repository_build(request['build_id'])
|
||||
|
||||
# check if there is already a DO node for this build job, if so clean it up
|
||||
old_id = repository_build.digitalocean_build_node_id
|
||||
if old_id
|
||||
old_droplet = digitalocean.Droplet(old_id)
|
||||
old_droplet.destroy()
|
||||
|
||||
# start the DO node
|
||||
name = 'dockerfile-build-%s' % repository_build.id
|
||||
droplet = digitalocean.Droplet(client_id=app.config['DO_CLIENT_ID'],
|
||||
api_key=app.config['DO_CLIENT_SECRET'],
|
||||
name=name,
|
||||
region_id=1, # New York,
|
||||
image_id=1004145, # Docker on 13.04
|
||||
size_id=66, # 512MB,
|
||||
backup_active=False)
|
||||
droplet.create(ssh_key_ids=[app.config['DO_SSH_KEY_ID']])
|
||||
repository_build.digitalocean_build_node_id = droplet.id
|
||||
repository_build.phase = 'starting'
|
||||
repository_build.save()
|
||||
|
||||
startup = droplet.get_events()[0]
|
||||
while int(startup.percentage) != 100:
|
||||
logger.debug('Droplet startup percentage: %s' % startup.percentage)
|
||||
time.sleep(5)
|
||||
startup.load()
|
||||
|
||||
droplet.load()
|
||||
logger.debug('Droplet started at ip address: %s' % droplet.ip_address)
|
||||
|
||||
# connect to it with ssh
|
||||
repository_build.phase = 'initializing'
|
||||
repository_build.save()
|
||||
|
||||
|
||||
# tell it to pull and run the buildserver
|
||||
|
||||
# wait for the server to be ready
|
||||
|
||||
# send it the job
|
||||
|
||||
# wait for the job to be complete
|
||||
|
||||
# clean up the DO node
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def process_work_items(pool):
|
||||
logger.debug('Getting work item from queue.')
|
||||
|
||||
item = dockerfile_build_queue.get()
|
||||
|
||||
while item:
|
||||
logger.debug('Queue gave us some work: %s' % item.body)
|
||||
|
||||
request = json.loads(item.body)
|
||||
|
||||
def build_callback(item):
|
||||
local_item = item
|
||||
def complete_callback(completed):
|
||||
if completed:
|
||||
dockerfile_build_queue.complete(local_item)
|
||||
return complete_callback
|
||||
|
||||
pool.apply_async(babysit_builder, [request], callback=build_callback(item))
|
||||
|
||||
item = dockerfile_build_queue.get()
|
||||
|
||||
logger.debug('No more work.')
|
||||
|
||||
|
||||
def start_worker():
|
||||
pool = ThreadPool(3)
|
||||
logger.debug("Scheduling worker.")
|
||||
|
||||
sched = Scheduler()
|
||||
sched.start()
|
||||
|
||||
sched.add_interval_job(process_work_items, args=[pool], seconds=30)
|
||||
|
||||
while True:
|
||||
time.sleep(60 * 60 * 24) # sleep one day, basically forever
|
||||
|
||||
|
||||
desc = 'Worker daemon to monitor dockerfile build'
|
||||
parser = argparse.ArgumentParser(description=desc)
|
||||
parser.add_argument('-D', action='store_true', default=False,
|
||||
help='Run the worker in daemon mode.')
|
||||
parser.add_argument('--log', default='dockerfilebuild.log',
|
||||
help='Specify the log file for the worker as a daemon.')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
if args.D:
|
||||
handler = logging.FileHandler(args.log)
|
||||
handler.setFormatter(formatter)
|
||||
root_logger.addHandler(handler)
|
||||
with daemon.DaemonContext(files_preserve=[handler.stream]):
|
||||
start_worker()
|
||||
|
||||
else:
|
||||
handler = logging.StreamHandler()
|
||||
handler.setFormatter(formatter)
|
||||
root_logger.addHandler(handler)
|
||||
start_worker()
|
Reference in a new issue