-
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor Job Implementation #11
Comments
@imgios do you feel like taking this? 😃 |
Sure, I can give it a try 😄 |
@fonzdm I was checking the project structure that's currently storing the What do you think if we place them all in a common directory since we are going to create several Python scripts? I was thinking to something like this: .
└── config/
└── scripts/
└── *.py |
Sounds good! And this will make life easier in case we rely on a single ConfigMap with all the scripts. |
I was checking the What's your POV on that? |
It's nice and could allow us to keep the current structure AND have a readable configuration. |
This is another valid option, would be good to evaluate pros/cons for both solution and see which one may be the best to adopt. |
Ok, let's write down some points.
Some psudo code for invocationSingle Script containers:
- name: <service>-operation-1
image: python:latest
command:
- "/bin/sh"
- "-ec"
args:
- "python3 -u /mnt/sevarr-configuration.py <service>-operation-1"
- name: <service>-operation-2
image: python:latest
command:
- "/bin/sh"
- "-ec"
args:
- "python3 -u /mnt/sevarr-configuration.py <service>-operation-2" Each parameter passed to the script will result in one/few API calls to configure a single feature. Multiple ScriptsOne job per service, each service will be like: env:
- name: ENV_VAR
value: VALUE
command:
- "/bin/sh"
- "-ec"
args:
- "python3 -u /mnt/init-<service>.py 2>&1;" And the What do you think? I would personally go for the second approach 😄 |
Thanks for your POV on that, @fonzdm. I also like the second approach if we do it for each app/service that should be configured, e.g.,:
Otherwise, if we have to create one script per operation (e.g., one script per API request) then this doesn't make so sense to me, because it means having a lot of small script to maintain and a bunch of duplicated code 😊 |
Hey @fonzdm, during the Jellyfin refactoring I noticed that there is the servarr/servarr/config/scripts/init_jellyfin.py Lines 18 to 19 in fb6d9bc
We should probably think about it and maybe expose them in the Chart values. Furthermore, I have a question regarding |
Nice, it was a leftover.
I can work on that, no worries.
I would say to keep the sequence of the job as it is but just split into different scripts.
|
@imgios , just tried to deploy the service, I'm getting the following error: k-user@k-node-0:~$ kubectl logs -n servarr radarr-init-9gcrp
Defaulted container "initialize-radarr" out of: initialize-radarr, wait-for-radarr (init)
2024-04-17 09:00:36,254 - __main__ - INFO - Setup qBitTorrent in Radarr
2024-04-17 09:00:36,254 - __main__ - DEBUG - POST http://servarr-radarr.servarr.svc.cluster.local:7878/api/v3/downloadclient c: o: n: t: e: n: t: -: t: y: p: e, x: -: a: p: i: -: k: e: y, x: -: r: e: q: u: e: s: t: e: d: -: w: i: t: h {'enable': 'true', 'protocol': 'torrent', 'priority': 1, 'removeCompletedDownloads': 'true', 'removeFailedDownloads': 'true', 'name': 'qBittorrent', 'fields': [{'name': 'host', 'value': 'servarr-qbittorrent'}, {'name': 'port', 'value': '10095'}, {'name': 'useSsl', 'value': 'false'}, {'name': 'urlBase'}, {'name': 'username', 'value': 'admin'}, {'name': 'password', 'value': 'v1c2X3Z4'}, {'name': 'movieCategory', 'value': 'radarr'}, {'name': 'movieImportedCategory'}, {'name': 'recentMoviePriority', 'value': 0}, {'name': 'olderMoviePriority', 'value': 0}, {'name': 'initialState', 'value': 0}, {'name': 'sequentialOrder', 'value': 'false'}, {'name': 'firstAndLast', 'value': 'false'}, {'name': 'contentLayout', 'value': 0}], 'implementationName': 'qBittorrent', 'implementation': 'QBittorrent', 'configContract': 'QBittorrentSettings', 'infoLink': 'https://wiki.servarr.com/radarr/supported#qbittorrent', 'tags': []}
Traceback (most recent call last):
File "/mnt/init-radarr.py", line 139, in <module>
post(
File "/mnt/init-radarr.py", line 49, in post
logger.debug(" ".join([
TypeError: sequence item 1: expected str instance, int found Let me know if you need something else! |
Hey @fonzdm, thanks for checking it! Will let you know 😄 |
The Python Now, casting it to string should have fixed it: servarr/servarr/config/scripts/init-radarr.py Lines 49 to 54 in cc687df
|
Tried again, here's the result: k get pods -n servarr
NAME READY STATUS RESTARTS AGE
pre-install-job-2rlbp 0/1 Completed 0 9m39s
servarr-flaresolverr-7857b84d4-xhz2r 1/1 Running 0 8m11s
servarr-qbittorrent-5f4f99d95c-gpbcq 1/1 Running 0 8m11s
servarr-jellyfin-7cfdc9466c-pxvtc 1/1 Running 0 8m12s
servarr-jellyseerr-74896db869-s5blz 1/1 Running 0 8m12s
servarr-prowlarr-9fb778f47-4mxj7 1/1 Running 0 8m12s
servarr-radarr-75f6fb5bcc-hgbw9 1/1 Running 0 8m12s
radarr-init-zq6m9 0/1 Completed 0 8m11s
servarr-sonarr-858d56ccc5-4xh9f 1/1 Running 0 8m12s
sonarr-init-p5ncs 0/1 Completed 0 5m33s
prowlarr-init-p9zzk 0/1 Completed 0 5m11s
jellyfin-init-h2m4b 0/1 Error 0 5m4s
jellyfin-init-87px2 0/1 Error 0 4m41s But i get 401 on sonarr, radarr, prwolarr (seems like an API key not set): kubectl logs -n servarr sonarr-init-p5ncs
Defaulted container "initialize-sonarr" out of: initialize-sonarr, wait-for-sonarr (init)
2024-04-17 14:31:19,592 - __main__ - INFO - Setup Sonarr and qBitTorrent interworking
2024-04-17 14:31:19,592 - __main__ - DEBUG - POST http://servarr-sonarr.servarr.svc.cluster.local:8989/api/v3/downloadclient content-type: application/json, x-api-key: None, x-requested-with: XMLHttpRequest {'enable': 'true', 'protocol': 'torrent', 'priority': 1, 'removeCompletedDownloads': 'true', 'removeFailedDownloads': 'true', 'name': 'qBittorrent', 'fields': [{'name': 'host', 'value': 'servarr-qbittorrent'}, {'name': 'port', 'value': '10095'}, {'name': 'useSsl', 'value': 'false'}, {'name': 'urlBase'}, {'name': 'username', 'value': 'admin'}, {'name': 'password', 'value': '<pass>'}, {'name': 'movieCategory', 'value': 'radarr'}, {'name': 'movieImportedCategory'}, {'name': 'recentMoviePriority', 'value': 0}, {'name': 'olderMoviePriority', 'value': 0}, {'name': 'initialState', 'value': 0}, {'name': 'sequentialOrder', 'value': 'false'}, {'name': 'firstAndLast', 'value': 'false'}, {'name': 'contentLayout', 'value': 0}], 'implementationName': 'qBittorrent', 'implementation': 'QBittorrent', 'configContract': 'QBittorrentSettings', 'infoLink': 'https://wiki.servarr.com/radarr/supported#qbittorrent', 'tags': []}
2024-04-17 14:31:19,648 - __main__ - DEBUG - Status Code: 401 Response body: and jellyfin is completely in error. kubectl logs -n servarr jellyfin-init-h2m4b
Defaulted container "initialize-jellyfin" out of: initialize-jellyfin, wait-for-jellyfin (init)
Traceback (most recent call last):
File "/mnt/init-jellyfin.py", line 21, in <module>
def post(url: str, headers: dict, body: dict | None): # -> str | dict
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType' Hint: We should make the job fail if an API returns an erronous status cose. What do you think? |
Thanks for testing it again! I'll dig into it and see what's happening.
The idea is to make it fail based on the response status code (e.g., if it's not equal to
|
While performing the refactoring I found out that we have an issue with the qBitTorrent integration in Prowlarr. This is the container performing the action: servarr/servarr/templates/init-downloaders.yaml Lines 105 to 118 in 810bb48
This is the API answer: ~$ kubectl logs -n servarr downloaders-post-install-job-mpj59 -c prowlarr-vs-qbt-finalizer % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
[
{
"isWarning": false,
"propertyName": "",
"errorMessage": "Test was aborted due to an error: Object reference not set to an instance of an object.",
"severity": "error"
}
100 1033 0 194 100 839 539 2333 --:--:-- --:--:-- --:--:-- 2869
] And those are the pod logs: [Error] QBittorrent: Test aborted due to exception
[v1.14.0.4286] System.NullReferenceException: Object reference not set to an instance of an object.
at NzbDrone.Core.Download.DownloadClientBase`1.ValidateCategories(List`1 failures) in ./Prowlarr.Core/Download/DownloadClientBase.cs:line 97
at NzbDrone.Core.Download.DownloadClientBase`1.Test() in ./Prowlarr.Core/Download/DownloadClientBase.cs:line 112
[Warn] ProwlarrErrorPipeline: Invalid request Validation failed:
-- : Test was aborted due to an error: Object reference not set to an instance of an object. |
Closed by #24 |
Description
At the moment, several pre and post deploy helm jobs are implemented as a series of containers running a "curl equipped" docker image that execute a single, hard to read, GET/POST request.
This introduces several fingerprint overhead and makes it difficult to edit or modify the requests themselves.
Moreover,
evil escapes
are needed to make a proper curl command into thecommand
section of a container, for example:servarr/templates/add-indexers-prowlarr.yaml
Lines 36 to 40 in 8a0aa86
Solution you'd like
It would be nice to replace this flow entirely with a proper python/easy-to-read language, as already done for the Jellyseerr post init job:
servarr/templates/init-jellyseerr.yaml
Lines 57 to 61 in 8a0aa86
The script can be loaded into a configmap and mounted in the hook job, for example:
servarr/templates/init-jellyseerr.yaml
Lines 62 to 68 in 8a0aa86
Code of Conduct
The text was updated successfully, but these errors were encountered: