Skip to content

Commit

Permalink
add minio stable (#87)
Browse files Browse the repository at this point in the history
* add minio stable

* update lib

* add ix_values
  • Loading branch information
stavros-k authored Jul 31, 2024
1 parent cfcd902 commit 9818170
Show file tree
Hide file tree
Showing 30 changed files with 2,111 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Thank you for your understanding.
| emby | charts | - | - |
| home-assistant | charts | - | - |
| ix-chart | charts | - | - |
| minio | charts | - | - |
| minio | charts | | |
| netdata | charts | - | - |
| nextcloud | charts | - | - |
| photoprism | charts | - | - |
Expand Down
5 changes: 5 additions & 0 deletions ix-dev/stable/minio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# MinIO

[MinIO](https://min.io) is a High Performance Object Storage released under Apache License v2.0.
It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance
infrastructure for machine learning, analytics and application data workloads.
34 changes: 34 additions & 0 deletions ix-dev/stable/minio/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
app_version: 2024-07-16T23-46-41Z
capabilities: []
categories:
- storage
description: The Object Store for AI Data Infrastructure
home: https://min.io
host_mounts: []
icon: https://media.sys.truenas.net/apps/minio/icons/icon.png
keywords:
- storage
- object-storage
- S3
lib_version: 1.0.0
lib_version_hash: 1653158d96bfa65906563cc4695a15254e1227ecdaa6975eb3163c398a371aa2
maintainers:
- email: [email protected]
name: truenas
url: https://www.truenas.com/
name: minio
run_as_context:
- description: Minio runs as any non-root user.
gid: 473
group_name: minio
uid: 473
user_name: minio
screenshots:
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot1.png
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot2.png
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot3.png
sources:
- https://github.com/minio/minio
title: MinIO
train: stable
version: 1.0.0
11 changes: 11 additions & 0 deletions ix-dev/stable/minio/item.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
categories:
- storage
icon_url: https://media.sys.truenas.net/apps/minio/icons/icon.png
screenshots:
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot1.png
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot2.png
- https://media.sys.truenas.net/apps/minio/screenshots/screenshot3.png
tags:
- storage
- object-storage
- S3
11 changes: 11 additions & 0 deletions ix-dev/stable/minio/ix_values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
images:
image:
repository: minio/minio
tag: RELEASE.2024-07-16T23-46-41Z

consts:
minio_container_name: minio
perms_container_name: permissions
run_as_user: 473
run_as_group: 473
certs_dir: /etc/minio/certs
52 changes: 52 additions & 0 deletions ix-dev/stable/minio/migrations/migrate_from_kubernetes
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/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")

new_values = {
"minio": {
"root_user": config["minioConfig"]["rootUser"],
"root_password": config["minioConfig"]["rootPassword"],
"extra_args": config["minioConfig"].get("extraArgs", []),
"additional_envs": config["minioConfig"].get("additionalEnvs", []),
},
"network": {
"domain": config["minioConfig"].get("domain", ""),
"console_port": config["minioNetwork"]["consolePort"],
"api_port": config["minioNetwork"]["apiPort"],
"certificate_id": config["minioNetwork"].get("certificateID", None),
"dns_opts": migrate_dns_config(config.get("podOptions", {}).get("dnsConfig", {})),
},
"storage": {
"distributed_mode": config["minioStorage"].get("distributedMode", False),
"distributed_uris": config["minioStorage"].get("distributedURIs", []),
"export": migrate_storage_item(config["minioStorage"]["export"]),
"additional_storage": [
migrate_storage_item(item, include_read_only=True)
for item in config["minioStorage"]["additionalStorages"]
],
},
"resources": migrate_resources(config["resources"]),
}

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.
27 changes: 27 additions & 0 deletions ix-dev/stable/minio/migrations/migration_helpers/cpu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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)

return result
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
def get_value_from_secret(secrets={}, secret_name="", key=""):
if not secrets or not secret_name or not key:
raise ValueError("Expected [secrets], [secret_name] and [key] to be set")
for secret in secrets.items():
curr_secret_name = secret[0]
curr_data = secret[1]

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")
49 changes: 49 additions & 0 deletions ix-dev/stable/minio/migrations/migration_helpers/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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
return int(result)
59 changes: 59 additions & 0 deletions ix-dev/stable/minio/migrations/migration_helpers/resources.py
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": (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", ""))}
)

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
Loading

0 comments on commit 9818170

Please sign in to comment.