Skip to content

Commit 01cbdbb

Browse files
authored
Closes #18658: Add start on boot field to VirtualMachine model (#20751)
1 parent a4365be commit 01cbdbb

File tree

15 files changed

+109
-22
lines changed

15 files changed

+109
-22
lines changed

docs/models/virtualization/virtualmachine.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ The VM's operational status.
2121
!!! tip
2222
Additional statuses may be defined by setting `VirtualMachine.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
2323

24+
### Start on boot
25+
26+
The start on boot setting from the hypervisor.
27+
28+
!!! tip
29+
Additional statuses may be defined by setting `VirtualMachine.start_on_boot` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
30+
2431
### Site & Cluster
2532

2633
The [site](../dcim/site.md) and/or [cluster](./cluster.md) to which the VM is assigned.

netbox/templates/virtualization/virtualmachine.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ <h2 class="card-header">{% trans "Virtual Machine" %}</h2>
1919
<th scope="row">{% trans "Status" %}</th>
2020
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
2121
</tr>
22+
<tr>
23+
<th scope="row">{% trans "Start on boot" %}</th>
24+
<td>{% badge object.get_start_on_boot_display bg_color=object.get_start_on_boot_color %}</td>
25+
</tr>
2226
<tr>
2327
<th scope="row">{% trans "Role" %}</th>
2428
<td>{{ object.role|linkify|placeholder }}</td>

netbox/virtualization/api/serializers_/virtualmachines.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
class VirtualMachineSerializer(PrimaryModelSerializer):
3333
status = ChoiceField(choices=VirtualMachineStatusChoices, required=False)
34+
start_on_boot = ChoiceField(choices=VirtualMachineStartOnBootChoices, required=False)
3435
site = SiteSerializer(nested=True, required=False, allow_null=True, default=None)
3536
cluster = ClusterSerializer(nested=True, required=False, allow_null=True, default=None)
3637
device = DeviceSerializer(nested=True, required=False, allow_null=True, default=None)
@@ -49,10 +50,10 @@ class VirtualMachineSerializer(PrimaryModelSerializer):
4950
class Meta:
5051
model = VirtualMachine
5152
fields = [
52-
'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role',
53-
'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description',
54-
'owner', 'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields', 'created',
55-
'last_updated', 'interface_count', 'virtual_disk_count',
53+
'id', 'url', 'display_url', 'display', 'name', 'status', 'start_on_boot', 'site', 'cluster', 'device',
54+
'serial', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory',
55+
'disk', 'description', 'owner', 'comments', 'config_template', 'local_context_data', 'tags',
56+
'custom_fields', 'created', 'last_updated', 'interface_count', 'virtual_disk_count',
5657
]
5758
brief_fields = ('id', 'url', 'display', 'name', 'description')
5859

@@ -62,10 +63,10 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
6263

6364
class Meta(VirtualMachineSerializer.Meta):
6465
fields = [
65-
'id', 'url', 'display_url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'serial', 'role',
66-
'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description',
67-
'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields', 'config_context', 'created',
68-
'last_updated', 'interface_count', 'virtual_disk_count',
66+
'id', 'url', 'display_url', 'display', 'name', 'status', 'start_on_boot', 'site', 'cluster', 'device',
67+
'serial', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory',
68+
'disk', 'description', 'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields',
69+
'config_context', 'created', 'last_updated', 'interface_count', 'virtual_disk_count',
6970
]
7071

7172
@extend_schema_field(serializers.JSONField(allow_null=True))

netbox/virtualization/choices.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,17 @@ class VirtualMachineStatusChoices(ChoiceSet):
4949
(STATUS_DECOMMISSIONING, _('Decommissioning'), 'yellow'),
5050
(STATUS_PAUSED, _('Paused'), 'orange'),
5151
]
52+
53+
54+
class VirtualMachineStartOnBootChoices(ChoiceSet):
55+
key = 'VirtualMachine.start_on_boot'
56+
57+
STATUS_ON = 'on'
58+
STATUS_OFF = 'off'
59+
STATUS_LAST_STATE = 'laststate'
60+
61+
CHOICES = [
62+
(STATUS_ON, _('On'), 'green'),
63+
(STATUS_OFF, _('Off'), 'gray'),
64+
(STATUS_LAST_STATE, _('Last State'), 'cyan')
65+
]

netbox/virtualization/filtersets.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class VirtualMachineFilterSet(
9292
choices=VirtualMachineStatusChoices,
9393
null_value=None
9494
)
95+
start_on_boot = django_filters.MultipleChoiceFilter(
96+
choices=VirtualMachineStartOnBootChoices,
97+
null_value=None
98+
)
9599
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
96100
field_name='cluster__group',
97101
queryset=ClusterGroup.objects.all(),

netbox/virtualization/forms/bulk_edit.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
8585
required=False,
8686
initial='',
8787
)
88+
start_on_boot = forms.ChoiceField(
89+
label=_('Start on boot'),
90+
choices=add_blank_choice(VirtualMachineStartOnBootChoices),
91+
required=False,
92+
initial='',
93+
)
8894
site = DynamicModelChoiceField(
8995
label=_('Site'),
9096
queryset=Site.objects.all(),
@@ -145,7 +151,7 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
145151

146152
model = VirtualMachine
147153
fieldsets = (
148-
FieldSet('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description'),
154+
FieldSet('site', 'cluster', 'device', 'status', 'start_on_boot', 'role', 'tenant', 'platform', 'description'),
149155
FieldSet('vcpus', 'memory', 'disk', name=_('Resources')),
150156
FieldSet('config_template', name=_('Configuration')),
151157
)

netbox/virtualization/forms/bulk_import.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ class VirtualMachineImportForm(PrimaryModelImportForm):
8989
choices=VirtualMachineStatusChoices,
9090
help_text=_('Operational status')
9191
)
92+
start_on_boot = CSVChoiceField(
93+
label=_('Start on boot'),
94+
choices=VirtualMachineStartOnBootChoices,
95+
help_text=_('Start on boot in hypervisor'),
96+
required=False,
97+
)
9298
site = CSVModelChoiceField(
9399
label=_('Site'),
94100
queryset=Site.objects.all(),
@@ -144,8 +150,8 @@ class VirtualMachineImportForm(PrimaryModelImportForm):
144150
class Meta:
145151
model = VirtualMachine
146152
fields = (
147-
'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
148-
'description', 'serial', 'config_template', 'comments', 'owner', 'tags',
153+
'name', 'status', 'start_on_boot', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus',
154+
'memory', 'disk', 'description', 'serial', 'config_template', 'comments', 'owner', 'tags',
149155
)
150156

151157

netbox/virtualization/forms/filtersets.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class VirtualMachineFilterForm(
109109
FieldSet('cluster_group_id', 'cluster_type_id', 'cluster_id', 'device_id', name=_('Cluster')),
110110
FieldSet('region_id', 'site_group_id', 'site_id', name=_('Location')),
111111
FieldSet(
112-
'status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'config_template_id',
112+
'status', 'start_on_boot', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'config_template_id',
113113
'local_context_data', 'serial', name=_('Attributes')
114114
),
115115
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
@@ -171,6 +171,11 @@ class VirtualMachineFilterForm(
171171
choices=VirtualMachineStatusChoices,
172172
required=False
173173
)
174+
start_on_boot = forms.MultipleChoiceField(
175+
label=_('Start on boot'),
176+
choices=VirtualMachineStartOnBootChoices,
177+
required=False
178+
)
174179
platform_id = DynamicModelMultipleChoiceField(
175180
queryset=Platform.objects.all(),
176181
required=False,

netbox/virtualization/forms/model_forms.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ class VirtualMachineForm(TenancyForm, PrimaryModelForm):
217217
)
218218

219219
fieldsets = (
220-
FieldSet('name', 'role', 'status', 'description', 'serial', 'tags', name=_('Virtual Machine')),
220+
FieldSet('name', 'role', 'status', 'start_on_boot', 'description', 'serial', 'tags', name=_('Virtual Machine')),
221221
FieldSet('site', 'cluster', 'device', name=_('Site/Cluster')),
222222
FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
223223
FieldSet('platform', 'primary_ip4', 'primary_ip6', 'config_template', name=_('Management')),
@@ -228,9 +228,9 @@ class VirtualMachineForm(TenancyForm, PrimaryModelForm):
228228
class Meta:
229229
model = VirtualMachine
230230
fields = [
231-
'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant_group', 'tenant', 'platform', 'primary_ip4',
232-
'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'serial', 'owner', 'comments', 'tags',
233-
'local_context_data', 'config_template',
231+
'name', 'status', 'start_on_boot', 'site', 'cluster', 'device', 'role', 'tenant_group', 'tenant',
232+
'platform', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'serial', 'owner',
233+
'comments', 'tags', 'local_context_data', 'config_template',
234234
]
235235

236236
def __init__(self, *args, **kwargs):
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.7 on 2025-11-05 13:36
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('virtualization', '0049_owner'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='virtualmachine',
15+
name='start_on_boot',
16+
field=models.CharField(default='off', max_length=32),
17+
),
18+
]

0 commit comments

Comments
 (0)