From 29c25e39fce5b549d4d960bcc7a65379059855ac Mon Sep 17 00:00:00 2001 From: Mika Busch Date: Fri, 7 Mar 2025 19:47:27 +0100 Subject: [PATCH] 17686 config option for disk divider (#18011) --- docs/configuration/miscellaneous.md | 12 +++++++ netbox/netbox/configuration_example.py | 5 +++ netbox/netbox/settings.py | 6 ++++ netbox/templates/virtualization/cluster.html | 4 +-- .../templates/virtualization/virtualdisk.html | 2 +- .../virtualization/virtualmachine.html | 4 +-- netbox/utilities/templatetags/helpers.py | 31 +++++++++++++++---- .../migrations/0040_convert_disk_size.py | 5 +-- .../virtualization/tables/virtualmachines.py | 6 ++-- 9 files changed, 59 insertions(+), 16 deletions(-) diff --git a/docs/configuration/miscellaneous.md b/docs/configuration/miscellaneous.md index c14c0ac77..b9d079564 100644 --- a/docs/configuration/miscellaneous.md +++ b/docs/configuration/miscellaneous.md @@ -233,3 +233,15 @@ This parameter controls how frequently a failed job is retried, up to the maximu Default: `0` (retries disabled) The maximum number of times a background task will be retried before being marked as failed. + +## DISK_BASE_UNIT + +Default: `1000` + +The base unit for disk sizes. Set this to `1024` to use binary prefixes (MiB, GiB, etc.) instead of decimal prefixes (MB, GB, etc.). + +## RAM_BASE_UNIT + +Default: `1000` + +The base unit for RAM sizes. Set this to `1024` to use binary prefixes (MiB, GiB, etc.) instead of decimal prefixes (MB, GB, etc.). diff --git a/netbox/netbox/configuration_example.py b/netbox/netbox/configuration_example.py index 84ead5339..d9861545c 100644 --- a/netbox/netbox/configuration_example.py +++ b/netbox/netbox/configuration_example.py @@ -221,6 +221,11 @@ SESSION_COOKIE_NAME = 'sessionid' # database access.) Note that the user as which NetBox runs must have read and write permissions to this path. SESSION_FILE_PATH = None +# By default the memory and disk sizes are displayed using base 10 (e.g. 1000 MB = 1 GB). +# If you would like to use base 2 (e.g. 1024 MB = 1 GB) set this to 1024. +# DISK_BASE_UNIT = 1024 +# RAM_BASE_UNIT = 1024 + # By default, uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the # class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example: # STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 84b86ba13..0248fa888 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -176,6 +176,12 @@ STORAGE_BACKEND = getattr(configuration, 'STORAGE_BACKEND', None) STORAGE_CONFIG = getattr(configuration, 'STORAGE_CONFIG', {}) TIME_ZONE = getattr(configuration, 'TIME_ZONE', 'UTC') TRANSLATION_ENABLED = getattr(configuration, 'TRANSLATION_ENABLED', True) +DISK_BASE_UNIT = getattr(configuration, 'DISK_BASE_UNIT', 1000) +if DISK_BASE_UNIT not in [1000, 1024]: + raise ImproperlyConfigured(f"DISK_BASE_UNIT must be 1000 or 1024 (found {DISK_BASE_UNIT})") +RAM_BASE_UNIT = getattr(configuration, 'RAM_BASE_UNIT', 1000) +if RAM_BASE_UNIT not in [1000, 1024]: + raise ImproperlyConfigured(f"RAM_BASE_UNIT must be 1000 or 1024 (found {RAM_BASE_UNIT})") # Load any dynamic configuration parameters which have been hard-coded in the configuration file for param in CONFIG_PARAMS: diff --git a/netbox/templates/virtualization/cluster.html b/netbox/templates/virtualization/cluster.html index 4155dacb2..f4d88f3d4 100644 --- a/netbox/templates/virtualization/cluster.html +++ b/netbox/templates/virtualization/cluster.html @@ -63,7 +63,7 @@ {% trans "Memory" %} {% if memory_sum %} - {{ memory_sum|humanize_megabytes }} + {{ memory_sum|humanize_ram_megabytes }} {% else %} {{ ''|placeholder }} {% endif %} @@ -73,7 +73,7 @@ {% trans "Disk Space" %} {% if disk_sum %} - {{ disk_sum|humanize_megabytes }} + {{ disk_sum|humanize_disk_megabytes }} {% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/templates/virtualization/virtualdisk.html b/netbox/templates/virtualization/virtualdisk.html index 3284d1668..805d779a9 100644 --- a/netbox/templates/virtualization/virtualdisk.html +++ b/netbox/templates/virtualization/virtualdisk.html @@ -29,7 +29,7 @@ {% trans "Size" %} {% if object.size %} - {{ object.size|humanize_megabytes }} + {{ object.size|humanize_disk_megabytes }} {% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/templates/virtualization/virtualmachine.html b/netbox/templates/virtualization/virtualmachine.html index 2bff51870..37a42b1d4 100644 --- a/netbox/templates/virtualization/virtualmachine.html +++ b/netbox/templates/virtualization/virtualmachine.html @@ -129,7 +129,7 @@ {% trans "Memory" %} {% if object.memory %} - {{ object.memory|humanize_megabytes }} + {{ object.memory|humanize_ram_megabytes }} {% else %} {{ ''|placeholder }} {% endif %} @@ -141,7 +141,7 @@ {% if object.disk %} - {{ object.disk|humanize_megabytes }} + {{ object.disk|humanize_disk_megabytes }} {% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index 3595c0666..2f175d2b6 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -8,6 +8,7 @@ from django.urls import NoReverseMatch, reverse from core.models import ObjectType from utilities.forms import get_selected_values, TableConfigForm from utilities.views import get_viewname +from netbox.settings import DISK_BASE_UNIT, RAM_BASE_UNIT __all__ = ( 'applied_filters', @@ -15,7 +16,8 @@ __all__ = ( 'divide', 'get_item', 'get_key', - 'humanize_megabytes', + 'humanize_disk_megabytes', + 'humanize_ram_megabytes', 'humanize_speed', 'icon_from_status', 'kg_to_pounds', @@ -84,17 +86,16 @@ def humanize_speed(speed): return '{} Kbps'.format(speed) -@register.filter() -def humanize_megabytes(mb): +def _humanize_megabytes(mb, divisor=1000): """ Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.). """ if not mb: return "" - PB_SIZE = 1000000000 - TB_SIZE = 1000000 - GB_SIZE = 1000 + PB_SIZE = divisor**3 + TB_SIZE = divisor**2 + GB_SIZE = divisor if mb >= PB_SIZE: return f"{mb / PB_SIZE:.2f} PB" @@ -105,6 +106,24 @@ def humanize_megabytes(mb): return f"{mb} MB" +@register.filter() +def humanize_disk_megabytes(mb): + """ + Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.). + Use the DISK_BASE_UNIT setting to determine the divisor. Default is 1000. + """ + return _humanize_megabytes(mb, DISK_BASE_UNIT) + + +@register.filter() +def humanize_ram_megabytes(mb): + """ + Express a number of megabytes in the most suitable unit (e.g. gigabytes, terabytes, etc.). + Use the RAM_BASE_UNIT setting to determine the divisor. Default is 1000. + """ + return _humanize_megabytes(mb, RAM_BASE_UNIT) + + @register.filter() def divide(x, y): """ diff --git a/netbox/virtualization/migrations/0040_convert_disk_size.py b/netbox/virtualization/migrations/0040_convert_disk_size.py index 4b0aec7bd..20153f7a0 100644 --- a/netbox/virtualization/migrations/0040_convert_disk_size.py +++ b/netbox/virtualization/migrations/0040_convert_disk_size.py @@ -1,13 +1,14 @@ from django.db import migrations from django.db.models import F, Sum +from netbox.settings import DISK_BASE_UNIT def convert_disk_size(apps, schema_editor): VirtualMachine = apps.get_model('virtualization', 'VirtualMachine') - VirtualMachine.objects.filter(disk__isnull=False).update(disk=F('disk') * 1000) + VirtualMachine.objects.filter(disk__isnull=False).update(disk=F('disk') * DISK_BASE_UNIT) VirtualDisk = apps.get_model('virtualization', 'VirtualDisk') - VirtualDisk.objects.filter(size__isnull=False).update(size=F('size') * 1000) + VirtualDisk.objects.filter(size__isnull=False).update(size=F('size') * DISK_BASE_UNIT) # Recalculate disk size on all VMs with virtual disks id_list = VirtualDisk.objects.values_list('virtual_machine_id').distinct() diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py index 20cfdd6d1..d56fe668a 100644 --- a/netbox/virtualization/tables/virtualmachines.py +++ b/netbox/virtualization/tables/virtualmachines.py @@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _ from dcim.tables.devices import BaseInterfaceTable from netbox.tables import NetBoxTable, columns from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin -from utilities.templatetags.helpers import humanize_megabytes +from utilities.templatetags.helpers import humanize_disk_megabytes from virtualization.models import VirtualDisk, VirtualMachine, VMInterface from .template_code import * @@ -93,7 +93,7 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable) ) def render_disk(self, value): - return humanize_megabytes(value) + return humanize_disk_megabytes(value) # @@ -183,7 +183,7 @@ class VirtualDiskTable(NetBoxTable): } def render_size(self, value): - return humanize_megabytes(value) + return humanize_disk_megabytes(value) class VirtualMachineVirtualDiskTable(VirtualDiskTable):