Compare commits

...

8 Commits

44 changed files with 260 additions and 130 deletions

View File

@ -93,7 +93,7 @@ ansible-playbook -i /path/to/your/inventory/servers.tmp "$(pkgmgr path cymais)pl
--- ---
## Using a Vault Password File ## Using a Password File
To avoid entering your vault password interactively every time, use the `--vault-password-file` option: To avoid entering your vault password interactively every time, use the `--vault-password-file` option:
```bash ```bash

54
07_SECURITY.md Normal file
View File

@ -0,0 +1,54 @@
# Security
CyMaIS is designed with security in mind. However, while following our guidelines can greatly improve your systems security, no IT system can be 100% secure. Please report any vulnerabilities as soon as possible.
---
## For End Users
For optimal personal security, we **strongly recommend** the following:
- **Use a Password Manager**
Use a reliable password manager such as [KeePass](https://keepass.info/) 🔐. (Learn more about [password managers](https://en.wikipedia.org/wiki/Password_manager) on Wikipedia.) KeePass is available for both smartphones and PCs, and it can automatically generate strong, random passwords.
- **Enable Two-Factor Authentication (2FA)**
Always enable 2FA whenever possible. Many password managers (like KeePass) can generate [TOTP](https://en.wikipedia.org/wiki/Time-based_One-Time_Password) tokens, adding an extra layer of security even if your password is compromised.
Synchronize your password database across devices using the [Nextcloud Client](https://nextcloud.com/) 📱💻.
- **Use Encrypted Systems**
We recommend running CyMaIS only on systems with full disk encryption. For example, Linux distributions such as [Manjaro](https://manjaro.org/) (based on ArchLinux) with desktop environments like [GNOME](https://en.wikipedia.org/wiki/GNOME) provide excellent security. (Learn more about [disk encryption](https://en.wikipedia.org/wiki/Disk_encryption) on Wikipedia.)
- **Beware of Phishing and Social Engineering**
Always verify email senders, avoid clicking on unknown links, and never share your passwords or 2FA codes with anyone. (Learn more about [Phishing](https://en.wikipedia.org/wiki/Phishing) and [Social Engineering](https://en.wikipedia.org/wiki/Social_engineering_(security)) on Wikipedia.)
Following these guidelines will significantly enhance your personal security—but remember, no system is completely immune to risk.
---
## For Administrators
Administrators have additional responsibilities to secure the entire system:
- **Deploy on an Encrypted Server**
It is recommended to install CyMaIS on an encrypted server to prevent hosting providers from accessing end-user data. For a practical guide on setting up an encrypted server, refer to the [Hetzner Arch LUKS repository](https://github.com/kevinveenbirkenbach/hetzner-arch-luks) 🔐. (Learn more about [disk encryption](https://en.wikipedia.org/wiki/Disk_encryption) on Wikipedia.)
- **Centralized User Management & SSO**
For robust authentication and central user management, set up CyMaIS using Keycloak and LDAP.
This configuration enables centralized [Single Sign-On (SSO)](https://en.wikipedia.org/wiki/Single_sign-on) (SSO), simplifying user management and boosting security.
- **Enforce 2FA and Use a Password Manager**
Administrators should also enforce [2FA](https://en.wikipedia.org/wiki/Multi-factor_authentication) and use a password manager with auto-generated passwords. We again recommend [KeePass](https://keepass.info/). The KeePass database can be stored securely in your Nextcloud instance and synchronized between devices.
- **Avoid Root Logins & Plaintext Passwords**
CyMaIS forbids logging in via the root user or using simple passwords. Instead, an SSH key must be generated and transferred during system initialization. When executing commands as root, always use `sudo` (or, if necessary, `sudo su`—but only if you understand the risks). (More information on [SSH](https://en.wikipedia.org/wiki/Secure_Shell) and [sudo](https://en.wikipedia.org/wiki/Sudo) is available on Wikipedia.)
- **Manage Inventories Securely**
Your inventories for running CyMaIS should be managed in a separate repository and secured with tools such as [Ansible Vault](https://en.wikipedia.org/wiki/Encryption) 🔒. Sensitive credentials must never be stored in plaintext; use a password file to secure these details.
- **Reporting Vulnerabilities**
If you discover a security vulnerability in CyMaIS, please report it immediately. We encourage proactive vulnerability reporting so that issues can be addressed as quickly as possible. Contact our security team at [security@cymais.cloud](mailto:security@cymais.cloud)
**DO NOT OPEN AN ISSUE.**
---
By following these guidelines, both end users and administrators can achieve a high degree of security. Stay vigilant, keep your systems updated, and report any suspicious activity. Remember: while we strive for maximum security, no system is completely infallible.

12
Makefile Normal file
View File

@ -0,0 +1,12 @@
.PHONY: install deinstall refresh
install:
$(MAKE) -C sphinx html
$(MAKE) -C sphinx install
deinstall:
$(MAKE) -C sphinx clean
refresh:
$(MAKE) -C sphinx clean
$(MAKE) -C sphinx html

View File

@ -20,7 +20,7 @@ Backup Remote to Local is a robust solution for retrieving backup data from remo
- **Integration with Other Roles:** Works alongside roles like backup-directory-validator, cleanup-failed-docker-backups, systemd-timer, backups-provider, and system-maintenance-lock. - **Integration with Other Roles:** Works alongside roles like backup-directory-validator, cleanup-failed-docker-backups, systemd-timer, backups-provider, and system-maintenance-lock.
- **Administrative Debugging:** Detailed debug instructions and administrative tasks are provided in a separate file. - **Administrative Debugging:** Detailed debug instructions and administrative tasks are provided in a separate file.
## 📚 Other Resources ## Other Resources
- **Backup Scheme:** - **Backup Scheme:**
![backup scheme](https://www.veen.world/wp-content/uploads/2020/12/server-backup-768x567.jpg) ![backup scheme](https://www.veen.world/wp-content/uploads/2020/12/server-backup-768x567.jpg)

View File

@ -20,7 +20,7 @@ The purpose of this role is to enhance the security of your backup system by pro
- **Sudo Configuration:** Grants passwordless sudo rights for rsync, enabling secure and automated backup transfers. - **Sudo Configuration:** Grants passwordless sudo rights for rsync, enabling secure and automated backup transfers.
- **Integration:** Supports seamless integration with your backup infrastructure by limiting the backup user's permissions to only the required commands. - **Integration:** Supports seamless integration with your backup infrastructure by limiting the backup user's permissions to only the required commands.
## 📚 Other Resources ## Other Resources
For more details on how the role works and advanced configuration options, please see the related references below: For more details on how the role works and advanced configuration options, please see the related references below:
- [Ansible Playbooks Lookups](https://docs.ansible.com/ansible/latest/user_guide/playbooks_lookups.html#id3) - [Ansible Playbooks Lookups](https://docs.ansible.com/ansible/latest/user_guide/playbooks_lookups.html#id3)

View File

@ -23,5 +23,5 @@ The primary purpose of this role is to maintain optimal backup storage by automa
- **Systemd Integration:** Configures a systemd service to run cleanup tasks. - **Systemd Integration:** Configures a systemd service to run cleanup tasks.
- **Dependency Integration:** Works in conjunction with related roles for comprehensive backup management. - **Dependency Integration:** Works in conjunction with related roles for comprehensive backup management.
## 📚 Other Resources ## Other Resources
- https://stackoverflow.com/questions/48929553/get-hard-disk-size-in-python - https://stackoverflow.com/questions/48929553/get-hard-disk-size-in-python

View File

@ -21,6 +21,6 @@ The primary purpose of this role is to enable proper routing and connectivity fo
- **NAT Support:** Configures the external interface for proper masquerading. - **NAT Support:** Configures the external interface for proper masquerading.
- **Role Integration:** Depends on the [client-wireguard](../client-wireguard/README.md) role to ensure that WireGuard is properly configured before applying firewall rules. - **Role Integration:** Depends on the [client-wireguard](../client-wireguard/README.md) role to ensure that WireGuard is properly configured before applying firewall rules.
## 📚 Other Resources ## Other Resources
- https://gist.github.com/insdavm/b1034635ab23b8839bf957aa406b5e39 - https://gist.github.com/insdavm/b1034635ab23b8839bf957aa406b5e39
- https://wiki.debian.org/iptables - https://wiki.debian.org/iptables

View File

@ -22,7 +22,7 @@ The primary purpose of this role is to configure WireGuard on a client by settin
- **Administration Support:** For client key creation and further setup, please refer to the [Administration](./Administration.md) file. - **Administration Support:** For client key creation and further setup, please refer to the [Administration](./Administration.md) file.
- **Modular Design:** Easily integrates with other WireGuard roles or network configuration roles. - **Modular Design:** Easily integrates with other WireGuard roles or network configuration roles.
## 📚 Other Resources ## Other Resources
- [WireGuard Documentation](https://www.wireguard.com/) - [WireGuard Documentation](https://www.wireguard.com/)
- [ArchWiki: WireGuard](https://wiki.archlinux.org/index.php/WireGuard) - [ArchWiki: WireGuard](https://wiki.archlinux.org/index.php/WireGuard)

View File

@ -31,7 +31,7 @@ Variables are crucial in configuring your Akaunting setup. Ensure you set the fo
- **Nginx Configuration**: Necessary steps to configure Nginx as a reverse proxy for Akaunting. - **Nginx Configuration**: Necessary steps to configure Nginx as a reverse proxy for Akaunting.
- **Database and Runtime Environment**: Instructions on how to set up the `db.env` and `run.env` files for database and runtime configurations. - **Database and Runtime Environment**: Instructions on how to set up the `db.env` and `run.env` files for database and runtime configurations.
## 📚 Other Resources ## Other Resources
For more details, visit the [Akaunting Docker Repository](https://github.com/akaunting/docker) and the [Akaunting Forums](https://akaunting.com/forum). For more details, visit the [Akaunting Docker Repository](https://github.com/akaunting/docker) and the [Akaunting Forums](https://akaunting.com/forum).
## Contribution and Feedback ## Contribution and Feedback

View File

@ -2,7 +2,7 @@
This role allows the setup of [baserole](https://baserow.io/). This role allows the setup of [baserole](https://baserow.io/).
## 📚 Other Resources ## Other Resources
It was created with the help of [Chat GPT-4](https://chat.openai.com/share/556c2d7f-6b6f-4256-a646-a50529554efc). It was created with the help of [Chat GPT-4](https://chat.openai.com/share/556c2d7f-6b6f-4256-a646-a50529554efc).

View File

@ -6,7 +6,7 @@ Role to deploy [BigBlueButton](https://bigbluebutton.org/).
## SSO ## SSO
- https://docs.bigbluebutton.org/greenlight/v3/external-authentication/ - https://docs.bigbluebutton.org/greenlight/v3/external-authentication/
## 📚 Other Resources ## Other Resources
- https://github.com/bigbluebutton/docker - https://github.com/bigbluebutton/docker
- https://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials - https://docs.bigbluebutton.org/greenlight/gl-install.html#setting-bigbluebutton-credentials
- https://goneuland.de/big-blue-button-mit-docker-und-traefik-installieren/ - https://goneuland.de/big-blue-button-mit-docker-und-traefik-installieren/

View File

@ -1,7 +1,7 @@
# DRAFT role docker-bluesky # DRAFT role docker-bluesky
## 📚 Other Resources ## Other Resources
- https://therobbiedavis.com/selfhosting-bluesky-with-docker-and-swag/ - https://therobbiedavis.com/selfhosting-bluesky-with-docker-and-swag/
- Relevant for proxy configuration: https://cprimozic.net/notes/posts/notes-on-self-hosting-bluesky-pds-alongside-other-services/ - Relevant for proxy configuration: https://cprimozic.net/notes/posts/notes-on-self-hosting-bluesky-pds-alongside-other-services/
- https://github.com/bluesky-social/pds - https://github.com/bluesky-social/pds

View File

@ -13,7 +13,7 @@ Ensure you have the following:
- A central MariaDB instance running - A central MariaDB instance running
- Necessary permissions to manage Docker and database configurations - Necessary permissions to manage Docker and database configurations
## 📚 Other Resources ## Other Resources
- [Friendica Docker Hub](https://hub.docker.com/_/friendica) - [Friendica Docker Hub](https://hub.docker.com/_/friendica)
- [Friendica Installation Docs](https://wiki.friendi.ca/docs/install) - [Friendica Installation Docs](https://wiki.friendi.ca/docs/install)

View File

@ -2,5 +2,5 @@
This role doesn't work and needs to be implemented This role doesn't work and needs to be implemented
## 📚 Other Resources ## Other Resources
- https://docs.funkwhale.audio/installation/docker.html - https://docs.funkwhale.audio/installation/docker.html

View File

@ -1,5 +1,5 @@
# role docker-gitea # role docker-gitea
## 📚 Other Resources ## Other Resources
- [Gitea LDAP integration](https://docs.gitea.com/usage/authentication) - [Gitea LDAP integration](https://docs.gitea.com/usage/authentication)
- [Gitea Alternatives](https://chatgpt.com/share/67a5f599-c9b0-800f-87fe-49a3b61263e6) - [Gitea Alternatives](https://chatgpt.com/share/67a5f599-c9b0-800f-87fe-49a3b61263e6)

View File

@ -33,7 +33,7 @@ Include this role in your Ansible playbooks and specify the necessary variables.
For a detailed walkthrough and explanation of this role, refer to the conversation at [ChatGPT Session Transcript](https://chat.openai.com/share/1b0147bf-d4de-4790-b8ed-c332aa4e3ce3). For a detailed walkthrough and explanation of this role, refer to the conversation at [ChatGPT Session Transcript](https://chat.openai.com/share/1b0147bf-d4de-4790-b8ed-c332aa4e3ce3).
## 📚 Other Resources ## Other Resources
- https://ralph.blog.imixs.com/2019/06/09/running-gitlab-on-docker/ - https://ralph.blog.imixs.com/2019/06/09/running-gitlab-on-docker/
## Performance Optimation ## Performance Optimation

View File

@ -13,7 +13,7 @@ The role integrates Keycloak with PostgreSQL as a database and supports operatio
- Support for running behind a reverse proxy (e.g., NGINX). - Support for running behind a reverse proxy (e.g., NGINX).
- Automatic creation and management of Docker Compose files. - Automatic creation and management of Docker Compose files.
## 📚 Other Resources 📚 ## Other Resources 📚
For more details about Keycloak, check out: For more details about Keycloak, check out:
- [Official Keycloak Documentation](https://www.keycloak.org/) - [Official Keycloak Documentation](https://www.keycloak.org/)

View File

@ -11,7 +11,7 @@ This role deploys the Listmonk application using Docker. Listmonk is a high perf
- **docker-compose.yml**: Defines the Docker setup for Listmonk and its database. - **docker-compose.yml**: Defines the Docker setup for Listmonk and its database.
- **config.toml**: Contains the application settings including the database connection, admin credentials, and server settings. - **config.toml**: Contains the application settings including the database connection, admin credentials, and server settings.
## 📚 Other Resources ## Other Resources
- For detailed installation instructions and configuration options, visit the [Listmonk Installation Documentation](https://listmonk.app/docs/installation/). - For detailed installation instructions and configuration options, visit the [Listmonk Installation Documentation](https://listmonk.app/docs/installation/).
- You can also find more information on the [Listmonk GitHub Repository](https://github.com/knadh/listmonk/). - You can also find more information on the [Listmonk GitHub Repository](https://github.com/knadh/listmonk/).

View File

@ -7,7 +7,7 @@ This project provides a **Docker-based setup for Mastodon**, including full **OI
This README and some parts of the code were created with the assistance of ChatGPT. You can follow the discussion and evolution of this project in [this conversation](https://chatgpt.com/c/67a4e19b-3884-800f-9d45-621dda2a6572). This README and some parts of the code were created with the assistance of ChatGPT. You can follow the discussion and evolution of this project in [this conversation](https://chatgpt.com/c/67a4e19b-3884-800f-9d45-621dda2a6572).
## 📚 Other Resources ## Other Resources
- [Mastodon with Docker & Traefik](https://goneuland.de/mastodon-mit-docker-und-traefik-installieren/) - [Mastodon with Docker & Traefik](https://goneuland.de/mastodon-mit-docker-und-traefik-installieren/)
- [Mastodon Configuration Guide](https://gist.github.com/TrillCyborg/84939cd4013ace9960031b803a0590c4) - [Mastodon Configuration Guide](https://gist.github.com/TrillCyborg/84939cd4013ace9960031b803a0590c4)
- [Check Website Availability](https://www.2daygeek.com/linux-command-check-website-is-up-down-alive/) - [Check Website Availability](https://www.2daygeek.com/linux-command-check-website-is-up-down-alive/)

View File

@ -1,4 +1,4 @@
# role docker-mediawiki # role docker-mediawiki
## 📚 Other Resources ## Other Resources
This role was adapted to solve some deprecation message. Please test it before using productive. [See this conversation](https://chatgpt.com/share/6781487e-45fc-800f-a35e-e93f49448176). This role was adapted to solve some deprecation message. Please test it before using productive. [See this conversation](https://chatgpt.com/share/6781487e-45fc-800f-a35e-e93f49448176).

View File

@ -1,4 +1,4 @@
# role docker-moodle # role docker-moodle
## 📚 Other Resources ## Other Resources
- https://github.com/bitnami/containers/tree/main/bitnami/moodle - https://github.com/bitnami/containers/tree/main/bitnami/moodle

View File

@ -3,5 +3,5 @@
## Credits 📝 ## Credits 📝
This README was created with the assistance of ChatGPT, based on a conversation held at this [link](https://chat.openai.com/share/83828f9a-b817-48d8-86ed-599f64850b4d). ChatGPT provided guidance on structuring this document and outlining the key components of the Docker MyBB role. This README was created with the assistance of ChatGPT, based on a conversation held at this [link](https://chat.openai.com/share/83828f9a-b817-48d8-86ed-599f64850b4d). ChatGPT provided guidance on structuring this document and outlining the key components of the Docker MyBB role.
## 📚 Other Resources ## Other Resources
- https://github.com/mybb/docker - https://github.com/mybb/docker

View File

@ -157,7 +157,8 @@ SELECT * FROM `oc_appconfig` WHERE appid LIKE "%cospend%";
SELECT * FROM `oc_migrations` WHERE app LIKE "%cospend%"; SELECT * FROM `oc_migrations` WHERE app LIKE "%cospend%";
``` ```
# Identity and Access Management (IAM) # IAM
IAM(Identity and Access Management) is setup via Keycloak and LDAP.
## OpenID Connect (OIDC) Support 🔐 ## OpenID Connect (OIDC) Support 🔐

View File

@ -1,9 +1,9 @@
# Docker Nextcloud Role 🚀 # Nextcloud Server
This repository contains an Ansible role for deploying and managing [Nextcloud](https://nextcloud.com/) using [Docker](https://www.docker.com/). It covers configuration modifications, updates, backups, database management, and more. Additionally, OIDC (OpenID Connect) is supported (for example, via **Keycloak**). This repository contains an Ansible role for deploying and managing [Nextcloud](https://nextcloud.com/) using [Docker](https://www.docker.com/). It covers configuration modifications, updates, backups, database management, and more. Additionally, OIDC (OpenID Connect) is supported (for example, via **Keycloak**).
--- ---
## 📚 Other Resources ## Other Resources
- [Nextcloud Docker Example with Nginx Proxy, MariaDB, and FPM](https://github.com/nextcloud/docker/blob/master/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml) - [Nextcloud Docker Example with Nginx Proxy, MariaDB, and FPM](https://github.com/nextcloud/docker/blob/master/.examples/docker-compose/with-nginx-proxy/mariadb/fpm/docker-compose.yml)
- [Nextcloud Upgrade via Docker by Goneuland](https://goneuland.de/nextcloud-upgrade-auf-neue-versionen-mittels-docker/) - [Nextcloud Upgrade via Docker by Goneuland](https://goneuland.de/nextcloud-upgrade-auf-neue-versionen-mittels-docker/)

View File

@ -1,7 +1,7 @@
# docker peertube # docker peertube
## 📚 Other Resources ## Other Resources
- https://docs.joinpeertube.org/install-docker - https://docs.joinpeertube.org/install-docker
- https://github.com/Chocobozzz/PeerTube/issues/3091 - https://github.com/Chocobozzz/PeerTube/issues/3091
- [OIDC Plugin installation](https://chatgpt.com/c/67a4f448-4be8-800f-8639-4c15cb2fb44e) - [OIDC Plugin installation](https://chatgpt.com/c/67a4f448-4be8-800f-8639-4c15cb2fb44e)

View File

@ -1,6 +1,6 @@
# docker roulette-wheel # docker roulette-wheel
## 📚 Other Resources ## Other Resources
- https://github.com/p-wojt/roulette-wheel - https://github.com/p-wojt/roulette-wheel
- https://dev.to/ms314006/how-to-package-front-end-projects-into-docker-images-and-use-it-with-webpack-go3 - https://dev.to/ms314006/how-to-package-front-end-projects-into-docker-images-and-use-it-with-webpack-go3
- https://stackoverflow.com/questions/53178820/dockerfile-to-run-nodejs-static-content-in-docker-container - https://stackoverflow.com/questions/53178820/dockerfile-to-run-nodejs-static-content-in-docker-container

View File

@ -1,5 +1,5 @@
# role driver-epson-multiprinter # role driver-epson-multiprinter
## 📚 Other Resources ## Other Resources
- https://bernhardsteindl.at/epson-ecotank-et-3600-unter-arch-linux-einrichten/ - https://bernhardsteindl.at/epson-ecotank-et-3600-unter-arch-linux-einrichten/
- http://download.ebz.epson.net/dsc/search/01/search/searchModule - http://download.ebz.epson.net/dsc/search/01/search/searchModule
- https://aur.archlinux.org/packages/epson-inkjet-printer-escpr - https://aur.archlinux.org/packages/epson-inkjet-printer-escpr

View File

@ -12,7 +12,7 @@ The `main.yml` file in this role consists of tasks that automate the installatio
There are commented-out tasks for installing additional AUR packages, such as `aacskeys` and `libbdplus`, which can be enabled as per the user's requirements. There are commented-out tasks for installing additional AUR packages, such as `aacskeys` and `libbdplus`, which can be enabled as per the user's requirements.
## 📚 Other Resources and Resources ## Other Resources and Resources
For more in-depth information and guidance on Blu-ray playback and software configuration, the following resources can be consulted: For more in-depth information and guidance on Blu-ray playback and software configuration, the following resources can be consulted:
- [Arch Linux Wiki on Blu-ray](https://wiki.archlinux.org/title/Blu-ray#Using_aacskeys) - [Arch Linux Wiki on Blu-ray](https://wiki.archlinux.org/title/Blu-ray#Using_aacskeys)
- [Guide to Play Blu-ray with VLC](https://videobyte.de/play-blu-ray-with-vlc) - [Guide to Play Blu-ray with VLC](https://videobyte.de/play-blu-ray-with-vlc)

View File

@ -1,6 +1,6 @@
# collection-blu-ray-player # collection-blu-ray-player
## 📚 Other Resources ## Other Resources
- https://wiki.archlinux.org/title/Blu-ray#Using_aacskeys - https://wiki.archlinux.org/title/Blu-ray#Using_aacskeys
- https://videobyte.de/play-blu-ray-with-vlc - https://videobyte.de/play-blu-ray-with-vlc
- https://archived.forum.manjaro.org/t/wie-kann-ich-bluray-uhd-abspielen/127396/12 - https://archived.forum.manjaro.org/t/wie-kann-ich-bluray-uhd-abspielen/127396/12

View File

@ -24,7 +24,7 @@ The `pc-gnome` role includes several tasks for installing GNOME software, managi
6. **Execute CLI GNOME Extension Manager Script**: 6. **Execute CLI GNOME Extension Manager Script**:
- Runs the CLI GNOME Extension Manager script to manage GNOME extensions based on the `{{gnome_extensions}}` variable. - Runs the CLI GNOME Extension Manager script to manage GNOME extensions based on the `{{gnome_extensions}}` variable.
## 📚 Other Resources ## Other Resources
For additional details on managing GNOME extensions via command line, visit [Ask Ubuntu](https://askubuntu.com/questions/1029376/how-do-i-enable-and-disable-gnome-extensions-from-the-command-line). For additional details on managing GNOME extensions via command line, visit [Ask Ubuntu](https://askubuntu.com/questions/1029376/how-do-i-enable-and-disable-gnome-extensions-from-the-command-line).
## Dependencies ## Dependencies

View File

@ -28,6 +28,6 @@ For more detailed information on Jrnl and its functionalities, visit [Jrnl's off
## Contributing ## Contributing
Contributions to this role are welcome. Please adhere to standard coding conventions and best practices. Contributions to this role are welcome. Please adhere to standard coding conventions and best practices.
## 📚 Other Resources ## Other Resources
This role was created as part of a larger playbook. For more context on this role, you can refer to the related ChatGPT conversation [here](https://chat.openai.com/share/ae168ca0-5191-4bec-96a0-ffcfabca0024). This role was created as part of a larger playbook. For more context on this role, you can refer to the related ChatGPT conversation [here](https://chat.openai.com/share/ae168ca0-5191-4bec-96a0-ffcfabca0024).

View File

@ -9,7 +9,7 @@ The `main.yml` file in the `pc-video-conference` role includes tasks for setting
1. **Install Video Conference Software**: 1. **Install Video Conference Software**:
- Utilizes the `kewlfft.aur.aur` module with `yay` as the helper to install `zoom`, a popular video conferencing application. - Utilizes the `kewlfft.aur.aur` module with `yay` as the helper to install `zoom`, a popular video conferencing application.
## 📚 Other Resources ## Other Resources
- As noted, the Microsoft Teams client is no longer natively supported on Linux. For more information and potential workarounds, you can visit the [AUR package page for Teams](https://aur.archlinux.org/packages/teams). - As noted, the Microsoft Teams client is no longer natively supported on Linux. For more information and potential workarounds, you can visit the [AUR package page for Teams](https://aur.archlinux.org/packages/teams).
## Dependencies ## Dependencies

View File

@ -21,6 +21,6 @@ The primary purpose of this role is to establish a secure SSH environment by dep
- **Systemd Integration:** Automatically restarts the SSH service upon configuration changes. - **Systemd Integration:** Automatically restarts the SSH service upon configuration changes.
- **Security Enhancements:** Enforces secure defaults such as disabled root login and public key authentication. - **Security Enhancements:** Enforces secure defaults such as disabled root login and public key authentication.
## 📚 Other Resources ## Other Resources
- https://www.google.com/search?client=firefox-b-d&q=sshd+why+to+deactivate+pam - https://www.google.com/search?client=firefox-b-d&q=sshd+why+to+deactivate+pam
- https://man7.org/linux/man-pages/man5/sshd_config.5.html - https://man7.org/linux/man-pages/man5/sshd_config.5.html

View File

@ -20,5 +20,5 @@ The primary purpose of this role is to streamline AUR package management on Arch
- **User Creation:** Creates a dedicated `aur_builder` user. - **User Creation:** Creates a dedicated `aur_builder` user.
- **Sudo Configuration:** Grants passwordless sudo rights to `aur_builder` for pacman. - **Sudo Configuration:** Grants passwordless sudo rights to `aur_builder` for pacman.
## 📚 Other Resources ## Other Resources
- https://github.com/kewlfft/ansible-aur - https://github.com/kewlfft/ansible-aur

View File

@ -19,6 +19,6 @@ The primary purpose of this role is to provide a comprehensive solution for auto
- **Secure Notifications:** Integrates with systemd to trigger email alerts when services fail. - **Secure Notifications:** Integrates with systemd to trigger email alerts when services fail.
- **Suite Integration:** Part of the `systemd-notifier` suite, offering a unified approach to service failure notifications. - **Suite Integration:** Part of the `systemd-notifier` suite, offering a unified approach to service failure notifications.
## 📚 Other Resources ## Other Resources
This role was created as part of a conversation with OpenAI's ChatGPT and can be found [here](https://chat.openai.com/share/96e4ca12-0888-41c0-9cfc-29c0180f0dba). This role was created as part of a conversation with OpenAI's ChatGPT and can be found [here](https://chat.openai.com/share/96e4ca12-0888-41c0-9cfc-29c0180f0dba).

View File

@ -19,6 +19,6 @@ The primary purpose of this role is to provide a robust solution for automated T
- **Secure Notifications:** Leverages systemd to trigger alerts automatically when services fail. - **Secure Notifications:** Leverages systemd to trigger alerts automatically when services fail.
- **Suite Integration:** Part of the [`systemd-notifier` suite](../) which includes related roles such as [systemd-notifier-email](../systemd-notifier-email/README.md) and others. - **Suite Integration:** Part of the [`systemd-notifier` suite](../) which includes related roles such as [systemd-notifier-email](../systemd-notifier-email/README.md) and others.
## 📚 Other Resources ## Other Resources
This role was developed as part of a conversation with OpenAI's ChatGPT and can be found [here](https://chat.openai.com/share/96e4ca12-0888-41c0-9cfc-29c0180f0dba). This role was developed as part of a conversation with OpenAI's ChatGPT and can be found [here](https://chat.openai.com/share/96e4ca12-0888-41c0-9cfc-29c0180f0dba).

View File

@ -1,4 +1,4 @@
# Update Debian-based Systems # Update apt
## Description ## Description

View File

@ -1,4 +1,4 @@
# Update-Pacman Role # Update Pacman
## Description ## Description

View File

@ -1,4 +1,4 @@
# Update-Yay Role # Update yay
## Description ## Description

View File

@ -25,7 +25,7 @@
systemctl status wg-quick@wg0.cymais.service systemctl status wg-quick@wg0.cymais.service
``` ```
## 📚 Other Resources ## Other Resources
- https://golb.hplar.ch/2019/01/expose-server-vpn.html - https://golb.hplar.ch/2019/01/expose-server-vpn.html
- https://wiki.archlinux.org/index.php/WireGuard - https://wiki.archlinux.org/index.php/WireGuard
- https://wireguard.how/server/raspbian/ - https://wireguard.how/server/raspbian/

25
sphinx/README.md Normal file
View File

@ -0,0 +1,25 @@
# Documentation
CyMaIS uses [Sphinx](https://www.sphinx-doc.org/) to automatically generate its documentation and leverages the [Awesome Sphinx Theme](https://sphinxawesome.xyz/) for a sleek and responsive design. Enjoy a seamless, visually engaging experience 🚀✨.
## For Users
You can access the documentation [here](https://docs.cymais.cloud/) 🔗. Browse the latest updates and guides to get started.
## For Administrators
### Setup
#### On Localhost
To generate the documentation locally, run the following command:
```bash
pkgmgr shell cymais -c "make refresh"
```
This command cleans the previous build and generates the updated documentation. Once complete, you can view it at the output location (e.g., [templates/html/index.html](templates/html/index.html)) 👀💻.
#### On Server
In your inventory file, enable the **Sphinx** role. When activated, the documentation will be automatically generated and deployed under the **docs** subdomain of your CyMaIS instance. This ensures your documentation is always current and easily accessible 🔄🌐.

View File

@ -1,72 +1,127 @@
import os import os
import re
from sphinx.util import logging from sphinx.util import logging
from .nav_utils import natural_sort_key, extract_headings_from_file, group_headings, sort_tree, MAX_HEADING_LEVEL, DEFAULT_MAX_NAV_DEPTH from .nav_utils import extract_headings_from_file, MAX_HEADING_LEVEL
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def collect_subfolder_tree(dir_path, base_url, current_depth, max_depth): def collect_folder_tree(dir_path, base_url):
""" """
Recursively collects navigation items from subdirectories. Recursively collects the folder tree starting from the given directory.
For each subfolder, it looks for a candidate file (prefer "index.rst" then "README.md").
Only subfolders with such a file will be included. For each folder:
If a candidate is found, the first level1 heading from that file is used as the title; - Hidden folders (names starting with a dot) are skipped.
if no heading is found, the folder name is used. - A folder is processed only if it contains one of the representative files:
The link is built pointing directly to the candidate file (by its base name) rather than the folder. index.rst, index.md, readme.md, or readme.rst.
Returns a list representing the subfolder tree. - The first heading of the representative file is used as the folder title.
- The representative file is not listed as a file in the folder.
- All other Markdown and reStructuredText files are listed without sub-headings,
using their first heading as the file title.
""" """
items = [] # Skip hidden directories
if os.path.basename(dir_path).startswith('.'):
return None
# List all files in the current directory with .md or .rst extension
files = [f for f in os.listdir(dir_path)
if os.path.isfile(os.path.join(dir_path, f))
and (f.endswith('.md') or f.endswith('.rst'))]
# Find representative file for folder title using index or readme
rep_file = None
for candidate in ['index.rst', 'index.md', 'readme.md', 'readme.rst']:
for f in files:
if f.lower() == candidate:
rep_file = f
break
if rep_file:
break
# Skip this folder if no representative file exists
if not rep_file:
return None
rep_path = os.path.join(dir_path, rep_file)
headings = extract_headings_from_file(rep_path, max_level=MAX_HEADING_LEVEL)
folder_title = headings[0]['text'] if headings else os.path.basename(dir_path)
folder_link = os.path.join(base_url, os.path.splitext(rep_file)[0])
# Remove the representative file from the list to avoid duplication,
# and filter out any additional "readme.md" or "index.rst" files.
files.remove(rep_file)
files = [f for f in files if f.lower() not in ['readme.md', 'index.rst']]
# Process the remaining files in the current directory
file_items = []
for file in sorted(files, key=lambda s: s.lower()):
file_path = os.path.join(dir_path, file)
file_headings = extract_headings_from_file(file_path, max_level=MAX_HEADING_LEVEL)
file_title = file_headings[0]['text'] if file_headings else file
file_base = os.path.splitext(file)[0]
file_link = os.path.join(base_url, file_base)
file_items.append({
'level': 1,
'text': file_title,
'link': file_link,
'anchor': '',
'priority': 1,
'filename': file
})
# Process subdirectories (ignoring hidden ones)
dir_items = []
for item in sorted(os.listdir(dir_path), key=lambda s: s.lower()): for item in sorted(os.listdir(dir_path), key=lambda s: s.lower()):
full_path = os.path.join(dir_path, item) full_path = os.path.join(dir_path, item)
if os.path.isdir(full_path): if os.path.isdir(full_path) and not item.startswith('.'):
candidate = None subtree = collect_folder_tree(full_path, os.path.join(base_url, item))
for cand in ['index.rst', 'README.md']: if subtree:
candidate_path = os.path.join(full_path, cand) dir_items.append(subtree)
if os.path.isfile(candidate_path):
candidate = candidate_path # Combine files and subdirectories as children of the current folder
break children = file_items + dir_items
# Only include the folder if a candidate file was found.
if candidate: return {
headings = extract_headings_from_file(candidate, max_level=MAX_HEADING_LEVEL) 'text': folder_title,
title = headings[0]['text'] if headings else item 'link': folder_link,
# Use the candidate file's base name as link target. 'children': children,
candidate_base = os.path.splitext(os.path.basename(candidate))[0] 'filename': os.path.basename(dir_path)
link = os.path.join(base_url, item, candidate_base)
entry = {
'level': 1,
'text': title,
'link': link,
'anchor': '',
'priority': 0,
'filename': item
} }
if current_depth < max_depth:
children = collect_subfolder_tree(full_path, os.path.join(base_url, item), current_depth + 1, max_depth) def mark_current(node, active):
if children: """
entry['children'] = children Recursively mark nodes as current if the active page (pagename)
items.append(entry) matches the node's link or is a descendant of it.
return items
The function sets node['current'] = True if:
- The node's link matches the active page exactly, or
- The active page begins with the node's link plus a separator (indicating a child).
Additionally, if any child node is current, the parent is marked as current.
"""
is_current = False
node_link = node.get('link', '').rstrip('/')
active = active.rstrip('/')
if node_link and (active == node_link or active.startswith(node_link + '/')):
is_current = True
# Recurse into children if they exist
children = node.get('children', [])
for child in children:
if mark_current(child, active):
is_current = True
node['current'] = is_current
return is_current
def add_local_subfolders(app, pagename, templatename, context, doctree): def add_local_subfolders(app, pagename, templatename, context, doctree):
""" """
Collects a tree of subfolder navigation items from the current directory. Sets the 'local_subfolders' context variable with the entire folder tree
For each subfolder, the title is determined by scanning for a candidate file starting from app.srcdir, and marks the tree with the 'current' flag up
(prefer "index.rst" then "README.md") and extracting its first level1 heading, to the active page.
or using the folder name if none is found.
The resulting tree is stored in context['local_subfolders'].
""" """
srcdir = app.srcdir root_dir = app.srcdir
directory = os.path.dirname(pagename) folder_tree = collect_folder_tree(root_dir, '')
abs_dir = os.path.join(srcdir, directory) if folder_tree:
if not os.path.isdir(abs_dir): mark_current(folder_tree, pagename)
logger.warning(f"Directory {abs_dir} not found for page {pagename}.") context['local_subfolders'] = [folder_tree] if folder_tree else []
context['local_subfolders'] = []
return
max_nav_depth = getattr(app.config, 'local_nav_max_depth', DEFAULT_MAX_NAV_DEPTH)
subfolder_tree = collect_subfolder_tree(abs_dir, directory, current_depth=0, max_depth=max_nav_depth)
sort_tree(subfolder_tree)
context['local_subfolders'] = subfolder_tree
def setup(app): def setup(app):
app.connect('html-page-context', add_local_subfolders) app.connect('html-page-context', add_local_subfolders)

View File

@ -3,25 +3,16 @@ import re
import yaml import yaml
DEFAULT_MAX_NAV_DEPTH = 4 DEFAULT_MAX_NAV_DEPTH = 4
MAX_HEADING_LEVEL = 2 MAX_HEADING_LEVEL = 0 # This can be overridden in your configuration
def natural_sort_key(text): def natural_sort_key(text):
"""
Generate a key for natural (human-friendly) sorting,
taking numeric parts into account.
"""
return [int(c) if c.isdigit() else c.lower() for c in re.split(r'(\d+)', text)] return [int(c) if c.isdigit() else c.lower() for c in re.split(r'(\d+)', text)]
def extract_headings_from_file(filepath, max_level=MAX_HEADING_LEVEL): def extract_headings_from_file(filepath, max_level=MAX_HEADING_LEVEL):
""" # If max_level is 0, set it to a very high value to effectively iterate infinitely
Extract headings from a file. if max_level == 0:
For Markdown (.md) files, looks for lines starting with '#' (up to max_level). max_level = 9999
For reStructuredText (.rst) files, looks for a line immediately followed by an underline.
If no headings are found and the file is an index file while a README.md exists in the same folder,
it will try to extract headings from the README.md instead.
Returns a list of dictionaries with keys: 'level', 'text', and 'anchor' (if applicable).
"""
import os, re
headings = [] headings = []
ext = os.path.splitext(filepath)[1].lower() ext = os.path.splitext(filepath)[1].lower()
try: try:
@ -34,7 +25,8 @@ def extract_headings_from_file(filepath, max_level=MAX_HEADING_LEVEL):
continue continue
if in_code_block: if in_code_block:
continue continue
match = re.match(r'^(#{1,})\s+(.*)$', line) # Assuming markdown headings are defined with '#' characters
match = re.match(r'^(#{1,})(.*?)$', line)
if match: if match:
level = len(match.group(1)) level = len(match.group(1))
if level <= max_level: if level <= max_level:
@ -53,9 +45,6 @@ def extract_headings_from_file(filepath, max_level=MAX_HEADING_LEVEL):
headings.append({'level': level, 'text': heading_text, 'anchor': ''}) headings.append({'level': level, 'text': heading_text, 'anchor': ''})
except Exception as e: except Exception as e:
print(f"Warning: Error reading {filepath}: {e}") print(f"Warning: Error reading {filepath}: {e}")
# If no headings were found and the file is an index file,
# then try to load headings from a README.md in the same folder.
if not headings: if not headings:
base = os.path.basename(filepath).lower() base = os.path.basename(filepath).lower()
if base == 'index.rst': if base == 'index.rst':
@ -69,10 +58,6 @@ def extract_headings_from_file(filepath, max_level=MAX_HEADING_LEVEL):
return headings return headings
def group_headings(headings): def group_headings(headings):
"""
Convert a flat list of headings into a tree structure based on their level.
Each heading gets a 'children' list.
"""
tree = [] tree = []
stack = [] stack = []
for heading in headings: for heading in headings:
@ -87,13 +72,7 @@ def group_headings(headings):
return tree return tree
def sort_tree(tree): def sort_tree(tree):
"""
Sort a tree of navigation items, first by a 'priority' value (lower comes first)
and then by a natural sort key based on the 'filename' field (or the 'text' field if no filename is provided).
This ensures that 'index' and 'readme' (priority 0) always appear at the top.
"""
tree.sort(key=lambda x: (x.get('priority', 1), natural_sort_key(x.get('filename', x['text'])))) tree.sort(key=lambda x: (x.get('priority', 1), natural_sort_key(x.get('filename', x['text']))))
for item in tree: for item in tree:
if item.get('children'): if item.get('children'):
sort_tree(item['children']) sort_tree(item['children'])

View File

@ -1,19 +1,21 @@
{% macro render_headings(headings, level=1) %} {% macro render_headings(headings, level=1) %}
<ul class="toctree-l{{ level }}" style="list-style: none; padding-left: 0;"> <ul class="toctree-l{{ level }}" style="list-style: none; padding-left: 0; overflow-x: auto; white-space: nowrap;">
{% for item in headings %} {% for item in headings %}
<li class="toctree-l{{ level }}{% if item.current %} current{% endif %}" <li class="toctree-l{{ level }}{% if item.current %} current{% endif %}"
{% if item.children %} x-data="{ expanded: false }" {% endif %} {% if item.children %}
x-data="{ expanded: {{ 'true' if item.current else 'false' }} }"
{% endif %}
style="white-space: nowrap;"> style="white-space: nowrap;">
<div class="menu-item" style="display: inline-flex; align-items: center; justify-content: space-between; width: 100%; white-space: nowrap;"> <div class="menu-item" style="display: inline-flex; align-items: center; justify-content: space-between; width: 100%; white-space: nowrap;">
<!-- Link- und "Datei öffnen"-Bereich --> <!-- Link and file open section -->
<div style="display: inline-flex; align-items: center; white-space: nowrap;"> <div style="display: inline-flex; align-items: center; white-space: nowrap;">
<a class="reference internal{% if item.children %} expandable{% endif %}" <a class="reference internal{% if item.children %} expandable{% endif %}{% if item.current %} current{% endif %}"
href="{{ pathto(item.link).replace('#', '') }}{% if item.anchor %}#{{ item.anchor }}{% endif %}" href="{{ pathto(item.link).replace('#', '') }}{% if item.anchor %}#{{ item.anchor }}{% endif %}"
style="text-decoration: none; white-space: nowrap;"> style="text-decoration: none; white-space: nowrap;">
{{ item.text }} {{ item.text }}
</a> </a>
</div> </div>
<!-- Expand-Toggle-Button --> <!-- Expand-Toggle Button -->
{% if item.children %} {% if item.children %}
<button @click.prevent.stop="expanded = !expanded" type="button" class="toggle-button" <button @click.prevent.stop="expanded = !expanded" type="button" class="toggle-button"
style="background: none; border: none; padding: 0; margin-left: auto;"> style="background: none; border: none; padding: 0; margin-left: auto;">
@ -37,13 +39,15 @@
</ul> </ul>
{% endmacro %} {% endmacro %}
{% if local_md_headings or local_subfolders %} {% if local_md_headings or local_subfolders %}
<div class="local-md-headings"> <div class="local-md-headings">
<h3 class="toctree-l1">Index</h3> <h3>Overview</h3>
<hr />
<h4 class="toctree-l1">Current Index</h4>
{% if local_md_headings %} {% if local_md_headings %}
{{ render_headings(local_md_headings) }} {{ render_headings(local_md_headings) }}
{% endif %} {% endif %}
<h4 class="toctree-l1">File Explorer</h4>
{% if local_subfolders %} {% if local_subfolders %}
{{ render_headings(local_subfolders) }} {{ render_headings(local_subfolders) }}
{% endif %} {% endif %}