From 6a4b13a0ee502393f4b8db120f9ec6adcd15d5d5 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 19 May 2017 18:07:35 -0700 Subject: [PATCH] Set up packer/docker --- README.md | 24 ++++++ configs/config.docker.yaml | 74 ++++++++++++++++++ db/dummy_data.sql | 99 +++++++++++++++++++++++++ ops/config/systemd/nginx-oncall.service | 13 ++++ ops/config/systemd/nginx-oncall.socket | 8 ++ ops/config/systemd/uwsgi-oncall.service | 13 ++++ ops/config/systemd/uwsgi-oncall.socket | 11 +++ ops/daemons/nginx.conf | 64 ++++++++++++++++ ops/daemons/uwsgi-docker.yaml | 43 +++++++++++ ops/entrypoint.py | 95 ++++++++++++++++++++++++ ops/packer/README.md | 3 + ops/packer/gen_packer_cfg.py | 35 +++++++++ ops/packer/oncall.yaml | 68 +++++++++++++++++ setup.py | 3 +- 14 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 configs/config.docker.yaml create mode 100644 db/dummy_data.sql create mode 100644 ops/config/systemd/nginx-oncall.service create mode 100644 ops/config/systemd/nginx-oncall.socket create mode 100644 ops/config/systemd/uwsgi-oncall.service create mode 100644 ops/config/systemd/uwsgi-oncall.socket create mode 100644 ops/daemons/nginx.conf create mode 100644 ops/daemons/uwsgi-docker.yaml create mode 100644 ops/entrypoint.py create mode 100644 ops/packer/README.md create mode 100644 ops/packer/gen_packer_cfg.py create mode 100644 ops/packer/oncall.yaml diff --git a/README.md b/README.md index 8878774..384e3f8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,24 @@ Oncall [![Gitter chat](https://badges.gitter.im/irisoncall/Lobby.png)](https://gitter.im/irisoncall/Lobby) ====== +--- + + +Quickstart +------------- +### For users +To set up a local instance of Oncall, we recommend using Docker. Docker is available for download at https://www.docker.com/community-edition. We have a publicly available Docker image that can be set up using just two commands. After downloading docker, use +```docker run --name oncall-mysql -e MYSQL_ROOT_PASSWORD='1234' -d mysql``` +to set up a MySQL database for Oncall to run with. Note that we set the MySQL root password to '1234'; you may wish to change this to something more secure. + +After setting up the mysql container, we can set up an instance of Oncall running on http://localhost:8080 with the following: +```docker run -d --link oncall-mysql:mysql -p 8080:8080 -e DOCKER_DB_BOOTSTRAP=1 quay.io/iris/oncall``` +Here, we link the mysql container created in the previous step with our Oncall container, allowing for easy MySQL access between the two containers. We also pass a DOCKER_DB_BOOTSTRAP environment variable indicating to our setup script that the database needs to be initialized. This will populate the database with a small amount of dummy data and set up the proper schema so we can get up and running. + +Once these two steps are complete, you can visit localhost:8080 in your browser to check out Oncall. Try logging in as the user "jdoe", with any password (the Docker image defaults to debug authentication, which authenticates all credentials so long as the user exists in the DB). You can navigate to the "Browse Teams" page and check out "Test Team", which shows a calendar page where you can create and modify events. + + +### For developers + @@ -21,6 +40,7 @@ Setup mysql schema: ``` mysql -u root -p < ./db/schema.v0.sql +mysql -u root -p < ./db/dummy_data.sql ``` Setup app config by editing configs/config.yaml. @@ -36,6 +56,10 @@ One of the following commands: * `make serve` * `oncall-dev ./configs/config.yaml` +This sets up a local instance of Oncall on localhost:8080 with gunicorn. Try logging in as the user "jdoe", with any password (the Docker image defaults to debug authentication, which authenticates all credentials so long as the user exists in the DB). You can navigate to the "Browse Teams" page and check out "Test Team", which shows a calendar page where you can create and modify events. + +Any changes made should be automatically picked up and displayed on refresh. Check out https://github.com/linkedin/oncall/issues for a list of outstanding issues, and tackle any one that catches your interest. Contributions are expected to be tested thoroughly and submitted with unit/end-to-end tests; look in the e2e directory for our suite of end-to-end tests. + Test --- diff --git a/configs/config.docker.yaml b/configs/config.docker.yaml new file mode 100644 index 0000000..ec8d19f --- /dev/null +++ b/configs/config.docker.yaml @@ -0,0 +1,74 @@ +server: + host: 0.0.0.0 + port: 8080 +debug: True +oncall_host: http://localhost:8080 +metrics: dummy +db: + conn: + kwargs: + scheme: mysql+pymysql + user: root + password: '1234' + host: mysql + database: oncall + charset: utf8 + echo: True + str: "%(scheme)s://%(user)s:%(password)s@%(host)s/%(database)s?charset=%(charset)s" + kwargs: + pool_recycle: 3600 +session: + encrypt_key: 'abc' + sign_key: '123' +auth: + debug: False + module: 'oncall.auth.modules.debug' +notifier: + skipsend: True +healthcheck_path: /tmp/status +messengers: + - type: dummy + application: oncall + iris_api_key: magic + +# allow_origins_list: +# - http://www.example.com + +index_content_setting: + footer: | + + +notifications: + default_roles: + - "primary" + - "secondary" + - "shadow" + - "manager" + default_times: + - 86400 + - 604800 + default_modes: + - "email" + +reminder: + activated: True + polling_interval: 360 + default_timezone: 'US/Pacific' + +user_validator: + activated: True + subject: 'Warning: Missing phone number in Oncall' + body: 'You are scheduled for an on-call shift in the future, but have no phone number recorded. Please update your information in Oncall.' + +slack_instance: foobar +header_color: '#3a3a3a' +iris_plan_integration: + activated: True + app: oncall + api_key: magic + api_host: http://localhost:16649 + plan_url: '/v0/applications/oncall/plans' diff --git a/db/dummy_data.sql b/db/dummy_data.sql new file mode 100644 index 0000000..2137f38 --- /dev/null +++ b/db/dummy_data.sql @@ -0,0 +1,99 @@ +-- Sample MySQL data. Can be loaded after initializing schema + +LOCK TABLES `user` WRITE; +/*!40000 ALTER TABLE `user` DISABLE KEYS */; +INSERT INTO `user` VALUES (1,'root',1,'God User',NULL,NULL,1),(2,'manager',1,'Team Admin',NULL,NULL,0),(3,'jdoe',1,'John Doe',NULL,NULL,0),(4,'asmith',1,'Alice Smith',NULL,NULL,0); +/*!40000 ALTER TABLE `user` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `team` WRITE; +/*!40000 ALTER TABLE `team` DISABLE KEYS */; +INSERT INTO `team` VALUES (1,'Test Team','#team','team@example.com','US/Pacific',1,NULL); +/*!40000 ALTER TABLE `team` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `service` WRITE; +/*!40000 ALTER TABLE `service` DISABLE KEYS */; +INSERT INTO `service` VALUES (1,'test service'); +/*!40000 ALTER TABLE `service` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `notification_setting` WRITE; +/*!40000 ALTER TABLE `notification_setting` DISABLE KEYS */; +INSERT INTO `notification_setting` VALUES (1,4,1,35,1,86400,NULL),(2,4,1,35,1,604800,NULL),(3,2,1,35,1,86400,NULL),(4,2,1,35,1,604800,NULL),(7,3,1,35,1,86400,NULL),(8,3,1,35,1,604800,NULL),(9,4,1,35,3,NULL,1); +/*!40000 ALTER TABLE `notification_setting` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `roster` WRITE; +/*!40000 ALTER TABLE `roster` DISABLE KEYS */; +INSERT INTO `roster` VALUES (1,'Test Roster',1),(2,'Test Roster 2',1); +/*!40000 ALTER TABLE `roster` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `roster_user` WRITE; +/*!40000 ALTER TABLE `roster_user` DISABLE KEYS */; +INSERT INTO `roster_user` VALUES (1,3,1),(1,4,1),(2,2,1); +/*!40000 ALTER TABLE `roster_user` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `schedule` WRITE; +/*!40000 ALTER TABLE `schedule` DISABLE KEYS */; +INSERT INTO `schedule` VALUES (1,1,1,1,21,0,1496559600),(2,1,2,4,21,0,1496559600); +/*!40000 ALTER TABLE `schedule` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `schedule_event` WRITE; +/*!40000 ALTER TABLE `schedule_event` DISABLE KEYS */; +INSERT INTO `schedule_event` VALUES (1,1,205200,604800),(2,2,205200,604800); +/*!40000 ALTER TABLE `schedule_event` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `setting_role` WRITE; +/*!40000 ALTER TABLE `setting_role` DISABLE KEYS */; +INSERT INTO `setting_role` VALUES (1,1),(2,1),(3,1),(4,1),(7,1),(8,1),(9,1),(1,2),(2,2),(3,2),(4,2),(7,2),(8,2),(1,3),(2,3),(3,3),(4,3),(7,3),(8,3),(1,4),(2,4),(3,4),(4,4),(7,4),(8,4); +/*!40000 ALTER TABLE `setting_role` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `team_admin` WRITE; +/*!40000 ALTER TABLE `team_admin` DISABLE KEYS */; +INSERT INTO `team_admin` VALUES (1,2),(1,4); +/*!40000 ALTER TABLE `team_admin` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `team_service` WRITE; +/*!40000 ALTER TABLE `team_service` DISABLE KEYS */; +INSERT INTO `team_service` VALUES (1,1); +/*!40000 ALTER TABLE `team_service` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `team_user` WRITE; +/*!40000 ALTER TABLE `team_user` DISABLE KEYS */; +INSERT INTO `team_user` VALUES (1,2),(1,3),(1,4); +/*!40000 ALTER TABLE `team_user` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `user_contact` WRITE; +/*!40000 ALTER TABLE `user_contact` DISABLE KEYS */; +INSERT INTO `user_contact` VALUES (1,8,'+1 111-111-1111'),(1,17,'root'),(1,26,'+1 111-111-1111'),(1,35,'root@example.com'),(2,8,'+1 222-222-2222'),(2,17,'manager'),(2,26,'+1 222-222-2222'),(2,35,'manager@example.com'),(3,8,'+1 333-333-3333'),(3,17,'jdoe'),(3,26,'+1 333-333-3333'),(3,35,'jdoe@example.com'),(4,8,'+1 444-444-4444'),(4,17,'asmith'),(4,26,'+1 444-444-4444'),(4,35,'asmith@example.com'); +/*!40000 ALTER TABLE `user_contact` ENABLE KEYS */; +UNLOCK TABLES; + + +LOCK TABLES `event` WRITE; +/*!40000 ALTER TABLE `event` DISABLE KEYS */; +INSERT INTO `event` VALUES (1,1,1,1,NULL,3,1495555200,1496160000),(2,1,1,1,NULL,4,1496160000,1496764800),(3,1,1,1,NULL,3,1496764800,1497369600),(7,1,4,2,NULL,2,1495555200,1496160000),(8,1,4,2,NULL,2,1496160000,1496764800),(9,1,4,2,NULL,2,1496764800,1497369600); +/*!40000 ALTER TABLE `event` ENABLE KEYS */; +UNLOCK TABLES; + diff --git a/ops/config/systemd/nginx-oncall.service b/ops/config/systemd/nginx-oncall.service new file mode 100644 index 0000000..d3d1900 --- /dev/null +++ b/ops/config/systemd/nginx-oncall.service @@ -0,0 +1,13 @@ +[Unit] +Description=nginx proxy for uwsgi-oncall +After=syslog.target + +[Service] +ExecStart=/usr/sbin/nginx -c /home/oncall/daemons/nginx.conf +User=oncall +Group=oncall +Restart=on-failure +KillSignal=SIGQUIT +Type=simple +StandardError=syslog +NotifyAccess=all diff --git a/ops/config/systemd/nginx-oncall.socket b/ops/config/systemd/nginx-oncall.socket new file mode 100644 index 0000000..181babd --- /dev/null +++ b/ops/config/systemd/nginx-oncall.socket @@ -0,0 +1,8 @@ +[Unit] +Description=Socket for oncall nginx proxy + +[Socket] +ListenStream=0.0.0.0:8080 + +[Install] +WantedBy=sockets.target diff --git a/ops/config/systemd/uwsgi-oncall.service b/ops/config/systemd/uwsgi-oncall.service new file mode 100644 index 0000000..22a265a --- /dev/null +++ b/ops/config/systemd/uwsgi-oncall.service @@ -0,0 +1,13 @@ +[Unit] +Description=oncall uWSGI app +After=syslog.target + +[Service] +ExecStart=/bin/bash -c 'cd /home/oncall && source ./env/bin/activate && DOCKER_DB_BOOTSTRAP=1 python ./entrypoint.py' +User=oncall +Group=oncall +Restart=on-failure +KillSignal=SIGQUIT +Type=simple +StandardError=syslog +NotifyAccess=all diff --git a/ops/config/systemd/uwsgi-oncall.socket b/ops/config/systemd/uwsgi-oncall.socket new file mode 100644 index 0000000..a74c4f8 --- /dev/null +++ b/ops/config/systemd/uwsgi-oncall.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Socket for uWSGI app oncall + +[Socket] +ListenStream=/home/oncall/var/run/uwsgi.sock +SocketUser=oncall +SocketGroup=oncall +SocketMode=0660 + +[Install] +WantedBy=sockets.target diff --git a/ops/daemons/nginx.conf b/ops/daemons/nginx.conf new file mode 100644 index 0000000..96d8321 --- /dev/null +++ b/ops/daemons/nginx.conf @@ -0,0 +1,64 @@ + +error_log /home/oncall/var/log/nginx/error.log; +pid /home/oncall/var/run/nginx.pid; +daemon off; + +events { + worker_connections 1024; + multi_accept on; +} + + +http { + + include /etc/nginx/mime.types; + default_type application/octet-stream; + +log_format main '$remote_addr - $http_CLIENT_IP - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent $request_time ' + '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; + + access_log /home/oncall/var/log/nginx/access.log main; + error_log /home/oncall/var/log/nginx/error.log warn; + + server { + listen 8080; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + underscores_in_headers on; + + keepalive_timeout 15; + reset_timedout_connection on; + + merge_slashes off; + + gzip on; + gzip_proxied any; + gzip_min_length 1024; + gzip_comp_level 6; + gzip_vary on; + gzip_http_version 1.0; + + gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + location / { + uwsgi_pass unix:///home/oncall/var/run/uwsgi.sock; + uwsgi_read_timeout 600; + include /etc/nginx/uwsgi_params ; + } + + location /healthcheck { + uwsgi_pass unix:///home/oncall/var/run/uwsgi.sock; + uwsgi_read_timeout 600; + include /etc/nginx/uwsgi_params ; + access_log /home/oncall/var/log/nginx/hc_access.log main; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} diff --git a/ops/daemons/uwsgi-docker.yaml b/ops/daemons/uwsgi-docker.yaml new file mode 100644 index 0000000..9fe8703 --- /dev/null +++ b/ops/daemons/uwsgi-docker.yaml @@ -0,0 +1,43 @@ +prod: + plugins: python,logfile + chdir: /home/oncall/source/src + socket: /home/oncall/var/run/uwsgi.sock + chmod-socket: 666 + master: True + # set the following two settings if you are running under root + # uid: 1000 + # gid: 1000 + workers: 12 + master-fifo: /home/oncall/var/run/uwsgi_master_fifo + touch-reload: /home/oncall/var/run/uwsgi_touch_reload + stats: /home/oncall/var/run/uwsgi_stats.sock + pidfile: /home/oncall/var/run/uwsgi.pid + module: oncall.app:get_wsgi_app() + virtualenv: /home/oncall/env + pyargv: /home/oncall/config/config.yaml + buffer-size: 32768 + + # Enable memory reporting + memory-report: true + + # Logging + logformat: '%(ltime) [%(status)] %(method) %(uri) %(addr) [%(uagent)] RT:%(msecs) REF:%(referer) SZ:%(size) %(proto)' + log-4xx: true + log-5xx: true + log-x-forwarded-for: true + log-slow: 1500 + + # access log + req-logger: file:/home/oncall/var/log/uwsgi/access.log + + # error log + logger: file:/home/oncall/var/log/uwsgi/error.log + + # put timestamp in the error log + logdate: true + + # control nginx and oncall scheduler/notifier + attach-daemon2: + - cmd=/usr/sbin/nginx -c /home/oncall/daemons/nginx.conf,pidfile=/home/oncall/var/run/nginx.pid + - cmd=/home/oncall/env/bin/oncall-notifier /home/oncall/config/config.yaml + - cmd=/home/oncall/env/bin/oncall-scheduler /home/oncall/config/config.yaml diff --git a/ops/entrypoint.py b/ops/entrypoint.py new file mode 100644 index 0000000..959353b --- /dev/null +++ b/ops/entrypoint.py @@ -0,0 +1,95 @@ +# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license. +# See LICENSE in the project root for license information. + +import subprocess +import os +import socket +import time +import sys +from glob import glob +from oncall.utils import read_config + +dbpath = '/home/oncall/db' +initializedfile = '/home/oncall/db_initialized' + + +def load_sqldump(config, sqlfile, one_db=True): + print 'Importing %s...' % sqlfile + with open(sqlfile) as h: + cmd = ['/usr/bin/mysql', '-h', config['host'], '-u', + config['user'], '-p' + config['password']] + if one_db: + cmd += ['-o', config['database']] + proc = subprocess.Popen(cmd, stdin=h) + proc.communicate() + + if proc.returncode == 0: + print 'DB successfully loaded ' + sqlfile + return True + else: + print ('Ran into problems during DB bootstrap. ' + 'oncall will likely not function correctly. ' + 'mysql exit code: %s for %s') % (proc.returncode, sqlfile) + return False + + +def wait_for_mysql(config): + print 'Checking MySQL liveness on %s...' % config['host'] + db_address = (config['host'], 3306) + tries = 0 + while True: + try: + sock = socket.socket() + sock.connect(db_address) + sock.close() + break + except socket.error: + if tries > 20: + print 'Waited too long for DB to come up. Bailing.' + sys.exit(1) + + print 'DB not up yet. Waiting a few seconds..' + time.sleep(2) + tries += 1 + continue + + +def initialize_mysql_schema(config): + print 'Initializing oncall database' + # disable one_db to let schema.v0.sql create the database + re = load_sqldump(config, os.path.join(dbpath, 'schema.v0.sql'), one_db=False) + if not re: + sys.exit('Failed to load schema into DB.') + + for f in glob(os.path.join(dbpath, 'patches', '*.sql')): + re = load_sqldump(config, f) + if not re: + sys.exit('Failed to load DB patche: %s.' % f) + + re = load_sqldump(config, os.path.join(dbpath, 'dummy_data.sql')) + if not re: + sys.stderr.write('Failed to load dummy data.') + + with open(initializedfile, 'w'): + print 'Wrote %s so we don\'t bootstrap db again' % initializedfile + + +def main(): + oncall_config = read_config( + os.environ.get('ONCALL_CFG_PATH', '/home/oncall/config/config.yaml')) + mysql_config = oncall_config['db']['conn']['kwargs'] + + # It often takes several seconds for MySQL to start up. oncall dies upon start + # if it can't immediately connect to MySQL, so we have to wait for it. + wait_for_mysql(mysql_config) + + if 'DOCKER_DB_BOOTSTRAP' in os.environ: + if not os.path.exists(initializedfile): + initialize_mysql_schema(mysql_config) + + os.execv('/usr/bin/uwsgi', + ['', '--yaml', '/home/oncall/daemons/uwsgi.yaml:prod']) + + +if __name__ == '__main__': + main() diff --git a/ops/packer/README.md b/ops/packer/README.md new file mode 100644 index 0000000..771bc07 --- /dev/null +++ b/ops/packer/README.md @@ -0,0 +1,3 @@ +```docker run --name oncall-mysql -e MYSQL_ROOT_PASSWORD='1234' -d mysql``` +```docker run -d --link oncall-mysql:mysql -p 8080:8080 -e DOCKER_DB_BOOTSTRAP=1 quay.io/iris/oncall``` + diff --git a/ops/packer/gen_packer_cfg.py b/ops/packer/gen_packer_cfg.py new file mode 100644 index 0000000..0a30c1d --- /dev/null +++ b/ops/packer/gen_packer_cfg.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- + +from __future__ import print_function + +import re +import os +import yaml +import json +import sys + +OUTPUT_DIR = 'output' + +def main(): + current_dir = os.path.dirname(os.path.realpath(__file__)) + with open('%s/../../src/oncall/__init__.py' % current_dir, 'r') as fd: + version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', + fd.read(), re.MULTILINE).group(1) + + print('Generating packer config for oncall v%s' % version) + yml_cfg = sys.argv[1] + with open(yml_cfg) as fp: + config = yaml.safe_load(fp) + + if not os.path.isdir(OUTPUT_DIR): + os.mkdir(OUTPUT_DIR) + + config['variables']['app_version'] = version + cfg_name = os.path.splitext(os.path.basename(yml_cfg))[0] + with open('%s/%s.json' % (OUTPUT_DIR, cfg_name), 'w') as fp: + json_str = json.dumps(config, indent=2) + print(json_str) + fp.write(json_str) + +main() diff --git a/ops/packer/oncall.yaml b/ops/packer/oncall.yaml new file mode 100644 index 0000000..0fc8993 --- /dev/null +++ b/ops/packer/oncall.yaml @@ -0,0 +1,68 @@ +variables: + app_name: "oncall" + app_version: "" + git_tag: "master" + +builders: + - type: "docker" + image: "ubuntu:16.04" + changes: + - 'EXPOSE 8080' + - 'CMD ["sudo", "-EHu", "oncall", "bash", "-c", "source /home/oncall/env/bin/activate && python /home/oncall/entrypoint.py"]' + commit: True + +provisioners: + - type: "shell" + inline: + - mkdir /tmp/repo + + - type: "file" + source: "../../src" + destination: "/tmp/repo" + + - type: "file" + source: "../../setup.py" + destination: "/tmp/repo/setup.py" + + - type: "file" + source: "../../db" + destination: "/tmp/repo" + + - type: "file" + source: "../../ops" + destination: "/tmp/repo" + + - type: "file" + source: "../../configs" + destination: "/tmp/repo" + + - type: "shell" + only: ["docker"] + inline: + - "apt-get update && apt-get -y install sudo" + + - type: "shell" + inline: + - sudo apt-get -y install curl python-pip uwsgi unzip virtualenv sudo python-dev libyaml-dev libsasl2-dev libldap2-dev nginx uwsgi-plugin-python mysql-client + - sudo rm -rf /var/cache/apt/archives/* + - sudo useradd -m -s /bin/bash oncall + - sudo chown -R oncall:oncall /home/oncall /var/log/nginx /var/lib/nginx + - sudo -Hu oncall mkdir -p /home/oncall/var/log/uwsgi /home/oncall/var/log/nginx /home/oncall/var/run + - sudo mv /tmp/repo /home/oncall/source + - "sudo chown -R oncall:oncall /home/oncall/source" + - sudo mv /home/oncall/source/ops/config/systemd/uwsgi-oncall.service /etc/systemd/system/uwsgi-oncall.service + - sudo mv /home/oncall/source/ops/config/systemd/nginx-oncall.service /etc/systemd/system/nginx-oncall.service + - sudo mv /home/oncall/source/ops/config/systemd/nginx-oncall.socket /etc/systemd/system/nginx-oncall.socket + - sudo -Hu oncall ln -s /home/oncall/source/ops/daemons /home/oncall/daemons + - sudo -Hu oncall ln -s /home/oncall/source/ops/entrypoint.py /home/oncall/entrypoint.py + - sudo -Hu oncall ln -s /home/oncall/source/db /home/oncall/db + - sudo -Hu oncall mkdir /home/oncall/config + - sudo -Hu oncall cp /home/oncall/source/configs/config.yaml /home/oncall/config/config.yaml + - sudo -Hu oncall virtualenv /home/oncall/env + - sudo -Hu oncall /bin/bash -c 'source /home/oncall/env/bin/activate && cd /home/oncall/source && pip install .' + + - type: "shell" + only: ["docker"] + inline: + - "sudo -Hu oncall mv -f /home/oncall/daemons/uwsgi-docker.yaml /home/oncall/daemons/uwsgi.yaml" + - sudo -Hu oncall cp /home/oncall/source/configs/config.docker.yaml /home/oncall/config/config.yaml diff --git a/setup.py b/setup.py index ecc3259..44d73f7 100644 --- a/setup.py +++ b/setup.py @@ -13,8 +13,9 @@ with open('src/oncall/__init__.py', 'r') as fd: setup( name='oncall', version=version, - packages=['oncall'], package_dir={'': 'src'}, + packages=setuptools.find_packages('src'), + include_package_data=True, install_requires=[ 'falcon==1.1.0', 'falcon-cors',