Skip to content

Commit

Permalink
update lib
Browse files Browse the repository at this point in the history
  • Loading branch information
stavros-k committed Jul 29, 2024
1 parent c77e4e9 commit 2f1bbde
Show file tree
Hide file tree
Showing 29 changed files with 291 additions and 100 deletions.
20 changes: 0 additions & 20 deletions ix-dev/charts/emby/migrations/migration_helpers/resources.py

This file was deleted.

34 changes: 0 additions & 34 deletions ix-dev/charts/emby/templates/library/base_v1_0_0/environment.py

This file was deleted.

16 changes: 0 additions & 16 deletions ix-dev/charts/emby/templates/library/base_v1_0_0/resources.py

This file was deleted.

File renamed without changes.
4 changes: 2 additions & 2 deletions ix-dev/charts/emby/app.yaml → ix-dev/stable/emby/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ keywords:
- tv
- streaming
lib_version: 1.0.0
lib_version_hash: 9c07d26150ab40c0f19ae3991ee02b338aecf50e6c3619414d114276d08e1c1f
lib_version_hash: 04058cefffe4eeadb07035ab157987492a31d5708705d6b7153d262beb75a796
maintainers:
- email: [email protected]
name: truenas
Expand All @@ -48,5 +48,5 @@ sources:
- https://hub.docker.com/r/emby/embyserver
- https://github.com/truenas/charts/tree/master/charts/emby
title: Emby
train: charts
train: stable
version: 1.0.0
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ def transform_memory(memory):

result = math.ceil(result)
result = min(result, TOTAL_MEM)
# Convert to Megabytes
result = result / 1024 / 1024
return f"{int(result)}M"
return int(result)
31 changes: 31 additions & 0 deletions ix-dev/stable/emby/migrations/migration_helpers/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from .memory import transform_memory, TOTAL_MEM
from .cpu import transform_cpu, CPU_COUNT


def migrate_resources(resources, gpus=None):
gpus = gpus or {}

result = {
"limits": {
"cpus": (CPU_COUNT or 2) / 2,
"memory": {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", ""))}
)

for gpu in gpus.items() if gpus else []:
if gpu[1] > 0 and ("amd" in gpu[0] or "intel" in gpu[0]):
result.update({"gpus": {"use_all_gpus": True}})
break
# We cannot migrate NVIDIA GPUs, as we don't know the UUIDs at this point
# and schema validation will fail.

return result
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def migrate_storage_item(storage_item):
def migrate_storage_item(storage_item, include_read_only=False):
if not storage_item:
raise ValueError("Expected [storage_item] to be set")

Expand All @@ -16,7 +16,8 @@ def migrate_storage_item(storage_item):
if mount_path:
result.update({"mount_path": mount_path})

result.update({"read_only": storage_item.get("readOnly", False)})
if include_read_only:
result.update({"read_only": storage_item.get("readOnly", False)})
return result


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,22 +239,22 @@ questions:
schema:
type: path
required: true
- variable: tmpfs_config
label: Tmpfs Configuration
description: The configuration for the tmpfs dataset.
schema:
type: dict
show_if: [["type", "=", "tmpfs"]]
attrs:
- variable: size
label: Tmpfs Size Limit (in Mi)
description: |
The maximum size (in Mi) of the temporary directory.</br>
For example: 500
- variable: tmpfs_config
label: Tmpfs Configuration
description: The configuration for the tmpfs dataset.
schema:
type: int
default: 500
required: true
type: dict
show_if: [["type", "=", "tmpfs"]]
attrs:
- variable: size
label: Tmpfs Size Limit (in Mi)
description: |
The maximum size (in Mi) of the temporary directory.</br>
For example: 500
schema:
type: int
default: 500
required: true
- variable: host_path_config
label: Host Path Configuration
schema:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
{# Stores the container volume mounts #}
{% set volume_mounts = namespace(items=[]) %}

{% do storage_items.items.append(ix_lib.base.storage.storage_item(data=dict(values.storage.config, **{"mount_path": "/config"}), ix_volumes=values.ix_volumes)) %}
{% do storage_items.items.append(ix_lib.base.storage.storage_item(data={"type":"anonymous", "mount_path": "/tmp"})) %}
{% set _ = storage_items.items.append(ix_lib.base.storage.storage_item(data=dict(values.storage.config, **{"mount_path": "/config"}), ix_volumes=values.ixVolumes)) %}
{% set _ = storage_items.items.append(ix_lib.base.storage.storage_item(data={"type":"anonymous", "mount_path": "/tmp"})) %}

{% for store in values.storage.additional_storage %}
{% do storage_items.items.append(ix_lib.base.storage.storage_item(data=store, ix_volumes=values.ix_volumes)) %}
{% set _ = storage_items.items.append(ix_lib.base.storage.storage_item(data=store, ix_volumes=values.ixVolumes)) %}
{% endfor %}

{# Add each item to the above lists #}
Expand Down Expand Up @@ -41,13 +41,9 @@ services:
{% endif %}
{% set test = ix_lib.base.healthchecks.wget_test(port=8096, path="/emby/System/Ping") %}
healthcheck: {{ ix_lib.base.healthchecks.check_health(test) | tojson }}
{% set app_env = {
"TZ": values.TZ,
"UID": values.run_as.user,
"GID": values.run_as.group,
} %}
{# {% do app_env.update({"GIDLIST": "TODO:!, Add GPU Groups when gpu is added, eg (44,107)"}) %} #}
environment: {{ ix_lib.base.environment.envs(app=app_env, user=values.emby.additional_envs) | tojson }}
{% set app_env = {} %}
{# {% set _ = app_env.update({"GIDLIST": "TODO:!, Add GPU Groups when gpu is added, eg (44,107)"}) %} #}
environment: {{ ix_lib.base.environment.envs(app=app_env, user=values.emby.additional_envs, values=values) | tojson }}
{% if not values.network.host_network %}
ports:
- {{ ix_lib.base.ports.get_port(port={"target": 8096, "published": values.network.web_port}) | tojson }}
Expand Down
90 changes: 90 additions & 0 deletions ix-dev/stable/emby/templates/library/base_v1_0_0/environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from . import utils
from .resources import get_nvidia_gpus_reservations


def envs(app: dict | None = None, user: list | None = None, values: dict | None = None):
app = app or {}
user = user or []
values = values or {}
result = {}

if not values:
utils.throw_error("Values cannot be empty in environment.py")

if not isinstance(user, list):
utils.throw_error(
f"Unsupported type for user environment variables [{type(user)}]"
)

# Always set TZ
result.update({"TZ": values.get("TZ", "Etc/UTC")})

# Update envs with nvidia variables
if values.get("resources", {}).get("gpus", {}):
result.update(get_nvidia_env(values.get("resources", {}).get("gpus", {})))

# Update envs with run_as variables
if values.get("run_as"):
result.update(get_run_as_envs(values.get("run_as", {})))

# Make sure we don't manually set any of the above
for item in app.items():
if not item[0]:
utils.throw_error("Environment variable name cannot be empty.")
if item[0] in result:
utils.throw_error(
f"Environment variable [{item[0]}] is already defined automatically from the library."
)
result[item[0]] = item[1]

for item in user:
if not item.get("name"):
utils.throw_error("Environment variable name cannot be empty.")
if item.get("name") in result:
utils.throw_error(
f"Environment variable [{item['name']}] is already defined from the application developer."
)
result[item["name"]] = item.get("value")

return result


# Sets some common variables that most applications use
def get_run_as_envs(run_as: dict) -> dict:
result = {}
user = run_as.get("user")
group = run_as.get("group")
if user:
result.update(
{
"PUID": user,
"UID": user,
"USER_ID": user,
}
)
if group:
result.update(
{
"PGID": group,
"GID": group,
"GROUP_ID": group,
}
)
return result


def get_nvidia_env(gpus: dict) -> dict:
reservations = get_nvidia_gpus_reservations(gpus)
if not reservations.get("device_ids"):
return {
"NVIDIA_VISIBLE_DEVICES": "void",
}

return {
"NVIDIA_VISIBLE_DEVICES": (
",".join(reservations["device_ids"])
if reservations.get("device_ids")
else "void"
),
"NVIDIA_DRIVER_CAPABILITIES": "all",
}
72 changes: 72 additions & 0 deletions ix-dev/stable/emby/templates/library/base_v1_0_0/metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from . import utils


def get_header(app_name: str):
return f"""# Welcome to TrueNAS SCALE
Thank you for installing {app_name}!
"""


def get_footer(app_name: str):
return f"""## Documentation
Documentation for {app_name} can be found at https://www.truenas.com/docs.
## Bug reports
If you find a bug in this app, please file an issue at
https://ixsystems.atlassian.net or https://github.com/truenas/apps
## Feature requests or improvements
If you find a feature request for this app, please file an issue at
https://ixsystems.atlassian.net or https://github.com/truenas/apps
"""


def get_notes(app_name: str, body: str = ""):
if not app_name:
utils.throw_error("Expected [app_name] to be set")

return f"{get_header(app_name)}\n\n{body}\n\n{get_footer(app_name)}"


def get_portals(portals: list):
valid_schemes = ["http", "https"]
result = []
for portal in portals:
# Most apps have a single portal, lets default to a standard name
name = portal.get("name", "Web UI")
scheme = portal.get("scheme", "http")
path = portal.get("path", "/")

if not name:
utils.throw_error("Expected [portal.name] to be set")
if name in [p["name"] for p in result]:
utils.throw_error(
f"Expected [portal.name] to be unique, got [{', '.join([p['name'] for p in result]+[name])}]"
)
if scheme not in valid_schemes:
utils.throw_error(
f"Expected [portal.scheme] to be one of [{', '.join(valid_schemes)}], got [{portal['scheme']}]"
)
if not portal.get("port"):
utils.throw_error("Expected [portal.port] to be set")
if not path.startswith("/"):
utils.throw_error(
f"Expected [portal.path] to start with /, got [{portal['path']}]"
)

result.append(
{
"name": name,
"scheme": scheme,
# TODO: Default to something else?
"host": portal.get("host", "0.0.0.0"),
"port": portal["port"],
"path": path,
}
)

return result
Loading

0 comments on commit 2f1bbde

Please sign in to comment.