sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #04059
[Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
Christian Grabowski has proposed merging ~cgrabowski/maas:fix_node_dns_generation into maas:master.
Commit message:
add trigger when existing static ip updates
add DELETE-IFACE-IP
add triggers for interface to ip dynamic DNS updates
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~cgrabowski/maas/+git/maas/+merge/434522
--
Your team MAAS Committers is subscribed to branch maas:master.
diff --git a/src/maasserver/dns/config.py b/src/maasserver/dns/config.py
index c484570..ea834de 100644
--- a/src/maasserver/dns/config.py
+++ b/src/maasserver/dns/config.py
@@ -21,6 +21,7 @@ from maasserver.models.dnsdata import DNSData
from maasserver.models.dnspublication import DNSPublication
from maasserver.models.dnsresource import DNSResource
from maasserver.models.domain import Domain
+from maasserver.models.interface import Interface
from maasserver.models.node import RackController
from maasserver.models.subnet import Subnet
from provisioningserver.dns.actions import (
@@ -348,7 +349,7 @@ def process_dns_update_notify(message):
case _:
# special case where we know an IP has been deleted but, we can't fetch the value
# and the rrecord may still have other answers
- if op == "DELETE-IP":
+ if op == "DELETE-IP" or op == "DELETE-IFACE-IP":
updates.append(
DynamicDNSUpdate.create_from_trigger(
operation="DELETE",
@@ -366,23 +367,33 @@ def process_dns_update_notify(message):
rectype="AAAA",
)
)
- resource = DNSResource.objects.get(
- name=update_list[2], domain__name=zone
- )
+
+ ttl = None
+ ip_addresses = []
+ if op == "DELETE-IP":
+ resource = DNSResource.objects.get(
+ name=update_list[2], domain__name=zone
+ )
+ ttl = int(resource.address_ttl) if resource.address_ttl else None
+ ip_addresses = list(resource.ip_addresses.exclude(ip__isnull=True))
+ else:
+ iface_id = int(update_list[-1])
+ iface = Interface.objects.get(id=iface_id)
+ default_domain = Domain.objects.get_default_domain()
+ ttl = int(default_domain.ttl) if default_domain.ttl else None
+ ip_addresses = list(iface.ip_addresses.exclude(ip__isnull=True))
+ print(ip_addresses)
updates += [
DynamicDNSUpdate.create_from_trigger(
operation="INSERT",
zone=zone,
name=name,
rectype=rectype,
- ttl=int(resource.address_ttl)
- if resource.address_ttl
- else None,
+ ttl=ttl,
answer=ip.ip,
)
- for ip in resource.ip_addresses.all()
+ for ip in ip_addresses
]
-
elif len(update_list) > 4: # has an answer
updates.append(
DynamicDNSUpdate.create_from_trigger(
diff --git a/src/maasserver/dns/tests/test_config.py b/src/maasserver/dns/tests/test_config.py
index 9a2835d..ded425f 100644
--- a/src/maasserver/dns/tests/test_config.py
+++ b/src/maasserver/dns/tests/test_config.py
@@ -873,7 +873,8 @@ class TestProcessDNSUpdateNotify(MAASServerTestCase):
domain = factory.make_Domain()
resource = factory.make_DNSResource(domain=domain)
ip = resource.ip_addresses.first().ip
- ip2 = factory.make_StaticIPAddress()
+ subnet = factory.make_Subnet()
+ ip2 = factory.make_StaticIPAddress(subnet=subnet, ip=subnet.get_next_ip_for_allocation()[0])
resource.ip_addresses.add(ip2)
message = f"DELETE-IP {domain.name} {resource.name} A {resource.address_ttl if resource.address_ttl else 60} {ip}"
resource.ip_addresses.first().delete()
@@ -902,3 +903,38 @@ class TestProcessDNSUpdateNotify(MAASServerTestCase):
],
result,
)
+
+ def test_delete_iface_ip(self):
+ domain = factory.make_Domain()
+ node = factory.make_Node_with_Interface_on_Subnet()
+ iface = node.current_config.interface_set.first()
+ ip1 = iface.ip_addresses.first()
+ ip2 = factory.make_StaticIPAddress(interface=iface)
+ ip1_id = ip1.id
+ ip1.delete()
+ message = f"DELETE-IFACE-IP {domain.name} {node.hostname} A {domain.ttl if domain.ttl else 60} {iface.id}"
+ result, _ = process_dns_update_notify(message)
+ self.assertCountEqual(
+ [
+ DynamicDNSUpdate(
+ operation="DELETE",
+ zone=domain.name,
+ name=f"{node.hostname}.{domain.name}",
+ rectype="A",
+ ),
+ DynamicDNSUpdate(
+ operation="DELETE",
+ zone=domain.name,
+ name=f"{node.hostname}.{domain.name}",
+ rectype="AAAA",
+ ),
+ DynamicDNSUpdate(
+ operation="INSERT",
+ zone=domain.name,
+ name=f"{node.hostname}.{domain.name}",
+ rectype="A" if IPAddress(ip2.ip).version == 4 else "AAAA",
+ answer=ip2.ip,
+ ),
+ ],
+ result,
+ )
diff --git a/src/maasserver/triggers/system.py b/src/maasserver/triggers/system.py
index a18fe8a..3e755f5 100644
--- a/src/maasserver/triggers/system.py
+++ b/src/maasserver/triggers/system.py
@@ -2054,6 +2054,134 @@ def render_dns_dynamic_update_subnet_procedure(op):
)
+def render_dns_dynamic_update_interface_static_ip_address(op):
+ return dedent(
+ f"""\
+ CREATE OR REPLACE FUNCTION sys_dns_updates_interface_ip_{op}()
+ RETURNS trigger as $$
+ DECLARE
+ current_hostname text;
+ default_domain_id bigint;
+ domain text;
+ iface_name text;
+ ip_addr text;
+ address_ttl int;
+ current_node_config_id bigint;
+ current_node_id bigint;
+ BEGIN
+ ASSERT TG_WHEN = 'AFTER', 'May only run as an AFTER trigger';
+ ASSERT TG_LEVEL <> 'STATEMENT', 'Should not be used as a STATEMENT level trigger', TG_NAME;
+ SELECT domain_id INTO default_domain_id FROM maasserver_globaldefault LIMIT 1;
+ SELECT name, COALESCE(ttl, 0) INTO domain, address_ttl FROM maasserver_domain WHERE id=default_domain_id;
+ IF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
+ SELECT name, node_config_id INTO iface_name, current_node_config_id FROM maasserver_interface WHERE id=NEW.interface_id;
+ SELECT node_id INTO current_node_id FROM maasserver_nodeconfig WHERE id=current_node_config_id;
+ SELECT hostname INTO current_hostname FROM maasserver_node WHERE id=current_node_id;
+ SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=NEW.staticipaddress_id;
+ PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr);
+ PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr);
+ ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
+ IF EXISTS(SELECT id FROM maasserver_interface WHERE id=OLD.interface_id) THEN
+ SELECT name, node_config_id INTO iface_name, current_node_config_id FROM maasserver_interface WHERE id=OLD.interface_id;
+ SELECT node_id INTO current_node_id FROM maasserver_nodeconfig WHERE id=current_node_config_id;
+ SELECT hostname INTO current_hostname FROM maasserver_node WHERE id=current_node_id;
+ IF EXISTS(SELECT id FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id) THEN
+ SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id;
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || current_hostname || ' A ' || ip_addr);
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || ip_addr);
+ ELSE
+ PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' A ' || OLD.interface_id);
+ PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' AAAA ' || OLD.interface_id);
+ END IF;
+ END IF;
+ END IF;
+ RETURN NULL;
+ END;
+ $$ LANGUAGE plpgsql;
+ """
+ )
+
+
+dns_dynamic_update_static_ip_address_update = dedent(
+ """\
+ CREATE OR REPLACE FUNCTION sys_dns_updates_ip_update()
+ RETURNS trigger as $$
+ DECLARE
+ current_hostname text;
+ default_domain_id bigint;
+ domain text;
+ iface_name text;
+ address_ttl int;
+ current_node_config_id bigint;
+ current_node_id bigint;
+ current_interface_id bigint;
+ BEGIN
+ IF NEW IS DISTINCT FROM OLD THEN
+ IF EXISTS(SELECT id FROM maasserver_interface_ip_addresses WHERE staticipaddress_id=NEW.id) THEN
+ SELECT domain_id INTO default_domain_id FROM maasserver_globaldefault LIMIT 1;
+ SELECT name, COALESCE(ttl, 0) INTO domain, address_ttl FROM maasserver_domain WHERE id=default_domain_id;
+ SELECT interface_id INTO current_interface_id FROM maasserver_interface_ip_addresses WHERE staticipaddress_id=NEW.id;
+ SELECT node_config_id, name INTO current_node_config_id, iface_name FROM maasserver_interface WHERE id=current_interface_id;
+ SELECT node_id INTO current_node_id FROM maasserver_nodeconfig WHERE id=current_node_config_id;
+ SELECT hostname INTO current_hostname FROM maasserver_node WHERE id=current_node_id;
+ IF OLD.ip IS NOT NULL THEN
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || current_hostname || ' A ' || host(OLD.ip));
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || host(OLD.ip));
+ END IF;
+ PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || current_hostname || ' A ' || address_ttl || ' ' || host(NEW.ip));
+ PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || address_ttl || ' ' || host(NEW.ip));
+ END IF;
+ END IF;
+ RETURN NULL;
+ END;
+ $$ LANGUAGE plpgsql;
+ """
+)
+
+dns_dynamic_update_node_delete = dedent(
+ """\
+ CREATE OR REPLACE FUNCTION sys_dns_updates_maasserver_node_delete()
+ RETURNS trigger as $$
+ DECLARE
+ hostname text;
+ default_domain_id bigint;
+ domain text;
+ address_ttl int;
+ BEGIN
+ SELECT domain_id INTO default_domain_id FROM maasserver_globaldefault LIMIT 1;
+ SELECT name, COALESCE(ttl, 0) INTO domain, address_ttl FROM maasserver_domain WHERE id=default_domain_id;
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || OLD.hostname || ' A');
+ RETURN NULL;
+ END;
+ $$ LANGUAGE plpgsql;
+ """
+)
+
+
+dns_dynamic_update_interface_delete = dedent(
+ """\
+ CREATE OR REPLACE FUNCTION sys_dns_updates_maasserver_interface_delete()
+ RETURNS trigger as $$
+ DECLARE
+ current_hostname text;
+ default_domain_id bigint;
+ domain text;
+ current_node_id bigint;
+ BEGIN
+ SELECT domain_id INTO default_domain_id FROM maasserver_globaldefault LIMIT 1;
+ SELECT name INTO domain FROM maasserver_domain WHERE id=default_domain_id;
+ IF EXISTS(SELECT id FROM maasserver_nodeconfig WHERE id=OLD.node_config_id) THEN
+ SELECT node_id INTO current_node_id FROM maasserver_nodeconfig WHERE id=OLD.node_config_id;
+ SELECT hostname INTO current_hostname FROM maasserver_node WHERE id=current_node_id;
+ PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || OLD.name || '.' || current_hostname || ' A');
+ END IF;
+ RETURN NULL;
+ END;
+ $$ LANGUAGE plpgsql;
+ """
+)
+
+
def render_sys_proxy_procedure(proc_name, on_delete=False):
"""Render a database procedure with name `proc_name` that notifies that a
proxy update is needed.
@@ -2403,3 +2531,33 @@ def register_system_triggers():
"sys_dns_updates_maasserver_subnet_delete",
"delete",
)
+ register_procedure(render_dns_dynamic_update_interface_static_ip_address("insert"))
+ register_trigger(
+ "maasserver_interface_ip_addresses",
+ "sys_dns_updates_maasserver_interface_ip_insert",
+ "insert",
+ )
+ register_procedure(render_dns_dynamic_update_interface_static_ip_address("delete"))
+ register_trigger(
+ "maasserver_interface_ip_addresses",
+ "sys_dns_updates_maasserver_interface_ip_delete",
+ "delete",
+ )
+ register_procedure(dns_dynamic_update_static_ip_address_update)
+ register_trigger(
+ "maasserver_staticipaddress",
+ "sys_dns_updates_ip_update",
+ "update",
+ )
+ register_procedure(dns_dynamic_update_node_delete)
+ register_trigger(
+ "maasserver_node",
+ "sys_dns_updates_maasserver_node_delete",
+ "delete",
+ )
+ register_procedure(dns_dynamic_update_interface_delete)
+ register_trigger(
+ "maasserver_interface",
+ "sys_dns_updates_maasserver_interface_delete",
+ "delete",
+ )
diff --git a/src/maasserver/triggers/tests/test_system.py b/src/maasserver/triggers/tests/test_system.py
index d5222b4..f4e9280 100644
--- a/src/maasserver/triggers/tests/test_system.py
+++ b/src/maasserver/triggers/tests/test_system.py
@@ -7,6 +7,8 @@ from contextlib import closing
from django.db import connection
from twisted.internet.defer import inlineCallbacks
+from maasserver.enum import NODE_STATUS
+from maasserver.models import Domain
from maasserver.models.dnspublication import zone_serial
from maasserver.testing.factory import factory
from maasserver.testing.testcase import (
@@ -367,3 +369,168 @@ class TestSysDNSUpdates(
finally:
self.stop_reading()
yield self.postgres_listener_service.stopService()
+
+ @wait_for_reactor
+ @inlineCallbacks
+ def test_dns_dynamic_update_interface_static_ip_address_insert(self):
+ listener = self.make_listener_without_delay()
+ yield self.set_service(listener)
+ yield deferToDatabase(
+ self.register_trigger,
+ "maasserver_interface_ip_addresses",
+ "sys_dns_updates",
+ ops=("insert",),
+ trigger="sys_dns_updates_interface_ip_insert",
+ )
+ vlan = yield deferToDatabase(self.create_vlan)
+ subnet = yield deferToDatabase(self.create_subnet, params={"vlan": vlan})
+ self.start_reading()
+ try:
+ node = yield deferToDatabase(self.create_node_with_interface, params={"subnet": subnet, "status": NODE_STATUS.DEPLOYED})
+ domain = yield deferToDatabase(Domain.objects.get_default_domain)
+ expected_iface = yield deferToDatabase(lambda : node.current_config.interface_set.first())
+ expected_ip = yield deferToDatabase(
+ lambda : self.create_staticipaddress(params={
+ "ip": subnet.get_next_ip_for_allocation()[0],
+ "interface": expected_iface,
+ "subnet": subnet,
+ })
+ )
+ msg1 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg1, f"INSERT {domain.name} {node.hostname} A 0 {expected_ip.ip}")
+ msg2 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg2, f"INSERT {domain.name} {expected_iface.name}.{node.hostname} A 0 {expected_ip.ip}")
+ finally:
+ self.stop_reading()
+ yield self.postgres_listener_service.stopService()
+
+ @wait_for_reactor
+ @inlineCallbacks
+ def test_dns_dynamic_update_interface_static_ip_address_delete(self):
+ listener = self.make_listener_without_delay()
+ yield self.set_service(listener)
+ yield deferToDatabase(
+ self.register_trigger,
+ "maasserver_interface_ip_addresses",
+ "sys_dns_updates",
+ ops=("delete",),
+ trigger="sys_dns_updates_interface_ip_delete",
+ )
+ vlan = yield deferToDatabase(self.create_vlan)
+ subnet = yield deferToDatabase(self.create_subnet, params={"vlan": vlan})
+ node = yield deferToDatabase(self.create_node_with_interface, params={"subnet": subnet, "status": NODE_STATUS.DEPLOYED})
+ domain = yield deferToDatabase(Domain.objects.get_default_domain)
+ iface = yield deferToDatabase(lambda : node.current_config.interface_set.first())
+ ip1 = yield deferToDatabase(
+ lambda : self.create_staticipaddress(params={
+ "ip": subnet.get_next_ip_for_allocation()[0],
+ "interface": iface,
+ "subnet": subnet,
+ })
+ )
+ ip2 = yield deferToDatabase(
+ lambda : self.create_staticipaddress(params={
+ "ip": subnet.get_next_ip_for_allocation()[0],
+ "interface": iface,
+ "subnet": subnet,
+ })
+ )
+ self.start_reading()
+ try:
+ yield deferToDatabase(iface.unlink_ip_address, ip1)
+ msg1 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg1, f"DELETE {domain.name} {node.hostname} A {ip1.ip}")
+ msg2 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg2, f"DELETE {domain.name} {iface.name}.{node.hostname} A {ip1.ip}")
+ finally:
+ self.stop_reading()
+ yield self.postgres_listener_service.stopService()
+
+ @wait_for_reactor
+ @inlineCallbacks
+ def test_dns_dynamc_update_ip_update(self):
+ listener = self.make_listener_without_delay()
+ yield self.set_service(listener)
+ yield deferToDatabase(
+ self.register_trigger,
+ "maasserver_staticipaddress",
+ "sys_dns_updates",
+ ops=("update",),
+ trigger="sys_dns_updates_ip_update",
+ )
+ vlan = yield deferToDatabase(self.create_vlan)
+ subnet = yield deferToDatabase(self.create_subnet, params={"vlan": vlan})
+ node = yield deferToDatabase(self.create_node_with_interface, params={"subnet": subnet, "status": NODE_STATUS.DEPLOYED})
+ domain = yield deferToDatabase(Domain.objects.get_default_domain)
+ iface = yield deferToDatabase(lambda : node.current_config.interface_set.first())
+ ip = yield deferToDatabase(
+ lambda : self.create_staticipaddress(params={
+ "ip": subnet.get_next_ip_for_allocation()[0],
+ "interface": iface,
+ "subnet": subnet,
+ })
+ )
+ old_ip = ip.ip
+ def _set_new_ip():
+ ip.ip = subnet.get_next_ip_for_allocation()[0]
+ ip.save()
+ self.start_reading()
+ try:
+ yield deferToDatabase(_set_new_ip)
+ msg1 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg1, f"DELETE {domain.name} {node.hostname} A {old_ip}")
+ msg2 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg2, f"DELETE {domain.name} {iface.name}.{node.hostname} A {old_ip}")
+ msg3 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg3, f"INSERT {domain.name} {node.hostname} A 0 {ip.ip}")
+ msg4 = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg4, f"INSERT {domain.name} {iface.name}.{node.hostname} A 0 {ip.ip}")
+ finally:
+ self.stop_reading()
+ yield self.postgres_listener_service.stopService()
+
+ @wait_for_reactor
+ @inlineCallbacks
+ def test_dns_dynamic_update_node_delete(self):
+ listener = self.make_listener_without_delay()
+ yield self.set_service(listener)
+ yield deferToDatabase(
+ self.register_trigger,
+ "maasserver_node",
+ "sys_dns_updates",
+ ops=("delete",),
+ )
+ node = yield deferToDatabase(self.create_node)
+ domain = yield deferToDatabase(Domain.objects.get_default_domain)
+ self.start_reading()
+ try:
+ yield deferToDatabase(node.delete)
+ msg = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg, f"DELETE {domain.name} {node.hostname} A")
+ finally:
+ self.stop_reading()
+ yield self.postgres_listener_service.stopService()
+
+ @wait_for_reactor
+ @inlineCallbacks
+ def test_dns_dynamic_update_interface_delete(self):
+ listener = self.make_listener_without_delay()
+ yield self.set_service(listener)
+ yield deferToDatabase(
+ self.register_trigger,
+ "maasserver_node",
+ "sys_dns_updates",
+ ops=("delete",),
+ )
+ subnet = yield deferToDatabase(self.create_subnet)
+ node = yield deferToDatabase(self.create_node_with_interface, params={"subnet": subnet})
+ domain = yield deferToDatabase(Domain.objects.get_default_domain)
+ iface = yield deferToDatabase(lambda : node.current_config.interface_set.first())
+ self.start_reading()
+ try:
+ yield deferToDatabase(iface.delete)
+ msg = yield self.get_notify("sys_dns_updates")
+ self.assertEqual(msg, f"DELETE {domain.name} {iface.name}.{node.hostname} A")
+ finally:
+ self.stop_reading()
+ yield self.postgres_listener_service.stopService()
diff --git a/src/provisioningserver/dns/zoneconfig.py b/src/provisioningserver/dns/zoneconfig.py
index 13dca69..905dd15 100644
--- a/src/provisioningserver/dns/zoneconfig.py
+++ b/src/provisioningserver/dns/zoneconfig.py
@@ -170,6 +170,19 @@ class DomainConfigBase:
else:
return True
+ def journal_file_exists(self, zone_info):
+ try:
+ os.stat(f"{zone_info.target_path}.jnl")
+ except FileNotFoundError:
+ return False
+ else:
+ return True
+
+
+ def _remove_journal_file(self, zone_info):
+ if self.journal_file_exists(zone_info):
+ os.unlink(f"{zone_info.target_path}.jnl")
+
def dynamic_update(self, zone_info):
nsupdate = NSUpdateCommand(
zone_info.zone_name,
@@ -323,6 +336,7 @@ class DNSForwardZoneConfig(DomainConfigBase):
if not self.force_config_write and self.zone_file_exists(zi):
self.dynamic_update(zi)
else:
+ self._remove_journal_file(zi)
self.requires_reload = True
self.write_zone_file(
zi.target_path,
@@ -612,6 +626,7 @@ class DNSReverseZoneConfig(DomainConfigBase):
if not self.force_config_write and self.zone_file_exists(zi):
self.dynamic_update(zi)
else:
+ self._remove_journal_file(zi)
self.requires_reload = True
self.write_zone_file(
zi.target_path,
Follow ups
-
[Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: MAAS Lander, 2022-12-13
-
[Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: Christian Grabowski, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS PASS
From: MAAS Lander, 2022-12-13
-
Re: [Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: Christian Grabowski, 2022-12-13
-
Re: [Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: Alberto Donato, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS PASS
From: MAAS Lander, 2022-12-13
-
Re: [Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: Christian Grabowski, 2022-12-13
-
Re: [Merge] ~cgrabowski/maas:fix_node_dns_generation into maas:master
From: Alberto Donato, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS PASS
From: MAAS Lander, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS FAILED
From: MAAS Lander, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS FAILED
From: MAAS Lander, 2022-12-13
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS FAILED
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b fix_node_dns_generation lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas - TESTS FAILED
From: MAAS Lander, 2022-12-12