-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WIP] Initial copy of Plex to add Channels
Copied Plex config to Channels folder and initial work
- Loading branch information
Showing
66 changed files
with
6,899 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Channels | ||
|
||
[Chanels](https://getchannels.com/) is a media server that allows you to record broadcast television. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
app_version: 1.41.2.9200-c6bbc1b53 | ||
capabilities: | ||
- description: Channels is able to chown files. | ||
name: CHOWN | ||
- description: Channels is able to bypass permission checks for it's sub-processes. | ||
name: FOWNER | ||
- description: Channels is able to bypass permission checks. | ||
name: DAC_OVERRIDE | ||
- description: Channels is able to set group ID for it's sub-processes. | ||
name: SETGID | ||
- description: Channels is able to set user ID for it's sub-processes. | ||
name: SETUID | ||
- description: Channels is able to kill processes. | ||
name: KILL | ||
categories: | ||
- media | ||
description: | ||
Channels is a media server that allows you to record broadcast television | ||
client. | ||
home: https://plex.tv | ||
host_mounts: [] | ||
icon: https://media.sys.truenas.net/apps/channels-dvr/icons/icon.png | ||
keywords: | ||
- channels | ||
- media | ||
- entertainment | ||
- movies | ||
- series | ||
- tv | ||
- streaming | ||
- dvr | ||
lib_version: 2.0.15 | ||
lib_version_hash: 556237781bb6a44e6b255244944456151dee1d05de2b6123dfec3f0ded635570 | ||
maintainers: | ||
- email: [email protected] | ||
name: truenas | ||
url: https://www.truenas.com/ | ||
name: plex | ||
run_as_context: | ||
- description: Channels runs as root user. | ||
gid: 0 | ||
group_name: root | ||
uid: 0 | ||
user_name: root | ||
screenshots: | ||
- https://media.sys.truenas.net/apps/channels-dvr/screenshots/screenshot1.png | ||
- https://media.sys.truenas.net/apps/channels-dvr/screenshots/screenshot2.png | ||
sources: | ||
- https://getchannels.com | ||
- https://hub.docker.com/r/fancybits/channels-dvr | ||
title: Channels | ||
train: stable | ||
version: 1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
categories: | ||
- media | ||
icon_url: https://media.sys.truenas.net/apps/channels-dvr/icons/icon.png | ||
screenshots: | ||
- https://media.sys.truenas.net/apps/channels-dvr/screenshots/screenshot1.png | ||
- https://media.sys.truenas.net/apps/channels-dvr/screenshots/screenshot2.png | ||
tags: | ||
- channels | ||
- media | ||
- entertainment | ||
- movies | ||
- series | ||
- tv | ||
- streaming | ||
- dvr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
images: | ||
image: | ||
repository: fancybits/channels-dvr | ||
tag: latest | ||
nvidia: | ||
repository: fancybits/channels-dvr | ||
tag: nvidia | ||
|
||
consts: | ||
plex_container_name: channels-dvr | ||
perms_container_name: permissions | ||
internal_web_port: 32400 |
Empty file.
70 changes: 70 additions & 0 deletions
70
ix-dev/community/channels-dvr/migrations/migrate_from_kubernetes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/python3 | ||
|
||
import os | ||
import sys | ||
import yaml | ||
|
||
from migration_helpers.resources import migrate_resources | ||
from migration_helpers.dns_config import migrate_dns_config | ||
from migration_helpers.storage import migrate_storage_item | ||
|
||
|
||
def migrate(values): | ||
config = values.get("helm_secret", {}).get("config", {}) | ||
if not config: | ||
raise ValueError("No config found in values") | ||
|
||
envs = [] | ||
allowed_networks = [] | ||
|
||
for env in config["plexConfig"].get("additionalEnvs", []): | ||
if env["name"] == "ALLOWED_NETWORKS": | ||
allowed_networks = env["value"].split(",") | ||
elif env["name"] != "NVIDIA_VISIBLE_DEVICES": | ||
envs.append(env) | ||
|
||
new_values = { | ||
"plex": { | ||
"additional_envs": envs, | ||
"claim_token": config["plexConfig"].get("claimToken", ""), | ||
"allowed_networks": allowed_networks, | ||
"image_selector": ( | ||
"image" | ||
if config["plexConfig"]["imageSelector"] == "image" | ||
else "plex_pass_image" | ||
), | ||
}, | ||
"run_as": { | ||
"user": config["plexID"].get("user", 568), | ||
"group": config["plexID"].get("group", 568), | ||
}, | ||
"network": { | ||
"host_network": config["plexNetwork"].get("hostNetwork", False), | ||
"web_port": config["plexNetwork"].get("webPort", 32400), | ||
"dns_opts": migrate_dns_config(config["podOptions"].get("dnsConfig", {})), | ||
}, | ||
"storage": { | ||
"config": migrate_storage_item(config["plexStorage"]["config"]), | ||
"data": migrate_storage_item(config["plexStorage"]["data"]), | ||
"logs": migrate_storage_item(config["plexStorage"]["logs"]), | ||
"transcode": migrate_storage_item(config["plexStorage"]["transcode"]), | ||
"additional_storage": [ | ||
migrate_storage_item(item, include_read_only=True) | ||
for item in config["plexStorage"]["additionalStorages"] | ||
], | ||
}, | ||
"resources": migrate_resources( | ||
config["resources"], config["plexGPU"], values.get("gpu_choices", {}) | ||
), | ||
} | ||
|
||
return new_values | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) != 2: | ||
exit(1) | ||
|
||
if os.path.exists(sys.argv[1]): | ||
with open(sys.argv[1], "r") as f: | ||
print(yaml.dump(migrate(yaml.safe_load(f.read())))) |
Empty file.
30 changes: 30 additions & 0 deletions
30
ix-dev/community/channels-dvr/migrations/migration_helpers/cpu.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import math | ||
import re | ||
import os | ||
|
||
CPU_COUNT = os.cpu_count() | ||
|
||
NUMBER_REGEX = re.compile(r"^[1-9][0-9]$") | ||
FLOAT_REGEX = re.compile(r"^[0-9]+\.[0-9]+$") | ||
MILI_CPU_REGEX = re.compile(r"^[0-9]+m$") | ||
|
||
|
||
def transform_cpu(cpu) -> int: | ||
result = 2 | ||
if NUMBER_REGEX.match(cpu): | ||
result = int(cpu) | ||
elif FLOAT_REGEX.match(cpu): | ||
result = int(math.ceil(float(cpu))) | ||
elif MILI_CPU_REGEX.match(cpu): | ||
num = int(cpu[:-1]) | ||
num = num / 1000 | ||
result = int(math.ceil(num)) | ||
|
||
if CPU_COUNT is not None: | ||
# Do not exceed the actual CPU count | ||
result = min(result, CPU_COUNT) | ||
|
||
if int(result) == 0: | ||
result = CPU_COUNT if CPU_COUNT else 2 | ||
|
||
return int(result) |
9 changes: 9 additions & 0 deletions
9
ix-dev/community/channels-dvr/migrations/migration_helpers/dns_config.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
def migrate_dns_config(dns_config): | ||
if not dns_config: | ||
return [] | ||
|
||
dns_opts = [] | ||
for opt in dns_config.get("options", []): | ||
dns_opts.append(f"{opt['name']}:{opt['value']}") | ||
|
||
return dns_opts |
16 changes: 16 additions & 0 deletions
16
ix-dev/community/channels-dvr/migrations/migration_helpers/kubernetes_secrets.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
def get_value_from_secret(secrets=None, secret_name=None, key=None): | ||
secrets = secrets if secrets else dict() | ||
secret_name = secret_name if secret_name else "" | ||
key = key if key else "" | ||
|
||
if not secrets or not secret_name or not key: | ||
raise ValueError("Expected [secrets], [secret_name] and [key] to be set") | ||
for curr_secret_name, curr_data in secrets.items(): | ||
if curr_secret_name.endswith(secret_name): | ||
if not curr_data.get(key, None): | ||
raise ValueError( | ||
f"Expected [{key}] to be set in secret [{curr_secret_name}]" | ||
) | ||
return curr_data[key] | ||
|
||
raise ValueError(f"Secret [{secret_name}] not found") |
53 changes: 53 additions & 0 deletions
53
ix-dev/community/channels-dvr/migrations/migration_helpers/memory.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import re | ||
import math | ||
import psutil | ||
|
||
TOTAL_MEM = psutil.virtual_memory().total | ||
|
||
SINGLE_SUFFIX_REGEX = re.compile(r"^[1-9][0-9]*([EPTGMK])$") | ||
DOUBLE_SUFFIX_REGEX = re.compile(r"^[1-9][0-9]*([EPTGMK])i$") | ||
BYTES_INTEGER_REGEX = re.compile(r"^[1-9][0-9]*$") | ||
EXPONENT_REGEX = re.compile(r"^[1-9][0-9]*e[0-9]+$") | ||
|
||
SUFFIX_MULTIPLIERS = { | ||
"K": 10**3, | ||
"M": 10**6, | ||
"G": 10**9, | ||
"T": 10**12, | ||
"P": 10**15, | ||
"E": 10**18, | ||
} | ||
|
||
DOUBLE_SUFFIX_MULTIPLIERS = { | ||
"Ki": 2**10, | ||
"Mi": 2**20, | ||
"Gi": 2**30, | ||
"Ti": 2**40, | ||
"Pi": 2**50, | ||
"Ei": 2**60, | ||
} | ||
|
||
|
||
def transform_memory(memory): | ||
result = 4096 # Default to 4GB | ||
|
||
if re.match(SINGLE_SUFFIX_REGEX, memory): | ||
suffix = memory[-1] | ||
result = int(memory[:-1]) * SUFFIX_MULTIPLIERS[suffix] | ||
elif re.match(DOUBLE_SUFFIX_REGEX, memory): | ||
suffix = memory[-2:] | ||
result = int(memory[:-2]) * DOUBLE_SUFFIX_MULTIPLIERS[suffix] | ||
elif re.match(BYTES_INTEGER_REGEX, memory): | ||
result = int(memory) | ||
elif re.match(EXPONENT_REGEX, memory): | ||
result = int(float(memory)) | ||
|
||
result = math.ceil(result) | ||
result = min(result, TOTAL_MEM) | ||
# Convert to Megabytes | ||
result = result / 1024 / 1024 | ||
|
||
if int(result) == 0: | ||
result = TOTAL_MEM if TOTAL_MEM else 4096 | ||
|
||
return int(result) |
59 changes: 59 additions & 0 deletions
59
ix-dev/community/channels-dvr/migrations/migration_helpers/resources.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from .memory import transform_memory, TOTAL_MEM | ||
from .cpu import transform_cpu, CPU_COUNT | ||
|
||
|
||
def migrate_resources(resources, gpus=None, system_gpus=None): | ||
gpus = gpus or {} | ||
system_gpus = system_gpus or [] | ||
|
||
result = { | ||
"limits": { | ||
"cpus": int((CPU_COUNT or 2) / 2), | ||
"memory": int(TOTAL_MEM / 1024 / 1024), | ||
} | ||
} | ||
|
||
if resources.get("limits", {}).get("cpu", ""): | ||
result["limits"].update( | ||
{"cpus": transform_cpu(resources.get("limits", {}).get("cpu", ""))} | ||
) | ||
if resources.get("limits", {}).get("memory", ""): | ||
result["limits"].update( | ||
{"memory": transform_memory(resources.get("limits", {}).get("memory", ""))} | ||
) | ||
|
||
gpus_result = {} | ||
for gpu in gpus.items() if gpus else []: | ||
kind = gpu[0].lower() # Kind of gpu (amd, nvidia, intel) | ||
count = gpu[1] # Number of gpus user requested | ||
|
||
if count == 0: | ||
continue | ||
|
||
if "amd" in kind or "intel" in kind: | ||
gpus_result.update({"use_all_gpus": True}) | ||
elif "nvidia" in kind: | ||
sys_gpus = [ | ||
gpu_item | ||
for gpu_item in system_gpus | ||
if gpu_item.get("error") is None | ||
and gpu_item.get("vendor", None) is not None | ||
and gpu_item.get("vendor", "").upper() == "NVIDIA" | ||
] | ||
for sys_gpu in sys_gpus: | ||
if count == 0: # We passed # of gpus that user previously requested | ||
break | ||
guid = sys_gpu.get("vendor_specific_config", {}).get("uuid", "") | ||
pci_slot = sys_gpu.get("pci_slot", "") | ||
if not guid or not pci_slot: | ||
continue | ||
|
||
gpus_result.update( | ||
{"nvidia_gpu_selection": {pci_slot: {"uuid": guid, "use_gpu": True}}} | ||
) | ||
count -= 1 | ||
|
||
if gpus_result: | ||
result.update({"gpus": gpus_result}) | ||
|
||
return result |
Oops, something went wrong.