Djadhere » Historique » Version 6
Élie Bouttier, 02/01/2017 21:01
1 | 1 | Élie Bouttier | h1. Djadhere |
---|---|---|---|
2 | 1 | Élie Bouttier | |
3 | 1 | Élie Bouttier | C’est le SI de tetaneutral.net ! Il est codé en Python avec le framework web Django. |
4 | 1 | Élie Bouttier | Il est accessible à l’adresse https://adherents.tetaneutral.net. |
5 | 1 | Élie Bouttier | |
6 | 1 | Élie Bouttier | h2. Contribuer |
7 | 1 | Élie Bouttier | |
8 | 1 | Élie Bouttier | Le code source est sur la forge de ffdn : https://code.ffdn.org/tetaneutral.net/djadhere |
9 | 1 | Élie Bouttier | Celle-ci permet également d’ouvrir des tickets ou de créer des pull-requests. |
10 | 1 | Élie Bouttier | Pour rejoindre l’équipe, demander à djanos ou nim65s sur IRC. |
11 | 2 | Élie Bouttier | Pad de travail : http://pad.tetaneutral.net/p/djadhere |
12 | 1 | Élie Bouttier | |
13 | 4 | Élie Bouttier | h2. Utilisation |
14 | 4 | Élie Bouttier | |
15 | 5 | Élie Bouttier | h3. Ligne de commande |
16 | 5 | Élie Bouttier | |
17 | 4 | Élie Bouttier | Accès au @manage.py@ : |
18 | 4 | Élie Bouttier | |
19 | 4 | Élie Bouttier | @# ./go-prod.sh |
20 | 4 | Élie Bouttier | $ cd app |
21 | 4 | Élie Bouttier | $ ./manage.py@ |
22 | 4 | Élie Bouttier | |
23 | 4 | Élie Bouttier | Création d’un super utilisateur : |
24 | 4 | Élie Bouttier | |
25 | 4 | Élie Bouttier | @$ ./manage.py createsuperuser@ |
26 | 4 | Élie Bouttier | |
27 | 4 | Élie Bouttier | Statistiques financières des services : |
28 | 4 | Élie Bouttier | |
29 | 4 | Élie Bouttier | @$ ./manage.py servicesstats@ |
30 | 5 | Élie Bouttier | |
31 | 5 | Élie Bouttier | h3. Interface django admin |
32 | 5 | Élie Bouttier | |
33 | 5 | Élie Bouttier | Accès : https://adherents.tetaneutral.net/admin/ |
34 | 5 | Élie Bouttier | |
35 | 5 | Élie Bouttier | h4. Création d’un nouveau type de service et délégation de sa gestion |
36 | 5 | Élie Bouttier | |
37 | 5 | Élie Bouttier | * Créer un groupe « equipage-toulouse » par exemple |
38 | 5 | Élie Bouttier | * Créer un nouveau type de service « Abo Toulouse » par exemple, et définir le groupe « equipage-toulouse » comme groupe de gestion |
39 | 5 | Élie Bouttier | * Dans le profil des utilisateurs gestionnaires : |
40 | 5 | Élie Bouttier | * Cocher « Statut équipe » pour lui permettre de se connecter à l’interface d’administration |
41 | 5 | Élie Bouttier | * L’ajouter au groupe « equipage-toulouse » pour lui donner les droits nécessaires |
42 | 5 | Élie Bouttier | * Créer un ou des services de type « Abo Toulouse » en configurant la / les IP associé(s) mais sans spécifier d’adhérent. |
43 | 5 | Élie Bouttier | |
44 | 5 | Élie Bouttier | h4. Gestion d’un service par un membre d’une équipe |
45 | 5 | Élie Bouttier | |
46 | 5 | Élie Bouttier | Un utilisateur appartenant à un équipage peut : |
47 | 5 | Élie Bouttier | |
48 | 5 | Élie Bouttier | * Consulter les utilisateurs, modifier leur nom, prénom, adresse emails, numéro de téléphone et adresse. |
49 | 5 | Élie Bouttier | * Définir comme adhérent un utilisateur et ainsi lui obtenir un numéro d’adhérent. |
50 | 6 | Élie Bouttier | * Consulter les adhérents (utilisateur ou personne morale) et ajouter une cotisation. |
51 | 6 | Élie Bouttier | Une cotisation reste modifiable ou supprimable jusqu’à validation par l’équipage « banque ». |
52 | 5 | Élie Bouttier | * Consulter les services des types correspondant aux groupes de gestion auquel l’utilisateur appartient. |
53 | 1 | Élie Bouttier | * Modifier les services : adhérent, date de début, date de fin et paiements liés au service. |
54 | 6 | Élie Bouttier | Les paiements sont modifiable et supprimable jusqu’à validation par l’équipage « banque ». |
55 | 6 | Élie Bouttier | |
56 | 6 | Élie Bouttier | h4. Configuration d’un équipage « banque » |
57 | 6 | Élie Bouttier | |
58 | 6 | Élie Bouttier | * Créer un groupe « equipage-banque » et lui donner les 4 permissions « banking | paiement » : add / change / delete / validate. |
59 | 6 | Élie Bouttier | * Éditer les utilisateurs voulus et les ajouter au groupe « equipage-banque ». |
60 | 6 | Élie Bouttier | |
61 | 6 | Élie Bouttier | h4. Gestion des paiements par l’équipage « banque » |
62 | 6 | Élie Bouttier | |
63 | 6 | Élie Bouttier | Un utilisateur avec les permissions « banking | paiement » peut consulter et modifier l’ensemble des paiements. |
64 | 6 | Élie Bouttier | Il peut en particulier les valider ; ceux-ci ne sont alors plus modifiable par les membres d’équipage « services ». |
65 | 6 | Élie Bouttier | FIXME: Il n’y a pour le moment aucun stoquage des coordonnées banquaires. |
66 | 4 | Élie Bouttier | |
67 | 1 | Élie Bouttier | h2. Déploiement |
68 | 1 | Élie Bouttier | |
69 | 1 | Élie Bouttier | Il est déployé sur la VM djadhere.tetaneutral.net (Debian 8.6 Jessie). |
70 | 1 | Élie Bouttier | Deux instances sont déployées, la première pour la version de production, et la deuxième pour la version de developpement. |
71 | 1 | Élie Bouttier | |
72 | 1 | Élie Bouttier | Le serveur web utilisé est nginx. |
73 | 1 | Élie Bouttier | La configuration se trouve dans le fichier @/etc/nginx/sites-available/djadhere@. |
74 | 1 | Élie Bouttier | |
75 | 1 | Élie Bouttier | Les certificats letsencrypt sont généré avec @certbot@ (installé depuis les backports) : |
76 | 1 | Élie Bouttier | |
77 | 1 | Élie Bouttier | @certbot -c /etc/letsencrypt/webroot.ini -d mondomaine.tetaneutral.net@ |
78 | 1 | Élie Bouttier | |
79 | 1 | Élie Bouttier | La base de données utilisée est postgresql. |
80 | 1 | Élie Bouttier | |
81 | 1 | Élie Bouttier | Django est lancé par @uwsgi@. |
82 | 1 | Élie Bouttier | La configuration de celui-ci se trouve dans le dossier @/etc/uwsgi/@. |
83 | 1 | Élie Bouttier | Les dossiers @apps-available@ et @apps-enabled@ ne sont pas utilisé. |
84 | 1 | Élie Bouttier | En effet, l’ajout du .service systemd uwsgi@.service permet de lancer de manière indépendante chaque instance. |
85 | 1 | Élie Bouttier | |
86 | 1 | Élie Bouttier | Voici une description du déploiement de la prod, le déploiement en dev étant analogue. |
87 | 1 | Élie Bouttier | |
88 | 1 | Élie Bouttier | Le dossier @/etc/uwsgi/djadhere/@ contient un lien symbolique vers la configuration uwsgi de cette instance. |
89 | 1 | Élie Bouttier | Le lien est nommé @prod@ permettant d’utiliser systemd ainsi : |
90 | 1 | Élie Bouttier | |
91 | 1 | Élie Bouttier | @systemctl {start,stop,restart,status} uwsgi@djadhere-prod@ |
92 | 1 | Élie Bouttier | |
93 | 1 | Élie Bouttier | Un utilisateur @djadhere-prod@ a été créé (et automatiquement un groupe du même nom). |
94 | 1 | Élie Bouttier | L’utilisateur @www-data@ a été rajouté au groupe @djadhere-prod@. |
95 | 1 | Élie Bouttier | L’umask de @djadhere-prod@ est définie à 077 dans son @.bashrc@. |
96 | 1 | Élie Bouttier | |
97 | 1 | Élie Bouttier | Le home de djadhere-prod se trouve dans le dossier @/srv/djadhere/prod@ et contient : |
98 | 1 | Élie Bouttier | |
99 | 1 | Élie Bouttier | * @uwsgi.ini@ : la conf uwsgi symlinké depuis @/etc/uwsgi/djadhere/prod@ |
100 | 1 | Élie Bouttier | * @uwsgi.socket@ : le socket unix référencé dans la conf de nginx |
101 | 1 | Élie Bouttier | * @touch-to-reload@ : un fichier permettant de relancer uwsgi via la commande touch : @touch touch-to-reload@ |
102 | 1 | Élie Bouttier | * @app@ : un clone du projet Git |
103 | 1 | Élie Bouttier | * @log@ : les logs (nginx + uwsgi + django) |
104 | 1 | Élie Bouttier | * @venv@ : le virtualenv dans lequel tourne django |
105 | 1 | Élie Bouttier | * @webdir@ : le dossier servie par nginx (g+rX) qui contient un dossier static et un dossier media (géré par django) |
106 | 1 | Élie Bouttier | * @update.sh@ : un script pour mettre à jour |
107 | 1 | Élie Bouttier | |
108 | 1 | Élie Bouttier | Voici la conf uwsgi.ini : |
109 | 1 | Élie Bouttier | |
110 | 1 | Élie Bouttier | <pre> |
111 | 1 | Élie Bouttier | [uwsgi] |
112 | 1 | Élie Bouttier | |
113 | 1 | Élie Bouttier | uid = djadhere-prod |
114 | 1 | Élie Bouttier | gid = djadhere-prod |
115 | 1 | Élie Bouttier | |
116 | 1 | Élie Bouttier | chdir = /srv/djadhere/prod/app |
117 | 1 | Élie Bouttier | |
118 | 1 | Élie Bouttier | plugin=python3 |
119 | 1 | Élie Bouttier | module=djadhere.wsgi:application |
120 | 1 | Élie Bouttier | virtualenv = /srv/djadhere/prod/venv |
121 | 1 | Élie Bouttier | env=DJANGO_SETTINGS_MODULE=djadhere.local_settings |
122 | 1 | Élie Bouttier | |
123 | 1 | Élie Bouttier | uwsgi-socket=/srv/djadhere/prod/uwsgi.socket |
124 | 1 | Élie Bouttier | chmod-socket=660 |
125 | 1 | Élie Bouttier | |
126 | 1 | Élie Bouttier | pidfile=/srv/djadhere/prod/uwsgi.pid |
127 | 1 | Élie Bouttier | touch-reload = /srv/djadhere/prod/touch-to-reload |
128 | 1 | Élie Bouttier | |
129 | 1 | Élie Bouttier | logto=/srv/djadhere/prod/log/uwsgi.log |
130 | 1 | Élie Bouttier | logfile-chmod=400 |
131 | 1 | Élie Bouttier | logfile-chown=djadhere-prod:djadhere-prod |
132 | 1 | Élie Bouttier | |
133 | 1 | Élie Bouttier | vacuum=True |
134 | 1 | Élie Bouttier | </pre> |
135 | 1 | Élie Bouttier | |
136 | 1 | Élie Bouttier | Voici une partie de la configuration local de django (situé dans @app/djadhere/local_settings.py@) : |
137 | 1 | Élie Bouttier | |
138 | 1 | Élie Bouttier | <pre> |
139 | 1 | Élie Bouttier | from djadhere.settings import * |
140 | 1 | Élie Bouttier | |
141 | 1 | Élie Bouttier | from os.path import join |
142 | 1 | Élie Bouttier | |
143 | 1 | Élie Bouttier | |
144 | 1 | Élie Bouttier | BASE_DIR = '/srv/djadhere/prod/' |
145 | 1 | Élie Bouttier | |
146 | 1 | Élie Bouttier | SECRET_KEY = 'removed' |
147 | 1 | Élie Bouttier | |
148 | 1 | Élie Bouttier | DATABASES = { |
149 | 1 | Élie Bouttier | 'default': { |
150 | 1 | Élie Bouttier | 'ENGINE': 'django.db.backends.postgresql_psycopg2', |
151 | 1 | Élie Bouttier | 'NAME': 'djadhere_prod', |
152 | 1 | Élie Bouttier | 'USER': 'djadhere_prod', |
153 | 1 | Élie Bouttier | 'PASSWORD': 'removed', |
154 | 1 | Élie Bouttier | 'HOST': 'localhost', |
155 | 1 | Élie Bouttier | 'PORT': '', |
156 | 1 | Élie Bouttier | }, |
157 | 1 | Élie Bouttier | } |
158 | 1 | Élie Bouttier | |
159 | 1 | Élie Bouttier | DEBUG = False |
160 | 1 | Élie Bouttier | |
161 | 1 | Élie Bouttier | LOGGING = { |
162 | 1 | Élie Bouttier | 'version': 1, |
163 | 1 | Élie Bouttier | 'disable_existing_loggers': False, |
164 | 1 | Élie Bouttier | 'handlers': { |
165 | 1 | Élie Bouttier | 'file': { |
166 | 1 | Élie Bouttier | 'level': 'WARNING', |
167 | 1 | Élie Bouttier | 'class': 'logging.FileHandler', |
168 | 1 | Élie Bouttier | 'filename': join(BASE_DIR, 'log/debug.log'), |
169 | 1 | Élie Bouttier | }, |
170 | 1 | Élie Bouttier | 'mail_admins': { |
171 | 1 | Élie Bouttier | 'class': 'django.utils.log.AdminEmailHandler', |
172 | 1 | Élie Bouttier | 'level': 'ERROR', |
173 | 1 | Élie Bouttier | # But the emails are plain text by default - HTML is nicer |
174 | 1 | Élie Bouttier | 'include_html': True, |
175 | 1 | Élie Bouttier | }, |
176 | 1 | Élie Bouttier | }, |
177 | 1 | Élie Bouttier | 'loggers': { |
178 | 1 | Élie Bouttier | 'django.request': { |
179 | 1 | Élie Bouttier | 'handlers': ['file', 'mail_admins'], |
180 | 1 | Élie Bouttier | 'level': 'WARNING', |
181 | 1 | Élie Bouttier | 'propagate': True, |
182 | 1 | Élie Bouttier | }, |
183 | 1 | Élie Bouttier | }, |
184 | 1 | Élie Bouttier | } |
185 | 1 | Élie Bouttier | |
186 | 1 | Élie Bouttier | STATIC_ROOT = join(BASE_DIR, 'webdir/static') |
187 | 1 | Élie Bouttier | STATIC_URL = '/static/' |
188 | 1 | Élie Bouttier | |
189 | 1 | Élie Bouttier | MEDIA_ROOT = join(BASE_DIR, 'webdir/media') |
190 | 1 | Élie Bouttier | MEDIA_URL = '/media/' |
191 | 1 | Élie Bouttier | |
192 | 1 | Élie Bouttier | ALLOWED_HOSTS = [ 'adherents.tetaneutral.net' ] |
193 | 1 | Élie Bouttier | |
194 | 1 | Élie Bouttier | DEFAULT_FROM_EMAIL = 'noreply@tetaneutral.net' |
195 | 1 | Élie Bouttier | SERVER_EMAIL = 'djadhere <projet-web-at-lists.tetaneutral.net>' |
196 | 1 | Élie Bouttier | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' |
197 | 1 | Élie Bouttier | EMAIL_HOST = 'smtp' |
198 | 1 | Élie Bouttier | EMAIL_SUBJECT_PREFIX = "[PROD] " |
199 | 1 | Élie Bouttier | |
200 | 1 | Élie Bouttier | ADMINS = ( |
201 | 1 | Élie Bouttier | ('Prénom Nom', 'adresse mail'), |
202 | 1 | Élie Bouttier | ) |
203 | 1 | Élie Bouttier | </pre> |
204 | 1 | Élie Bouttier | |
205 | 1 | Élie Bouttier | Et le script d’easy update : |
206 | 1 | Élie Bouttier | |
207 | 1 | Élie Bouttier | <pre> |
208 | 1 | Élie Bouttier | #!/bin/bash |
209 | 1 | Élie Bouttier | |
210 | 1 | Élie Bouttier | cd ~/app |
211 | 1 | Élie Bouttier | git fetch |
212 | 1 | Élie Bouttier | git checkout master |
213 | 1 | Élie Bouttier | pip install --upgrade -r requirements.txt |
214 | 1 | Élie Bouttier | ./manage.py migrate |
215 | 3 | Élie Bouttier | ./manage.py collectstatic --noinput |
216 | 1 | Élie Bouttier | |
217 | 1 | Élie Bouttier | cd ~ |
218 | 1 | Élie Bouttier | chmod g+rX webdir -R |
219 | 1 | Élie Bouttier | touch touch-to-reload |
220 | 1 | Élie Bouttier | </pre> |