diff --git a/README.md b/README.md index 7d69ac2..692d0a0 100644 --- a/README.md +++ b/README.md @@ -6,24 +6,24 @@ This role installs nmgfitness: https://gitea.caret.be/jens/nmgfitness Requirements ------------ -This role requires a database server to to be present where im can connect to +This role requires a database server to to be present where the django app can connect to Role Variables -------------- -- `im_admin_password`: required, password for 'admin' user for im -- `im_secret_key`: optional Secret Key for Django app, defaults to random 56char string recreated on every run (This will invalidated current open sessions) -- `im_user`: user running the app, defaults to 'im' (this user will be created) -- `im_home`: path to install the im app in, defaults to /home/im (this path will be created) -- `im_domain`: the domain this app will run on (Needed for django's ALLOWED_HOSTS), default localhost -- `im_db_name`: database name, defaults to 'im' -- `im_db_user`: database user, defaults to 'im' -- `im_db_password`: database password, defaults to '', (ignored for unix socket connection) -- `im_db_host`: database server, defaults to '/run/postgresql/' for local unix socket connection -- `im_db_port`: database port, defaults to 5432 (ignored for unix socket connection) -- `im_workers`: the number of gunicorn http worker threads (defaults to 4) -- `im_http_listen`: the ip address to bind to, change this to ip address of the host if you use a reverse proxy on a different host, defaults to localhost -- `im_http_port`: the http port to bind to, defaults to 80 +- `django_admin_password`: required, password for 'admin' user +- `django_secret_key`: optional Secret Key for Django app, defaults to random 56char string recreated on every run (This will invalidated current open sessions) +- `django_user`: user running the app, defaults to 'django' (this user will be created) +- `django_home`: path to install the djangoapp in, defaults to /home/django (this path will be created) +- `django_domain`: the domain this app will run on (Needed for django's ALLOWED_HOSTS), default localhost +- `django_db_name`: database name, defaults to 'django' +- `django_db_user`: database user, defaults to 'django' +- `django_db_password`: database password, defaults to '', (ignored for unix socket connection) +- `django_db_host`: database server, defaults to '/run/postgresql/' for local unix socket connection +- `django_db_port`: database port, defaults to 5432 (ignored for unix socket connection) +- `django_workers`: the number of gunicorn http worker threads (defaults to 4) +- `django_http_listen`: the ip address to bind to, change this to ip address of the host if you use a reverse proxy on a different host, defaults to localhost +- `django_http_port`: the http port to bind to, defaults to 80 Dependencies ------------ @@ -36,24 +36,30 @@ Example Playbook - name: "Install im pantry app" hosts: im roles: - - ansible-role-nmgfitness + - ansible-role-djangoapp vars: - - im_domain: "im.example.com" - - im_http_listen: "{{inventory_hostname}}" - - im_admin_password: "test" + - django_domain: "im.example.com" + - django_http_listen: "{{inventory_hostname}}" + - django_admin_password: "test" + - django_app_releaseurl: "https://gitea.caret.be/jens/im/archive/main.tar.gz" ``` ```yaml - name: "Install im pantry app" hosts: im roles: - - ansible-role-im + - ansible-role-djangoapp vars: - - im_domain: "im.example.com" - - im_admin_email: "im@example.com" - - im_http_listen: "192.168.1.112" - - im_http_port: 8000 - - im_admin_password: !vault | + - django_appname: "im" + - django_domain: "im.example.com" + - django_admin_email: "im@example.com" + - django_http_listen: "{{inventory_hostname}}" + - django_http_listen: "192.168.1.112" + - django_http_port: 8000 + # needs to be a tar.gz for now + # needs to have a settings_template.py.j2 file in the django_appname folder + - django_app_releaseurl: "https://gitea.caret.be/jens/im/archive/main.tar.gz" + - django_admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 33366337663233346138373232353438613362636634393334613935303466343238646361613037 3738623833643738636162303362383665646132616362320a366338313363356634636534653932 diff --git a/defaults/main.yml b/defaults/main.yml index c2ca67a..ef8521a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,16 +1,18 @@ --- -# defaults file for im -im_home: /home/im -im_secret_key: "{{ lookup('password', im_home + '/.imsecretfile chars=ascii_letters length=56') }}" -im_domain: 'localhost' -im_db_name: 'im' -im_db_user: 'im' -im_user: 'im' -im_db_server: '/run/postgresql/' -im_db_port: '5432' -im_db_password: '' -im_workers: 4 -im_http_listen: 'localhost' -im_http_port: 80 -im_admin_email: root@localhost -im_mail_server: 'localhost' +# defaults file for django +django_home: /home/django +django_secret_key: "{{ lookup('password', django_home + '/.djangosecretfile chars=ascii_letters length=56') }}" +django_domain: 'localhost' +django_db_name: 'django' +django_appname: 'django' +django_db_user: 'django' +django_user: 'django' +django_group: 'django' +django_db_server: '/run/postgresql/' +django_db_port: '5432' +django_db_password: '' +django_workers: 4 +django_http_listen: 'localhost' +django_http_port: 80 +django_admin_email: root@localhost +django_mail_server: 'localhost' diff --git a/handlers/main.yml b/handlers/main.yml index 306c8e5..b2de546 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,13 +1,14 @@ --- -# handlers file for im -- name: "Restart im" - service: - name: im - state: restarted - when: ansible_service_mgr == "systemd" - - +# handlers file for djangoapp - name: "Reload systemd" systemd: daemon_reload: true when: ansible_service_mgr == "systemd" + +- name: "Restart djangapp" + service: + name: {{ django_appname }} + state: restarted + when: ansible_service_mgr == "systemd" + + diff --git a/templates/settings.py.j2 b/settings_template.py.j2 similarity index 84% rename from templates/settings.py.j2 rename to settings_template.py.j2 index 5e45598..bc63030 100644 --- a/templates/settings.py.j2 +++ b/settings_template.py.j2 @@ -1,10 +1,13 @@ """ -Django settings for im project. +Example settings file for djangoapp ansible role Generated by 'django-admin startproject' using Django 2.1.1. +edited for template by jens + For more information on this file, see https://docs.djangoproject.com/en/2.1/topics/settings/ +https://gitea.caret.be/jens/ansible-role-djangoapp/ For the full list of settings and their values, see https://docs.djangoproject.com/en/2.1/ref/settings/ @@ -20,13 +23,13 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '{{im_secret_key}}' +SECRET_KEY = '{{django_secret_key}}' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False ALLOWED_HOSTS = [ - '{{im_domain}}' + '{{django_domain}}' ] @@ -40,9 +43,8 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'nmgfitness', + '{{ django_appname }}', 'bootstrap4', - ] MIDDLEWARE = [ @@ -56,12 +58,12 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -ROOT_URLCONF = 'nmgfitness.urls' +ROOT_URLCONF = '{{ django_appname }}.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': ['nmgfitness'], + 'DIRS': ['{{ django_appname }}'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -74,7 +76,7 @@ TEMPLATES = [ }, ] -WSGI_APPLICATION = 'nmgfitness.wsgi.application' +WSGI_APPLICATION = '{{ django_appname }}.wsgi.application' # Database @@ -83,11 +85,11 @@ WSGI_APPLICATION = 'nmgfitness.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': '{{im_db_name}}', - 'USER': '{{im_db_user}}', - 'PASSWORD': '{{im_db_password}}', - 'HOST': '{{im_db_server}}', - 'PORT': '{{im_db_port}}', + 'NAME': '{{django_db_name}}', + 'USER': '{{django_db_user}}', + 'PASSWORD': '{{django_db_password}}', + 'HOST': '{{django_db_server}}', + 'PORT': '{{django_db_port}}', } } @@ -98,7 +100,7 @@ LOGGING = { 'file': { 'level': 'DEBUG', 'class': 'logging.FileHandler', - 'filename': '{{im_home}}/im_debug.log', + 'filename': '{{django_home}}/{{ django_appname }}_debug.log', }, }, 'loggers': { diff --git a/tasks/main.yml b/tasks/main.yml index 027cd77..da69534 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,5 +1,5 @@ --- -# tasks file for im +# tasks file for django - name: 'install dependencies' package: name: @@ -16,95 +16,103 @@ name: - bootstrap4 -- name: 'Create im user' +- name: 'Create django user' user: - name: "{{ im_user }}" - comment: "im user" - home: "{{ im_home }}" + name: "{{ django_user }}" + comment: "django user" + home: "{{ django_home }}" shell: "/bin/false" -- name: 'download latest im stable' +- name: 'download latest stable version of the app' get_url: - dest: "{{im_home}}/im-latest.tar.gz" - url: https://gitea.caret.be/jens/nmgfitness/archive/main.tar.gz - owner: im - group: im + dest: "{{ django_home }}/latest.tar.gz" + url: "{{ django_app_releaseurl }}" + owner: "{{ django_user }}" + group: "{{ django_group }}" mode: '0400' force: true - name: 'remove previous install stable' file: - dest: "{{im_home}}/nmgfitness" + dest: "{{django_home}}/{{ django_appname }}" state: absent -- name: 'unarchive latest im stable' +- name: 'unarchive latest stable' unarchive: - src: "{{im_home}}/im-latest.tar.gz" + src: "{{django_home}}/latest.tar.gz" remote_src: yes - dest: "{{ im_home }}" - owner: im - group: im - notify: "Restart im" + dest: "{{ django_home }}" + owner: "{{ django_user }}" + group: "{{ django_group }}" + notify: "Restart djangoapp" + + +- name: 'install pip dependencies' + pip: + requirements: '{{ django_home }}/{{ django_appname }}/requirements.txt' + notify: "Restart djangoapp" + - name: "Setup systemd service" template: - src: im.service.j2 - dest: /lib/systemd/system/im.service + src: djangoapp.service.j2 + dest: "/lib/systemd/system/{{ django_appname }}.service" owner: root group: root mode: 0644 notify: - "Reload systemd" - - "Restart im" + - "Restart djangoapp" when: ansible_service_mgr == "systemd" -- name: "Configure im" +- name: "Configure djangoapp" template: - src: "settings.py.j2" - dest: "{{im_home}}/nmgfitness/nmgfitness/settings.py" - owner: "{{ im_user }}" + src: "{{ django_appname }}/settings_template.py.j2" + dest: "{{django_home }}/{{ django_appname }}/settings.py" + owner: "{{ django_user }}" + group: "{{ django_group }}" mode: 0600 - notify: "Restart im" + notify: "Restart djangoapp" -- name: 'migrate django im app' +- name: 'migrate django app' django_manage: command: migrate - app_path: "{{im_home}}/nmgfitness" + app_path: "{{django_home }}/{{ django_appname }}/" become: true - become_user: "{{im_user}}" + become_user: "{{ django_user }}" - name: check if django superuser exists django_manage: command: 'shell -c "from django.contrib.auth.models import User; print(User.objects.filter(is_superuser=True).exists())"' - app_path: "{{im_home}}/nmgfitness" + app_path: "{{django_home }}/{{ django_appname }}/" register: superuser_exists become: true - become_user: "{{im_user}}" + become_user: "{{ django_user }}" -- name: "create superjuser for django im app if it doesn't exist" +- name: "create superjuser for django app if it doesn't exist" django_manage: - command: "createsuperuser --noinput --username=admin --email={{im_admin_email}}" - app_path: "{{im_home}}/nmgfitness" + command: "createsuperuser --noinput --username=admin --email={{django_admin_email}}" + app_path: "{{django_home }}/{{ django_appname }}/" become: true - become_user: "{{im_user}}" + become_user: "{{ django_user }}" when: superuser_exists.out.find("True") == -1 -- name: "set superjuser password" +- name: "set superuser password" django_manage: command: shell -c "from django.contrib.auth.models import User; usr = User.objects.get(username='admin'); usr.set_password('{{im_admin_password}}'); usr.save()" - app_path: "{{im_home}}/nmgfitness" + app_path: "{{django_home }}/{{ django_appname }}/" become: true - become_user: "{{im_user}}" + become_user: "{{ django_user }}" - name: 'collect static content' django_manage: command: "collectstatic" - app_path: "{{im_home}}/nmgfitness" + app_path: "{{django_home }}/{{ django_appname }}/" -- name: "Service im" +- name: "Service djangoapp" service: - name: im + name: "{{ django_appname }}" state: started enabled: true when: ansible_service_mgr == "systemd" diff --git a/templates/djangoapp.service.j2 b/templates/djangoapp.service.j2 new file mode 100644 index 0000000..654e556 --- /dev/null +++ b/templates/djangoapp.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=ansible managed {{ django_appname }} server trought gunicorn +After=network.target + +[Service] +User=root +WorkingDirectory={{ django_home }}/{{ django_appname }} +ExecStart=gunicorn -g={{ django_group }} -u={{django_user }} --workers {{django_workers}} --bind {{ django_http_listen }}:{{ django_http_port }} {{ django_appname }}.wsgi:application +Restart=on-failure + + +[Install] +WantedBy=multi-user.target diff --git a/templates/im.service.j2 b/templates/im.service.j2 deleted file mode 100644 index c7776a9..0000000 --- a/templates/im.service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=im pantry inventory management server trought gunicorn -After=network.target - -[Service] -User=root -WorkingDirectory={{ im_home }}/nmgfitness -ExecStart=gunicorn -g={{im_user}} -u={{im_user}} --workers {{im_workers}} --bind {{ im_http_listen }}:{{ im_http_port }} nmgfitness.wsgi:application -Restart=on-failure - - -[Install] -WantedBy=multi-user.target diff --git a/tests/test.yml b/tests/test.yml index b6374d5..f4de9c2 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -2,4 +2,4 @@ - hosts: localhost remote_user: root roles: - - im \ No newline at end of file + - djangoapp diff --git a/vars/main.yml b/vars/main.yml index 0db7686..b997ac9 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,3 +1,3 @@ --- -# vars file for im +# vars file for djangoapp