Compare commits

...

55 Commits

Author SHA1 Message Date
Trez.One f0bca64e7b Merge pull request 'Adding Audiomuse to Homepage.' (#96) from audiomuse-homepage-add_2026-05-18T08-45-42 into main
Reviewed-on: #96
2026-05-21 08:32:00 -04:00
Trez.One aa0257308b Adding Audiomuse to Homepage.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 43s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Successful in 2m2s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Has been skipped
2026-05-18 08:45:42 -04:00
Trez.One 87f6839423 Merge pull request 'Updating server_name.' (#95) from audiomuse-swag-proxy_2026-05-18T07-57-59 into main
Reviewed-on: #95
2026-05-18 08:30:03 -04:00
Trez.One eb0d52295b Updating server_name. 2026-05-18 08:29:30 -04:00
gitea-sonarqube-bot 7ede2d12fe Auto Merge of PR 94 - audiomuse-swag-proxy_2026-05-18T07-57-59
Merged by Trez.One
2026-05-18 08:24:29 -04:00
Trez.One 88e9cfe684 Proxy conf for Audiomuse on Ultima.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 2m12s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Successful in 3m19s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 5m48s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 52s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Has been cancelled
2026-05-18 07:58:16 -04:00
Trez.One 618909ad4b Moving Dagu from Rinoa to Aranea. 2026-05-12 07:45:00 -04:00
gitea-sonarqube-bot 39eeb029ae Auto Merge of PR 93 - dagu-aranea-proxy-conf_2026-05-10T16-57-13
Merged by Trez.One
2026-05-10 17:59:37 -04:00
Trez.One 0c7a84690f Forgot to adjust server_name.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 40s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Successful in 2m17s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 32s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Failing after 2m47s
2026-05-10 16:59:49 -04:00
Trez.One 20cecfdaf4 Adding reverse proxy for Dagu.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been cancelled
2026-05-10 16:57:54 -04:00
gitea-sonarqube-bot 118f1edc02 Auto Merge of PR 92 - aranea-setup-app-configs_2026-05-08T18-56-15
Merged by Trez.One
2026-05-09 12:19:28 -04:00
Trez.One 75d9486e2d Incorrect sudo for Lunafreya vars.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 19s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Successful in 2m36s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Successful in 2m38s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 2m48s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 3m1s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 4m33s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 15s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Failing after 2m11s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Failing after 2m13s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Successful in 2m28s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Successful in 2m37s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Failing after 4m3s
2026-05-09 12:12:47 -04:00
Trez.One 7b47835749 Become passwords for Lunafreya and Aranea.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 20s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Successful in 2m38s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Failing after 2m54s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 2m52s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 2m59s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 4m46s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
2026-05-09 12:05:37 -04:00
Trez.One 854ed976db Updating Hashicorp Vault token.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 34s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Failing after 8m40s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Failing after 8m47s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 9m8s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 9m21s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 11m13s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (aranea) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
2026-05-09 11:43:42 -04:00
Trez.One 9bd2815f64 Forgot to update actual deployment job. 2026-05-09 11:35:10 -04:00
Trez.One f239b37126 Adding host Aranea into Ansible.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (aranea) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been cancelled
2026-05-09 11:33:05 -04:00
Trez.One b4c29a693b Bumping Tea CLI version. 2026-05-08 18:51:05 -04:00
gitea-sonarqube-bot 0b74444e76 Auto Merge of PR 90 - searxng-limiter-config_2026-04-07T17-23-37
Auto-Unseal for Vault / Unseal Vault (push) Failing after 14m58s
Renovate / renovate (push) Successful in 1m43s
Merged by Trez.One
2026-04-09 20:31:58 -04:00
Trez.One 1425bf4efa Adding limiter.toml, small settings changes.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 33s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (lunafreya) (push) Successful in 3m52s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 3m54s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 4m4s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 5m55s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 2m51s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (lunafreya) (push) Failing after 2m58s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Successful in 3m16s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Successful in 3m35s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Failing after 5m41s
2026-04-09 20:23:39 -04:00
Trez.One 3205a4a1e2 Renaming host_vars for Lunafreya.
Renovate / renovate (push) Successful in 3m20s
2026-04-09 20:22:56 -04:00
Trez.One 8377ba7cc6 Merge pull request 'Adding Mitogen Plugin' (#91) from mitogen-plugin-add_2026-04-09T19-48-02 into main
Reviewed-on: #91
2026-04-09 20:17:36 -04:00
Trez.One 90bc869b3d Removing tar. 2026-04-09 19:55:44 -04:00
Trez.One 87218e5be7 Fixing path. 2026-04-09 19:52:14 -04:00
Trez.One 3ae80ef3bb Adding Mitogen plugin and strategy. 2026-04-09 19:51:43 -04:00
Trez.One a85f7f50e9 Updating HC Vault token.
Renovate / renovate (push) Successful in 3m39s
2026-04-09 19:44:48 -04:00
Trez.One 2ce3900c47 Replacing references to Benedikta with Lunafreya.
Auto-Unseal for Vault / Unseal Vault (push) Failing after 26m19s
Renovate / renovate (push) Successful in 1m45s
2026-03-03 06:25:44 -05:00
Trez.One 4aa0bdc783 Updating Vault token.
Auto-Unseal for Vault / Unseal Vault (push) Successful in 1m47s
Renovate / renovate (push) Successful in 1m21s
2026-02-28 08:42:43 -05:00
gitea-sonarqube-bot badadef12a Auto Merge of PR 88 - mcpo-server-wikipedia-add_2026-01-04T14-58-41
Auto-Unseal for Vault / Unseal Vault (push) Successful in 3m52s
Renovate / renovate (push) Successful in 1m41s
Merged by Trez.One
2026-01-07 08:14:36 -05:00
Trez.One 04afce167a Adding Wikipedia to MCPO proxy.
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 55s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 2m5s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 3m27s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 8m4s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 1m30s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 17s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Failing after 1m3s
2026-01-04 14:59:58 -05:00
gitea-sonarqube-bot 8ab2c8bb1b Auto Merge of PR 87 - searxng-config-fix_2026-01-02T16-03-17
Auto-Unseal for Vault / Unseal Vault (push) Failing after 3m56s
Renovate / renovate (push) Successful in 1m35s
Merged by Trez.One
2026-01-03 12:31:57 -05:00
Trez.One e3c9344517 Updating vars for Benedikta.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 34s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 2m18s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 2m43s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 4m16s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 8m29s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 1m8s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Failing after 2m19s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Successful in 2m55s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Successful in 4m21s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Successful in 8m6s
2026-01-03 12:21:41 -05:00
Trez.One 45d57a4585 SearXNG.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 1m27s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 3m14s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 4m46s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 8m51s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Failing after 1m14s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
2026-01-03 08:57:09 -05:00
Trez.One 56a3e5473e Updating Vault token.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 21s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Failing after 1m57s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 2m22s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 3m54s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Failing after 5m27s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
2026-01-03 07:36:13 -05:00
Trez.One b32340700b Updating SearXNG config.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Failing after 2m32s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Failing after 2m44s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Failing after 4m49s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 26s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Failing after 1m27s
2026-01-02 16:03:42 -05:00
Trez.One f96b1131c0 Correcting MCP setup. 2025-12-19 08:53:25 -05:00
gitea-sonarqube-bot 42bb6ed218 Auto Merge of PR 86 - mcp-server-proxy-config_2025-12-18T08-27-26
Auto-Unseal for Vault / Unseal Vault (push) Failing after 2m24s
Renovate / renovate (push) Successful in 1m42s
Merged by Trez.One
2025-12-18 09:54:20 -05:00
Trez.One ed1fa33bf7 Adding MCP server config.
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 51s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 7m35s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 7m46s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 9m38s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 13m33s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 33s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Successful in 1m40s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Successful in 2m3s
2025-12-18 09:02:25 -05:00
gitea-sonarqube-bot a358f9c953 Auto Merge of PR 85 - benedikta-overhaul_2025-12-01T13-17-06
Auto-Unseal for Vault / Unseal Vault (push) Successful in 2m39s
Renovate / renovate (push) Successful in 2m2s
Merged by Trez.One
2025-12-07 10:25:19 -05:00
Trez.One ded7865e89 Hivemind config trial and error...
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 1m5s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 10m19s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 10m19s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 14m36s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 19m10s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 26s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Failing after 6m0s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Successful in 6m11s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Successful in 9m9s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Successful in 13m5s
2025-12-07 09:44:55 -05:00
Trez.One 127aa27530 Saving OVOS progress for now... 2025-12-07 09:43:19 -05:00
gitea-sonarqube-bot 82637347b5 Auto Merge of PR 84 - benedikta-overhaul_2025-12-01T13-17-06
Auto-Unseal for Vault / Unseal Vault (push) Successful in 3m45s
Renovate / renovate (push) Successful in 4m10s
Merged by Trez.One
2025-12-03 17:58:18 -05:00
Trez.One 89886d0c9b ...
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 1m21s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 11m27s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 11m41s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 15m36s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 18m29s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 38s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Successful in 4m54s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Failing after 5m6s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Failing after 10m57s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Successful in 13m37s
2025-12-03 17:34:14 -05:00
Trez.One fc75831f12 Hivemind and OVOS config shuffling.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been cancelled
2025-12-03 17:10:47 -05:00
gitea-sonarqube-bot 2d6ff36a4f Auto Merge of PR 83 - benedikta-overhaul_2025-12-01T13-17-06
Renovate / renovate (push) Successful in 3m4s
Merged by Trez.One
2025-12-03 13:39:59 -05:00
Trez.One 5c23f4cbea Nuking Grafana as it's no longer in use.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 38s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 8m27s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 9m1s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 11m59s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Successful in 15m8s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Successful in 31s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Successful in 8m16s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Failing after 8m42s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Successful in 10m11s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Successful in 14m24s
2025-12-03 13:23:33 -05:00
Trez.One 7ad9d1ed7d .....
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 37s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 3m58s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Successful in 5m30s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Successful in 5m50s
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Failing after 8m5s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been skipped
2025-12-03 13:04:29 -05:00
Trez.One 9ab66a7be1 Updating Vault password for Ultima creds.
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Successful in 29s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Failing after 5m26s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (ultima) (push) Successful in 5m28s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Failing after 6m4s
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Failing after 8m19s
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been skipped
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (ultima) (push) Has been skipped
2025-12-03 11:57:08 -05:00
Trez.One 44d706b891 Forgot to add Ultima to list of hosts in config playbook. 2025-12-03 10:39:59 -05:00
Trez.One 160bca4f50 Adding Ultima to general workflow. 2025-12-03 06:58:54 -05:00
Trez.One 4d6d6b4b38 Benedikta updates and Ultima config for Hivemind.
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (benedikta) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Check and Create PR (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Dry Run (rinoa) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / PR Merge (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (benedikta) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rikku) (push) Has been cancelled
Gitea Branch PR & Ansible Deployment / Ansible Config Deployment (rinoa) (push) Has been cancelled
2025-12-03 06:57:07 -05:00
Trez.One eed76199b1 Adding Ultima to inventory.
Auto-Unseal for Vault / Unseal Vault (push) Successful in 2m12s
Renovate / renovate (push) Successful in 3m36s
2025-11-30 14:25:58 -05:00
Trez.One 08b5295427 Updating Hashicorp Vault token.
Auto-Unseal for Vault / Unseal Vault (push) Successful in 1m57s
Renovate / renovate (push) Successful in 2m17s
2025-11-29 15:01:13 -05:00
Trez.One 8b04252c1c Temporarily disabling AdGuard monitoring in Loggifly.
Auto-Unseal for Vault / Unseal Vault (push) Successful in 2m28s
Renovate / renovate (push) Failing after 1m42s
2025-11-28 08:10:21 -05:00
Trez.One d46d109c20 Pinning Gotify action version.
Auto-Unseal for Vault / Unseal Vault (push) Successful in 1m41s
Renovate / renovate (push) Successful in 1m45s
2025-11-16 06:29:00 -05:00
gitea-sonarqube-bot 094a0d2d41 Auto Merge of PR 81 - homepage-layout-change
Auto-Unseal for Vault / Unseal Vault (push) Successful in 1m35s
Renovate / renovate (push) Failing after 2m34s
Merged by Trez.One
2025-11-14 06:32:49 -05:00
200 changed files with 26668 additions and 1755 deletions
+4 -4
View File
@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -59,7 +59,7 @@ jobs:
run: pip install hvac
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -88,7 +88,7 @@ jobs:
- name: Gotify Notification
if: steps.validate-dags.outputs.exit_code == '0'
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -97,7 +97,7 @@ jobs:
- name: Gotify Notification
if: steps.validate-dags.outputs.exit_code != '0'
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -22,7 +22,7 @@ on:
- "!renovate.json"
env:
TEA_VERSION: "0.10.1"
TEA_VERSION: "0.14.0"
VAULT_VERSION: "1.21.0"
VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }}
VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }}
@@ -39,7 +39,7 @@ jobs:
fetch-depth: 1
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -55,7 +55,7 @@ jobs:
assignee: ${{ github.actor }}
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -68,7 +68,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
host: [rinoa, rikku, benedikta]
host: [aranea, lunafreya, rinoa, rikku, ultima]
env:
VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }}
VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }}
@@ -108,7 +108,7 @@ jobs:
run: pip install hvac
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -129,7 +129,7 @@ jobs:
--check
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -161,7 +161,7 @@ jobs:
echo "pr_index=${pr_index}" >> $GITHUB_OUTPUT
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -174,7 +174,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
host: [rinoa, rikku, benedikta]
host: [aranea, lunafreya, rinoa, rikku, ultima]
env:
VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }}
VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }}
@@ -214,7 +214,7 @@ jobs:
run: pip install hvac
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -234,7 +234,7 @@ jobs:
--limit ${{ matrix.host }}
- name: Gotify Notification
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Gotify Notification (start check)
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: ${{ secrets.RUNNER_GOTIFY_URL }}
gotify_app_token: ${{ secrets.RUNNER_GOTIFY_TOKEN }}
@@ -32,7 +32,7 @@ jobs:
version: "stable"
- name: Gotify Notification (done)
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: ${{ secrets.RUNNER_GOTIFY_URL }}
gotify_app_token: ${{ secrets.RUNNER_GOTIFY_TOKEN }}
+2 -2
View File
@@ -19,7 +19,7 @@ jobs:
VAULT_NAMESPACE: ""
steps:
- name: Vault Unseal Start
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
@@ -46,7 +46,7 @@ jobs:
done
- name: Vault Unseal Completion
uses: eikendev/gotify-action@master
uses: eikendev/gotify-action@0.0.3
with:
gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}"
gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}"
+1
View File
@@ -3,3 +3,4 @@ inventory = inventory/hosts.yml
collections_path = ./collections
host_key_checking = False
retry_files_enabled = False
strategy_plugins = plugins/mitogen-0.3.44/ansible_mitogen/plugins/strategy
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,14 +0,0 @@
{
"__mycroft_skill_firstrun": false,
"type": "ovos_common_play",
"preferred_audio_services": [
"mpv",
"vlc",
"simple"
],
"disable_mpris": true,
"dbus_type": "session",
"manage_external_players": false,
"active": true,
"mode": "auto"
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"first_boot": false
}
@@ -1,15 +0,0 @@
{
"speak_alarm": false,
"speak_timer": true,
"sound_alarm": "constant_beep.mp3",
"sound_timer": "beep4.mp3",
"snooze_mins": 15,
"timeout_min": 1,
"play_volume": 90,
"escalate_volume": true,
"priority_cutoff": 8,
"services": "",
"frequency": 15,
"sync_ask": false,
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,4 +0,0 @@
{
"play_sound": true,
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,4 +0,0 @@
{
"log_level": "WARNING",
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,5 +0,0 @@
{
"gender": "male",
"haunted": false,
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,6 +0,0 @@
{
"apiv3": "8a2e8882b465b1cf7cce9ff6b35bdd7e",
"search_depth": 5,
"match_confidence": 0.8,
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -1,3 +0,0 @@
{
"__mycroft_skill_firstrun": false
}
@@ -0,0 +1,13 @@
{
"log_level": "INFO",
"logs": { "path": "stdout" },
"listener": {
"continuous_listen": true,
"microphone": {
"module": "ovos-microphone-plugin-socket"
},
"VAD": {
"module": "ovos-vad-plugin-silero"
}
}
}
@@ -0,0 +1,84 @@
# otel_collector.yaml
receivers:
# ────────────────────────────────────────────────────────────────
# 1) Host log collection
# ────────────────────────────────────────────────────────────────
filelog:
# Optional: give the receiver a humanreadable name
name: host_logs
# Paths to monitor adjust glob patterns as needed
include:
- /var/log/*.log
- /var/log/syslog
- /var/log/messages
# Optional: skip log files that match these patterns
exclude: []
# Optional: start reading from the beginning of the file
start_at: beginning
# Optional: decode JSON logs if they are JSONformatted
# json:
# keys: [timestamp, level, msg]
# timestamp_key: timestamp
# timestamp_format: RFC3339
# Optional: throttle log ingestion
# throttle:
# max_per_second: 1000
# Optional: keep track of processed offsets
# cache:
# file: /var/log/filelog_cache.json
# ────────────────────────────────────────────────────────────────
# 2) Docker container log collection
# ────────────────────────────────────────────────────────────────
docker:
# Connect to the local Docker daemon
host: unix:///var/run/docker.sock
# By default, the Docker receiver pulls container metrics, logs, and healthchecks.
# If you only need logs, set the following to true (enabled by default):
logs: true
# Optional: enable or disable container log collection for specific containers
# include: [ "my-app", "api-service" ]
# exclude: [ "debug-container" ]
# Optional: set the maximum number of log files to keep open
# max_open_files: 100
processors:
# ────────────────────────────────────────────────────────────────
# 1) Batch processor (recommended for all pipelines)
# ────────────────────────────────────────────────────────────────
batch:
timeout: 5s
send_batch_size: 5000
# ────────────────────────────────────────────────────────────────
# 2) Optional resource processor add host name to every log record
# ────────────────────────────────────────────────────────────────
resource:
attributes:
- key: host.name
from_env: HOSTNAME
action: upsert
- key: service.namespace
value: host-logs
action: upsert
exporters:
# ────────────────────────────────────────────────────────────────
# 1) OTLP exporter sends logs to the central collector
# ────────────────────────────────────────────────────────────────
otlp:
endpoint: "centralized-collector:4317"
# If you want insecure connections (e.g., local dev), set insecure true
tls:
insecure: true
# Optional: use HTTP instead of gRPC
# http:
# path: "/v1/logs"
service:
pipelines:
logs:
receivers: [filelog, docker]
processors: [batch, resource]
exporters: [otlp]
@@ -1,404 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Agent globals
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
local.file "endpoints" {
// The endpoints file is used to define the endpoints, credentials and options
// for the Agent export to.
filename = "/etc/alloy/endpoints.json"
}
discovery.docker "rinoadocker" {
host = env("DOCKER_HOST")
}
tracing {
write_to = [otelcol.exporter.otlp.tempo.input]
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Metrics
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
prometheus.remote_write "mimir" {
endpoint {
url = json_path(local.file.endpoints.content, ".metrics.url")[0]
basic_auth {
username = json_path(local.file.endpoints.content, ".metrics.basicAuth.username")[0]
password = json_path(local.file.endpoints.content, ".metrics.basicAuth.password")[0]
}
}
}
prometheus.scrape "prometheus" {
targets = [{
__address__ = "localhost:12345",
}]
forward_to = [prometheus.remote_write.mimir.receiver]
job_name = "prometheus"
}
prometheus.exporter.unix "rinoa" {
procfs_path = "/host/proc"
sysfs_path = "/host/sys"
rootfs_path = "/rootfs"
}
prometheus.scrape "rinoa" {
targets = prometheus.exporter.unix.rinoa.targets
forward_to = [prometheus.remote_write.mimir.receiver]
job_name = "rinoa_host"
}
prometheus.exporter.cadvisor "docker" {
docker_host = env("DOCKER_HOST")
storage_duration = "5m"
}
prometheus.scrape "docker" {
targets = prometheus.exporter.cadvisor.docker.targets
forward_to = [prometheus.remote_write.mimir.receiver]
job_name = "docker_stats"
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Logging
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
loki.write "loki" {
endpoint {
url = json_path(local.file.endpoints.content, ".logs.url")[0]
basic_auth {
username = json_path(local.file.endpoints.content, ".logs.basicAuth.username")[0]
password = json_path(local.file.endpoints.content, ".logs.basicAuth.password")[0]
}
}
external_labels = {}
}
loki.source.journal "hostjournal" {
forward_to = [loki.write.loki.receiver]
max_age = "24h"
path = "/rootfs/var/log/journal/"
labels = {
job = "host-journal",
}
}
local.file_match "system" {
path_targets = [{
__address__ = "localhost",
__path__ = "/rootfs/var/log/*log",
job = "varlogs",
}]
}
loki.source.file "system" {
targets = local.file_match.system.targets
forward_to = [loki.write.loki.receiver]
}
loki.source.docker "containers" {
host = env("DOCKER_HOST")
targets = discovery.docker.rinoadocker.targets
forward_to = [loki.write.loki.receiver]
labels = {
job = "containerlogs",
}
}
loki.process "containers" {
forward_to = [loki.write.loki.receiver]
// stage.docker {}
stage.json {
expressions = {
attrs = "",
output = "log",
stream = "stream",
}
}
stage.json {
expressions = {
tag = "",
}
source = "attrs"
}
stage.regex {
expression = "(?P<image_name>(?:[^|]*[^|])).(?P<container_name>(?:[^|]*[^|])).(?P<image_id>(?:[^|]*[^|])).(?P<container_id>(?:[^|]*[^|]))"
source = "tag"
}
stage.timestamp {
source = "time"
format = "RFC3339Nano"
}
stage.labels {
values = {
container_id = null,
container_name = null,
image_id = null,
image_name = null,
stream = null,
tag = null,
}
}
stage.output {
source = "output"
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Traces
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
beyla.ebpf "rinoadocker" {
open_port = "80-65535"
routes {
unmatched = "heauristic"
}
output {
traces = [
otelcol.connector.servicegraph.tracemetrics.input,
otelcol.connector.spanmetrics.tracemetrics.input,
otelcol.processor.batch.default.input,
otelcol.connector.spanlogs.autologging.input,
]
}
}
prometheus.scrape "beyla" {
targets = beyla.ebpf.rinoadocker.targets
forward_to = [prometheus.remote_write.mimir.receiver]
}
otelcol.auth.headers "tempo" {
header {
key = "Authorization"
value = join(["Basic ", json_path(local.file.endpoints.content, ".traces.basicAuthToken")[0]], "")
}
}
otelcol.processor.batch "default" {
// Wait until we've received 16K of data.
send_batch_size = 16384
send_batch_max_size = 16384
// Or until 2 seconds have elapsed.
timeout = "2s"
// When the Agent has enough batched data, send it to the OpenTelemetry exporter named 'tempo'.
output {
traces = [otelcol.exporter.otlp.tempo.input]
}
}
otelcol.exporter.otlp "tempo" {
// Define the client for exporting.
client {
// Authentication block.
auth = otelcol.auth.headers.tempo.handler
// Send to the locally running Tempo instance, on port 4317 (OTLP gRPC).
endpoint = json_path(local.file.endpoints.content, ".traces.url")[0]
// Configure TLS settings for communicating with the endpoint.
tls {
// The connection is insecure.
insecure = json_path(local.file.endpoints.content, ".traces.tls.insecure")[0]
// Do not verify TLS certificates when connecting.
insecure_skip_verify = json_path(local.file.endpoints.content, ".traces.tls.insecureSkipVerify")[0]
}
}
}
otelcol.connector.spanlogs "autologging" {
// We only want to output a line for each root span (ie. every single trace), and not for every
// process or span (outputting a line for every span would be extremely verbose).
spans = false
roots = true
processes = false
// We want to ensure that the following three span attributes are included in the log line, if
// present.
span_attributes = [ "http.method", "http.target", "http.status_code" ]
// Overrides the default key in the log line to be `traceId`, which is then used by Grafana to
// identify the trace ID for correlation with the Tempo datasource.
overrides {
trace_id_key = "traceId"
}
// Send to the OpenTelemetry Loki exporter.
output {
logs = [otelcol.exporter.loki.autologging.input]
}
}
// Simply forwards the incoming OpenTelemetry log format out as a Loki log.
// We need this stage to ensure we can then process the logline as a Loki object.
otelcol.exporter.loki "autologging" {
forward_to = [loki.process.autologging.receiver]
}
// The Loki processor allows us to accept a correctly formatted Loki log and mutate it into
// a set of fields for output.
loki.process "autologging" {
// The JSON stage simply extracts the `body` (the actual logline) from the Loki log, ignoring
// all other fields.
stage.json {
expressions = { "body" = "" }
}
// The output stage takes the body (the main logline) and uses this as the source for the output
// logline. In this case, it essentially turns it into logfmt.
stage.output {
source = "body"
}
// Finally send the processed logline onto the Loki exporter.
forward_to = [loki.write.autologging.receiver]
}
// The Loki writer receives a processed Loki log and then writes it to a Loki instance.
loki.write "autologging" {
// Add the `agent` value to the `job` label, so we can identify it as having been generated
// by Grafana Agent when querying.
external_labels = {
job = "agent",
}
// Output the Loki log to the local Loki instance.
endpoint {
url = json_path(local.file.endpoints.content, ".logs.url")[0]
// The basic auth credentials for the Loki instance.
basic_auth {
username = json_path(local.file.endpoints.content, ".logs.basicAuth.username")[0]
password = json_path(local.file.endpoints.content, ".logs.basicAuth.password")[0]
}
}
}
// The Tail Sampling processor will use a set of policies to determine which received traces to keep
// and send to Tempo.
otelcol.processor.tail_sampling "errors" {
// Total wait time from the start of a trace before making a sampling decision. Note that smaller time
// periods can potentially cause a decision to be made before the end of a trace has occurred.
decision_wait = "30s"
// The following policies follow a logical OR pattern, meaning that if any of the policies match,
// the trace will be kept. For logical AND, you can use the `and` policy. Every span of a trace is
// examined by each policy in turn. A match will cause a short-circuit.
// This policy defines that traces that contain errors should be kept.
policy {
// The name of the policy can be used for logging purposes.
name = "sample-erroring-traces"
// The type must match the type of policy to be used, in this case examing the status code
// of every span in the trace.
type = "status_code"
// This block determines the error codes that should match in order to keep the trace,
// in this case the OpenTelemetry 'ERROR' code.
status_code {
status_codes = [ "ERROR" ]
}
}
// This policy defines that only traces that are longer than 200ms in total should be kept.
policy {
// The name of the policy can be used for logging purposes.
name = "sample-long-traces"
// The type must match the policy to be used, in this case the total latency of the trace.
type = "latency"
// This block determines the total length of the trace in milliseconds.
latency {
threshold_ms = 200
}
}
// The output block forwards the kept traces onto the batch processor, which will marshall them
// for exporting to Tempo.
output {
traces = [otelcol.processor.batch.default.input]
}
}
// The Spanmetrics Connector will generate RED metrics based on the incoming trace span data.
otelcol.connector.spanmetrics "tracemetrics" {
// The namespace explicit adds a prefix to all the generated span metrics names.
// In this case, we'll ensure they match as closely as possible those generated by Tempo.
namespace = "traces.spanmetrics"
// Each extra dimension (metrics label) to be added to the generated metrics from matching span attributes. These
// need to be defined with a name and optionally a default value (in the following cases, we do not want a default
// value if the span attribute is not present).
dimension {
name = "http.method"
}
dimension {
name = "http.target"
}
dimension {
name = "http.status_code"
}
dimension {
name = "service.version"
}
// A histogram block must be present, either explicitly defining bucket values or via an exponential block.
// We do the latter here.
histogram {
explicit {
}
}
// The exemplar block is added to ensure we generate exemplars for traces on relevant metric values.
exemplars {
enabled = true
}
// Generated metrics data is in OTLP format. We send this data to the OpenTelemetry Prometheus exporter to ensure
// it gets transformed into Prometheus format data.
output {
metrics = [otelcol.exporter.prometheus.tracemetrics.input]
}
}
// The Servicegraph Connector will generate service graph metrics (edges and nodes) based on incoming trace spans.
otelcol.connector.servicegraph "tracemetrics" {
// Extra dimensions (metrics labels) to be added to the generated metrics from matching span attributes.
// For this component, this is defined as an array. There are no default values and the labels will not be generated
// for missing span attributes.
dimensions = [
"http.method",
"http.target",
"http.status_code",
"service.version",
]
// Generated metrics data is in OTLP format. We send this data to the OpenTelemetry Prometheus exporter to ensure
// it gets transformed into Prometheus format data.
output {
metrics = [otelcol.exporter.prometheus.tracemetrics.input]
}
}
otelcol.exporter.prometheus "tracemetrics" {
// Forward to our local Prometheus remote writer which will send the metrics to Mimir.
forward_to = [prometheus.remote_write.mimir.receiver]
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Profiling
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
pyroscope.write "pyroscope" {
endpoint {
url = json_path(local.file.endpoints.content, ".profiles.url")[0]
basic_auth {
username = json_path(local.file.endpoints.content, ".profiles.basicAuth.username")[0]
password = json_path(local.file.endpoints.content, ".profiles.basicAuth.password")[0]
}
}
external_labels = {}
}
pyroscope.ebpf "rinoadocker" {
forward_to = [pyroscope.write.pyroscope.receiver]
targets = discovery.docker.rinoadocker.targets
}
@@ -1,34 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
{
"metrics": {
"url": "http://grafana-mimir:9009/api/v1/push",
"basicAuth": {
"username": "",
"password": ""
}
},
"logs": {
"url": "http://grafana-loki:3100/loki/api/v1/push",
"basicAuth": {
"username": "",
"password": ""
}
},
"traces": {
"url": "http://grafana-tempo:4317",
"basicAuthToken": "",
"tls": {
"insecure": true,
"insecureSkipVerify": true
}
},
"profiles": {
"url": "http://grafana-pyroscope:4040",
"basicAuth": {
"username": "",
"password": ""
}
}
}
@@ -1,7 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
routes:
patterns:
- /*
unmatched: heuristic
@@ -1,77 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
multitenancy_enabled: false
no_auth_tenant: rinoa_mimir
# target: query-frontend
# api:
# prometheus_http_prefix: '/prometheus'
server:
http_listen_port: 9009
# frontend:
# split_queries_by_interval: 24h
# align_queries_with_step: true
# cache_results: true
# results_cache:
# backend: "memcached"
# memcached:
# addresses: "memcached-mimir:11211"
# downstream_url: http://grafana-agent:12345
common:
storage:
backend: s3
s3:
endpoint: minio:9000
access_key_id: "Q8KAihuXtGgmretKNh7C"
secret_access_key: "hOlRODtnvFlNlL26Bj3GizZG6Ys3rlpG8p6Vo3NX"
bucket_name: "mimir"
insecure: true
blocks_storage:
storage_prefix: rinoa
tsdb:
dir: /tmp/mimir/tsdb
memberlist:
tls_enabled: false
compactor:
# Directory to temporarily store blocks underdoing compaction.
data_dir: /tmp/mimir/compactor
# The sharding ring type used to share the hashed ring for the compactor.
sharding_ring:
# Use memberlist backend store (the default).
kvstore:
store: memberlist
# The distributor receives incoming metrics data for the system.
distributor:
# The ring to share hash ring data across instances.
ring:
# The address advertised in the ring. Localhost.
instance_addr: 127.0.0.1
# Use memberlist backend store (the default).
kvstore:
store: memberlist
# The ingester receives data from the distributor and processes it into indices and blocks.
ingester:
# The ring to share hash ring data across instances.
ring:
# The address advertised in the ring. Localhost.
instance_addr: 127.0.0.1
# Use memberlist backend store (the default).
kvstore:
store: memberlist
# Only run one instance of the ingesters.
# Note: It is highly recommended to run more than one ingester in production, the default is an RF of 3.
replication_factor: 1
# The store gateway block configures gateway storage.
store_gateway:
# Configuration for the hash ring.
sharding_ring:
# Only run a single instance. In production setups, the replication factor must
# be set on the querier and ruler as well.
replication_factor: 1
@@ -1,12 +0,0 @@
storage:
backend: s3
s3:
bucket_name: pyroscope
endpoint: minio:9000
region: us-east-fh-pln
access_key_id: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['MINIO_PYROSCOPE_STORAGE_ACCESS_KEY'] }}
secret_access_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['MINIO_PYROSCOPE_STORAGE_SECRET_KEY'] }}
insecure: true
analytics:
reporting_enabled: false
@@ -1,787 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
target: all
http_api_prefix: ""
autocomplete_filtering_enabled: true
server:
http_listen_network: tcp
http_listen_address: ""
http_listen_port: 80
http_listen_conn_limit: 0
grpc_listen_network: tcp
grpc_listen_address: ""
grpc_listen_port: 9095
grpc_listen_conn_limit: 0
tls_cipher_suites: ""
tls_min_version: ""
http_tls_config:
cert: ""
key: null
client_ca: ""
cert_file: ""
key_file: ""
client_auth_type: ""
client_ca_file: ""
grpc_tls_config:
cert: ""
key: null
client_ca: ""
cert_file: ""
key_file: ""
client_auth_type: ""
client_ca_file: ""
register_instrumentation: true
report_grpc_codes_in_instrumentation_label_enabled: false
graceful_shutdown_timeout: 30s
http_server_read_timeout: 30s
http_server_read_header_timeout: 0s
http_server_write_timeout: 30s
http_server_idle_timeout: 2m0s
http_log_closed_connections_without_response_enabled: false
grpc_server_max_recv_msg_size: 16777216
grpc_server_max_send_msg_size: 16777216
grpc_server_max_concurrent_streams: 100
grpc_server_max_connection_idle: 2562047h47m16.854775807s
grpc_server_max_connection_age: 2562047h47m16.854775807s
grpc_server_max_connection_age_grace: 2562047h47m16.854775807s
grpc_server_keepalive_time: 2h0m0s
grpc_server_keepalive_timeout: 20s
grpc_server_min_time_between_pings: 10s
grpc_server_ping_without_stream_allowed: true
grpc_server_num_workers: 0
log_format: logfmt
log_level: info
log_source_ips_enabled: false
log_source_ips_header: ""
log_source_ips_regex: ""
log_request_headers: false
log_request_at_info_level_enabled: false
log_request_exclude_headers_list: ""
http_path_prefix: ""
internal_server:
http_listen_network: tcp
http_listen_address: ""
http_listen_port: 3101
http_listen_conn_limit: 0
grpc_listen_network: ""
grpc_listen_address: ""
grpc_listen_port: 0
grpc_listen_conn_limit: 0
tls_cipher_suites: ""
tls_min_version: ""
http_tls_config:
cert: ""
key: null
client_ca: ""
cert_file: ""
key_file: ""
client_auth_type: ""
client_ca_file: ""
grpc_tls_config:
cert: ""
key: null
client_ca: ""
cert_file: ""
key_file: ""
client_auth_type: ""
client_ca_file: ""
register_instrumentation: false
report_grpc_codes_in_instrumentation_label_enabled: false
graceful_shutdown_timeout: 30s
http_server_read_timeout: 30s
http_server_read_header_timeout: 0s
http_server_write_timeout: 30s
http_server_idle_timeout: 2m0s
http_log_closed_connections_without_response_enabled: false
grpc_server_max_recv_msg_size: 0
grpc_server_max_send_msg_size: 0
grpc_server_max_concurrent_streams: 0
grpc_server_max_connection_idle: 0s
grpc_server_max_connection_age: 0s
grpc_server_max_connection_age_grace: 0s
grpc_server_keepalive_time: 0s
grpc_server_keepalive_timeout: 0s
grpc_server_min_time_between_pings: 0s
grpc_server_ping_without_stream_allowed: false
grpc_server_num_workers: 0
log_format: logfmt
log_level: info
log_source_ips_enabled: false
log_source_ips_header: ""
log_source_ips_regex: ""
log_request_headers: false
log_request_at_info_level_enabled: false
log_request_exclude_headers_list: ""
http_path_prefix: ""
enable: false
distributor:
ring:
kvstore:
store: memberlist
prefix: collectors/
consul:
host: localhost:8500
acl_token: ""
http_client_timeout: 20s
consistent_reads: false
watch_rate_limit: 1
watch_burst_size: 1
cas_retry_delay: 1s
etcd:
endpoints: []
dial_timeout: 10s
max_retries: 10
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
username: ""
password: ""
multi:
primary: ""
secondary: ""
mirror_enabled: false
mirror_timeout: 2s
heartbeat_period: 5s
heartbeat_timeout: 5m0s
instance_id: local-instance
instance_interface_names:
- eth0
- en0
instance_port: 0
instance_addr: ""
receivers: {}
override_ring_key: distributor
forwarders: []
extend_writes: true
retry_after_on_resource_exhausted: 0s
ingester_client:
pool_config:
checkinterval: 15s
healthcheckenabled: true
healthchecktimeout: 1s
maxconcurrenthealthchecks: 0
remote_timeout: 5s
grpc_client_config:
max_recv_msg_size: 104857600
max_send_msg_size: 104857600
grpc_compression: snappy
rate_limit: 0
rate_limit_burst: 0
backoff_on_ratelimits: false
backoff_config:
min_period: 100ms
max_period: 10s
max_retries: 10
initial_stream_window_size: 63KiB1023B
initial_connection_window_size: 63KiB1023B
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
connect_timeout: 5s
connect_backoff_base_delay: 1s
connect_backoff_max_delay: 5s
metrics_generator_client:
pool_config:
checkinterval: 15s
healthcheckenabled: true
healthchecktimeout: 1s
maxconcurrenthealthchecks: 0
remote_timeout: 5s
grpc_client_config:
max_recv_msg_size: 104857600
max_send_msg_size: 104857600
grpc_compression: snappy
rate_limit: 0
rate_limit_burst: 0
backoff_on_ratelimits: false
backoff_config:
min_period: 100ms
max_period: 10s
max_retries: 10
initial_stream_window_size: 63KiB1023B
initial_connection_window_size: 63KiB1023B
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
connect_timeout: 5s
connect_backoff_base_delay: 1s
connect_backoff_max_delay: 5s
querier:
search:
query_timeout: 30s
prefer_self: 10
external_hedge_requests_at: 8s
external_hedge_requests_up_to: 2
external_backend: ""
google_cloud_run: null
external_endpoints: []
trace_by_id:
query_timeout: 10s
max_concurrent_queries: 20
frontend_worker:
frontend_address: 127.0.0.1:9095
dns_lookup_duration: 10s
parallelism: 2
match_max_concurrent: true
id: ""
grpc_client_config:
max_recv_msg_size: 104857600
max_send_msg_size: 16777216
grpc_compression: gzip
rate_limit: 0
rate_limit_burst: 0
backoff_on_ratelimits: false
backoff_config:
min_period: 100ms
max_period: 1s
max_retries: 5
initial_stream_window_size: 0B
initial_connection_window_size: 0B
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
connect_timeout: 0s
connect_backoff_base_delay: 0s
connect_backoff_max_delay: 0s
query_relevant_ingesters: false
query_frontend:
max_outstanding_per_tenant: 2000
querier_forget_delay: 0s
max_batch_size: 5
max_retries: 2
search:
concurrent_jobs: 1000
target_bytes_per_job: 104857600
default_result_limit: 20
max_result_limit: 0
max_duration: 168h0m0s
query_backend_after: 15m0s
query_ingesters_until: 30m0s
trace_by_id:
query_shards: 50
hedge_requests_at: 2s
hedge_requests_up_to: 2
metrics:
concurrent_jobs: 1000
target_bytes_per_job: 104857600
max_duration: 0s
query_backend_after: 1h0m0s
interval: 5m0s
multi_tenant_queries_enabled: true
compactor:
ring:
kvstore:
store: ""
prefix: collectors/
consul:
host: localhost:8500
acl_token: ""
http_client_timeout: 20s
consistent_reads: false
watch_rate_limit: 1
watch_burst_size: 1
cas_retry_delay: 1s
etcd:
endpoints: []
dial_timeout: 10s
max_retries: 10
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
username: ""
password: ""
multi:
primary: ""
secondary: ""
mirror_enabled: false
mirror_timeout: 2s
heartbeat_period: 5s
heartbeat_timeout: 1m0s
wait_stability_min_duration: 1m0s
wait_stability_max_duration: 5m0s
instance_id: local-instance
instance_interface_names:
- eth0
- en0
instance_port: 0
instance_addr: ""
enable_inet6: false
wait_active_instance_timeout: 10m0s
compaction:
v2_in_buffer_bytes: 5242880
v2_out_buffer_bytes: 20971520
v2_prefetch_traces_count: 1000
compaction_window: 1h0m0s
max_compaction_objects: 6000000
max_block_bytes: 107374182400
block_retention: 336h0m0s
compacted_block_retention: 1h0m0s
retention_concurrency: 10
max_time_per_tenant: 5m0s
compaction_cycle: 30s
override_ring_key: compactor
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
prefix: collectors/
consul:
host: localhost:8500
acl_token: ""
http_client_timeout: 20s
consistent_reads: false
watch_rate_limit: 1
watch_burst_size: 1
cas_retry_delay: 1s
etcd:
endpoints: []
dial_timeout: 10s
max_retries: 10
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
username: ""
password: ""
multi:
primary: ""
secondary: ""
mirror_enabled: false
mirror_timeout: 2s
heartbeat_timeout: 5m0s
replication_factor: 1
zone_awareness_enabled: false
excluded_zones: ""
num_tokens: 128
heartbeat_period: 5s
heartbeat_timeout: 1m0s
observe_period: 0s
join_after: 0s
min_ready_duration: 15s
interface_names:
- en0
- bridge100
enable_inet6: false
final_sleep: 0s
tokens_file_path: ""
availability_zone: ""
unregister_on_shutdown: true
readiness_check_ring_health: true
address: 127.0.0.1
port: 0
id: local-instance
concurrent_flushes: 4
flush_check_period: 10s
flush_op_timeout: 5m0s
trace_idle_period: 10s
max_block_duration: 30m0s
max_block_bytes: 524288000
complete_block_timeout: 15m0s
override_ring_key: ring
flush_all_on_shutdown: false
metrics_generator:
ring:
kvstore:
store: inmemory
prefix: collectors/
consul:
host: localhost:8500
acl_token: ""
http_client_timeout: 20s
consistent_reads: false
watch_rate_limit: 1
watch_burst_size: 1
cas_retry_delay: 1s
etcd:
endpoints: []
dial_timeout: 10s
max_retries: 10
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
username: ""
password: ""
multi:
primary: ""
secondary: ""
mirror_enabled: false
mirror_timeout: 2s
heartbeat_period: 5s
heartbeat_timeout: 1m0s
instance_id: local-instance
instance_interface_names:
- eth0
- en0
instance_addr: 127.0.0.1
instance_port: 0
enable_inet6: false
processor:
service_graphs:
wait: 10s
max_items: 10000
workers: 10
histogram_buckets:
- 0.1
- 0.2
- 0.4
- 0.8
- 1.6
- 3.2
- 6.4
- 12.8
dimensions: []
enable_client_server_prefix: false
peer_attributes:
- peer.service
- db.name
- db.system
span_multiplier_key: ""
span_metrics:
histogram_buckets:
- 0.002
- 0.004
- 0.008
- 0.016
- 0.032
- 0.064
- 0.128
- 0.256
- 0.512
- 1.024
- 2.048
- 4.096
- 8.192
- 16.384
intrinsic_dimensions:
service: true
span_name: true
span_kind: true
status_code: true
dimensions: []
dimension_mappings: []
enable_target_info: false
span_multiplier_key: ""
subprocessors:
0: true
1: true
2: true
filter_policies: []
target_info_excluded_dimensions: []
local_blocks:
block:
bloom_filter_false_positive: 0.01
bloom_filter_shard_size_bytes: 102400
version: vParquet3
search_encoding: snappy
search_page_size_bytes: 1048576
v2_index_downsample_bytes: 1048576
v2_index_page_size_bytes: 256000
v2_encoding: zstd
parquet_row_group_size_bytes: 100000000
parquet_dedicated_columns: []
search:
chunk_size_bytes: 1000000
prefetch_trace_count: 1000
read_buffer_count: 32
read_buffer_size_bytes: 1048576
cache_control:
footer: false
column_index: false
offset_index: false
flush_check_period: 10s
trace_idle_period: 10s
max_block_duration: 1m0s
max_block_bytes: 500000000
complete_block_timeout: 1h0m0s
max_live_traces: 0
concurrent_blocks: 10
filter_server_spans: true
registry:
collection_interval: 15s
stale_duration: 15m0s
max_label_name_length: 1024
max_label_value_length: 2048
storage:
path: ""
wal:
wal_segment_size: 134217728
wal_compression: none
stripe_size: 16384
truncate_frequency: 2h0m0s
min_wal_time: 300000
max_wal_time: 14400000
no_lockfile: false
remote_write_flush_deadline: 1m0s
remote_write_add_org_id_header: true
traces_storage:
path: ""
completedfilepath: ""
blocksfilepath: ""
v2_encoding: none
search_encoding: none
ingestion_time_range_slack: 0s
version: vParquet3
metrics_ingestion_time_range_slack: 30s
query_timeout: 30s
override_ring_key: metrics-generator
storage:
trace:
pool:
max_workers: 400
queue_depth: 20000
wal:
path: /tmp/tempo/wal
completedfilepath: /tmp/tempo/wal/completed
blocksfilepath: /tmp/tempo/wal/blocks
v2_encoding: snappy
search_encoding: none
ingestion_time_range_slack: 2m0s
version: vParquet3
block:
bloom_filter_false_positive: 0.01
bloom_filter_shard_size_bytes: 102400
version: vParquet3
search_encoding: snappy
search_page_size_bytes: 1048576
v2_index_downsample_bytes: 1048576
v2_index_page_size_bytes: 256000
v2_encoding: zstd
parquet_row_group_size_bytes: 100000000
parquet_dedicated_columns: []
search:
chunk_size_bytes: 1000000
prefetch_trace_count: 1000
read_buffer_count: 32
read_buffer_size_bytes: 1048576
cache_control:
footer: false
column_index: false
offset_index: false
blocklist_poll: 5m0s
blocklist_poll_concurrency: 50
blocklist_poll_fallback: true
blocklist_poll_tenant_index_builders: 2
blocklist_poll_stale_tenant_index: 0s
blocklist_poll_jitter_ms: 0
blocklist_poll_tolerate_consecutive_errors: 1
backend: local
local:
path: /tmp/tempo/traces
gcs:
bucket_name: ""
prefix: ""
chunk_buffer_size: 10485760
endpoint: ""
hedge_requests_at: 0s
hedge_requests_up_to: 2
insecure: false
object_cache_control: ""
object_metadata: {}
list_blocks_concurrency: 3
s3:
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: VersionTLS12
bucket: ""
prefix: ""
endpoint: ""
region: ""
access_key: ""
secret_key: ""
session_token: ""
insecure: false
part_size: 0
hedge_requests_at: 0s
hedge_requests_up_to: 2
signature_v2: false
forcepathstyle: false
bucket_lookup_type: 0
tags: {}
storage_class: ""
metadata: {}
native_aws_auth_enabled: false
list_blocks_concurrency: 3
azure:
storage_account_name: ""
storage_account_key: ""
use_managed_identity: false
use_federated_token: false
user_assigned_id: ""
container_name: ""
prefix: ""
endpoint_suffix: blob.core.windows.net
max_buffers: 4
buffer_size: 3145728
hedge_requests_at: 0s
hedge_requests_up_to: 2
use_v2_sdk: false
cache: ""
background_cache:
writeback_goroutines: 10
writeback_buffer: 10000
memcached: null
redis: null
cache_min_compaction_level: 0
cache_max_block_age: 0s
overrides:
defaults:
ingestion:
rate_strategy: local
rate_limit_bytes: 15000000
burst_size_bytes: 20000000
max_traces_per_user: 10000
read:
max_bytes_per_tag_values_query: 5000000
global:
max_bytes_per_trace: 5000000
per_tenant_override_config: ""
per_tenant_override_period: 10s
user_configurable_overrides:
enabled: false
poll_interval: 1m0s
client:
backend: ""
confirm_versioning: true
local:
path: ""
gcs:
bucket_name: ""
prefix: ""
chunk_buffer_size: 10485760
endpoint: ""
hedge_requests_at: 0s
hedge_requests_up_to: 2
insecure: false
object_cache_control: ""
object_metadata: {}
list_blocks_concurrency: 3
s3:
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: VersionTLS12
bucket: ""
prefix: ""
endpoint: ""
region: ""
access_key: ""
secret_key: ""
session_token: ""
insecure: false
part_size: 0
hedge_requests_at: 0s
hedge_requests_up_to: 2
signature_v2: false
forcepathstyle: false
bucket_lookup_type: 0
tags: {}
storage_class: ""
metadata: {}
native_aws_auth_enabled: false
list_blocks_concurrency: 3
azure:
storage_account_name: ""
storage_account_key: ""
use_managed_identity: false
use_federated_token: false
user_assigned_id: ""
container_name: ""
prefix: ""
endpoint_suffix: blob.core.windows.net
max_buffers: 4
buffer_size: 3145728
hedge_requests_at: 0s
hedge_requests_up_to: 2
use_v2_sdk: false
api:
check_for_conflicting_runtime_overrides: false
memberlist:
node_name: ""
randomize_node_name: true
stream_timeout: 2s
retransmit_factor: 2
pull_push_interval: 30s
gossip_interval: 1s
gossip_nodes: 2
gossip_to_dead_nodes_time: 30s
dead_node_reclaim_time: 0s
compression_enabled: false
advertise_addr: ""
advertise_port: 7946
cluster_label: ""
cluster_label_verification_disabled: false
join_members: []
min_join_backoff: 1s
max_join_backoff: 1m0s
max_join_retries: 10
abort_if_cluster_join_fails: false
rejoin_interval: 0s
left_ingesters_timeout: 5m0s
leave_timeout: 20s
message_history_buffer_bytes: 0
bind_addr: []
bind_port: 7946
packet_dial_timeout: 2s
packet_write_timeout: 5s
tls_enabled: false
tls_cert_path: ""
tls_key_path: ""
tls_ca_path: ""
tls_server_name: ""
tls_insecure_skip_verify: false
tls_cipher_suites: ""
tls_min_version: ""
usage_report:
reporting_enabled: true
backoff:
min_period: 100ms
max_period: 10s
max_retries: 0
cache:
background:
writeback_goroutines: 10
writeback_buffer: 10000
caches: []
@@ -1,54 +0,0 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
server:
http_listen_port: 3200
distributor:
receivers: # this configuration will listen on all ports and protocols that tempo is capable of.
jaeger: # the receives all come from the OpenTelemetry collector. more configuration information can
protocols: # be found there: https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver
thrift_http: #
grpc: # for a production deployment you should only enable the receivers you need!
thrift_binary:
thrift_compact:
zipkin:
otlp:
protocols:
http:
grpc:
opencensus:
ingester:
max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally
compactor:
compaction:
block_retention: 1h # overall Tempo trace retention. set for demo purposes
# metrics_generator:
# registry:
# external_labels:
# source: tempo
# cluster: docker-compose
# storage:
# path: /tmp/tempo/generator/wal
# remote_write:
# - url: http://grafana-alloy:12345/api/v1/write
# send_exemplars: true
storage:
trace:
backend: s3 # backend configuration to use
wal:
path: /tmp/tempo/wal # where to store the the wal locally
s3:
bucket: tempo # how to store data in s3
endpoint: minio:9000
access_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['MINIO_TEMPO_STORAGE_ACCESS_KEY'] }}
secret_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['MINIO_TEMPO_STORAGE_SECRET_KEY'] }}
insecure: true
usage_report:
reporting_enabled: false
@@ -31,3 +31,9 @@
url: http://192.168.1.252:8123
key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['HOMEPAGE_HOME_ASSISTANT_API_KEY'] }}
- Media Library:
- Audiomuse:
href: https://muse.trez.wtf
description: Automatic playlist generation using AI
icon: /icons/audiomuseai.png
weight: 0
+4 -4
View File
@@ -1,10 +1,10 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
containers:
adguard:
action_keywords:
- restart:
regex: '\[error\] dnsproxy.*timeout'
# adguard:
# action_keywords:
# - restart:
# regex: '\[error\] dnsproxy.*timeout'
ghost_blog:
action_keywords:
- restart:
@@ -26,17 +26,6 @@
},
"sources": [
{
"type": "spotify",
"enabled": true,
"name": "spotifySource",
"clients": ["lastFmClient", "ListenBrainzClient", "malojaClient"],
"data": {
"clientId": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['YOUR_SPOTIFY_ID'] }}",
"clientSecret": "{{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['YOUR_SPOTIFY_SECRET'] }}",
"redirectUri": "https://scrobble.trez.wtf/callback"
}
},
{
"type": "lastfm",
"enabled": true,
+55
View File
@@ -0,0 +1,55 @@
[botdetection]
# The prefix defines the number of leading bits in an address that are compared
# to determine whether or not an address is part of a (client) network.
ipv4_prefix = 32
ipv6_prefix = 48
# If the request IP is in trusted_proxies list, the client IP address is
# extracted from the X-Forwarded-For and X-Real-IP headers. This should be
# used if SearXNG is behind a reverse proxy or load balancer.
trusted_proxies = [
'127.0.0.0/8',
'::1',
'192.168.0.0/16',
'172.16.0.0/12',
'172.17.0.0/12',
'172.18.0.0/12'
# '10.0.0.0/8',
# 'fd00::/8',
]
[botdetection.ip_limit]
# To get unlimited access in a local network, by default link-local addresses
# (networks) are not monitored by the ip_limit
filter_link_local = false
# activate link_token method in the ip_limit method
link_token = false
[botdetection.ip_lists]
# In the limiter, the ip_lists method has priority over all other methods -> if
# an IP is in the pass_ip list, it has unrestricted access and it is also not
# checked if e.g. the "user agent" suggests a bot (e.g. curl).
block_ip = [
# '93.184.216.34', # IPv4 of example.org
# '257.1.1.1', # invalid IP --> will be ignored, logged in ERROR class
]
pass_ip = [
# '192.168.0.0/16', # IPv4 private network
# 'fe80::/10' # IPv6 linklocal / wins over botdetection.ip_limit.filter_link_local
'192.168.0.0/16',
'172.16.0.0/12',
'172.17.0.0/12',
'172.18.0.0/12'
]
# Activate passlist of (hardcoded) IPs from the SearXNG organization,
# e.g. `check.searx.space`.
pass_searxng_org = true
+43 -166
View File
@@ -1,5 +1,6 @@
{% set vault_addr = 'https://vault.trez.wtf' %}
{% set secrets_path = 'rinoa-docker/env' %}
general:
# Debug mode, only for development. Is overwritten by ${SEARXNG_DEBUG}
debug: false
@@ -16,7 +17,6 @@ general:
enable_metrics: true
# expose stats in open metrics format at /metrics
# leave empty to disable (no password set)
# open_metrics: <password>
open_metrics: ''
brand:
@@ -25,87 +25,35 @@ brand:
public_instances: https://searx.space
wiki_url: https://github.com/searxng/searxng/wiki
issue_url: https://github.com/searxng/searxng/issues
# custom:
# maintainer: "Jon Doe"
# # Custom entries in the footer: [title]: [link]
# links:
# Uptime: https://uptime.searxng.org/history/darmarit-org
# About: "https://searxng.org"
search:
# Filter results. 0: None, 1: Moderate, 2: Strict
safe_search: 0
# Existing autocomplete backends: "360search", "baidu", "brave", "dbpedia", "duckduckgo", "google", "yandex",
# "mwmbl", "naver", "seznam", "sogou", "startpage", "stract", "swisscows", "quark", "qwant", "wikipedia" -
# leave blank to turn it off by default.
autocomplete: ""
# minimun characters to type before autocompleter starts
autocomplete_min: 4
# backend for the favicon near URL in search results.
# Available resolvers: "allesedv", "duckduckgo", "google", "yandex" - leave blank to turn it off by default.
favicon_resolver: ""
# Default search language - leave blank to detect from browser information or
# use codes from 'languages.py'
default_lang: "auto"
# max_page: 0 # if engine supports paging, 0 means unlimited numbers of pages
# Available languages
# languages:
# - all
# - en
# - en-US
# - de
# - it-IT
# - fr
# - fr-BE
# ban time in seconds after engine errors
ban_time_on_fail: 5
# max ban time in seconds after engine errors
max_ban_time_on_fail: 120
suspended_times:
# Engine suspension time after error (in seconds; set to 0 to disable)
# For error "Access denied" and "HTTP error [402, 403]"
SearxEngineAccessDenied: 86400
# For error "CAPTCHA"
SearxEngineCaptcha: 86400
# For error "Too many request" and "HTTP error 429"
SearxEngineTooManyRequests: 3600
# Cloudflare CAPTCHA
cf_SearxEngineCaptcha: 1296000
cf_SearxEngineAccessDenied: 86400
# ReCAPTCHA
recaptcha_SearxEngineCaptcha: 604800
# remove format to deny access, use lower case.
# formats: [html, csv, json, rss]
formats:
- html
server:
# Is overwritten by ${SEARXNG_PORT} and ${SEARXNG_BIND_ADDRESS}
port: 8888
bind_address: "127.0.0.1"
# public URL of the instance, to ensure correct inbound links. Is overwritten
# by ${SEARXNG_BASE_URL}.
base_url: false # "http://example.com/location"
# rate limit the number of request on the instance, block some bots.
# Is overwritten by ${SEARXNG_LIMITER}
base_url: false
limiter: false
# enable features designed only for public instances.
# Is overwritten by ${SEARXNG_PUBLIC_INSTANCE}
public_instance: false
# If your instance owns a /etc/searxng/settings.yml file, then set the following
# values there.
secret_key: {{ lookup('community.hashi_vault.vault_kv2_get', 'env', engine_mount_point='rinoa-docker', url=vault_addr, token=vault_token)['secret']['SEARXNG_SECRET_KEY'] }} # Is overwritten by ${SEARXNG_SECRET}
# Proxy image results through SearXNG. Is overwritten by ${SEARXNG_IMAGE_PROXY}
image_proxy: true
# 1.0 and 1.1 are supported
http_protocol_version: "1.0"
# POST queries are "more secure!" but are also the source of hard-to-locate
# annoyances, which is why GET may be better for end users and their browsers.
# see https://github.com/searxng/searxng/pull/3619
# Is overwritten by ${SEARXNG_METHOD}
method: "POST"
default_http_headers:
X-Content-Type-Options: nosniff
@@ -114,41 +62,20 @@ server:
Referrer-Policy: no-referrer
valkey:
# URL to connect valkey database. Is overwritten by ${SEARXNG_VALKEY_URL}.
# https://docs.searxng.org/admin/settings/settings_valkey.html#settings-valkey
# url: valkey://localhost:6379/0
url: redis://searxng-valkey:6379/0
ui:
# Custom static path - leave it blank if you didn't change
static_path: ""
# Custom templates path - leave it blank if you didn't change
templates_path: ""
# query_in_title: When true, the result page's titles contains the query
# it decreases the privacy, since the browser can records the page titles.
query_in_title: true
# infinite_scroll: When true, automatically loads the next page when scrolling to bottom of the current page.
infinite_scroll: true
# ui theme
default_theme: simple
# center the results ?
center_alignment: false
# URL prefix of the internet archive, don't forget trailing slash (if needed).
# cache_url: "https://webcache.googleusercontent.com/search?q=cache:"
# Default interface locale - leave blank to detect from browser information or
# use codes from the 'locales' config section
default_locale: ""
# Open result links in a new tab by default
# results_on_new_tab: false
theme_args:
# style of simple theme: auto, light, dark
simple_style: auto
# Perform search immediately if a category selected.
# Disable to select multiple categories at once and start the search manually.
search_on_category_select: true
# Hotkeys: default or vim
hotkeys: default
# URL formatting: pretty, full or host
url_formatting: pretty
# Lock arbitrary settings on the preferences page.
@@ -165,7 +92,6 @@ ui:
# - locale
# - theme
# - results_on_new_tab
# - infinite_scroll
# - search_on_category_select
# - method
# - image_proxy
@@ -177,7 +103,7 @@ outgoing:
# default timeout in seconds, can be override by engine
request_timeout: 3.0
# the maximum timeout in seconds
# max_request_timeout: 10.0
max_request_timeout: 10.0
# suffix of searxng_useragent, could contain information like an email address
# to the administrator
useragent_suffix: ""
@@ -217,6 +143,7 @@ outgoing:
# - 1.1.1.2
# - fe80::/126
# Plugin configuration, for more details see
# https://docs.searxng.org/admin/settings/settings_plugins.html
#
@@ -225,6 +152,9 @@ plugins:
searx.plugins.calculator.SXNGPlugin:
active: true
searx.plugins.infinite_scroll.SXNGPlugin:
active: true
searx.plugins.hash_plugin.SXNGPlugin:
active: true
@@ -390,25 +320,6 @@ engines:
timeout: 6
disabled: true
- name: alexandria
engine: json_engine
shortcut: alx
categories: general
paging: true
search_url: https://api.alexandria.org/?a=1&q={query}&p={pageno}
results_query: results
title_query: title
url_query: url
content_query: snippet
timeout: 1.5
disabled: true
about:
website: https://alexandria.org/
official_api_documentation: https://github.com/alexandria-org/alexandria-api/raw/master/README.md
use_official_api: true
require_api_key: false
results: JSON
- name: astrophysics data system
engine: astrophysics_data_system
shortcut: ads
@@ -498,6 +409,15 @@ engines:
shortcut: ask
disabled: true
# - name: azure
# engine: azure
# shortcut: az
# categories: [it, cloud]
# azure_tenant_id: "your_tenant_id"
# azure_client_id: "your_client_id"
# azure_client_secret: "your_client_secret"
# disabled: true
# tmp suspended: dh key too small
# - name: base
# engine: base
@@ -667,12 +587,6 @@ engines:
api_key: ""
inactive: true
# - name: cppreference
# engine: cppreference
# shortcut: cpp
# paging: false
# disabled: true
- name: crossref
engine: crossref
shortcut: cr
@@ -736,6 +650,11 @@ engines:
shortcut: da
timeout: 3.0
- name: devicons
engine: devicons
shortcut: di
timeout: 3.0
- name: ddg definitions
engine: duckduckgo_definitions
shortcut: ddd
@@ -1072,6 +991,12 @@ engines:
play_categ: movies
disabled: true
- name: grokipedia
engine: grokipedia
shortcut: gp
disabled: true
inactive: true
- name: material icons
engine: material_icons
shortcut: mi
@@ -1300,6 +1225,11 @@ engines:
require_api_key: false
results: HTML
- name: lucide
engine: lucide
shortcut: luc
timeout: 3.0
- name: marginalia
engine: marginalia
shortcut: mar
@@ -1434,22 +1364,6 @@ engines:
require_api_key: false
results: JSON
# https://docs.searxng.org/dev/engines/online/mullvad_leta.html
- name: mullvadleta
engine: mullvad_leta
disabled: true
leta_engine: google
categories: [general, web]
shortcut: ml
- name: mullvadleta brave
engine: mullvad_leta
network: mullvadleta
disabled: true
leta_engine: brave
categories: [general, web]
shortcut: mlb
- name: odysee
engine: odysee
shortcut: od
@@ -1640,6 +1554,7 @@ engines:
engine: pixiv
disabled: true
inactive: true
remove_ai_images: false
pixiv_image_proxies:
- https://pximg.example.org
# A proxy is required to load the images. Hosting an image proxy server
@@ -2134,22 +2049,21 @@ engines:
search_type: web
shortcut: yd
disabled: true
inactive: true
- name: yandex images
engine: yandex
network: yandex
categories: images
search_type: images
shortcut: ydi
disabled: true
inactive: true
- name: yandex music
engine: yandex_music
network: yandex
shortcut: ydm
disabled: true
# https://yandex.com/support/music/access.html
inactive: true
- name: yahoo
engine: yahoo
@@ -2298,31 +2212,27 @@ engines:
- name: wikicommons.images
engine: wikicommons
shortcut: wc
shortcut: wci
categories: images
search_type: images
number_of_results: 10
wc_search_type: image
- name: wikicommons.videos
engine: wikicommons
shortcut: wcv
categories: videos
search_type: videos
number_of_results: 10
wc_search_type: video
- name: wikicommons.audio
engine: wikicommons
shortcut: wca
categories: music
search_type: audio
number_of_results: 10
wc_search_type: audio
- name: wikicommons.files
engine: wikicommons
shortcut: wcf
categories: files
search_type: files
number_of_results: 10
wc_search_type: file
- name: wolframalpha
shortcut: wa
@@ -2681,43 +2591,10 @@ engines:
- name: sourcehut
shortcut: srht
engine: xpath
paging: true
search_url: https://sr.ht/projects?page={pageno}&search={query}
results_xpath: (//div[@class="event-list"])[1]/div[@class="event"]
url_xpath: ./h4/a[2]/@href
title_xpath: ./h4/a[2]
content_xpath: ./p
first_page_num: 1
categories: [it, repos]
engine: sourcehut
# https://docs.searxng.org/dev/engines/online/sourcehut.html
# sourcehut_sort_order: longest-active
disabled: true
about:
website: https://sr.ht
wikidata_id: Q78514485
official_api_documentation: https://man.sr.ht/
use_official_api: false
require_api_key: false
results: HTML
- name: goo
shortcut: goo
engine: xpath
paging: true
search_url: https://search.goo.ne.jp/web.jsp?MT={query}&FR={pageno}0
url_xpath: //div[@class="result"]/p[@class='title fsL1']/a/@href
title_xpath: //div[@class="result"]/p[@class='title fsL1']/a
content_xpath: //p[contains(@class,'url fsM')]/following-sibling::p
first_page_num: 0
categories: [general, web]
disabled: true
timeout: 4.0
about:
website: https://search.goo.ne.jp
wikidata_id: Q249044
use_official_api: false
require_api_key: false
results: HTML
language: ja
- name: bt4g
engine: bt4g
@@ -0,0 +1,47 @@
## Version 2025/07/18
# make sure that your <container_name> container is named <container_name>
# make sure that your dns has a cname set for <container_name>
server {
listen 443 ssl;
# listen 443 quic;
listen [::]:443 ssl;
# listen [::]:443 quic;
server_name muse.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
# enable for ldap auth (requires ldap-location.conf in the location block)
#include /config/nginx/ldap-server.conf;
# enable for Authelia (requires authelia-location.conf in the location block)
#include /config/nginx/authelia-server.conf;
# enable for Authentik (requires authentik-location.conf in the location block)
#include /config/nginx/authentik-server.conf;
# enable for Tinyauth (requires tinyauth-location.conf in the location block)
#include /config/nginx/tinyauth-server.conf;
location / {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable for ldap auth (requires ldap-server.conf in the server block)
#include /config/nginx/ldap-location.conf;
# enable for Authelia (requires authelia-server.conf in the server block)
#include /config/nginx/authelia-location.conf;
# enable for Authentik (requires authentik-server.conf in the server block)
#include /config/nginx/authentik-location.conf;
# enable for Tinyauth (requires tinyauth-server.conf in the server block)
#include /config/nginx/tinyauth-location.conf;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app 192.168.1.248;
set $upstream_port 8000;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
@@ -0,0 +1,47 @@
## Version 2025/07/18
# make sure that your <container_name> container is named <container_name>
# make sure that your dns has a cname set for <container_name>
server {
listen 443 ssl;
# listen 443 quic;
listen [::]:443 ssl;
# listen [::]:443 quic;
server_name cron.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
# enable for ldap auth (requires ldap-location.conf in the location block)
#include /config/nginx/ldap-server.conf;
# enable for Authelia (requires authelia-location.conf in the location block)
#include /config/nginx/authelia-server.conf;
# enable for Authentik (requires authentik-location.conf in the location block)
#include /config/nginx/authentik-server.conf;
# enable for Tinyauth (requires tinyauth-location.conf in the location block)
#include /config/nginx/tinyauth-server.conf;
location / {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable for ldap auth (requires ldap-server.conf in the server block)
#include /config/nginx/ldap-location.conf;
# enable for Authelia (requires authelia-server.conf in the server block)
#include /config/nginx/authelia-location.conf;
# enable for Authentik (requires authentik-server.conf in the server block)
#include /config/nginx/authentik-location.conf;
# enable for Tinyauth (requires tinyauth-server.conf in the server block)
#include /config/nginx/tinyauth-location.conf;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app 192.168.1.241;
set $upstream_port 8080;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
@@ -0,0 +1,54 @@
{
"binarize": true,
"allowed_encodings": [
"JSON-B64",
"JSON-URLSAFE-B64",
"JSON-B91",
"JSON-Z85B",
"JSON-Z85P",
"JSON-B32",
"JSON-HEX"
],
"allowed_ciphers": [
"CHACHA20-POLY1305",
"AES-GCM"
],
"agent_protocol": {
"module": "hivemind-ovos-agent-plugin",
"hivemind-ovos-agent-plugin": {
"host": "127.0.0.1",
"port": 8181
}
},
"binary_protocol": {
"module": "hivemind-audio-binary-protocol-plugin",
"hivemind-audio-binary-protocol-plugin": {},
"network_protocol": {
"hivemind-websocket-plugin": {
"host": "0.0.0.0",
"port": 5678,
"ssl": false,
"cert_dir": "/home/hivemind/.local/share/hivemind",
"cert_name": "hivemind"
},
"hivemind-http-plugin": {
"host": "0.0.0.0",
"port": 5679,
"ssl": false,
"cert_dir": "/home/hivemind/.local/share/hivemind",
"cert_name": "hivemind"
}
},
"database": {
"module": "hivemind-json-db-plugin",
"hivemind-json-db-plugin": {
"name": "clients",
"subfolder": "hivemind-core"
}
}
}
+24
View File
@@ -0,0 +1,24 @@
{
"mcpServers": {
"context7": {
"type": "streamable-http",
"url": "http://context7-mcp:8080/mcp"
},
"gitea": {
"type": "streamable-http",
"url": "http://gitea-mcp:8080/mcp"
},
"searxng": {
"type": "streamable-http",
"url": "http://searxng-mcp:3000/mcp"
},
"signoz": {
"type": "streamable-http",
"url": "http://signoz-mcp-server:8000/mcp"
},
"wikipedia": {
"type": "streamable-http",
"url": "http://wikipedia-mcp:8000/mcp"
}
}
}
@@ -10,7 +10,7 @@
"confirm_listening": true,
"intents": {
"persona": {
"handle_fallback": true,
"handle_fallback": true,
"default_persona": "Benedikta"
},
"pipeline": [
@@ -38,7 +38,7 @@
}
},
"tts": {
"module": "ovos-tts-plugin-server",
"module": "ovos-tts-plugin-server",
"ovos-tts-plugin-server": {
"voice": "alba-medium"
},
@@ -52,14 +52,11 @@
"module": "ovos-stt-plugin-server",
"fallback_module": "ovos-stt-plugin-fasterwhisper",
"ovos-stt-plugin-fasterwhisper": {
"model": "tiny.en"
"model": "base.en"
}
},
"listener": {
"wake_word": "hey_benedikta",
"VAD": {
"module": "ovos-vad-plugin-silero"
}
"wake_word": "hey_benedikta"
},
"hotwords": {
"hey_benedikta": {
+10 -10
View File
@@ -4,13 +4,13 @@ template_base_path: "{{ playbook_dir }}/app-configs"
# Vault server address
vault_addr: "https://vault.trez.wtf"
vault_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
31386335336463633735623162613537393463393064393062626636343363636131633634666433
3634316561633766613436346233333932353763656631360a366266643366636337336338613834
61353833663862346533303135363531646166623138613563373738646637303437373264613765
3363393563653637310a363736663232643066356266316535393265376236663635353065636138
34303935383661633364393864656135323639336463323736653866643238356166356139623733
37623438353739343565646464666433656465373135643562383163383862646435393564353166
37306663646339313330383465393937353830643235666362393630643065336161363434316563
64633563363465313165393461393866313662346135313139363436363365643839643839323532
3264
$ANSIBLE_VAULT;1.1;AES256
33356331366463343032656164363437313263623962303365306632336362353038653738336338
3261303838386531653661353231343361316566633531300a326637636135383832386466656235
32316564653863346336316331306130333739663832613536323264336530383834323461313064
6639383633643866310a343332616235343462346436373035636266636239346438346633303932
64383135616261326466643661356539346233633639343865303964366236373161393764353838
65633631346166323961393532393133353838393332663963383566663136613232383662626165
63643838306332373237393938326131633838613331363663653638623830633364373464376463
39623034306164393863343133313135653839363236613232663563346334303333313634333334
6635
+9
View File
@@ -0,0 +1,9 @@
appdata_base_path: /home/charish/.config/docker
ansible_become_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
65303564363831353738376239316665393435363663323231383436366566353534636164656336
6661633033623139376338656131353964666232383331660a343933643030383438626661633661
39333338306565383435326465386366356164643834303431623961653731303139633332326133
6561653432656462330a303966633132366637633235316631353839383331333765336237353135
39363465623933393535643862316262303333363038636634326233316636396666
secrets_path: aranea-docker/env
-2
View File
@@ -1,2 +0,0 @@
appdata_base_path: /home/ovos/ovos/config
secrets_path: benedikta-docker/env
+9
View File
@@ -0,0 +1,9 @@
appdata_base_path: /home/charish/.config/docker
ansible_become_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
35396634626231373032376235343761316638376262333766376362363930666364303031306533
3664323164363738663965343933643536616135393036350a306161626161303935383434326536
66376165623634653966313033613230306365393334663334363730653330313031326231383739
3036633032376133370a316463653162633566303363376631383033396234383366633737383066
35393931393132323062386262623966646139613838373536313631643330313761
secrets_path: benedikta-docker/env
+5 -5
View File
@@ -1,11 +1,11 @@
appdata_base_path: /home/charish/.docker/config/appdata
ansible_become_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
33393031336537653965343539636434613066326131653737396561653031336665633430353837
3166363261623634363162626161633831316539643339620a326538663930396335646631356335
39643539313531646566353034313734646432626462646530303762323939613833663237316631
3134383462306432630a626163356437336331356339353332613265366564323234613732626331
64333464306531303163376566393065643136633165373364373733323838616437
30646333393563333364333935396530353265616233323839616266653938396561343539336337
6531313061626132636362373833356631336161626435660a643539353930396532653234393663
31623863633966303738643733643633353265396264613734333461643862663965663230663437
6136373035303834630a653263626365623838363236303931643565656232326536643239653238
64313034313663653332343464383565383964373438663661346538366636323162
secrets_path: rinoa-docker/env
file_metadata:
"hashicorp-vault/config/vault-config.hcl.j2":
+9
View File
@@ -0,0 +1,9 @@
appdata_base_path: /home/charish/.config/docker
ansible_become_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
37363634303539386437373433653834326537613239373539383731333364316461373436646233
3965616330356537666537323433666339653166616361370a616639363432643964343131636265
64623239343238363763386466626632383230633062383263323433353634373539373861383038
3837383436363138330a653566653731653065343538363733353432646136336335643666376133
31623634636561636635396136636538613338313862396439376435613337373637
secrets_path: ultima-docker/env
+11 -5
View File
@@ -1,11 +1,17 @@
all:
hosts:
rinoa:
ansible_host: 192.168.1.254
aranea:
ansible_host: 192.168.1.241
ansible_user: charish
lunafreya:
ansible_host: 192.168.1.250
ansible_user: charish
rikku:
ansible_host: 192.168.1.252
ansible_user: pi
benedikta:
ansible_host: 192.168.1.250
ansible_user: ovos
rinoa:
ansible_host: 192.168.1.254
ansible_user: charish
ultima:
ansible_host: 192.168.1.248
ansible_user: charish
+26
View File
@@ -0,0 +1,26 @@
Copyright 2021, the Mitogen authors
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+1
View File
@@ -0,0 +1 @@
include LICENSE
+52
View File
@@ -0,0 +1,52 @@
Metadata-Version: 2.4
Name: mitogen
Version: 0.3.44
Summary: Library for writing distributed self-replicating programs.
Home-page: https://github.com/mitogen-hq/mitogen/
Author: David Wilson
License: BSD-3-Clause
Classifier: Environment :: Console
Classifier: Framework :: Ansible
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: System :: Distributed Computing
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=2.4, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: requires-python
Dynamic: summary
# Mitogen
[![PyPI - Version](https://img.shields.io/pypi/v/mitogen)](https://pypi.org/project/mitogen/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mitogen)](https://pypi.org/project/mitogen/)
[![Build Status](https://img.shields.io/github/actions/workflow/status/mitogen-hq/mitogen/tests.yml?branch=master)](https://github.com/mitogen-hq/mitogen/actions?query=branch%3Amaster)
<a href="https://mitogen.networkgenomics.com/">Please see the documentation</a>.
![](https://i.imgur.com/eBM6LhJ.gif)
+9
View File
@@ -0,0 +1,9 @@
# Mitogen
[![PyPI - Version](https://img.shields.io/pypi/v/mitogen)](https://pypi.org/project/mitogen/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mitogen)](https://pypi.org/project/mitogen/)
[![Build Status](https://img.shields.io/github/actions/workflow/status/mitogen-hq/mitogen/tests.yml?branch=master)](https://github.com/mitogen-hq/mitogen/actions?query=branch%3Amaster)
<a href="https://mitogen.networkgenomics.com/">Please see the documentation</a>.
![](https://i.imgur.com/eBM6LhJ.gif)
@@ -0,0 +1,287 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
As Mitogen separates asynchronous IO out to a broker thread, communication
necessarily involves context switching and waking that thread. When application
threads and the broker share a CPU, this can be almost invisibly fast - around
25 microseconds for a full A->B->A round-trip.
However when threads are scheduled on different CPUs, round-trip delays
regularly vary wildly, and easily into milliseconds. Many contributing factors
exist, not least scenarios like:
1. A is preempted immediately after waking B, but before releasing the GIL.
2. B wakes from IO wait only to immediately enter futex wait.
3. A may wait 10ms or more for another timeslice, as the scheduler on its CPU
runs threads unrelated to its transaction (i.e. not B), wake only to release
its GIL, before entering IO sleep waiting for a reply from B, which cannot
exist yet.
4. B wakes, acquires GIL, performs work, and sends reply to A, causing it to
wake. B is preempted before releasing GIL.
5. A wakes from IO wait only to immediately enter futex wait.
6. B may wait 10ms or more for another timeslice, wake only to release its GIL,
before sleeping again.
7. A wakes, acquires GIL, finally receives reply.
Per above if we are unlucky, on an even moderately busy machine it is possible
to lose milliseconds just in scheduling delay, and the effect is compounded
when pairs of threads in process A are communicating with pairs of threads in
process B using the same scheme, such as when Ansible WorkerProcess is
communicating with ContextService in the connection multiplexer. In the worst
case it could involve 4 threads working in lockstep spread across 4 busy CPUs.
Since multithreading in Python is essentially useless except for waiting on IO
due to the presence of the GIL, at least in Ansible there is no good reason for
threads in the same process to run on distinct CPUs - they always operate in
lockstep due to the GIL, and are thus vulnerable to issues like above.
Linux lacks any natural API to describe what we want, it only permits
individual threads to be constrained to run on specific CPUs, and for that
constraint to be inherited by new threads and forks of the constrained thread.
This module therefore implements a CPU pinning policy for Ansible processes,
providing methods that should be called early in any new process, either to
rebalance which CPU it is pinned to, or in the case of subprocesses, to remove
the pinning entirely. It is likely to require ongoing tweaking, since pinning
necessarily involves preventing the scheduler from making load balancing
decisions.
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import ctypes
import logging
import mmap
import multiprocessing
import os
import struct
import mitogen.parent
LOG = logging.getLogger(__name__)
try:
_libc = ctypes.CDLL(None, use_errno=True)
_strerror = _libc.strerror
_strerror.restype = ctypes.c_char_p
_sem_init = _libc.sem_init
_sem_wait = _libc.sem_wait
_sem_post = _libc.sem_post
_sched_setaffinity = _libc.sched_setaffinity
except (OSError, AttributeError):
_libc = None
_strerror = None
_sem_init = None
_sem_wait = None
_sem_post = None
_sched_setaffinity = None
class sem_t(ctypes.Structure):
"""
Wrap sem_t to allow storing a lock in shared memory.
"""
_fields_ = [
('data', ctypes.c_uint8 * 128),
]
def init(self):
if _sem_init(self.data, 1, 1):
raise Exception(_strerror(ctypes.get_errno()))
def acquire(self):
if _sem_wait(self.data):
raise Exception(_strerror(ctypes.get_errno()))
def release(self):
if _sem_post(self.data):
raise Exception(_strerror(ctypes.get_errno()))
class State(ctypes.Structure):
"""
Contents of shared memory segment. This allows :meth:`Manager.assign` to be
called from any child, since affinity assignment must happen from within
the context of the new child process.
"""
_fields_ = [
('lock', sem_t),
('counter', ctypes.c_uint8),
]
class Policy(object):
"""
Process affinity policy.
"""
def assign_controller(self):
"""
Assign the Ansible top-level policy to this process.
"""
def assign_muxprocess(self, index):
"""
Assign the MuxProcess policy to this process.
"""
def assign_worker(self):
"""
Assign the WorkerProcess policy to this process.
"""
def assign_subprocess(self):
"""
Assign the helper subprocess policy to this process.
"""
class FixedPolicy(Policy):
"""
:class:`Policy` for machines where the only control method available is
fixed CPU placement. The scheme here was tested on an otherwise idle 16
thread machine.
- The connection multiplexer is pinned to CPU 0.
- The Ansible top-level (strategy) is pinned to CPU 1.
- WorkerProcesses are pinned sequentually to 2..N, wrapping around when no
more CPUs exist.
- Children such as SSH may be scheduled on any CPU except 0/1.
If the machine has less than 4 cores available, the top-level and workers
are pinned between CPU 2..N, i.e. no CPU is reserved for the top-level
process.
This could at least be improved by having workers pinned to independent
cores, before reusing the second hyperthread of an existing core.
A hook is installed that causes :meth:`reset` to run in the child of any
process created with :func:`mitogen.parent.popen`, ensuring CPU-intensive
children like SSH are not forced to share the same core as the (otherwise
potentially very busy) parent.
"""
def __init__(self, cpu_count=None):
#: For tests.
self.cpu_count = cpu_count or multiprocessing.cpu_count()
self.mem = mmap.mmap(-1, 4096)
self.state = State.from_buffer(self.mem)
self.state.lock.init()
if self.cpu_count < 2:
# uniprocessor
self._reserve_mux = False
self._reserve_controller = False
self._reserve_mask = 0
self._reserve_shift = 0
elif self.cpu_count < 4:
# small SMP
self._reserve_mux = True
self._reserve_controller = False
self._reserve_mask = 1
self._reserve_shift = 1
else:
# big SMP
self._reserve_mux = True
self._reserve_controller = True
self._reserve_mask = 3
self._reserve_shift = 2
def _set_affinity(self, descr, mask):
if descr:
LOG.debug('CPU mask for %s: %#08x', descr, mask)
mitogen.parent._preexec_hook = self._clear
self._set_cpu_mask(mask)
def _balance(self, descr):
self.state.lock.acquire()
try:
n = self.state.counter
self.state.counter += 1
finally:
self.state.lock.release()
self._set_cpu(descr, self._reserve_shift + (
(n % (self.cpu_count - self._reserve_shift))
))
def _set_cpu(self, descr, cpu):
self._set_affinity(descr, 1 << (cpu % self.cpu_count))
def _clear(self):
all_cpus = (1 << self.cpu_count) - 1
self._set_affinity(None, all_cpus & ~self._reserve_mask)
def assign_controller(self):
if self._reserve_controller:
self._set_cpu('Ansible top-level process', 1)
else:
self._balance('Ansible top-level process')
def assign_muxprocess(self, index):
self._set_cpu('MuxProcess %d' % (index,), index)
def assign_worker(self):
self._balance('WorkerProcess')
def assign_subprocess(self):
self._clear()
class LinuxPolicy(FixedPolicy):
def _mask_to_bytes(self, mask):
"""
Convert the (type long) mask to a cpu_set_t.
"""
chunks = []
shiftmask = (2 ** 64) - 1
for x in range(16):
chunks.append(struct.pack('<Q', mask & shiftmask))
mask >>= 64
return b''.join(chunks)
def _get_thread_ids(self):
try:
ents = os.listdir('/proc/self/task')
except OSError:
LOG.debug('cannot fetch thread IDs for current process')
return [os.getpid()]
return [int(s) for s in ents if s.isdigit()]
def _set_cpu_mask(self, mask):
s = self._mask_to_bytes(mask)
for tid in self._get_thread_ids():
_sched_setaffinity(tid, len(s), s)
if _sched_setaffinity is not None:
policy = LinuxPolicy()
else:
policy = Policy()
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,86 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
Stable names for PluginLoader instances across Ansible versions.
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import ansible.errors
import ansible_mitogen.utils
__all__ = [
'action_loader',
'become_loader',
'connection_loader',
'module_loader',
'module_utils_loader',
'shell_loader',
'strategy_loader',
]
ANSIBLE_VERSION_MIN = (2, 10)
OLD_VERSION_MSG = (
"Your version of Ansible (%s) is too old. The oldest version supported by "
"Mitogen for Ansible is %s."
)
def assert_supported_release():
"""
Throw AnsibleError with a descriptive message in case of being loaded into
an unsupported Ansible release.
"""
v = ansible_mitogen.utils.ansible_version
if v[:2] < ANSIBLE_VERSION_MIN:
raise ansible.errors.AnsibleError(
OLD_VERSION_MSG % (v, ANSIBLE_VERSION_MIN)
)
# this is the first file our strategy plugins import, so we need to check this here
# in prior Ansible versions, connection_loader.get_with_context didn't exist, so if a user
# is trying to load an old Ansible version, we'll fail and error gracefully
assert_supported_release()
from ansible.plugins.loader import action_loader
from ansible.plugins.loader import become_loader
from ansible.plugins.loader import connection_loader
from ansible.plugins.loader import module_loader
from ansible.plugins.loader import module_utils_loader
from ansible.plugins.loader import shell_loader
from ansible.plugins.loader import strategy_loader
# These are original, unwrapped implementations
action_loader__get_with_context = action_loader.get_with_context
connection_loader__get_with_context = connection_loader.get_with_context
@@ -0,0 +1,127 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import logging
import os
import ansible.utils.display
import mitogen.utils
display = ansible.utils.display.Display()
#: The process name set via :func:`set_process_name`.
_process_name = None
#: The PID of the process that last called :func:`set_process_name`, so its
#: value can be ignored in unknown fork children.
_process_pid = None
def set_process_name(name):
"""
Set a name to adorn log messages with.
"""
global _process_name
_process_name = name
global _process_pid
_process_pid = os.getpid()
class Handler(logging.Handler):
"""
Use Mitogen's log format, but send the result to a Display method.
"""
def __init__(self, normal_method):
logging.Handler.__init__(self)
self.formatter = mitogen.utils.log_get_formatter()
self.normal_method = normal_method
#: Set of target loggers that produce warnings and errors that spam the
#: console needlessly. Their log level is forced to INFO. A better strategy
#: may simply be to bury all target logs in DEBUG output, but not by
#: overriding their log level as done here.
NOISY_LOGGERS = frozenset([
'dnf', # issue #272; warns when a package is already installed.
'boto', # issue #541; normal boto retry logic can cause ERROR logs.
])
def emit(self, record):
mitogen_name = getattr(record, 'mitogen_name', '')
if mitogen_name == 'stderr':
record.levelno = logging.ERROR
if mitogen_name in self.NOISY_LOGGERS and record.levelno >= logging.WARNING:
record.levelno = logging.DEBUG
if _process_pid == os.getpid():
process_name = _process_name
else:
process_name = '?'
s = '[%-4s %d] %s' % (process_name, os.getpid(), self.format(record))
if record.levelno >= logging.ERROR:
display.error(s, wrap_text=False)
elif record.levelno >= logging.WARNING:
display.warning(s, formatted=True)
else:
self.normal_method(s)
def setup():
"""
Install handlers for Mitogen loggers to redirect them into the Ansible
display framework. Ansible installs its own logging framework handlers when
C.DEFAULT_LOG_PATH is set, therefore disable propagation for our handlers.
"""
l_mitogen = logging.getLogger('mitogen')
l_mitogen_io = logging.getLogger('mitogen.io')
l_ansible_mitogen = logging.getLogger('ansible_mitogen')
l_operon = logging.getLogger('operon')
for logger in l_mitogen, l_mitogen_io, l_ansible_mitogen, l_operon:
logger.handlers = [Handler(display.vvv)]
logger.propagate = False
if display.verbosity > 2:
l_ansible_mitogen.setLevel(logging.DEBUG)
l_mitogen.setLevel(logging.DEBUG)
else:
# Mitogen copies the active log level into new children, allowing them
# to filter tiny messages before they hit the network, and therefore
# before they wake the IO loop. Explicitly setting INFO saves ~4%
# running against just the local machine.
l_mitogen.setLevel(logging.ERROR)
l_ansible_mitogen.setLevel(logging.ERROR)
if display.verbosity > 3:
l_mitogen_io.setLevel(logging.DEBUG)
@@ -0,0 +1,504 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
import logging
import os
import pwd
import random
import traceback
import ansible
import ansible.plugins.action
import ansible.utils.unsafe_proxy
import ansible.vars.clean
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.module_utils.six.moves import shlex_quote
import mitogen.core
import mitogen.select
import ansible_mitogen.connection
import ansible_mitogen.planner
import ansible_mitogen.target
import ansible_mitogen.utils
import ansible_mitogen.utils.unsafe
LOG = logging.getLogger(__name__)
class ActionModuleMixin(ansible.plugins.action.ActionBase):
"""
The Mitogen-patched PluginLoader dynamically mixes this into every action
class that Ansible attempts to load. It exists to override all the
assumptions built into the base action class that should really belong in
some middle layer, or at least in the connection layer.
Functionality is defined here for:
* Capturing the final set of task variables and giving Connection a chance
to update its idea of the correct execution environment, before any
attempt is made to call a Connection method. While it's not expected for
the interpreter to change on a per-task basis, Ansible permits this, and
so it must be supported.
* Overriding lots of methods that try to call out to shell for mundane
reasons, such as copying files around, changing file permissions,
creating temporary directories and suchlike.
* Short-circuiting any use of Ansiballz or related code for executing a
module remotely using shell commands and SSH.
* Short-circuiting most of the logic in dealing with the fact that Ansible
always runs become: tasks across at least the SSH user account and the
destination user account, and handling the security permission issues
that crop up due to this. Mitogen always runs a task completely within
the target user account, so it's not a problem for us.
"""
def __init__(self, task, connection, *args, **kwargs):
"""
Verify the received connection is really a Mitogen connection. If not,
transmute this instance back into the original unadorned base class.
This allows running the Mitogen strategy in mixed-target playbooks,
where some targets use SSH while others use WinRM or some fancier UNIX
connection plug-in. That's because when the Mitogen strategy is active,
ActionModuleMixin is unconditionally mixed into any action module that
is instantiated, and there is no direct way for the monkey-patch to
know what kind of connection will be used upfront.
"""
super(ActionModuleMixin, self).__init__(task, connection, *args, **kwargs)
if not isinstance(connection, ansible_mitogen.connection.Connection):
_, self.__class__ = type(self).__bases__
# required for python interpreter discovery
connection.templar = self._templar
self._mitogen_discovering_interpreter = False
self._mitogen_interpreter_candidate = None
self._mitogen_rediscovered_interpreter = False
def run(self, tmp=None, task_vars=None):
"""
Override run() to notify Connection of task-specific data, so it has a
chance to know e.g. the Python interpreter in use.
"""
self._connection.on_action_run(
task_vars=task_vars,
delegate_to_hostname=self._task.delegate_to,
loader_basedir=self._loader.get_basedir(),
)
return super(ActionModuleMixin, self).run(tmp, task_vars)
COMMAND_RESULT = {
'rc': 0,
'stdout': '',
'stdout_lines': [],
'stderr': ''
}
def fake_shell(self, func, stdout=False):
"""
Execute a function and decorate its return value in the style of
_low_level_execute_command(). This produces a return value that looks
like some shell command was run, when really func() was implemented
entirely in Python.
If the function raises :py:class:`mitogen.core.CallError`, this will be
translated into a failed shell command with a non-zero exit status.
:param func:
Function invoked as `func()`.
:returns:
See :py:attr:`COMMAND_RESULT`.
"""
dct = self.COMMAND_RESULT.copy()
try:
rc = func()
if stdout:
dct['stdout'] = repr(rc)
except mitogen.core.CallError:
LOG.exception('While emulating a shell command')
dct['rc'] = 1
dct['stderr'] = traceback.format_exc()
return dct
def _remote_file_exists(self, path):
"""
Determine if `path` exists by directly invoking os.path.exists() in the
target user account.
"""
LOG.debug('_remote_file_exists(%r)', path)
return self._connection.get_chain().call(
ansible_mitogen.target.file_exists,
ansible_mitogen.utils.unsafe.cast(path)
)
def _configure_module(self, module_name, module_args, task_vars=None):
"""
Mitogen does not use the Ansiballz framework. This call should never
happen when ActionMixin is active, so crash if it does.
"""
assert False, "_configure_module() should never be called."
def _is_pipelining_enabled(self, module_style, wrap_async=False):
"""
Mitogen does not use SSH pipelining. This call should never happen when
ActionMixin is active, so crash if it does.
"""
assert False, "_is_pipelining_enabled() should never be called."
def _generate_tmp_path(self):
return os.path.join(
self._connection.get_good_temp_dir(),
'ansible_mitogen_action_%016x' % (
random.getrandbits(8*8),
)
)
def _make_tmp_path(self, remote_user=None):
"""
Create a temporary subdirectory as a child of the temporary directory
managed by the remote interpreter.
"""
LOG.debug('_make_tmp_path(remote_user=%r)', remote_user)
path = self._generate_tmp_path()
LOG.debug('Temporary directory: %r', path)
self._connection.get_chain().call_no_reply(os.mkdir, path)
self._connection._shell.tmpdir = path
return path
def _remove_tmp_path(self, tmp_path):
"""
Replace the base implementation's invocation of rm -rf, replacing it
with a pipelined call to :func:`ansible_mitogen.target.prune_tree`.
"""
LOG.debug('_remove_tmp_path(%r)', tmp_path)
if tmp_path is None and ansible_mitogen.utils.ansible_version[:2] >= (2, 6):
tmp_path = self._connection._shell.tmpdir # 06f73ad578d
if tmp_path is not None:
self._connection.get_chain().call_no_reply(
ansible_mitogen.target.prune_tree,
tmp_path,
)
self._connection._shell.tmpdir = None
def _transfer_data(self, remote_path, data):
"""
Used by the base _execute_module(), and in <2.4 also by the template
action module, and probably others.
"""
if data is None and ansible_mitogen.utils.ansible_version[:2] <= (2, 18):
data = '{}'
if isinstance(data, dict):
try:
data = json.dumps(data, ensure_ascii=False)
except UnicodeDecodeError:
data = json.dumps(data)
if not isinstance(data, bytes):
data = to_bytes(data, errors='surrogate_or_strict')
LOG.debug('_transfer_data(%r, %s ..%d bytes)',
remote_path, type(data), len(data))
self._connection.put_data(remote_path, data)
return remote_path
#: Actions listed here cause :func:`_fixup_perms2` to avoid a needless
#: roundtrip, as they modify file modes separately afterwards. This is due
#: to the method prototype having a default of `execute=True`.
FIXUP_PERMS_RED_HERRING = set(['copy'])
def _fixup_perms2(self, remote_paths, remote_user=None, execute=True):
"""
Mitogen always executes ActionBase helper methods in the context of the
target user account, so it is never necessary to modify permissions
except to ensure the execute bit is set if requested.
"""
LOG.debug('_fixup_perms2(%r, remote_user=%r, execute=%r)',
remote_paths, remote_user, execute)
if execute and self._task.action not in self.FIXUP_PERMS_RED_HERRING:
return self._remote_chmod(remote_paths, mode='u+x')
return self.COMMAND_RESULT.copy()
def _remote_chmod(self, paths, mode, sudoable=False):
"""
Issue an asynchronous set_file_mode() call for every path in `paths`,
then format the resulting return value list with fake_shell().
"""
LOG.debug('_remote_chmod(%r, mode=%r, sudoable=%r)',
paths, mode, sudoable)
return self.fake_shell(lambda: mitogen.select.Select.all(
self._connection.get_chain().call_async(
ansible_mitogen.target.set_file_mode,
ansible_mitogen.utils.unsafe.cast(path),
mode,
)
for path in paths
))
def _remote_chown(self, paths, user, sudoable=False):
"""
Issue an asynchronous os.chown() call for every path in `paths`, then
format the resulting return value list with fake_shell().
"""
LOG.debug('_remote_chown(%r, user=%r, sudoable=%r)',
paths, user, sudoable)
ent = self._connection.get_chain().call(pwd.getpwnam, user)
return self.fake_shell(lambda: mitogen.select.Select.all(
self._connection.get_chain().call_async(
os.chown, path, ent.pw_uid, ent.pw_gid
)
for path in paths
))
def _remote_expand_user(self, path, sudoable=True):
"""
Replace the base implementation's attempt to emulate
os.path.expanduser() with an actual call to os.path.expanduser().
:param bool sudoable:
If :data:`True`, indicate unqualified tilde ("~" with no username)
should be evaluated in the context of the login account, not any
become_user.
"""
LOG.debug('_remote_expand_user(%r, sudoable=%r)', path, sudoable)
if not path.startswith('~'):
# /home/foo -> /home/foo
return path
if sudoable or not self._connection.become:
if path == '~':
# ~ -> /home/dmw
return self._connection.homedir
if path.startswith('~/'):
# ~/.ansible -> /home/dmw/.ansible
return os.path.join(self._connection.homedir, path[2:])
# ~root/.ansible -> /root/.ansible
return self._connection.get_chain(use_login=(not sudoable)).call(
os.path.expanduser,
ansible_mitogen.utils.unsafe.cast(path),
)
def get_task_timeout_secs(self):
"""
Return the task "async:" value, portable across 2.4-2.5.
"""
try:
return self._task.async_val
except AttributeError:
return getattr(self._task, 'async')
def _set_temp_file_args(self, module_args, wrap_async):
# Ansible>2.5 module_utils reuses the action's temporary directory if
# one exists. Older versions error if this key is present.
if ansible_mitogen.utils.ansible_version[:2] >= (2, 5):
if wrap_async:
# Sharing is not possible with async tasks, as in that case,
# the directory must outlive the action plug-in.
module_args['_ansible_tmpdir'] = None
else:
module_args['_ansible_tmpdir'] = self._connection._shell.tmpdir
# If _ansible_tmpdir is unset, Ansible>2.6 module_utils will use
# _ansible_remote_tmp as the location to create the module's temporary
# directory. Older versions error if this key is present.
if ansible_mitogen.utils.ansible_version[:2] >= (2, 6):
module_args['_ansible_remote_tmp'] = (
self._connection.get_good_temp_dir()
)
def _execute_module(self, module_name=None, module_args=None, tmp=None,
task_vars=None, persist_files=False,
delete_remote_tmp=True, wrap_async=False,
ignore_unknown_opts=False,
):
"""
Collect up a module's execution environment then use it to invoke
target.run_module() or helpers.run_module_async() in the target
context.
"""
if module_name is None:
module_name = self._task.action
if module_args is None:
module_args = self._task.args
if task_vars is None:
task_vars = {}
if ansible_mitogen.utils.ansible_version[:2] >= (2, 17):
self._update_module_args(
module_name, module_args, task_vars,
ignore_unknown_opts=ignore_unknown_opts,
)
else:
self._update_module_args(module_name, module_args, task_vars)
env = {}
self._compute_environment_string(env)
self._set_temp_file_args(module_args, wrap_async)
# there's a case where if a task shuts down the node and then immediately calls
# wait_for_connection, the `ping` test from Ansible won't pass because we lost connection
# clearing out context forces a reconnect
# see https://github.com/dw/mitogen/issues/655 and Ansible's `wait_for_connection` module for more info
if module_name == 'ansible.legacy.ping' and type(self).__name__ == 'wait_for_connection':
self._connection.context = None
self._connection._connect()
result = ansible_mitogen.planner.invoke(
ansible_mitogen.planner.Invocation(
action=self,
connection=self._connection,
module_name=ansible_mitogen.utils.unsafe.cast(mitogen.core.to_text(module_name)),
module_args=ansible_mitogen.utils.unsafe.cast(module_args),
task_vars=task_vars,
templar=self._templar,
env=ansible_mitogen.utils.unsafe.cast(env),
wrap_async=wrap_async,
timeout_secs=self.get_task_timeout_secs(),
)
)
if tmp and delete_remote_tmp and ansible_mitogen.utils.ansible_version[:2] < (2, 5):
# Built-in actions expected tmpdir to be cleaned up automatically
# on _execute_module().
self._remove_tmp_path(tmp)
# prevents things like discovered_interpreter_* or ansible_discovered_interpreter_* from being set
ansible.vars.clean.remove_internal_keys(result)
# taken from _execute_module of ansible 2.8.6
# propagate interpreter discovery results back to the controller
if self._discovered_interpreter_key:
if result.get('ansible_facts') is None:
result['ansible_facts'] = {}
# only cache discovered_interpreter if we're not running a rediscovery
# rediscovery happens in places like docker connections that could have different
# python interpreters than the main host
if not self._mitogen_rediscovered_interpreter:
result['ansible_facts'][self._discovered_interpreter_key] = self._discovered_interpreter
discovery_warnings = getattr(self, '_discovery_warnings', [])
if discovery_warnings:
if result.get('warnings') is None:
result['warnings'] = []
result['warnings'].extend(discovery_warnings)
discovery_deprecation_warnings = getattr(self, '_discovery_deprecation_warnings', [])
if discovery_deprecation_warnings:
if result.get('deprecations') is None:
result['deprecations'] = []
result['deprecations'].extend(discovery_deprecation_warnings)
return ansible.utils.unsafe_proxy.wrap_var(result)
def _postprocess_response(self, result):
"""
Apply fixups mimicking ActionBase._execute_module(); this is copied
verbatim from action/__init__.py, the guts of _parse_returned_data are
garbage and should be removed or reimplemented once tests exist.
:param dict result:
Dictionary with format::
{
"rc": int,
"stdout": "stdout data",
"stderr": "stderr data"
}
"""
if ansible_mitogen.utils.ansible_version[:2] >= (2, 19):
data = self._parse_returned_data(result, profile='legacy')
else:
data = self._parse_returned_data(result)
# Cutpasted from the base implementation.
if 'stdout' in data and 'stdout_lines' not in data:
data['stdout_lines'] = (data['stdout'] or u'').splitlines()
if 'stderr' in data and 'stderr_lines' not in data:
data['stderr_lines'] = (data['stderr'] or u'').splitlines()
return data
def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
executable=None,
encoding_errors='surrogate_then_replace',
chdir=None):
"""
Override the base implementation by simply calling
target.exec_command() in the target context.
"""
LOG.debug('_low_level_execute_command(%r, in_data=%r, exe=%r, dir=%r)',
cmd, type(in_data), executable, chdir)
if executable is None: # executable defaults to False
executable = self._play_context.executable
if executable:
cmd = executable + ' -c ' + shlex_quote(cmd)
# TODO: HACK: if finding python interpreter then we need to keep
# calling exec_command until we run into the right python we'll use
# chicken-and-egg issue, mitogen needs a python to run low_level_execute_command
# which is required by Ansible's discover_interpreter function
if self._mitogen_discovering_interpreter:
possible_pythons = self._mitogen_interpreter_candidates
else:
# not used, just adding a filler value
possible_pythons = ['python']
for possible_python in possible_pythons:
try:
self._mitogen_interpreter_candidate = possible_python
rc, stdout, stderr = self._connection.exec_command(
cmd, in_data, sudoable, mitogen_chdir=chdir,
)
except BaseException as exc:
# we've reached the last python attempted and failed
if possible_python == possible_pythons[-1]:
raise
else:
LOG.debug(
'%r._low_level_execute_command: candidate=%r ignored: %s, %r',
self, possible_python, type(exc), exc,
)
continue
stdout_text = to_text(stdout, errors=encoding_errors)
stderr_text = to_text(stderr, errors=encoding_errors)
return {
'rc': rc,
'stdout': stdout_text,
'stdout_lines': stdout_text.splitlines(),
'stderr': stderr_text,
'stderr_lines': stderr_text.splitlines(),
}
@@ -0,0 +1,279 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
__metaclass__ = type
import collections
import logging
import os
import re
import sys
if sys.version_info >= (3, 4):
import importlib.machinery
import importlib.util
else:
import imp
import mitogen.imports
LOG = logging.getLogger(__name__)
PREFIX = 'ansible.module_utils.'
# Analog of `importlib.machinery.ModuleSpec` or `pkgutil.ModuleInfo`.
# name Unqualified name of the module.
# path Filesystem path of the module.
# kind One of the constants in `imp`, as returned in `imp.find_module()`
# parent `ansible_mitogen.module_finder.Module` of parent package (if any).
Module = collections.namedtuple('Module', 'name path kind parent')
def get_fullname(module):
"""
Reconstruct a Module's canonical path by recursing through its parents.
"""
bits = [str(module.name)]
while module.parent:
bits.append(str(module.parent.name))
module = module.parent
return '.'.join(reversed(bits))
def get_code(module):
"""
Compile and return a Module's code object.
"""
fp = open(module.path, 'rb')
try:
return compile(fp.read(), str(module.name), 'exec')
finally:
fp.close()
def is_pkg(module):
"""
Return :data:`True` if a Module represents a package.
"""
return module.kind == imp.PKG_DIRECTORY
def find(name, path=(), parent=None):
"""
Return a Module instance describing the first matching module found on the
search path.
:param str name:
Module name.
:param list path:
List of directory names to search for the module.
:param Module parent:
Optional module parent.
"""
assert isinstance(path, tuple)
head, _, tail = name.partition('.')
try:
tup = imp.find_module(head, list(path))
except ImportError:
return parent
fp, modpath, (suffix, mode, kind) = tup
if fp:
fp.close()
if parent and modpath == parent.path:
# 'from timeout import timeout', where 'timeout' is a function but also
# the name of the module being imported.
return None
if kind == imp.PKG_DIRECTORY:
modpath = os.path.join(modpath, '__init__.py')
module = Module(head, modpath, kind, parent)
# TODO: this code is entirely wrong on Python 3.x, but works well enough
# for Ansible. We need a new find_child() that only looks in the package
# directory, never falling back to the parent search path.
if tail and kind == imp.PKG_DIRECTORY:
return find_relative(module, tail, path)
return module
def find_relative(parent, name, path=()):
if parent.kind == imp.PKG_DIRECTORY:
path = (os.path.dirname(parent.path),) + path
return find(name, path, parent=parent)
def scan_fromlist(code):
"""Return an iterator of (level, name) for explicit imports in a code
object.
Not all names identify a module. `from os import name, path` generates
`(0, 'os.name'), (0, 'os.path')`, but `os.name` is usually a string.
>>> src = 'import a; import b.c; from d.e import f; from g import h, i\\n'
>>> code = compile(src, '<str>', 'exec')
>>> list(scan_fromlist(code))
[(0, 'a'), (0, 'b.c'), (0, 'd.e.f'), (0, 'g.h'), (0, 'g.i')]
"""
for level, modname_s, fromlist in mitogen.imports.codeobj_imports(code):
for name in fromlist:
yield level, str('%s.%s' % (modname_s, name))
if not fromlist:
yield level, modname_s
def walk_imports(code, prefix=None):
"""Return an iterator of names for implicit parent imports & explicit
imports in a code object.
If a prefix is provided, then only children of that prefix are included.
Not all names identify a module. `from os import name, path` generates
`'os', 'os.name', 'os.path'`, but `os.name` is usually a string.
>>> source = 'import a; import b; import b.c; from b.d import e, f\\n'
>>> code = compile(source, '<str>', 'exec')
>>> list(walk_imports(code))
['a', 'b', 'b', 'b.c', 'b', 'b.d', 'b.d.e', 'b.d.f']
>>> list(walk_imports(code, prefix='b'))
['b.c', 'b.d', 'b.d.e', 'b.d.f']
"""
if prefix is None:
prefix = ''
pattern = re.compile(r'(^|\.)(\w+)')
start = len(prefix)
for _, name, fromlist in mitogen.imports.codeobj_imports(code):
if not name.startswith(prefix):
continue
for match in pattern.finditer(name, start):
yield name[:match.end()]
for leaf in fromlist:
yield str('%s.%s' % (name, leaf))
def scan(module_name, module_path, search_path):
# type: (str, str, list[str]) -> list[(str, str, bool)]
"""Return a list of (name, path, is_package) for ansible.module_utils
imports used by an Ansible module.
"""
log = LOG.getChild('scan')
log.debug('%r, %r, %r', module_name, module_path, search_path)
if sys.version_info >= (3, 4):
result = _scan_importlib_find_spec(
module_name, module_path, search_path,
)
log.debug('_scan_importlib_find_spec %r', result)
else:
result = _scan_imp_find_module(module_name, module_path, search_path)
log.debug('_scan_imp_find_module %r', result)
return result
def _scan_importlib_find_spec(module_name, module_path, search_path):
# type: (str, str, list[str]) -> list[(str, str, bool)]
module = importlib.machinery.ModuleSpec(
module_name, loader=None, origin=module_path,
)
prefix = importlib.machinery.ModuleSpec(
PREFIX.rstrip('.'), loader=None,
)
prefix.submodule_search_locations = search_path
queue = collections.deque([module])
specs = {prefix.name: prefix}
while queue:
spec = queue.popleft()
if spec.origin is None:
continue
try:
with open(spec.origin, 'rb') as f:
code = compile(f.read(), spec.name, 'exec')
except Exception as exc:
raise ValueError((exc, module, spec, specs))
for name in walk_imports(code, prefix.name):
if name in specs:
continue
parent_name = name.rpartition('.')[0]
parent = specs[parent_name]
if parent is None or not parent.submodule_search_locations:
specs[name] = None
continue
child = importlib.util._find_spec(
name, parent.submodule_search_locations,
)
if child is None or child.origin is None:
specs[name] = None
continue
specs[name] = child
queue.append(child)
del specs[prefix.name]
return sorted(
(spec.name, spec.origin, spec.submodule_search_locations is not None)
for spec in specs.values() if spec is not None
)
def _scan_imp_find_module(module_name, module_path, search_path):
# type: (str, str, list[str]) -> list[(str, str, bool)]
module = Module(module_name, module_path, imp.PY_SOURCE, None)
stack = [module]
seen = set()
while stack:
module = stack.pop(0)
for level, fromname in scan_fromlist(get_code(module)):
if not fromname.startswith(PREFIX):
continue
imported = find(fromname[len(PREFIX):], search_path)
if imported is None or imported in seen:
continue
seen.add(imported)
stack.append(imported)
parent = imported.parent
while parent:
fullname = get_fullname(parent)
module = Module(fullname, parent.path, parent.kind, None)
if module not in seen:
seen.add(module)
stack.append(module)
parent = parent.parent
return sorted(
(PREFIX + get_fullname(module), module.path, is_pkg(module))
for module in seen
)
@@ -0,0 +1,77 @@
# Copyright 2019, David Wilson
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
__metaclass__ = type
import mitogen.core
def parse_script_interpreter(source):
"""
Parse the script interpreter portion of a UNIX hashbang using the rules
Linux uses.
:param str source: String like "/usr/bin/env python".
:returns:
Tuple of `(interpreter, arg)`, where `intepreter` is the script
interpreter and `arg` is its sole argument if present, otherwise
:py:data:`None`.
"""
# Find terminating newline. Assume last byte of binprm_buf if absent.
nl = source.find(b'\n', 0, 128)
if nl == -1:
nl = min(128, len(source))
# Split once on the first run of whitespace. If no whitespace exists,
# bits just contains the interpreter filename.
bits = source[0:nl].strip().split(None, 1)
if len(bits) == 1:
return mitogen.core.to_text(bits[0]), None
return mitogen.core.to_text(bits[0]), mitogen.core.to_text(bits[1])
def parse_hashbang(source):
"""
Parse a UNIX "hashbang line" using the syntax supported by Linux.
:param str source: String like "#!/usr/bin/env python".
:returns:
Tuple of `(interpreter, arg)`, where `intepreter` is the script
interpreter and `arg` is its sole argument if present, otherwise
:py:data:`None`.
"""
# Linux requires first 2 bytes with no whitespace, pretty sure it's the
# same everywhere. See binfmt_script.c.
if not source.startswith(b'#!'):
return None, None
return parse_script_interpreter(source[2:])

Some files were not shown because too many files have changed in this diff Show More