Skip to content

Commit 89ae3da

Browse files
author
Roey Darwish Dror
committed
Merge branch 'release/0.27.0'
2 parents d6cee1e + 082265a commit 89ae3da

File tree

35 files changed

+289
-327
lines changed

35 files changed

+289
-327
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ celerybeat.pid
5858
client_secret.json
5959
webapp/tmp
6060
conf.d
61+
tests/.cache

_lib/db.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ def ensure():
5858
elif match.group('db_type') == 'postgresql':
5959
_create_postgres(match)
6060

61-
with app.app_context():
62-
db.create_all()
6361
logbook.info("DB successfully created")
6462

6563

_lib/deployment.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import os
2-
import sys
32
from multiprocessing import cpu_count
43

54
import click
65

7-
from .bootstrapping import from_env, from_env_bin, requires_env, from_project_root
6+
from .bootstrapping import from_env_bin, requires_env, from_project_root
87
from .params import APP_NAME
98

109
_UNIX_SOCKET_NAME = "/var/run/{}/wsgi.sock".format(APP_NAME)
@@ -13,6 +12,7 @@
1312
@click.command()
1413
@requires_env("app")
1514
def run_gunicorn():
15+
num_workers = (2 * cpu_count()) + 1
1616
gunicorn_bin = from_env_bin('gunicorn')
17-
cmd = [gunicorn_bin, '--log-syslog', '-b', 'unix://{}'.format(_UNIX_SOCKET_NAME), 'flask_app.wsgi:app', '--chdir', from_project_root('.')]
17+
cmd = [gunicorn_bin, '--log-syslog', '-b', 'unix://{}'.format(_UNIX_SOCKET_NAME), 'flask_app.wsgi:app', '--chdir', from_project_root('.'), '-w', str(num_workers)]
1818
os.execv(gunicorn_bin, cmd)

ansible/roles/db/handlers/main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
- name: restart postgres
3+
service: name=postgresql state=restarted

ansible/roles/db/tasks/main.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,26 @@
4444
- name: enable local authentication in postresql
4545
lineinfile: dest=/var/lib/pgsql/data/pg_hba.conf regexp="^host.*::1/128" line="host all all ::1/128 md5" state=present
4646
when: ansible_distribution == 'CentOS'
47+
- name: config postgres local hosts
48+
lineinfile: dest=/etc/postgresql/{{postgres_version}}/main/pg_hba.conf regexp='^local.*all.*all.*[pm]' line="local all all md5"
49+
notify: restart postgres
50+
when: groups['db'][0] != groups['webapp'][0] and ansible_distribution == 'Debian'
51+
- name: enable remote authentication in postresql
52+
lineinfile: dest=/etc/postgresql/{{postgres_version}}/main/pg_hba.conf regexp='0\.0\.0\.0' line="host all all 0.0.0.0/0 md5"
53+
notify: restart postgres
54+
when: groups['db'][0] != groups['webapp'][0] and ansible_distribution == 'Debian'
55+
- name: config postgresql
56+
lineinfile: dest=/etc/postgresql/{{postgres_version}}/main/postgresql.conf regexp=^listen_addresses line="listen_addresses='*'"
57+
notify: restart postgres
58+
when: groups['db'][0] != groups['webapp'][0] and ansible_distribution == 'Debian'
4759
- service: name=postgresql state=started enabled=True
4860
- name: setup db
4961
action: postgresql_db name={{app_name}} encoding=utf8
50-
sudo_user: postgres
51-
sudo: true
62+
become: true
63+
become_user: postgres
5264
tags: db
5365
- name: setup db user
5466
action: postgresql_user name={{app_name}} password={{app_name}} db={{app_name}} priv=ALL role_attr_flags=SUPERUSER
55-
sudo_user: postgres
56-
sudo: true
67+
become: true
68+
become_user: postgres
5769
tags: db

ansible/roles/db/vars/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
postgres_version: 9.4

ansible/roles/webapp/tasks/install_sources.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
- name: untar to temporary location
22
shell: cd /tmp/ && rm -rf {{webapp_archive_location}}.untarred && mkdir {{webapp_archive_location}}.untarred && cd {{webapp_archive_location}}.untarred && tar xzf {{webapp_archive_location}}
3-
- name: rsync to src dir
4-
shell: rsync -avP --delete {{webapp_archive_location}}.untarred/ {{src_root}}/
3+
- synchronize: src="{{webapp_archive_location}}.untarred/" dest="{{src_root}}/"
4+
delegate_to: "{{ inventory_hostname }}"
55
- name: bootstrap
66
shell: python {{src_root}}/manage.py bootstrap --app
77
- name: ensure private config
88
shell: python {{src_root}}/manage.py ensure-secret {{deploy_root}}/conf.d/000-private.yml
99
- name: migrate db
1010
shell: cd {{src_root}} && python manage.py db upgrade
1111
- name: fix permissions
12-
shell: chown -R {{user_name}}:{{group_name}} {{deploy_root}}
12+
file: path={{deploy_root}} owner={{user_name}} group={{group_name}} recurse=true
1313
- name: fix permissions of static folder
1414
file: path={{src_root}}/static owner={{nginx_user}} group={{nginx_group}} recurse=true state=directory
1515
- name: ensure that nginx sites directory exists

ansible/roles/webapp/tasks/main.yml

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,13 @@
5252
- name: ensure /var/run/{{app_name}} directory on boot
5353
template: src=../templates/tmpfiles.d.conf.j2 dest=/etc/tmpfiles.d/{{app_name}}.conf
5454
- file: path=/var/run/{{app_name}} state=directory mode=0770 owner={{app_name}} group={{nginx_group}}
55-
- name: install systemd service
56-
action: template src=../templates/gunicorn.service.j2 dest=/lib/systemd/system/{{app_name}}-wsgi.service
57-
when: sources.changed or configuration.changed
58-
register: systemd_change
59-
- name: install systemd service (Celery worker)
60-
action: template src=../templates/celery-worker.service.j2 dest=/lib/systemd/system/{{app_name}}-celery-worker.service
61-
when: sources.changed or configuration.changed
62-
register: systemd_change
63-
- name: install systemd service (Celery beat)
64-
action: template src=../templates/celery-beat.service.j2 dest=/lib/systemd/system/{{app_name}}-celery-beat.service
65-
when: sources.changed or configuration.changed
66-
register: systemd_change
55+
56+
- name: Configure systemd services
57+
include: systemd_services.yml
58+
register: systemd_services
6759
- name: reload systemd daemon
6860
action: shell systemctl daemon-reload
69-
when: systemd_change.changed
61+
when: systemd_services.changed
7062
- name: enable the services
7163
action: service name={{item}} enabled=true state=started
7264
with_items:
@@ -79,6 +71,6 @@
7971
- "{{app_name}}-wsgi"
8072
- "{{app_name}}-celery-worker"
8173
- "{{app_name}}-celery-beat"
82-
when: systemd_change.changed or sources.changed or configuration.changed
74+
when: systemd_services.changed or sources.changed or configuration.changed
8375
- name: try to get local page
8476
shell: curl http://localhost/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
- name: install systemd service
2+
action: template src=../templates/gunicorn.service.j2 dest=/lib/systemd/system/{{app_name}}-wsgi.service
3+
when: sources.changed or configuration.changed
4+
- name: install systemd service (Celery worker)
5+
action: template src=../templates/celery-worker.service.j2 dest=/lib/systemd/system/{{app_name}}-celery-worker.service
6+
when: sources.changed or configuration.changed
7+
- name: install systemd service (Celery beat)
8+
action: template src=../templates/celery-beat.service.j2 dest=/lib/systemd/system/{{app_name}}-celery-beat.service
9+
when: sources.changed or configuration.changed
10+

ansible/roles/webapp/templates/deployment_conf.yml.j2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
SQLALCHEMY_DATABASE_URI: "postgresql://{{app_name}}:{{app_name}}@localhost/{{app_name}}"
1+
SQLALCHEMY_DATABASE_URI: "postgresql://{{app_name}}:{{app_name}}@{% if groups['db'][0] != groups['webapp'][0] %}{{groups['db'][0]}}{% else %}localhost{% endif %}/{{app_name}}"
2+
23
STORAGE_PATH: /var/scotty
34
SENTRY_DSN: "{{sentry_dsn}}"
45

ansible/roles/webapp/templates/nginx_site_conf.conf.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ server {
2626

2727
location /file_contents {
2828
alias /var/scotty;
29+
types {
30+
text/plain log txt;
31+
}
2932
}
3033

3134

conf.d/.gitkeep

Whitespace-only changes.

deps/app.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ alembic>=0.7.3
22
psycopg2
33
Flask>=0.10.1
44
Flask-Mail
5-
Flask-Login>=0.3.0
6-
Flask-Security
5+
Flask-Login>=0.3.0,<0.4.0
6+
Flask-Security>=1.7.5
77
Flask-Migrate>=1.3.0
88
Flask-SQLAlchemy
99
URLObject

flask_app/app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
app_name: scotty
2-
APP_VERSION: 0.26.2
2+
APP_VERSION: 0.27.0
33
SECURITY_PASSWORD_HASH: sha512_crypt
44
SQLALCHEMY_TRACK_MODIFICATIONS: false

flask_app/blueprints/files.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def get_all():
6464
if "filter" in request.args and request.args["filter"]:
6565
query = query.filter(File.file_name.like("%{}%".format(request.args['filter'])))
6666

67-
query = query.order_by(File.storage_name)
67+
query = query.order_by(File.file_name)
6868

6969
total = query.count()
7070

flask_app/blueprints/issues.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
def create():
2626
data = request.json['issue']
2727
id_in_tracker = data['id_in_tracker'].strip()
28+
if not id_in_tracker:
29+
return 'Invalid issue id', http.client.CONFLICT
30+
2831
issue = Issue(tracker_id=data['tracker_id'], id_in_tracker=id_in_tracker, open=True)
2932
db.session.add(issue)
3033
try:

manage.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ def testserver(tmux, livereload, port):
7575
if tmux:
7676
return _run_tmux_frontend(port=port)
7777
from flask_app.app import create_app
78-
app = create_app({'DEBUG': True, 'TESTING': True, 'SECRET_KEY': 'dummy', 'SECURITY_PASSWORD_SALT': 'dummy'})
7978

8079
extra_files=[
8180
from_project_root("flask_app", "app.yml")

tests/slashconf.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ def dump(self):
6363
def delete(self):
6464
os.unlink(self._path)
6565

66-
def create_issue(self):
67-
id_in_tracker = str(uuid.uuid4())
66+
def create_issue(self, id_in_tracker=None):
67+
if id_in_tracker is None:
68+
id_in_tracker = str(uuid.uuid4())
6869
self._issues[id_in_tracker] = True
6970
id_in_scotty = self._scotty.create_issue(self._id, id_in_tracker)
7071
issue = self.Issue(self, id_in_scotty, id_in_tracker)

tests/test_deployment/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-

tests/test_deployment/test__issue_tracker.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import http
2+
import requests
13
import slash
24
import uuid
35
from itertools import chain, combinations
@@ -8,6 +10,13 @@ def powerset(iterable):
810
return (frozenset(p) for p in chain.from_iterable((combinations(s, r)) for r in range(len(s)+1)))
911

1012

13+
def test_empty_issue(tracker):
14+
with slash.assert_raises(requests.exceptions.HTTPError) as e:
15+
tracker.create_issue(' ')
16+
17+
assert e.exception.response.status_code == http.client.CONFLICT
18+
19+
1120
def test_issue_creation(beam, issue):
1221
beam, _ = beam
1322
assert len(beam.associated_issues) == 0

tests/test_deployment/test__sanity.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ def test_independent_beam(beam, local_beam_dir, download_dir):
1818
for file_ in beam.beam.iter_files():
1919
file_.download(download_dir)
2020

21+
assert beam.beam.completed
22+
2123
subprocess.check_call(['diff', '-rq', local_beam_dir, download_dir])

webapp/app/app.js

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Ember from 'ember';
2-
import Resolver from 'ember/resolver';
3-
import loadInitializers from 'ember/load-initializers';
2+
import Resolver from './resolver';
3+
import loadInitializers from 'ember-load-initializers';
44
import config from './config/environment';
55

66
let App;
@@ -13,55 +13,6 @@ App = Ember.Application.extend({
1313
Resolver
1414
});
1515

16-
App.Pollster = Ember.Object.extend({
17-
interval: function() {
18-
return 5000; // Time between polls (in ms)
19-
}.property(),
20-
21-
// Schedules the function `f` to be executed every `interval` time.
22-
schedule: function(f) {
23-
return Ember.run.later(this, function() {
24-
if (f.apply(this)) {
25-
this.set('timer', this.schedule(f));
26-
}
27-
}, this.get('interval'));
28-
},
29-
30-
// Stops the pollster
31-
stop: function() {
32-
Ember.run.cancel(this.get('timer'));
33-
},
34-
35-
// Starts the pollster, i.e. executes the `onPoll` function every interval.
36-
start: function() {
37-
this.set('timer', this.schedule(this.get('onPoll')));
38-
},
39-
40-
onPoll: function() {
41-
// Issue JSON request and add data to the store
42-
}
43-
});
44-
45-
App.instanceInitializer({
46-
name: "relative_time_update",
47-
48-
initialize: function(instance) {
49-
let storage = instance.lookup("service:store");
50-
App.update_reltime = App.Pollster.create({
51-
onPoll: function() {
52-
let beams = storage.peekAll("beam").content;
53-
for (var i = 0; i < beams.length; i++) {
54-
let beam = beams[i].getRecord();
55-
beam.set("tick", beam.get("tick") + 1);
56-
}
57-
return true;
58-
}
59-
});
60-
App.update_reltime.set("interval", 60000);
61-
App.update_reltime.start();
62-
}
63-
});
64-
6516
loadInitializers(App, config.modulePrefix);
6617
config.torii.providers['google-oauth2'].redirectUri = window.location.origin;
6718
export default App;

0 commit comments

Comments
 (0)