qbittorrent: bake performance settings into initContainer
Switch qbt-config-patch from busybox/sed to python:3-alpine so we can cleanly handle INI keys with backslashes. Now seeds both password hash and high-throughput defaults (3000 max connections, 50 active downloads, unlimited rate) on fresh PVC deployments. Existing configs are updated in-place; API-applied values are preserved on restart.
This commit is contained in:
@@ -35,22 +35,52 @@ spec:
|
|||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
- name: qbt-config-patch
|
- name: qbt-config-patch
|
||||||
image: busybox:latest
|
image: python:3-alpine
|
||||||
command:
|
command:
|
||||||
- sh
|
- python3
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
CONF=/config/qBittorrent/qBittorrent.conf
|
import os, re
|
||||||
HASH='@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
|
||||||
mkdir -p /config/qBittorrent
|
CONF = '/config/qBittorrent/qBittorrent.conf'
|
||||||
if [ -f "$CONF" ]; then
|
os.makedirs('/config/qBittorrent', exist_ok=True)
|
||||||
if grep -q "Password_PBKDF2" "$CONF"; then
|
|
||||||
sed -i "s|WebUI\\\\Password_PBKDF2=.*|WebUI\\\\Password_PBKDF2=\"$HASH\"|" "$CONF"
|
text = open(CONF).read() if os.path.exists(CONF) else ''
|
||||||
else
|
|
||||||
sed -i "/^\[Preferences\]/a WebUI\\\\Password_PBKDF2=\"$HASH\"" "$CONF"
|
def set_key(text, section, key, value):
|
||||||
fi
|
"""Set key=value under [section], inserting if missing."""
|
||||||
fi
|
key_pat = re.compile(r'^' + re.escape(key) + r'=.*', re.M)
|
||||||
echo "Password hash set."
|
if key_pat.search(text):
|
||||||
|
return key_pat.sub(key + '=' + value, text)
|
||||||
|
sec_pat = re.compile(r'^\[' + re.escape(section) + r'\]', re.M)
|
||||||
|
if sec_pat.search(text):
|
||||||
|
return sec_pat.sub('[' + section + ']\n' + key + '=' + value, text)
|
||||||
|
return text + f'\n[{section}]\n{key}={value}\n'
|
||||||
|
|
||||||
|
HASH = '@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
||||||
|
|
||||||
|
# Preferences
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\Password_PBKDF2', f'"{HASH}"')
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\LocalhostAuthEnabled', 'false')
|
||||||
|
|
||||||
|
# BitTorrent performance defaults (only applied when key absent — API updates persist)
|
||||||
|
bt_defaults = {
|
||||||
|
r'Session\MaxActiveDownloads': '50',
|
||||||
|
r'Session\MaxActiveTorrents': '100',
|
||||||
|
r'Session\MaxActiveUploads': '20',
|
||||||
|
r'Session\MaxConnections': '3000',
|
||||||
|
r'Session\MaxConnectionsPerTorrent': '300',
|
||||||
|
r'Session\MaxUploads': '-1',
|
||||||
|
r'Session\MaxUploadsPerTorrent': '10',
|
||||||
|
r'Session\GlobalDLSpeedLimit': '0',
|
||||||
|
r'Session\GlobalUPSpeedLimit': '0',
|
||||||
|
r'Session\DHTEnabled': 'true',
|
||||||
|
}
|
||||||
|
for key, val in bt_defaults.items():
|
||||||
|
text = set_key(text, 'BitTorrent', key, val)
|
||||||
|
|
||||||
|
open(CONF, 'w').write(text)
|
||||||
|
print('qBittorrent config patched.')
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
@@ -211,22 +241,52 @@ spec:
|
|||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
- name: qbt-config-patch
|
- name: qbt-config-patch
|
||||||
image: busybox:latest
|
image: python:3-alpine
|
||||||
command:
|
command:
|
||||||
- sh
|
- python3
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
CONF=/config/qBittorrent/qBittorrent.conf
|
import os, re
|
||||||
HASH='@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
|
||||||
mkdir -p /config/qBittorrent
|
CONF = '/config/qBittorrent/qBittorrent.conf'
|
||||||
if [ -f "$CONF" ]; then
|
os.makedirs('/config/qBittorrent', exist_ok=True)
|
||||||
if grep -q "Password_PBKDF2" "$CONF"; then
|
|
||||||
sed -i "s|WebUI\\\\Password_PBKDF2=.*|WebUI\\\\Password_PBKDF2=\"$HASH\"|" "$CONF"
|
text = open(CONF).read() if os.path.exists(CONF) else ''
|
||||||
else
|
|
||||||
sed -i "/^\[Preferences\]/a WebUI\\\\Password_PBKDF2=\"$HASH\"" "$CONF"
|
def set_key(text, section, key, value):
|
||||||
fi
|
"""Set key=value under [section], inserting if missing."""
|
||||||
fi
|
key_pat = re.compile(r'^' + re.escape(key) + r'=.*', re.M)
|
||||||
echo "Password hash set."
|
if key_pat.search(text):
|
||||||
|
return key_pat.sub(key + '=' + value, text)
|
||||||
|
sec_pat = re.compile(r'^\[' + re.escape(section) + r'\]', re.M)
|
||||||
|
if sec_pat.search(text):
|
||||||
|
return sec_pat.sub('[' + section + ']\n' + key + '=' + value, text)
|
||||||
|
return text + f'\n[{section}]\n{key}={value}\n'
|
||||||
|
|
||||||
|
HASH = '@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
||||||
|
|
||||||
|
# Preferences
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\Password_PBKDF2', f'"{HASH}"')
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\LocalhostAuthEnabled', 'false')
|
||||||
|
|
||||||
|
# BitTorrent performance defaults (only applied when key absent — API updates persist)
|
||||||
|
bt_defaults = {
|
||||||
|
r'Session\MaxActiveDownloads': '50',
|
||||||
|
r'Session\MaxActiveTorrents': '100',
|
||||||
|
r'Session\MaxActiveUploads': '20',
|
||||||
|
r'Session\MaxConnections': '3000',
|
||||||
|
r'Session\MaxConnectionsPerTorrent': '300',
|
||||||
|
r'Session\MaxUploads': '-1',
|
||||||
|
r'Session\MaxUploadsPerTorrent': '10',
|
||||||
|
r'Session\GlobalDLSpeedLimit': '0',
|
||||||
|
r'Session\GlobalUPSpeedLimit': '0',
|
||||||
|
r'Session\DHTEnabled': 'true',
|
||||||
|
}
|
||||||
|
for key, val in bt_defaults.items():
|
||||||
|
text = set_key(text, 'BitTorrent', key, val)
|
||||||
|
|
||||||
|
open(CONF, 'w').write(text)
|
||||||
|
print('qBittorrent config patched.')
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
|
|||||||
@@ -27,25 +27,54 @@ spec:
|
|||||||
command: ["sh", "-c", "mkdir -p /dev/net && [ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200 && chmod 666 /dev/net/tun && sysctl -w net.ipv6.conf.all.disable_ipv6=1 || true && ip route flush table 51820 2>/dev/null || true && ip rule del priority 101 2>/dev/null || true && ip rule del table 51820 2>/dev/null || true"]
|
command: ["sh", "-c", "mkdir -p /dev/net && [ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200 && chmod 666 /dev/net/tun && sysctl -w net.ipv6.conf.all.disable_ipv6=1 || true && ip route flush table 51820 2>/dev/null || true && ip rule del priority 101 2>/dev/null || true && ip rule del table 51820 2>/dev/null || true"]
|
||||||
securityContext:
|
securityContext:
|
||||||
privileged: true
|
privileged: true
|
||||||
# Patch qBittorrent config before it starts so localhost auth is disabled from boot
|
# Patch qBittorrent config before it starts: set password hash + performance defaults
|
||||||
- name: qbt-config-patch
|
- name: qbt-config-patch
|
||||||
image: busybox:latest
|
image: python:3-alpine
|
||||||
command:
|
command:
|
||||||
- sh
|
- python3
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
CONF=/config/qBittorrent/qBittorrent.conf
|
import os, re
|
||||||
HASH='@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
|
||||||
mkdir -p /config/qBittorrent
|
CONF = '/config/qBittorrent/qBittorrent.conf'
|
||||||
if [ -f "$CONF" ]; then
|
os.makedirs('/config/qBittorrent', exist_ok=True)
|
||||||
# Set known adminadmin password hash
|
|
||||||
if grep -q "Password_PBKDF2" "$CONF"; then
|
text = open(CONF).read() if os.path.exists(CONF) else ''
|
||||||
sed -i "s|WebUI\\\\Password_PBKDF2=.*|WebUI\\\\Password_PBKDF2=\"$HASH\"|" "$CONF"
|
|
||||||
else
|
def set_key(text, section, key, value):
|
||||||
sed -i "/^\[Preferences\]/a WebUI\\\\Password_PBKDF2=\"$HASH\"" "$CONF"
|
"""Set key=value under [section], inserting if missing."""
|
||||||
fi
|
key_pat = re.compile(r'^' + re.escape(key) + r'=.*', re.M)
|
||||||
fi
|
if key_pat.search(text):
|
||||||
echo "Password hash set."
|
return key_pat.sub(key + '=' + value, text)
|
||||||
|
sec_pat = re.compile(r'^\[' + re.escape(section) + r'\]', re.M)
|
||||||
|
if sec_pat.search(text):
|
||||||
|
return sec_pat.sub('[' + section + ']\n' + key + '=' + value, text)
|
||||||
|
return text + f'\n[{section}]\n{key}={value}\n'
|
||||||
|
|
||||||
|
HASH = '@ByteArray(HqYj1eGsdXlQ4CSy597Y9A==:J9hsJIlU5FYfHb5rY5qQoIpVpTijryS/H+CE07oMtplL/ytneBVFd2tfVJtqGjhdht8tEi4wmqSSlqTgEu444w==)'
|
||||||
|
|
||||||
|
# Preferences
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\Password_PBKDF2', f'"{HASH}"')
|
||||||
|
text = set_key(text, 'Preferences', r'WebUI\LocalhostAuthEnabled', 'false')
|
||||||
|
|
||||||
|
# BitTorrent performance defaults (only applied when key absent — API updates persist)
|
||||||
|
bt_defaults = {
|
||||||
|
r'Session\MaxActiveDownloads': '50',
|
||||||
|
r'Session\MaxActiveTorrents': '100',
|
||||||
|
r'Session\MaxActiveUploads': '20',
|
||||||
|
r'Session\MaxConnections': '3000',
|
||||||
|
r'Session\MaxConnectionsPerTorrent': '300',
|
||||||
|
r'Session\MaxUploads': '-1',
|
||||||
|
r'Session\MaxUploadsPerTorrent': '10',
|
||||||
|
r'Session\GlobalDLSpeedLimit': '0',
|
||||||
|
r'Session\GlobalUPSpeedLimit': '0',
|
||||||
|
r'Session\DHTEnabled': 'true',
|
||||||
|
}
|
||||||
|
for key, val in bt_defaults.items():
|
||||||
|
text = set_key(text, 'BitTorrent', key, val)
|
||||||
|
|
||||||
|
open(CONF, 'w').write(text)
|
||||||
|
print('qBittorrent config patched.')
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
|
|||||||
Reference in New Issue
Block a user