##// END OF EJS Templates
SIR with docker-compose working
jespinoza -
r299:d18e81484ac8
parent child
Show More
@@ -0,0 +1,4
1 migrations/
2 .vscode/
3 *.pyc
4 .env
@@ -0,0 +1,39
1 # Integrated Radar System (SIR)
2
3 The Integrated Radar System (SIR) is a web application that allows the configuration of the radar devices as required by the experiment,
4 This app allows the creation of Campaigns, Experiment and Device Configurations.
5 For more information visit: http://jro-dev.igp.gob.pe:3000/projects/sistema-integrado-de-radar/wiki
6
7 ## Installation
8
9 We recommend use docker/docker-compose for test/production but you can install the aplication as a normal django app.
10
11 ### 1. Download
12
13 Download the application *radarsys* to your workspace
14
15 $ cd /path/to/your/workspace
16 $ git clone http://jro-dev.igp.gob.pe/rhodecode/radarsys && cd radarsys
17
18 ### 2. Config app
19
20 Create enviroment vars (/path/to/radarsys/.env)
21
22 HOST_REDIS=radarsys-redis
23 POSTGRES_DB_NAME=radarsys
24 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
25 POSTGRES_PORT_5432_TCP_PORT=5432
26 POSTGRES_USER=docker
27 POSTGRES_PASSWORD=****
28 PGDATA=/var/lib/postgresql/data
29 LC_ALL=C.UTF-8
30
31 Set database user/password in /path/to/radarsys/settings.py
32
33 ### 3. Build application
34
35 $ docker-compose build
36
37 ### 4. Run containers
38
39 $ docker-compose up -d No newline at end of file
@@ -0,0 +1,3
1 FROM postgres:10.1-alpine
2
3 RUN mkdir -p "$PGDATA" && chmod 700 "$PGDATA" No newline at end of file
@@ -0,0 +1,3
1 #!/bin/env bash
2 psql -U postgres -c "CREATE USER $POSTGRES_USER PASSWORD '$POSTGRES_PASSWORD'"
3 psql -U postgres -c "CREATE DATABASE $POSTGRES_DB_NAME OWNER $POSTGRES_USER" No newline at end of file
@@ -1,7 +1,8
1 HOST_MYSQL=mysql
2 HOST_REDIS=redis
3 MYSQL_ROOT_PASSWORD=r00tJRO
4 MYSQL_DATABASE=radarsys
5 MYSQL_USER=developer
6 MYSQL_PASSWORD=idi2015
7 HOST_REDIS=redis No newline at end of file
1 HOST_REDIS=radarsys-redis
2 POSTGRES_DB_NAME=radarsys
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_PORT=5432
5 POSTGRES_USER=docker
6 POSTGRES_PASSWORD=docker
7 PGDATA=/var/lib/postgresql/data
8 LC_ALL=C.UTF-8 No newline at end of file
@@ -1,4 +1,4
1 FROM python:2.7.11
1 FROM python:2.7-slim
2 2
3 3 # set working directory
4 4 RUN mkdir /radarsys
@@ -6,11 +6,18 WORKDIR /radarsys
6 6
7 7 # Install python dependences
8 8 ADD requirements.txt ./requirements.txt
9 RUN pip install -v --timeout 120 -r requirements.txt --no-cache-dir
9 RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends \
10 gcc \
11 g++ \
12 && pip install -v --timeout 120 -r requirements.txt --no-cache-dir --index-url http://10.10.20.128:8010/simple --trusted-host 10.10.20.128 \
13 && apt-get purge -y --auto-remove gcc g++\
14 && rm -rf /var/lib/apt/lists/*
10 15
11 16 # Copy the main application.
12 17 COPY . ./
13 18
19 EXPOSE 8000
20
14 21 RUN python manage.py collectstatic --noinput
15 22
16 23
@@ -25,7 +25,7 import matplotlib
25 25 # matplotlib.use("Agg")
26 26 #else:
27 27 # matplotlib.use('TKAgg')
28 #matplotlib.use("Agg")
28 matplotlib.use("Agg")
29 29 #matplotlib.interactive(1)
30 30 import matplotlib.pyplot
31 31 #import Numeric
@@ -5,6 +5,6
5 5
6 6 {% block content %}
7 7
8 {% lorem %}
8 <p>{% lorem %}</p>
9 9
10 10 {% endblock %}
@@ -72,8 +72,8 ror = lambda val, r_bits: \
72 72
73 73 class RCConfiguration(Configuration):
74 74
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
@@ -109,9 +109,7 class RCConfiguration(Configuration):
109 109
110 110 def clone(self, **kwargs):
111 111
112 lines = self.get_lines()
113 print 'LINES'
114 print lines
112 lines = self.get_lines()
115 113 self.pk = None
116 114 self.id = None
117 115 for attr, value in kwargs.items():
@@ -124,7 +122,7 class RCConfiguration(Configuration):
124 122 new_lines = self.get_lines()
125 123 for line in new_lines:
126 124 line_params = json.loads(line.params)
127 if 'TX_ref' in line_params:
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
128 126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
129 127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
130 128 line.params = json.dumps(line_params)
@@ -242,17 +240,17 class RCConfiguration(Configuration):
242 240 for x in points:
243 241 dum = []
244 242 for i, tups in enumerate(pulses):
245 ups = [tup[0] for tup in tups]
246 dws = [tup[1] for tup in tups]
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
247 245 if x in ups:
248 246 dum.append(1)
249 247 elif x in dws:
250 248 dum.append(0)
251 249 else:
252 250 dum.append(last[i])
253 states.append(dum)
251 states.append(dum)
254 252 last = dum
255
253
256 254 if binary:
257 255 ret = []
258 256 for flips in states:
@@ -351,6 +349,8 class RCConfiguration(Configuration):
351 349
352 350 def plot_pulses2(self, km=False):
353 351
352 import matplotlib
353 matplotlib.use('Agg')
354 354 import matplotlib.pyplot as plt
355 355 from bokeh.resources import CDN
356 356 from bokeh.embed import components
@@ -545,11 +545,17 class RCConfiguration(Configuration):
545 545
546 546 return True
547 547
548 def write_device(self):
549
550 values = zip(self.get_pulses(),
551 [x-1 for x in self.get_delays()])
552
548 def write_device(self):
549
550 #values = zip(self.get_pulses(), [x-1 for x in self.get_delays()])
551
552 values = []
553 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
554 while delay>65535:
555 values.append((pulse, 65535))
556 delay -= 65535
557 values.append((pulse, delay-1))
558
553 559 data = bytearray()
554 560 #reset
555 561 data.extend((128, 0))
@@ -570,8 +576,16 class RCConfiguration(Configuration):
570 576 data.extend((129, 1))
571 577
572 578 try:
579 payload = self.request('stop', 'post')
580 payload = self.request('reset', 'post')
581 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
582 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
583 n = len(data)
584 x = 0
585 #while x < n:
573 586 payload = self.request('write', 'post', data=b64encode(data))
574
587 # x += 1024
588
575 589 if payload['write']=='ok':
576 590 self.device.status = 3
577 591 self.device.save()
@@ -582,6 +596,8 class RCConfiguration(Configuration):
582 596 self.message = 'RC write: {}'.format(payload['write'])
583 597 return False
584 598
599 #payload = self.request('start', 'post')
600
585 601 except Exception as e:
586 602 if 'No route to host' not in str(e):
587 603 self.device.status = 4
@@ -641,7 +657,7 class RCLine(models.Model):
641 657
642 658 def __str__(self):
643 659 if self.rc_configuration:
644 return u'%s - %s' % (self.rc_configuration, self.get_name())
660 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
645 661
646 662 def jsonify(self):
647 663
@@ -856,12 +872,16 class RCLine(models.Model):
856 872 elif self.line_type.name=='windows':
857 873 params = json.loads(self.params)
858 874 if 'params' in params and len(params['params'])>0:
859 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
860 tr_ranges = tr_params['range'].split(',')
875 tr_lines = self.get_lines(line_type__name='tr')
876 if tr_lines:
877 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
878 tr_ranges = tr_params['range'].split(',')
879 else:
880 tr_ranges = []
861 881 for p in params['params']:
862 882 y_win = self.points(ntx, ipp_u,
863 883 p['resolution']*p['number_of_samples']*km2unit,
864 before=int(self.rc_configuration.time_before*us2unit),
884 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
865 885 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
866 886
867 887
@@ -21,7 +21,8 class RCApi(object):
21 21 def load(self, filename):
22 22
23 23 self.params = json.load(open(filename))
24 print 'RC Configuration: {}'.format(self.params['name'])
24 self.pk = self.params['configurations']['allIds'][0]
25 print 'RC Configuration: {}'.format(self.params['configurations']['byId'][self.pk]['name'])
25 26
26 27 def status(self):
27 28
@@ -56,40 +57,45 class RCApi(object):
56 57 def write(self):
57 58
58 59 url_write = os.path.join(self.url, 'write')
59 url_divider = os.path.join(self.url, 'divisor')
60
61 values = zip(self.params['pulses'],
62 [x-1 for x in self.params['delays']])
60 url_divider = os.path.join(self.url, 'divider')
61
62 values = zip(self.params['configurations']['byId'][self.pk]['pulses'],
63 [x-1 for x in self.params['configurations']['byId'][self.pk]['delays']])
63 64 payload = ''
64 65
65 66 for tup in values:
66 67 vals = pack('<HH', *tup)
67 payload += '\x05'+vals[0]+'\x04'+vals[1]+'\x05'+vals[2]+'\x04'+vals[3]
68 payload += '\x85'+vals[0]+'\x84'+vals[1]+'\x85'+vals[2]+'\x84'+vals[3]
68 69
69 70 req = requests.post(url_divider,
70 data={'divisor':int(self.params['clock_divider'])-1})
71
71 data={'divider':int(self.params['configurations']['byId'][self.pk]['clock_divider'])-1})
72
72 73 if 'ok' not in req.text:
73 74 print 'Error sending divider'
74 75 return False
75
76
76 77 req = requests.post(url_write,
77 78 data=b64encode(payload))
78 79 return req.json()
79 80
80 81 if __name__ == '__main__':
81
82 import time
82 83 ip = '10.10.10.100'
83 filename = '/home/jespinoza/Downloads/rc_150EEJ.json'
84
84
85 filename = './dia.json'
86
85 87 rc = RCApi(ip)
86 88 rc.load(filename)
87 89
88 print rc.status()
89 print rc.reset()
90 print rc.stop()
90 # print rc.status()
91 # time.sleep(1)
92 # print rc.reset()
93 # time.sleep(1)
94 # print rc.stop()
95 # time.sleep(1)
91 96 print rc.write()
92 print rc.start()
97 # time.sleep(1)
98 # print rc.start()
93 99
94 100
95 101
@@ -1,25 +1,26
1 1 version: '2'
2 2 services:
3 # Django app
3 4 web:
4 container_name: 'radarsys_web'
5 container_name: 'radarsys'
5 6 build: .
6 7 restart: always
7 8 image: radarsys
8 command: gunicorn radarsys.wsgi:application -w 2 -b :8080
9 command: gunicorn radarsys.wsgi:application -w 2 -b :8000
9 10 env_file: .env
10 ports:
11 - "8080:8080"
11
12 12 links:
13 13 - redis
14 - mysql
14 - postgres
15 15 volumes:
16 - './:/data'
16 - './:/radarsys'
17 - '/data/dockers/radarsys/static:/radarsys/static'
17 18 depends_on:
18 19 - redis
19 - mysql
20 - postgres
20 21
21 22 redis:
22 container_name: 'redis'
23 container_name: 'radarsys-redis'
23 24 image: 'redis:3.2-alpine'
24 25 ports:
25 26 - '127.0.0.1:6300:6379'
@@ -27,6 +28,7 services:
27 28 - '/data/dockers/radarsys/redis:/data'
28 29
29 30 celery_worker:
31 container_name: 'radarsys-celery'
30 32 image: radarsys
31 33 env_file: .env
32 34 command: celery -A radarsys worker -l info
@@ -35,26 +37,31 services:
35 37 depends_on:
36 38 - web
37 39
38 mysql:
39 container_name: 'mysql'
40 image: 'mysql:5.6'
41 env_file: .env
40 # PostgreSQL
41 postgres:
42 container_name: 'radarsys-postgres'
43 build: ./postgres/
42 44 ports:
43 - '127.0.0.1:6301:3306'
45 - 5432:5432
44 46 volumes:
45 - '/data/dockers/radarsys/mysql:/var/lib/mysql'
47 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
48 - pgdata:/var/lib/postgresql/data
49 env_file: .env
46 50
51 # Web Server
47 52 nginx:
48 container_name: 'radarsys_nginx'
53 container_name: 'radarsys-nginx'
49 54 restart: always
50 55 build: ./nginx/
51 56 ports:
52 - "3000:80"
53 volumes:
54 - '/data/dockers/radarsys/nginx:/data/nginx'
57 - '8030:8030'
55 58 volumes_from:
56 59 - web
57 60 links:
58 61 - web:web
59 62 depends_on:
60 63 - web
64
65 volumes:
66 pgdata:
67 driver: local No newline at end of file
@@ -1,5 +1,3
1 FROM tutum/nginx
2
3 RUN rm /etc/nginx/sites-enabled/default
4 ADD sites-enabled/ /etc/nginx/sites-enabled
5 ADD sites-enabled/radarsys /etc/nginx/conf.d/
1 FROM nginx:1.13.8-alpine
2 RUN rm /etc/nginx/conf.d/default.conf
3 ADD sites-enabled/radarsys.conf /etc/nginx/conf.d/
@@ -1,17 +1,17
1 1 server {
2 2
3 listen 80;
4 server_name sir.com;
3 listen 8030;
4 server_name localhost;
5 5
6 6 access_log /dev/stdout;
7 7 error_log /dev/stdout info;
8 8
9 9 location /static {
10 alias /data/media/static;
10 alias /radarsys/static;
11 11 }
12 12
13 13 location / {
14 proxy_pass http://web:8080;
14 proxy_pass http://web:8000;
15 15 }
16 16
17 17 }
@@ -13,7 +13,7 https://docs.djangoproject.com/en/1.8/ref/settings/
13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 14 import os
15 15
16 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 17
18 18 # Quick-start development settings - unsuitable for production
19 19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
@@ -85,20 +85,15 WSGI_APPLICATION = 'radarsys.wsgi.application'
85 85
86 86 DATABASES = {
87 87 'default': {
88 #'ENGINE': 'django.db.backends.sqlite3',
89 #'NAME': os.path.join(BASE_DIR, 'radarsys.sqlite'),
90 'ENGINE': 'django.db.backends.mysql',
91 'NAME': 'radarsys',
92 'USER': 'developer',
93 #'HOST': 'mysql',
94 'PASSWORD': 'idi2015',
95 'OPTIONS': {
96 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
97 }
88 'ENGINE': 'django.db.backends.postgresql_psycopg2',
89 'NAME': os.environ.get('POSTGRES_DB_NAME', 'radarsys'),
90 'USER': os.environ.get('POSTGRES_USER', 'docker'),
91 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'docker'),
92 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'postgres'),
93 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', ''),
98 94 }
99 95 }
100 96
101
102 97 # Internationalization
103 98 # https://docs.djangoproject.com/en/1.8/topics/i18n/
104 99
@@ -115,41 +110,25 USE_TZ = False
115 110 # Static files (CSS, JavaScript, Images)
116 111 # https://docs.djangoproject.com/en/1.8/howto/static-files/
117 112
118 MEDIA_ROOT = 'media'#os.path.join(BASE_DIR, 'media')
119 MEDIA_URL = '/site_media/'
113 MEDIA_URL = '/media/'
114 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
120 115
121 116 STATIC_URL = '/static/'
122 #STATIC_ROOT = '/var/www/html/static/'
123 STATIC_ROOT = os.path.join(MEDIA_ROOT, 'static')
124
125 #STATICFILES_DIRS = (
126 # os.path.join(BASE_DIR, 'apps', 'main', 'static'),
127 #
128 #)
129
117 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
130 118
131 119 STATICFILES_FINDERS = (
132 120 'django.contrib.staticfiles.finders.FileSystemFinder',
133 121 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
134 122 )
135 123
136 FIXTURE_DIRS = (
137 os.path.join(BASE_DIR, 'apps', 'rc', 'fixtures'),
138 os.path.join(BASE_DIR, 'apps', 'main', 'fixtures'),
139 os.path.join(BASE_DIR, 'apps', 'jars', 'fixtures'),
140 )
141
142 124 # Celery stuff
143 REDIS_HOST = 'redis'
125 REDIS_HOST = os.environ.get('HOST_REDIS', '127.0.0.1')
126
144 127 BROKER_TRANSPORT = 'redis'
145 #--Development--# (Para Pruebas Locales)
146 BROKER_URL = 'redis://127.0.0.1:6300'
147 CELERY_RESULT_BACKEND = 'redis://localhost:6300'
148 #---------------#
149 #--Production---# (Para Docker)
150 #CELERY_BROKER_TRANSPORT = BROKER_URL = 'redis://%s:6379/0' % REDIS_HOST
151 #CELERY_RESULT_BACKEND = 'redis://%s:6379/0' % REDIS_HOST
152 #---------------#
128 BROKER_URL = 'redis://%s:6379/0' % REDIS_HOST
129
130 CELERY_RESULT_BACKEND = 'redis://%s:6379/0' % REDIS_HOST
131 CELERY_BROKER_TRANSPORT = BROKER_URL
153 132 CELERY_ACCEPT_CONTENT = ['application/json']
154 133 CELERY_TASK_SERIALIZER = 'json'
155 134 CELERY_RESULT_SERIALIZER = 'json'
@@ -1,53 +1,8
1 ### Docker de la base de datos ###
2 # 'NAME': 'radarsys',
3 # 'USER': 'developer',
4 # 'PASSWORD': 'idi2015',
5
6 #Preparar Base de Datos para la aplicacion:
7 ## Crear imagen "mysql:5.6"
8 docker create -v /var/lib/mysql --name mysql-radarsys-data mysql:5.6 /bin/true
9 ## Ejecutar Container "mysql-radarsys-server"
10 docker run --name mysql-radarsys-server -d -e MYSQL_ROOT_PASSWORD=r00tJRO -e MYSQL_DATABASE=radarsys \
11 -e MYSQL_USER=developer -e MYSQL_PASSWORD=idi2015 --volumes-from mysql-radarsys-data mysql:5.6
12
13 #Aplicacion Sistema Integrado de Radar
14 ## Debe crearse *Dockerfile*
15 ## Crear la imagen
16 docker build -t radarsys:v01 .
17 # Ejecutar Container
18 docker run -d --name radarsys01 --link mysql-radarsys-server -p 3000:3000 \
19 -v /home/ubuntu/docker_shared/radarsys/media:/radarsys/media \
20 --add-host smtp_server:172.17.0.1 radarsys:v01
21
22 ## Dentro del Container: se debe realizar las siguiente modificaciones
23 ### Para ingresar al container:
24 docker exec -i -t radarsys01 /bin/bash
25 ### Es necesario ejecutar:
26 apt-get update
27 apt-get install nano
28 ### Modificar radarsys.setting.py, HOST debe estar habilitado
29 'HOST': 'mysql-sysinv-server',
30 ### Asegurarse que:
31 MEDIA_ROOT: 'media'
32 ### En el script abs/utils/Graphics_OverJro.py, matplotlib Agg debe estar habilitado
33 matplotlib.use("Agg")
34 ### En el script radarsys/urls.py comentar para que nginx sirva "static":
35 #from django.contrib.staticfiles.urls import staticfiles_urlpatterns
36 #urlpatterns += staticfiles_urlpatterns()
37
38 ### Ejecutar los siguientes comandos (solo si ya se creo mysql-radarsys-server):
39 python manage.py makemigrations \
40 && python manage.py migrate \
41 && python manage.py loaddata apps/main/fixtures/main_initial_data.json \
42 && python manage.py loaddata apps/rc/fixtures/rc_initial_data.json \
43 && python manage.py loaddata apps/jars/fixtures/initial_filters_data.json \
44 && python manage.py collectstatic
45
46 ### Por ultimo reiniciar el docker
47 docker stop radarsys01
48 docker start radarsys01
49
50
51 #### Archivos Compartidos:
52 # /home/ubuntu/docker_shared/radarsys/media
53 # (debe coincidir con la carpeta que se ingresar en "docker run")
1 # Commands after dockers creations
2
3 docker-compose run web python manage.py makemigrations
4 docker-compose run web python manage.py migrate
5 docker-compose run web python manage.py loaddata apps/main/fixtures/main_initial_data.json \
6 docker-compose run web python manage.py loaddata apps/rc/fixtures/rc_initial_data.json \
7 docker-compose run web python manage.py loaddata apps/jars/fixtures/initial_filters_data.json \
8 docker-compose run web python manage.py collectstatic
@@ -1,12 +1,12
1 1 Django==1.10.1
2 2 django-bootstrap3
3 mysqlclient
3 psycopg2
4 4 django-polymorphic
5 bokeh
6 numpy
5 bokeh==0.12.1
6 numpy==1.13.3
7 7 matplotlib
8 8 scipy
9 9 celery
10 10 gunicorn
11 requests==2.11.1
12 redis
11 requests
12 redis No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now