Initial commit

This commit is contained in:
Laur Ivan 2023-06-09 15:41:22 +02:00
commit 6b3ad7f286
34 changed files with 722 additions and 0 deletions

10
.ansible-lint Normal file
View File

@ -0,0 +1,10 @@
---
exclude_paths:
- ./molecule
- ./.travis.yml
- ./.github
parseable: true
skip_list:
- '204'
use_default_rules: true
verbosity: 1

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.yml linguist-detectable=true
*.yaml linguist-detectable=true
*.html linguist-detectable=false

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: equinoxel
patreon: laurivan

49
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,49 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:**
[What you expect to happen]
**Actual behavior:**
[What actually happens]
**Reproduces how often:**
[What percentage of the time does it reproduce?]
### Environment
- The release version/s you are using:
- OS:
- Ansible Version:
- Python Version:
- Others:
### Additional Information
[Any additional information, configuration or data that might be necessary to reproduce the issue.]

3
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,3 @@
---
blank_issues_enabled: false

View File

@ -0,0 +1,31 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: enhancement
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Why is this needed?
[A clear and concise description of why do you think this is needed]
### Additional Information
[Any additional information, configuration or data.]

27
.github/ISSUE_TEMPLATE/refactor.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: Refactor
about: Found anything to refactor in this project?
title: "[REFACTOR]"
labels: clean-up
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Link/s to the specific code that needs a refactor (if applicable)
[Links]

View File

@ -0,0 +1,27 @@
---
name: Support Request
about: Support request or question about this project
title: "[SUPPORT]"
labels: question
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.

33
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,33 @@
---
issues:
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "pinned"
- "security"
- "good first issue"
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
pulls:
# Number of days of inactivity before a pull request becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale pull request is closed
daysUntilClose: 7
# Comment to post when marking a pull request as stale. Set to `false` to disable
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale pull request. Set to `false` to disable
closeComment: false

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
tests/playbook.retry
tests/.cache
__pycache__
.pytest_cache
.molecule
.cache
.venv
*.iml
.idea
.project
*.pyc
**/.vscode

25
.travis.yml Normal file
View File

@ -0,0 +1,25 @@
---
dist: xenial
language: python
python: "3.9"
os: linux
services:
- docker
install:
- pip install -I pipenv
- pipenv sync
env:
jobs:
- MOLECULE_DISTRO=debian:buster-slim
- MOLECULE_DISTRO=debian:bullseye-slim
script:
- pipenv run molecule test --all
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
email:
if: branch = main
on_success: change
on_failure: always
recipients:
- laur.ivan@gmail.com

33
.yamllint Normal file
View File

@ -0,0 +1,33 @@
---
# Based on ansible-lint config
extends: default
ignore: |
molecule/**/tests/
.venv
.github
.travis.yml
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
empty-lines:
max: 3
level: error
hyphens:
level: error
key-duplicates: enable
line-length: disable
new-lines:
type: unix
truthy: disable

18
CHANGELOG.md Normal file
View File

@ -0,0 +1,18 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a changelog](https://github.com/olivierlacan/keep-a-changelog).
## [Unreleased](https://github.com/equinoxel/ansible-role-calibre/tree/develop)
### Changed
### Added
### Removed
### Fixed
## [X.Y.Z](https://github.com/equinoxel/ansible-role-calibre/tree/X.Y.Z)
### [Full Changelog](https://github.com/equinoxel/ansible-role-calibre/compare/1.0.0...X.Y.Z)
### Changed
*[#<issue_number>](https://github.com/equinoxel/ansible-role-calibre/issues/<issue_number>) \<Change description\>* @\<author\>
## [1.0.0](https://github.com/equinoxel/ansible-role-calibre/tree/1.0.0)
- Initial release

10
LICENSE Normal file
View File

@ -0,0 +1,10 @@
The MIT License (MIT)
=====================
Copyright © 2023 Laur IVAN
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

47
README.md Normal file
View File

@ -0,0 +1,47 @@
# Calibre Ansible role
This role installs Calibre via Docker compose.
## Requirements
None
## Role Variables
All variables are listed below (see also `defaults/main.yml`).
```yml
---
```
## Dependencies
You need a machine with docker and docker-compose installed.
## Example Playbook
```yml
- hosts: servers
roles:
- 'laurivan.calibre'
```
## License
This project is licensed under the [MIT](https://opensource.org/licenses/MIT) license - see the [LICENSE](LICENSE) file for details.
![MIT License](https://img.shields.io/badge/license-MIT%20License-brightgreen)
## Author Information
This role was created in 2023 by [Laur Ivan](https://www.laurivan.com).
## Built With
![Ansible](https://img.shields.io/badge/ansible-5.2.0-green.svg)
![Molecule](https://img.shields.io/badge/molecule-3.4.0-green.svg)
![Goss](https://img.shields.io/badge/goss-0.3.16-green.svg)
## Contributing
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.

11
ansible.cfg Normal file
View File

@ -0,0 +1,11 @@
# Custom .cfg file
[defaults]
roles_path= ./cache/roles
collections_path= ./cache/collections
host_key_checking = false
[privilege_escalation]
become = false
[ssh_connection]
pipelining = True

40
defaults/main.yml Normal file
View File

@ -0,0 +1,40 @@
---
## General
calibre_image: lscr.io/linuxserver/calibre-web:latest
calibre_http_port: 8083
# Calibre paths
calibre_root_path: /var/local
calibre_data_base: "{{ calibre_root_path }}/calibre"
calibre_config_path: "{{ calibre_root_path }}/conf/calibre"
# Calibre volumes
calibre_config_volume: "{{ calibre_data_base }}/calibre_config"
calibre_library_volume: "{{ calibre_data_base }}/calibre_library"
calibre_timezone: "Etc/UTC"
calibre_user_id:
calibre_group_id:
# Calibre-specific options
calibre_has_convertor: false
calibre_relax_oauth: true
# Add other paths here to make sure they're created automatically
#
calibre_skeleton_paths:
- "{{ calibre_config_path }}"
- "{{ calibre_config_volume }}"
- "{{ calibre_library_volume }}"
# Add more templates to be copied into the config
calibre_configuration_files:
- "docker-compose.yml"
- "env.calibre.conf"
# Documentation
calibre_documentation_link: "https://www.laurivan.com"

BIN
files/metadata.db Normal file

Binary file not shown.

2
handlers/main.yml Normal file
View File

@ -0,0 +1,2 @@
---
# Handlers for calibre

25
meta/main.yml Normal file
View File

@ -0,0 +1,25 @@
---
galaxy_info:
author: Laur Ivan (laur.ivan@gmail.com)
namespace: laurivan
role_name: calibre
description: Calibre Role
min_ansible_version: "2.4"
min_ansible_container_version: "2.4"
license: MIT
galaxy_tags:
- calibre
- ebook
- manager
platforms:
- name: Debian
versions:
- bullseye
- buster
- name: Ubuntu
versions:
- bionic
- focal
- jammy

View File

@ -0,0 +1,27 @@
---
- name: Clean up
hosts: all
gather_facts: true
tasks:
- name: "CALIBRE | Load the defaults."
ansible.builtin.include_vars:
dir: "../../defaults"
- name: "CALIBRE | Check if the docker-compose file exists."
ansible.builtin.stat:
path: "{{ calibre_config_path | expanduser | realpath }}/docker-compose.yml"
register: "docker_compose_file"
- name: "CALIBRE | Remove docker-compose."
community.docker.docker_compose:
project_src: "{{ calibre_config_path | expanduser | realpath }}/"
build: false
state: absent
when: "docker_compose_file.stat.exists"
become: false
- name: "CALIBRE | Remove the docker-compose file"
ansible.builtin.file:
path: "{{ calibre_config_path | expanduser | realpath }}/docker-compose.yml"
state: "absent"
when: "docker_compose_file.stat.exists"

View File

@ -0,0 +1,5 @@
---
- name: "CALIBRE | Converge"
hosts: "calibre_group"
roles:
- role: "laurivan.calibre"

View File

@ -0,0 +1,27 @@
---
- name: "CALIBRE | Destroy"
hosts: "localhost"
connection: "local"
gather_facts: false
no_log: "{{ molecule_no_log }}"
tasks:
# Developer must implement.
- name: "CALIBRE | Remove the docker image"
community.docker.docker_container:
name: "calibre"
state: "absent"
# Mandatory configuration for Molecule to function.
- name: "CALIBRE | Populate instance config"
ansible.builtin.set_fact:
instance_conf: {}
- name: "CALIBRE | Dump instance config"
ansible.builtin.copy:
content: |
# Molecule managed
{{ instance_conf | to_json | from_json | to_yaml }}
dest: "{{ molecule_instance_config }}"
mode: 0600
when: "server.changed | default(false) | bool"

View File

@ -0,0 +1,38 @@
---
dependency:
name: galaxy
options:
ignore-certs: true
ignore-errors: true
role-file: molecule/requirements.yml
requirements-file: molecule/requirements.yml
driver:
name: docker
lint: |
yamllint .
ansible-lint .
platforms:
- name: calibre
groups:
- calibre_group
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos8}-ansible:latest"
privileged: true
pre_build_image: true
capabilities:
- SYS_ADMIN
tmpfs:
- /tmp
- /run
- /run/lock
volumes:
- '/sys/fs/cgroup:/sys/fs/cgroup:ro'
- '/var/run/docker.sock:/tmp/docker_mounted.sock'
- '/var/local:/var/local'
command: '/lib/systemd/systemd'
stop_signal: 'RTMIN+3'
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
verifier:
name: ansible

View File

@ -0,0 +1,45 @@
---
- name: "CALIBRE | Prepare dependencies"
hosts: "localhost"
tasks:
- name: "Run ansible-galaxy"
ansible.builtin.command: "ansible-galaxy install --force -r ../requirements.yml"
- name: "CALIBRE | Setup the test machine"
hosts: "calibre"
tasks:
- name: "CALIBRE | Check if /var/run/docker.sock already exists"
ansible.builtin.stat:
path: "/var/run/docker.sock"
register: "docker_sock_stat"
- name: "CALIBRE | Create docker.sock"
ansible.builtin.raw: touch /var/run/docker.sock
become: true
changed_when: false
when: "not docker_sock_stat.stat.exists"
- name: "CALIBRE | Move docker.sock from tmp"
ansible.builtin.raw: >
mount --move /tmp/docker_mounted.sock /var/run/docker.sock
become: true
changed_when: false
when: "not docker_sock_stat.stat.exists"
- name: "CALIBRE | Update apt cache."
ansible.builtin.apt: update_cache=yes cache_valid_time=600
when: "ansible_os_family == 'Debian'"
- name: "CALIBRE | Install python requests"
ansible.builtin.pip:
name:
- "requests"
- "docker"
- "docker-compose"
- name: "CALIBRE | Install docker"
vars:
docker_service_manage: false
ansible.builtin.include_role:
name: "geerlingguy.docker"

View File

@ -0,0 +1,12 @@
---
## TODO: Remember to adapt goss tests to your convenience
## Check if ports are really exposed
# port:
# # Check port at IPv6
# # https://github.com/aelsabbahy/goss/issues/177
# tcp6:<port>:
# listening: true
# ip:
# - '::'

View File

@ -0,0 +1,59 @@
---
# This is an example playbook to execute goss tests.
# Tests need distributed to the appropriate ansible host/groups
# prior to execution by `goss validate`.
- name: Verify calibre
hosts:
- "calibre"
become: true
vars:
goss_version: "v0.3.16"
goss_arch: "amd64"
goss_dst: "/usr/local/bin/goss"
goss_sha256sum: "827e354b48f93bce933f5efcd1f00dc82569c42a179cf2d384b040d8a80bfbfb"
goss_url: "https://github.com/aelsabbahy/goss/releases/download/{{ goss_version }}/goss-linux-{{ goss_arch }}"
goss_test_directory:" /tmp"
goss_format: "documentation"
vars_files:
- ../../defaults/main.yml
tasks:
- name: "CALIBRE | Download and install Goss"
get_url:
url: "{{ goss_url }}"
dest: "{{ goss_dst }}"
checksum: "sha256:{{ goss_sha256sum }}"
mode: 0755
register: "download_goss"
until: "download_goss is succeeded"
retries: 3
- name: "CALIBRE | Copy Goss tests to remote"
template:
src: "{{ item }}"
dest: "{{ goss_test_directory }}/{{ item | basename }}"
with_fileglob:
- "tests/test_*.yml"
- name: "CALIBRE | Register test files"
shell: "ls {{ goss_test_directory }}/test_*.yml"
register: "test_files"
- name: "CALIBRE | Execute Goss tests"
command: "{{ goss_dst }} -g {{ item }} validate --format {{ goss_format }}"
register: "test_results"
with_items: "{{ test_files.stdout_lines }}"
ignore_errors: true
- name: "CALIBRE | Display details about the Goss results"
debug:
msg: "{{ item.stdout_lines }}"
with_items: "{{ test_results.results }}"
- name: "CALIBRE | Fail when tests fail"
fail:
msg: "Goss failed to validate"
when: item.rc != 0
with_items: "{{ test_results.results }}"

View File

@ -0,0 +1,6 @@
---
roles:
- "geerlingguy.docker"
collections:
- "community.general"

34
tasks/config.yml Normal file
View File

@ -0,0 +1,34 @@
---
- name: "CALIBRE | Set up directories"
ansible.builtin.file:
state: directory
path: "{{ item }}"
owner: "{{ ansible_effective_user_id }}"
group: "{{ ansible_effective_group_id }}"
mode: "0755"
with_items:
- "{{ calibre_skeleton_paths }}"
tags:
- calibre_configure
become: true
- name: "CALIBRE | Write configuration files"
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "{{ calibre_config_path | expanduser | realpath }}/{{ item }}"
mode: '0640'
with_items:
- "{{ calibre_configuration_files }}"
tags:
- calibre_configure
- name: "CALIBRE | Copy default database"
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ calibre_config_volume | expanduser | realpath }}/{{ item }}"
mode: '0644'
with_items:
- "metadata.db"
tags:
- calibre_configure

7
tasks/install.yml Normal file
View File

@ -0,0 +1,7 @@
---
- name: "CALIBRE | Ensure calibre is running"
community.docker.docker_compose:
project_src: "{{ calibre_config_path | expanduser | realpath }}"
build: false
tags:
- calibre_install

11
tasks/main.yml Normal file
View File

@ -0,0 +1,11 @@
---
- name: "CALIBRE | Configure"
import_tasks: config.yml
tags:
- calibre_configure
- name: "CALIBRE | Install"
import_tasks: install.yml
tags:
- calibre_install

View File

@ -0,0 +1,21 @@
# calibre docker compose
version: '3.9'
services:
calibre:
image: "{{ calibre_image }}"
container_name: calibre-service
restart: always
env_file:
- "{{ calibre_config_path | expanduser }}/env.calibre.conf"
ports:
- "{{ calibre_http_port }}:8083"
# Add more ports if necessary
networks:
- calibre-net
# optional
volumes:
- "{{ calibre_config_volume }}:/config"
- "{{ calibre_library_volume }}:/books"
networks:
calibre-net: {}

View File

@ -0,0 +1,13 @@
# Add environment variables for calibre here
# Note: This is a .ini file format
{% if calibre_user_id is defined and calibre_user_id != "" %}PUID={{ calibre_user_id }}{%endif%}
{% if calibre_group_id is defined and calibre_group_id != "" %}GUID={{ calibre_group_id }}{%endif%}
TZ={{ calibre_timezone }}
{% if calibre_has_convertor == true %}
DOCKER_MODS=linuxserver/mods:universal-calibre #optional
{% endif %}
{% if calibre_relax_oauth == true %}
OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
{% endif %}

6
test-requirements.txt Normal file
View File

@ -0,0 +1,6 @@
ansible-core==2.15.0
ansible-compat==4.1.2
molecule==5.0.1
molecule-plugins[docker]==23.4.1
molecule[lint]==1.16.0
requests==2.28.1