mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00

Recursive remote copy is supported starting with 2.8 only Indentation behaviour in literal yaml strings seems to have changed Regex logic for ImageMagic was flawed (no idea why this worked before)
387 lines
13 KiB
YAML
387 lines
13 KiB
YAML
---
|
|
- name: verify operating system
|
|
fail:
|
|
msg: Sorry, only Debian and Ubuntu supported at the moment.
|
|
when: not(ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu')
|
|
|
|
- name: install base dependencies
|
|
apt:
|
|
update_cache: yes
|
|
pkg:
|
|
# paperless-ng
|
|
- python3-dev
|
|
- python3-pip
|
|
- imagemagick
|
|
- unpaper
|
|
- ghostscript
|
|
- optipng
|
|
- tesseract-ocr
|
|
- gnupg
|
|
- libpoppler-cpp-dev
|
|
- libmagic-dev
|
|
- libpq-dev
|
|
# OCRmyPDF
|
|
- icc-profiles-free
|
|
- qpdf
|
|
- liblept5
|
|
- libxml2
|
|
- pngquant
|
|
- zlib1g
|
|
# dev
|
|
- sudo
|
|
- build-essential
|
|
- python3-setuptools
|
|
- python3-wheel
|
|
- python3-virtualenv
|
|
|
|
- name: install ocr languages
|
|
apt:
|
|
pkg: "{{ paperlessng_ocr_languages | map('regex_replace', '^(.*)$', 'tesseract-ocr-\\1') | list }}"
|
|
|
|
- name: set up notesalexp repository key (for jbig2enc)
|
|
apt_key:
|
|
url: https://notesalexp.org/debian/alexp_key.asc
|
|
state: present
|
|
when: paperlessng_use_jbig2enc
|
|
|
|
- name: set up notesalexp repository (for jbig2enc)
|
|
apt_repository:
|
|
repo: "deb https://notesalexp.org/debian/{{ ansible_distribution_release }}/ {{ ansible_distribution_release }} main"
|
|
state: present
|
|
when: paperlessng_use_jbig2enc
|
|
|
|
- name: set up notesalexp repository pinning
|
|
copy:
|
|
content: |
|
|
Package: *
|
|
Pin: release o=notesalexp.org
|
|
Pin-Priority: 1
|
|
|
|
Package: jbig2enc
|
|
Pin: release o=notesalexp.org
|
|
Pin-Priority: 500
|
|
dest: /etc/apt/preferences.d/notesalexp
|
|
when: paperlessng_use_jbig2enc
|
|
|
|
- name: install jbig2enc
|
|
apt:
|
|
pkg: jbig2enc
|
|
update_cache: yes
|
|
when: paperlessng_use_jbig2enc
|
|
|
|
- name: install redis
|
|
apt:
|
|
pkg: redis-server
|
|
when: paperlessng_redis_host == 'localhost' or paperlessng_redis_host == '127.0.0.1'
|
|
|
|
- name: enable redis
|
|
systemd:
|
|
name: redis-server
|
|
enabled: yes
|
|
masked: no
|
|
state: started
|
|
when: paperlessng_redis_host == 'localhost' or paperlessng_redis_host == '127.0.0.1'
|
|
|
|
- name: create paperless system group
|
|
group:
|
|
name: "{{ paperlessng_system_group }}"
|
|
|
|
- name: create paperless system user
|
|
user:
|
|
name: "{{ paperlessng_system_user }}"
|
|
groups:
|
|
- "{{ paperlessng_system_group }}"
|
|
shell: /usr/sbin/nologin
|
|
# GNUPG_HOME required due to paperless db.py
|
|
create_home: yes
|
|
|
|
- name: check for paperless-ng installation
|
|
command:
|
|
cmd: 'grep -Po "(?<=Paperless-ng )\d+\.\d+\.\d+" {{ paperlessng_directory }}/docs/changelog.html'
|
|
changed_when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
failed_when: false
|
|
ignore_errors: yes
|
|
register: paperlessng_current_version
|
|
|
|
- name: backup current paperless-ng installation
|
|
copy:
|
|
src: "{{ paperlessng_directory }}"
|
|
remote_src: yes
|
|
dest: "{{ paperlessng_directory }}-{{ ansible_date_time.iso8601 }}/"
|
|
when: '"No such file or directory" not in paperlessng_current_version.stderr and paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: create temporary directory
|
|
tempfile:
|
|
state: directory
|
|
register: tempdir
|
|
when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: extract paperless-ng
|
|
unarchive:
|
|
src: "https://github.com/jonaswinkler/paperless-ng/releases/download/ng-{{ paperlessng_version }}/paperless-ng-{{ paperlessng_version }}.tar.xz"
|
|
remote_src: yes
|
|
dest: "{{ tempdir.path }}"
|
|
when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: change owner and permissions of paperless-ng
|
|
command:
|
|
cmd: "{{ item }}"
|
|
warn: false
|
|
with_items:
|
|
- "chown -R {{ paperlessng_system_user }}:{{ paperlessng_system_group }} {{ tempdir.path }}"
|
|
- "find {{ tempdir.path }} -type d -exec chmod 0750 {} ;"
|
|
- "find {{ tempdir.path }} -type f -exec chmod 0640 {} ;"
|
|
when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: move paperless-ng
|
|
command:
|
|
cmd: "cp -a {{ tempdir.path }}/paperless-ng/ {{ paperlessng_directory }}"
|
|
when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: remove temporary directory
|
|
file:
|
|
path: "{{ tempdir.path }}"
|
|
state: absent
|
|
when: '"No such file or directory" in paperlessng_current_version.stderr or paperlessng_current_version.stdout != paperlessng_version | string'
|
|
|
|
- name: create paperless-ng directories and set permissions
|
|
file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
owner: "{{ paperlessng_system_user }}"
|
|
group: "{{ paperlessng_system_group }}"
|
|
mode: "750"
|
|
with_items:
|
|
- "{{ paperlessng_directory }}" # ansible `copy:` does not set correct permissions on `dest:` for recursive copies
|
|
- "{{ paperlessng_consumption_dir }}"
|
|
- "{{ paperlessng_data_dir }}"
|
|
- "{{ paperlessng_media_root }}"
|
|
- "{{ paperlessng_static_dir }}"
|
|
|
|
- name: configure paperless-ng
|
|
lineinfile:
|
|
path: "{{ paperlessng_directory }}/paperless.conf"
|
|
regexp: "{{ item.regexp }}"
|
|
line: "{{ item.line }}"
|
|
with_items:
|
|
- regexp: "^#?PAPERLESS_REDIS="
|
|
line: "PAPERLESS_REDIS=redis://{{ paperlessng_redis_host }}:{{ paperlessng_redis_port }}"
|
|
- regexp: "^#?PAPERLESS_CONSUMPTION_DIR="
|
|
line: "PAPERLESS_CONSUMPTION_DIR={{ paperlessng_consumption_dir }}"
|
|
- regexp: "^#?PAPERLESS_DATA_DIR="
|
|
line: "PAPERLESS_DATA_DIR={{ paperlessng_data_dir }}"
|
|
- regexp: "^#?PAPERLESS_MEDIA_ROOT="
|
|
line: "PAPERLESS_MEDIA_ROOT={{ paperlessng_media_root }}"
|
|
- regexp: "^#?PAPERLESS_STATICDIR="
|
|
line: "PAPERLESS_STATICDIR={{ paperlessng_static_dir }}"
|
|
- regexp: "^#?PAPERLESS_FILENAME_FORMAT="
|
|
line: "PAPERLESS_FILENAME_FORMAT={{ paperlessng_filename_format }}"
|
|
- regexp: "^#?PAPERLESS_OCR_LANGUAGE="
|
|
line: "PAPERLESS_OCR_LANGUAGE={{ paperlessng_ocr_languages | join('+') }}"
|
|
# - regexp: "^#PAPERLESS_OCR_USER_ARG="
|
|
# # TODO JSON dict required in conf
|
|
# # https://paperless-ng.readthedocs.io/en/latest/configuration.html#ocr-settings
|
|
# line: "PAPERLESS_OCR_USER_ARG=\"{{ paperlessng_ocrmypdf_args }}{{ ' --jbig2-lossy' if paperlessng_use_jbig2enc else '' }}\""
|
|
- regexp: "^#?PAPERLESS_TIME_ZONE="
|
|
line: "PAPERLESS_TIME_ZONE={{ paperlessng_time_zone }}"
|
|
no_log: true
|
|
|
|
- name: configure paperless-ng database [sqlite]
|
|
lineinfile:
|
|
path: "{{ paperlessng_directory }}/paperless.conf"
|
|
regexp: "^#?PAPERLESS_DBHOST="
|
|
state: absent
|
|
when: paperlessng_db_type == 'sqlite'
|
|
|
|
- name: configure paperless-ng database [postgresql]
|
|
lineinfile:
|
|
path: "{{ paperlessng_directory }}/paperless.conf"
|
|
regexp: "{{ item.regexp }}"
|
|
line: "{{ item.line }}"
|
|
with_items:
|
|
- regexp: "^#?PAPERLESS_DBHOST="
|
|
line: "PAPERLESS_DBHOST={{ paperlessng_db_host }}"
|
|
- regexp: "^#?PAPERLESS_DBPORT="
|
|
line: "PAPERLESS_DBPORT={{ paperlessng_db_port }}"
|
|
- regexp: "^#?PAPERLESS_DBNAME="
|
|
line: "PAPERLESS_DBNAME={{ paperlessng_db_name }}"
|
|
- regexp: "^#?PAPERLESS_DBUSER="
|
|
line: "PAPERLESS_DBUSER={{ paperlessng_db_user }}"
|
|
- regexp: "^#?PAPERLESS_DBPASS="
|
|
line: "PAPERLESS_DBPASS={{ paperlessng_db_pass }}"
|
|
when: paperlessng_db_type == 'postgresql'
|
|
no_log: true
|
|
|
|
- name: create paperlessng venv
|
|
become: yes
|
|
become_user: "{{ paperlessng_system_user }}"
|
|
command:
|
|
cmd: "python3 -m virtualenv {{ paperlessng_virtualenv }} -p /usr/bin/python3"
|
|
creates: "{{ paperlessng_virtualenv }}"
|
|
register: venv
|
|
|
|
- name: install paperlessng requirements
|
|
become: yes
|
|
become_user: "{{ paperlessng_system_user }}"
|
|
pip:
|
|
requirements: "{{ paperlessng_directory }}/requirements.txt"
|
|
executable: "{{ paperlessng_virtualenv }}/bin/pip3"
|
|
extra_args: --upgrade
|
|
when: paperlessng_current_version.stdout != paperlessng_version | string
|
|
|
|
- name: collect static files
|
|
become: yes
|
|
become_user: "{{ paperlessng_system_user }}"
|
|
command: "{{ paperlessng_virtualenv }}/bin/python3 manage.py collectstatic --no-input"
|
|
args:
|
|
chdir: "{{ paperlessng_directory }}/src"
|
|
when: paperlessng_current_version.stdout != paperlessng_version | string
|
|
register: static_files
|
|
changed_when: "'188 unmodified' not in static_files.stdout"
|
|
|
|
- name: create database schema
|
|
become: yes
|
|
become_user: "{{ paperlessng_system_user }}"
|
|
command: "{{ paperlessng_virtualenv }}/bin/python3 manage.py migrate"
|
|
args:
|
|
chdir: "{{ paperlessng_directory }}/src"
|
|
when: paperlessng_current_version.stdout != paperlessng_version | string
|
|
register: database_schema
|
|
changed_when: '"No migrations to apply." not in database_schema.stdout'
|
|
|
|
- name: configure paperless superuser
|
|
become: yes
|
|
become_user: "{{ paperlessng_system_user }}"
|
|
# "manage.py createsuperuser" only works on interactive TTYs
|
|
vars:
|
|
creation_script: |
|
|
from django.contrib.auth.models import User
|
|
from django.contrib.auth.hashers import get_hasher
|
|
|
|
if User.objects.filter(username='{{ paperlessng_superuser_name }}').exists():
|
|
user = User.objects.get(username='{{ paperlessng_superuser_name }}')
|
|
old = user.__dict__.copy()
|
|
|
|
user.is_superuser = True
|
|
user.email = '{{ paperlessng_superuser_email }}'
|
|
user.set_password('{{ paperlessng_superuser_password }}')
|
|
user.save()
|
|
new = user.__dict__
|
|
|
|
algorithm, iterations, old_salt, old_hash = old['password'].split('$')
|
|
new_password_old_salt = get_hasher(algorithm).encode(password='{{ paperlessng_superuser_password }}', salt=old_salt, iterations=int(iterations))
|
|
_, _, _, new_hash = new_password_old_salt.split('$')
|
|
if not (old_hash == new_hash and old['is_superuser'] == new['is_superuser'] and old['email'] == new['email']):
|
|
print('changed')
|
|
else:
|
|
User.objects.create_superuser('{{ paperlessng_superuser_name }}', '{{ paperlessng_superuser_email }}', '{{ paperlessng_superuser_password }}')
|
|
print('changed')
|
|
command: |
|
|
{{ paperlessng_virtualenv }}/bin/python3 manage.py shell -c "{{ creation_script }}"
|
|
args:
|
|
chdir: "{{ paperlessng_directory }}/src"
|
|
register: superuser
|
|
changed_when: superuser.stdout == 'changed'
|
|
no_log: true
|
|
|
|
- name: set ownership and permissions on paperlessng venv
|
|
file:
|
|
path: "{{ paperlessng_virtualenv }}"
|
|
state: directory
|
|
recurse: yes
|
|
owner: "{{ paperlessng_system_user }}"
|
|
group: "{{ paperlessng_system_group }}"
|
|
mode: g-w,o-rwx
|
|
when: venv.changed or paperlessng_current_version.stdout != paperlessng_version | string
|
|
|
|
- name: configure ghostscript for PDF
|
|
lineinfile:
|
|
path: /etc/ImageMagick-6/policy.xml
|
|
regexp: '(\s+)<policy domain="coder" rights=".*" pattern="PDF" />'
|
|
line: '\1<policy domain="coder" rights="read|write" pattern="PDF" />'
|
|
backrefs: yes
|
|
|
|
- name: configure systemd services
|
|
ini_file:
|
|
path: "{{ paperlessng_directory }}/scripts/{{ item[0] }}"
|
|
section: "{{ item[1].section }}"
|
|
option: "{{ item[1].option }}"
|
|
value: "{{ item[1].value }}"
|
|
with_nested:
|
|
- [
|
|
paperless-consumer.service,
|
|
paperless-scheduler.service,
|
|
paperless-webserver.service,
|
|
]
|
|
- [
|
|
{
|
|
section: "Service",
|
|
option: "User",
|
|
value: "{{ paperlessng_system_user }}",
|
|
},
|
|
{
|
|
section: "Service",
|
|
option: "Group",
|
|
value: "{{ paperlessng_system_group }}",
|
|
},
|
|
{
|
|
section: "Service",
|
|
option: "WorkingDirectory",
|
|
value: "{{ paperlessng_directory }}/src",
|
|
},
|
|
]
|
|
|
|
- name: configure paperless-consumer service
|
|
ini_file:
|
|
path: "{{ paperlessng_directory }}/scripts/paperless-consumer.service"
|
|
section: "Service"
|
|
option: "ExecStart"
|
|
value: "{{ paperlessng_virtualenv }}/bin/python3 manage.py document_consumer"
|
|
|
|
- name: configure paperless-scheduler service
|
|
ini_file:
|
|
path: "{{ paperlessng_directory }}/scripts/paperless-scheduler.service"
|
|
section: "Service"
|
|
option: "ExecStart"
|
|
value: "{{ paperlessng_virtualenv }}/bin/python3 manage.py qcluster"
|
|
|
|
- name: configure paperless-webserver service
|
|
ini_file:
|
|
path: "{{ paperlessng_directory }}/scripts/paperless-webserver.service"
|
|
section: "Service"
|
|
option: "ExecStart"
|
|
value: "{{ paperlessng_virtualenv }}/bin/gunicorn paperless.wsgi -w 2 -b {{ paperlessng_listen_address }}:{{ paperlessng_listen_port }}"
|
|
|
|
- name: copy systemd services
|
|
copy:
|
|
src: "{{ paperlessng_directory }}/scripts/{{ item }}"
|
|
remote_src: yes
|
|
dest: "/etc/systemd/system/{{ item }}"
|
|
with_items:
|
|
- paperless-consumer.service
|
|
- paperless-scheduler.service
|
|
- paperless-webserver.service
|
|
register: paperless_services
|
|
|
|
- name: reload systemd daemon
|
|
systemd:
|
|
name: "{{ item }}"
|
|
state: restarted
|
|
daemon_reload: yes
|
|
with_items:
|
|
- paperless-consumer
|
|
- paperless-scheduler
|
|
- paperless-webserver
|
|
when: paperless_services.changed
|
|
|
|
- name: enable paperlessng services
|
|
systemd:
|
|
name: "{{ item }}"
|
|
enabled: yes
|
|
masked: no
|
|
state: started
|
|
with_items:
|
|
- paperless-consumer
|
|
- paperless-scheduler
|
|
- paperless-webserver
|