implement baikal

Reviewed-on: #1
Co-authored-by: Denis Nutiu <dnutiu@nuculabs.dev>
Co-committed-by: Denis Nutiu <dnutiu@nuculabs.dev>
This commit is contained in:
Denis-Cosmin Nutiu 2025-02-22 18:23:55 +00:00 committed by Denis-Cosmin Nutiu
parent 11bc038937
commit 708cffd759
22 changed files with 439 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

15
.idea/ansible-playbooks.iml generated Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.13" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/fresh-rss/templates" />
</list>
</option>
</component>
</module>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ansible-playbooks.iml" filepath="$PROJECT_DIR$/.idea/ansible-playbooks.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

164
sabre-dav/.gitignore vendored Normal file
View file

@ -0,0 +1,164 @@
# Created by https://www.gitignore.io/api/macos,python,ansible
# Edit at https://www.gitignore.io/?templates=macos,python,ansible
### Ansible ###
*.retry
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that dont work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Downloaded files
root@*
# End of https://www.gitignore.io/api/macos,python,ansible

8
sabre-dav/.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
sabre-dav/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13 (sabre-dav)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (sabre-dav)" project-jdk-type="Python SDK" />
</project>

8
sabre-dav/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/sabre-dav.iml" filepath="$PROJECT_DIR$/.idea/sabre-dav.iml" />
</modules>
</component>
</project>

17
sabre-dav/.idea/sabre-dav.iml generated Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (sabre-dav)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
</list>
</option>
</component>
</module>

6
sabre-dav/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

9
sabre-dav/Makefile Normal file
View file

@ -0,0 +1,9 @@
install:
sudo dnf install ansible
ansible-galaxy collection install community.general
ansible-galaxy collection install containers.podman
ansible-galaxy collection install ansible.posix
list-hosts:
ansible-inventory -i inventory.ini --list
run:
ansible-playbook -i inventory.ini playbook.yaml --ask-become-pass

BIN
sabre-dav/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

5
sabre-dav/inventory.ini Normal file
View file

@ -0,0 +1,5 @@
[nuculabs]
my-linux.box ansible_user=ansible
[local]
localhost

100
sabre-dav/playbook.yaml Normal file
View file

@ -0,0 +1,100 @@
- name: Install Baïkal server
hosts: nuculabs
become: true
become_method: sudo
vars_files:
- variables.yaml
tasks:
# Create necessary directories.
- name: "Create directories"
block:
- name: Create base directory
ansible.builtin.file:
path: "{{ baikal.base_directory }}"
state: directory
mode: "0755"
ignore_errors: true
- name: Create data directory
ansible.builtin.file:
path: "{{ baikal.base_directory }}/{{ baikal.data_directory }}"
state: directory
mode: "0755"
ignore_errors: true
- name: Create extensions directory
ansible.builtin.file:
path: "{{ baikal.base_directory }}/{{ baikal.config_directory }}"
state: directory
mode: "0755"
ignore_errors: true
# - name: Setup SELinux
# block:
# - name: Ensure Udica is installed
# ansible.builtin.package:
# name: udica
# state: present
# - name: Ensure container-selinux is installed
# ansible.builtin.package:
# name: container-selinux
# state: present
# - name: Copy baikal cil
# ansible.builtin.copy:
# src: ./templates/selinux/baikal.cil
# dest: /tmp/baikal.cil
# mode: "0644"
# - name: Load baikal CIL policy
# ansible.builtin.command:
# argv:
# - semodule
# - -i
# - /tmp/baikal.cil
# - /usr/share/udica/templates/base_container.cil
# - /usr/share/udica/templates/net_container.cil
# when: setup_selinux
- name: Setup Container
block:
- name: Ensure Podman is installed
ansible.builtin.package:
name: podman
state: present
- name: Pull image
containers.podman.podman_image:
name: "{{ baikal.container_image }}"
state: present
- name: "Copy container"
ansible.builtin.template:
src: ./templates/container/baikal.container.j2
dest: /etc/containers/systemd/baikal.container
mode: "0644"
- name: Reload systemd
ansible.builtin.command:
cmd: systemctl daemon-reload
- name: Stop service
ansible.builtin.systemd_service:
name: baikal.service
state: stopped
enabled: true
- name: Enable service
ansible.builtin.systemd_service:
name: baikal.service
state: started
enabled: true
- name: Setup firewall
block:
- name: Create firewalld service
ansible.builtin.template:
src: ./templates/firewall/baikal.xml.j2
dest: /etc/firewalld/services/baikal.xml
mode: "0644"
- name: Reload firewalld
ansible.builtin.command:
argv:
- firewall-cmd
- --reload
- name: Enable firewalld service
ansible.posix.firewalld:
service: baikal
state: enabled
permanent: true
immediate: true
offline: true
when: setup_firewall

11
sabre-dav/readme.md Normal file
View file

@ -0,0 +1,11 @@
# Self Hosted Baïkal server
Baïkal is a lightweight CalDAV+CardDAV server. It offers an extensive web interface with easy management of users,
address books and calendars. It is fast and simple to install and only needs a basic php capable server.
The data can be stored in a MySQL or a SQLite database.
It was tested on Fedora 41.
References:
- https://sabre.io/baikal/
- https://hub.docker.com/r/ckulka/baikal

View file

@ -0,0 +1,18 @@
[Unit]
Description=baikal
[Container]
Image={{ baikal.container_image }}
AutoUpdate=registry
PublishPort={{ baikal.port }}:80/tcp
Volume={{ baikal.base_directory }}/{{ baikal.data_directory }}:/var/www/baikal/Specific:Z
Volume={{ baikal.base_directory }}/{{ baikal.config_directory }}:/var/www/baikal/config:Z
Environment=MSMTPRC={{ baikal.mail }}
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Baikal Calendar</short>
<description>A lightweight CalDAV+CardDAV server.</description>
<port protocol="tcp" port="{{ baikal.port }}" />
</service>

View file

@ -0,0 +1,8 @@
(block freshrss
(blockinherit container)
(blockinherit restricted_net_container)
(allow process default_t (dir (setattr add_name write create)))
(allow process default_t (file (create)))
(allow process http_port_t (tcp_socket (name_bind)))
)

19
sabre-dav/variables.yaml Normal file
View file

@ -0,0 +1,19 @@
setup_selinux: true
setup_firewall: true # exposes the firewall ports
baikal:
container_image: "docker.io/ckulka/baikal:nginx"
port: 8069
base_directory: "/baikal"
data_directory: "data"
config_directory: "config"
mail: "" # note you will need to inline the following variables
# defaults
# auth on
# tls on
# tls_trust_file /etc/ssl/certs/ca-certificates.crt
# account default
# host <smtp host>
# port 587
# from baikal@example.com
# user <user>
# password <password>