From cab565304ae74291bef5d847b997bf99bc1f4003 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Wed, 1 Apr 2020 19:37:02 +1300 Subject: [PATCH] write netplan directly to the target rather than via curtin and then cloud-init --- console_conf/models/console_conf.py | 2 +- subiquity/controllers/network.py | 2 +- subiquity/models/subiquity.py | 2 +- subiquity/models/tests/test_subiquity.py | 13 +++++++++-- subiquitycore/controllers/network.py | 10 ++++----- subiquitycore/models/network.py | 28 ++++++++++++++++++++++-- 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/console_conf/models/console_conf.py b/console_conf/models/console_conf.py index 22e48d7e..76421460 100644 --- a/console_conf/models/console_conf.py +++ b/console_conf/models/console_conf.py @@ -7,5 +7,5 @@ class ConsoleConfModel: """The overall model for console-conf.""" def __init__(self): - self.network = NetworkModel(support_wlan=True) + self.network = NetworkModel("console-conf", support_wlan=True) self.identity = IdentityModel() diff --git a/subiquity/controllers/network.py b/subiquity/controllers/network.py index cd20a409..0b79cbef 100644 --- a/subiquity/controllers/network.py +++ b/subiquity/controllers/network.py @@ -77,4 +77,4 @@ class NetworkController(NetworkController, SubiquityController): super().done() def make_autoinstall(self): - return self.model.render()['network'] + return self.model.render_config()['network'] diff --git a/subiquity/models/subiquity.py b/subiquity/models/subiquity.py index f5a2df7f..634ce279 100644 --- a/subiquity/models/subiquity.py +++ b/subiquity/models/subiquity.py @@ -94,7 +94,7 @@ class SubiquityModel: self.locale = LocaleModel() self.keyboard = KeyboardModel(self.root) - self.network = NetworkModel(support_wlan=False) + self.network = NetworkModel("subiquity", support_wlan=False) self.proxy = ProxyModel() self.mirror = MirrorModel() self.filesystem = FilesystemModel() diff --git a/subiquity/models/tests/test_subiquity.py b/subiquity/models/tests/test_subiquity.py index 5ada1c07..41e2daf5 100644 --- a/subiquity/models/tests/test_subiquity.py +++ b/subiquity/models/tests/test_subiquity.py @@ -15,6 +15,7 @@ import fnmatch import unittest +import yaml from subiquity.models.subiquity import SubiquityModel @@ -117,10 +118,18 @@ class TestSubiquityModel(unittest.TestCase): config = model.render('ident') self.assertConfigHasVal(config, 'storage.version', 1) - def test_network_version(self): + def test_write_netplan(self): model = SubiquityModel('test') config = model.render('ident') - self.assertConfigHasVal(config, 'network.version', 2) + netplan_content = None + for fspec in config['write_files'].values(): + if fspec['path'].startswith('etc/netplan'): + if netplan_content is not None: + self.fail("writing two files to netplan?") + netplan_content = fspec['content'] + self.assertIsNot(netplan_content, None) + netplan = yaml.safe_load(netplan_content) + self.assertConfigHasVal(netplan, 'network.version', 2) def test_has_sources(self): model = SubiquityModel('test') diff --git a/subiquitycore/controllers/network.py b/subiquitycore/controllers/network.py index dad74208..744ca8ad 100644 --- a/subiquitycore/controllers/network.py +++ b/subiquitycore/controllers/network.py @@ -331,7 +331,7 @@ class NetworkController(BaseController): log.info("deleting %s failed with %r", dev.name, cp.stderr) def render_config(self): - return self.model.render() + return self.model.render_config() def _write_config(self): config = self.render_config() @@ -344,10 +344,10 @@ class NetworkController(BaseController): continue os.rename(p, p + ".dist-" + self.opts.project) - write_file(self.netplan_path, '\n'.join(( - ("# This is the network config written by '%s'" % - self.opts.project), - yaml.dump(config, default_flow_style=False))), omode="w") + write_file( + self.netplan_path, + self.model.stringify_config(config), + omode="w") self.model.parse_netplan_configs(self.root) diff --git a/subiquitycore/models/network.py b/subiquitycore/models/network.py index a75bdc97..6095dd5f 100644 --- a/subiquitycore/models/network.py +++ b/subiquitycore/models/network.py @@ -17,6 +17,7 @@ import copy import enum import ipaddress import logging +import yaml from socket import AF_INET, AF_INET6 from subiquitycore import netplan @@ -253,10 +254,11 @@ class NetworkDev(object): class NetworkModel(object): """ """ - def __init__(self, support_wlan=True): + def __init__(self, project, support_wlan=True): self.support_wlan = support_wlan self.devices_by_name = {} # Maps interface names to NetworkDev self.has_network = False + self.project = project def parse_netplan_configs(self, netplan_root): self.config = netplan.Config() @@ -350,7 +352,14 @@ class NetworkModel(object): def get_netdev_by_name(self, name): return self.devices_by_name[name] - def render(self): + def stringify_config(self, config): + return '\n'.join([ + "# This is the network config written by '{}'".format( + self.project), + yaml.dump(config, default_flow_style=False), + ]) + + def render_config(self): config = { 'network': { 'version': 2, @@ -369,3 +378,18 @@ class NetworkModel(object): configs[dev.name] = dev.config return config + + def render(self): + return { + 'write_files': { + 'etc_netplan_installer': { + 'path': 'etc/netplan/00-installer-config.yaml', + 'content': self.stringify_config(self.render_config()), + }, + 'nonet': { + 'path': ('etc/cloud/cloud.cfg.d/' + 'subiquity-disable-cloudinit-networking.cfg'), + 'content': 'network: {config: disabled}\n', + }, + }, + }