Merge ~ack/maas:virsh-pod-same-hostname into maas:master

Proposed by Alberto Donato
Status: Merged
Approved by: Alberto Donato
Approved revision: ff5f2fe70fc6b82997baeba300449766f4e068ec
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ack/maas:virsh-pod-same-hostname
Merge into: maas:master
Diff against target: 118 lines (+43/-7)
4 files modified
src/maasserver/forms/pods.py (+9/-1)
src/maasserver/forms/tests/test_pods.py (+13/-0)
src/maasserver/models/bmc.py (+5/-6)
src/maasserver/models/tests/test_bmc.py (+16/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Blake Rouse (community) Approve
Review via email: mp+332981@code.launchpad.net

Commit message

LP: #1716328 - check if pod machine hostname is already in use

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b virsh-pod-same-hostname lp:~ack/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 98f36263d0458d5f9b6eaa0a1d96f47f81a03db2

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Code looks good, just a comment that should be changed before landing.

review: Approve
Revision history for this message
Alberto Donato (ack) :
Revision history for this message
Andres Rodriguez (andreserl) wrote :

Isn’t “format” the python3 way of dealing with this though?

On Mon, Oct 30, 2017 at 12:54 PM Alberto Donato <
<email address hidden>> wrote:

>
>
> Diff comments:
>
> > diff --git a/src/maasserver/forms/pods.py b/src/maasserver/forms/pods.py
> > index 03b8f06..bedf9a9 100644
> > --- a/src/maasserver/forms/pods.py
> > +++ b/src/maasserver/forms/pods.py
> > @@ -306,7 +307,15 @@ class ComposeMachineForm(forms.Form):
> > else:
> > self.fields['cpu_speed'] = IntegerField(
> > min_value=300, required=False)
> > - self.fields['hostname'] = CharField(required=False)
> > +
> > + def duplicated_hostname(hostname):
> > + if Node.objects.filter(hostname=hostname).exists():
> > + raise ValidationError(
> > + 'Machine with hostname "{}" already exists'.format(
>
> Done. I switched to %s, but I think we should consider using format() for
> new messages (and progressively update code when we touch it. format() is
> nicer to read and more flexible.
>
> > + hostname))
> > +
> > + self.fields['hostname'] = CharField(
> > + required=False, validators=[duplicated_hostname])
> > self.initial['hostname'] = make_unique_hostname()
> > self.fields['domain'] = ModelChoiceField(
> > required=False, queryset=Domain.objects.all())
>
>
> --
> https://code.launchpad.net/~ack/maas/+git/maas/+merge/332981
> You are reviewing the proposed merge of ~ack/maas:virsh-pod-same-hostname
> into maas:master.
>
--
Andres Rodriguez
Engineering Manager, MAAS
Canonical USA, Inc.

Revision history for this message
MAAS Lander (maas-lander) wrote :

LANDING
-b virsh-pod-same-hostname lp:~ack/maas into -b master lp:~maas-committers/maas

STATUS: FAILED BUILD
LOG: http://maas-ci-jenkins.internal:8080/job/maas/job/branch-tester/587/consoleText

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b virsh-pod-same-hostname lp:~ack/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci-jenkins.internal:8080/job/maas/job/branch-tester/589/console
COMMIT: 3a3db0764dca64282c9ca58898af31677e345e00

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b virsh-pod-same-hostname lp:~ack/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: ff5f2fe70fc6b82997baeba300449766f4e068ec

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

@andres yes, format() is the preferred way in python3

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/forms/pods.py b/src/maasserver/forms/pods.py
2index 03b8f06..334bb88 100644
3--- a/src/maasserver/forms/pods.py
4+++ b/src/maasserver/forms/pods.py
5@@ -38,6 +38,7 @@ from maasserver.models import (
6 BMCRoutableRackControllerRelationship,
7 Domain,
8 Machine,
9+ Node,
10 Pod,
11 RackController,
12 Zone,
13@@ -306,7 +307,14 @@ class ComposeMachineForm(forms.Form):
14 else:
15 self.fields['cpu_speed'] = IntegerField(
16 min_value=300, required=False)
17- self.fields['hostname'] = CharField(required=False)
18+
19+ def duplicated_hostname(hostname):
20+ if Node.objects.filter(hostname=hostname).exists():
21+ raise ValidationError(
22+ 'Node with hostname "%s" already exists' % hostname)
23+
24+ self.fields['hostname'] = CharField(
25+ required=False, validators=[duplicated_hostname])
26 self.initial['hostname'] = make_unique_hostname()
27 self.fields['domain'] = ModelChoiceField(
28 required=False, queryset=Domain.objects.all())
29diff --git a/src/maasserver/forms/tests/test_pods.py b/src/maasserver/forms/tests/test_pods.py
30index 9731d18..9b530bc 100644
31--- a/src/maasserver/forms/tests/test_pods.py
32+++ b/src/maasserver/forms/tests/test_pods.py
33@@ -751,6 +751,19 @@ class TestComposeMachineForm(MAASTransactionServerTestCase):
34 cpu_speed=Equals(300))))
35 self.assertThat(mock_commissioning, MockCalledOnce())
36
37+ def test__compose_duplicated_hostname(self):
38+ factory.make_Node(hostname='test')
39+
40+ request = MagicMock()
41+ pod = make_pod_with_hints()
42+
43+ form = ComposeMachineForm(
44+ data={'hostname': 'test'}, request=request, pod=pod)
45+ self.assertFalse(form.is_valid())
46+ self.assertEqual(
47+ {'hostname': ['Node with hostname "test" already exists']},
48+ form.errors)
49+
50 def test__compose_without_commissioning(self):
51 request = MagicMock()
52 pod = make_pod_with_hints()
53diff --git a/src/maasserver/models/bmc.py b/src/maasserver/models/bmc.py
54index 3fcc8b9..5cc286c 100644
55--- a/src/maasserver/models/bmc.py
56+++ b/src/maasserver/models/bmc.py
57@@ -9,7 +9,6 @@ __all__ = [
58
59 from functools import partial
60 import re
61-import string
62
63 from django.contrib.postgres.fields import ArrayField
64 from django.core.exceptions import ValidationError
65@@ -433,6 +432,8 @@ class Pod(BMC):
66
67 objects = PodManager()
68
69+ _machine_name_re = re.compile(r'[a-z][a-z0-9-]+$', flags=re.I)
70+
71 def __init__(self, *args, **kwargs):
72 super(Pod, self).__init__(
73 bmc_type=BMC_TYPE.POD, *args, **kwargs)
74@@ -562,14 +563,12 @@ class Pod(BMC):
75
76 # Check to see if discovered machine's hostname is legal and unique.
77 if discovered_machine.hostname:
78- for char in discovered_machine.hostname:
79- if char not in (string.ascii_letters + string.digits + '-'):
80- discovered_machine.hostname = None
81- break
82- if discovered_machine.hostname:
83 if Node.objects.filter(
84 hostname=discovered_machine.hostname).exists():
85 discovered_machine.hostname = None
86+ elif not self._machine_name_re.match(
87+ discovered_machine.hostname):
88+ discovered_machine.hostname = None
89
90 # Create the machine.
91 machine = Machine(
92diff --git a/src/maasserver/models/tests/test_bmc.py b/src/maasserver/models/tests/test_bmc.py
93index 46c913b..2e2477f 100644
94--- a/src/maasserver/models/tests/test_bmc.py
95+++ b/src/maasserver/models/tests/test_bmc.py
96@@ -806,6 +806,22 @@ class TestPod(MAASServerTestCase):
97 # that will cause a database exception.
98 pod.create_machine(discovered_machine, factory.make_User())
99
100+ def test_create_machine_invalid_hostname(self):
101+ discovered_machine = self.make_discovered_machine()
102+ discovered_machine.hostname = 'invalid_name'
103+ self.patch(Machine, "set_default_storage_layout")
104+ self.patch(Machine, "set_initial_networking_configuration")
105+ self.patch(Machine, "start_commissioning")
106+ fabric = factory.make_Fabric()
107+ factory.make_VLAN(
108+ fabric=fabric, dhcp_on=True,
109+ primary_rack=factory.make_RackController())
110+ pod = factory.make_Pod()
111+ # Doesn't raise an exception ensures that the hostname is unique as
112+ # that will cause a database exception.
113+ machine = pod.create_machine(discovered_machine, factory.make_User())
114+ self.assertNotEqual(machine.hostname, 'invalid_name')
115+
116 def test_sync_pod_creates_new_machines_connected_to_dhcp_vlan(self):
117 discovered = self.make_discovered_pod()
118 mock_set_default_storage_layout = self.patch(

Subscribers

People subscribed via source and target branches