Merge pull request #205 from CanonicalLtd/mwhudson/do-something-with-network-config

actually use the network config the user enters
This commit is contained in:
Michael Hudson-Doyle 2017-03-20 10:44:58 +13:00 committed by GitHub
commit ea96a72e9b
5 changed files with 54 additions and 40 deletions

View File

@ -67,12 +67,12 @@ done
# Create menuentry for installer # Create menuentry for installer
menuentry "Boot Installer - Graphical Console" { menuentry "Boot Installer - Graphical Console" {
set root=(hd0,msdos2) set root=(hd0,msdos2)
linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs net.ifnames=0 console=ttyS0 console=tty0 quiet splash linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs console=ttyS0 console=tty0 quiet splash
initrd /initrd.img initrd /initrd.img
} }
menuentry "Boot Installer - Serial Console" { menuentry "Boot Installer - Serial Console" {
set root=(hd0,msdos2) set root=(hd0,msdos2)
linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs net.ifnames=0 console=tty0 console=ttyS0 linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs console=tty0 console=ttyS0
initrd /initrd.img initrd /initrd.img
} }

View File

@ -16,6 +16,7 @@
import fcntl import fcntl
import logging import logging
import os import os
import yaml
from subiquitycore import utils from subiquitycore import utils
from subiquitycore.controller import BaseController from subiquitycore.controller import BaseController
@ -23,7 +24,8 @@ from subiquitycore.controller import BaseController
from subiquity.curtin import (CURTIN_CONFIGS, from subiquity.curtin import (CURTIN_CONFIGS,
CURTIN_INSTALL_LOG, CURTIN_INSTALL_LOG,
CURTIN_POSTINSTALL_LOG, CURTIN_POSTINSTALL_LOG,
curtin_install_cmd) curtin_install_cmd,
curtin_write_network_config)
from subiquity.models import InstallProgressModel from subiquity.models import InstallProgressModel
from subiquity.ui.views import ProgressView from subiquity.ui.views import ProgressView
@ -39,12 +41,12 @@ class InstallState:
DONE_POSTINSTALL = 4 DONE_POSTINSTALL = 4
ERROR = -1 ERROR = -1
class InstallProgressController(BaseController): class InstallProgressController(BaseController):
signals = [ signals = [
('installprogress:curtin-install', 'curtin_start_install'), ('installprogress:curtin-install', 'curtin_start_install'),
('installprogress:wrote-install', 'curtin_wrote_install'), ('installprogress:wrote-install', 'curtin_wrote_install'),
('installprogress:wrote-postinstall', 'curtin_wrote_postinstall'), ('installprogress:wrote-postinstall', 'curtin_wrote_postinstall'),
('network-config-written', 'curtin_wrote_network_config'),
] ]
def __init__(self, common): def __init__(self, common):
@ -55,6 +57,9 @@ class InstallProgressController(BaseController):
self.postinstall_written = False self.postinstall_written = False
self.tail_proc = None self.tail_proc = None
def curtin_wrote_network_config(self, path):
curtin_write_network_config(open(path).read())
def curtin_wrote_install(self): def curtin_wrote_install(self):
pass pass
@ -85,7 +90,8 @@ class InstallProgressController(BaseController):
"{ i=0;while [ $i -le 25 ];do i=$((i+1)); echo install line $i; sleep 1; done; } > %s 2>&1"%CURTIN_INSTALL_LOG] "{ i=0;while [ $i -le 25 ];do i=$((i+1)); echo install line $i; sleep 1; done; } > %s 2>&1"%CURTIN_INSTALL_LOG]
else: else:
log.debug("Installprogress: this is the *REAL* thing") log.debug("Installprogress: this is the *REAL* thing")
configs = [CURTIN_CONFIGS['storage']] configs = [CURTIN_CONFIGS['storage'],
CURTIN_CONFIGS['network']]
curtin_cmd = curtin_install_cmd(configs) curtin_cmd = curtin_install_cmd(configs)
log.debug('Curtin install cmd: {}'.format(curtin_cmd)) log.debug('Curtin install cmd: {}'.format(curtin_cmd))

View File

@ -139,37 +139,35 @@ def setup_yaml():
yaml.add_representer(OrderedDict, represent_dict_order) yaml.add_representer(OrderedDict, represent_dict_order)
setup_yaml() setup_yaml()
def curtin_write_network_actions(actions): def curtin_write_network_config(netplan_config):
curtin_config = yaml.dump(actions, default_flow_style=False) # As soon as curtin and cloud-init support v2 network config
curtin_config = " " + "\n ".join(curtin_config.splitlines()) # (RSN!) we can just pass this sensibly to curtin. But for now,
datestr = '# Autogenerated by SUbiquity: {} UTC'.format( # just use write_files to install the config and make sure curtin
# and cloud-init doesn't do any networking stuff of their own
# accord.
curtin_conf = {
'write_files': {
'netplan': {
'path': 'etc/netplan/00-installer.yaml',
'content': netplan_config,
'permissions': '0600',
},
'nonet': {
'path': 'etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg',
'content': 'network: {config: disabled}\n',
}
},
'network_commands': {'builtin': []},
}
curtin_config = yaml.dump(curtin_conf, default_flow_style=False)
datestr = '# Autogenerated by SUbiquity: {} UTC\n'.format(
str(datetime.datetime.utcnow())) str(datetime.datetime.utcnow()))
with open(CURTIN_NETWORK_CONFIG_FILE, 'w') as conf: with open(CURTIN_NETWORK_CONFIG_FILE, 'w') as conf:
conf.write(datestr) conf.write(datestr)
conf.write(CURTIN_CONFIG_HEADER + CURTIN_NETWORK_CONFIG_HEADER)
conf.write(curtin_config) conf.write(curtin_config)
conf.close() conf.close()
def curtin_apply_networking(actions, dryrun=True):
log.info('Applying network actions:\n%s', actions)
network_commands = []
for entry in actions:
if entry['type'] == 'physical':
for subnet in entry.get('subnets', []):
if subnet['type'] == 'static':
cmd = "ifconfig %s %s" % (entry['name'], subnet['address'])
if 'netmask' in subnet:
cmd += " netmask %s" % subnet['netmask']
cmd += " up"
network_commands += [cmd]
for cmd in network_commands:
log.info('Running command: [%s]', cmd)
if not dryrun:
utils.run_command(cmd.split(), shell=False)
def curtin_write_preserved_actions(actions): def curtin_write_preserved_actions(actions):
''' caller must use models.actions.preserve_action on ''' caller must use models.actions.preserve_action on
all elements of the actions''' all elements of the actions'''

View File

@ -17,7 +17,6 @@ import copy
from functools import partial from functools import partial
import logging import logging
import os import os
import queue
import random import random
import select import select
import socket import socket
@ -213,8 +212,6 @@ class TaskSequence:
self.watcher.task_error(self.stage, info) self.watcher.task_error(self.stage, info)
netplan_config_file_name = '00-snapd-config.yaml'
def sanitize_config(config): def sanitize_config(config):
"""Return a copy of config with passwords redacted.""" """Return a copy of config with passwords redacted."""
config = copy.deepcopy(config) config = copy.deepcopy(config)
@ -321,12 +318,15 @@ class NetworkController(BaseController):
def __init__(self, common): def __init__(self, common):
super().__init__(common) super().__init__(common)
if self.opts.dry_run: if self.opts.dry_run:
import atexit, shutil, tempfile self.root = os.path.abspath(".subiquity")
self.root = tempfile.mkdtemp()
self.tried_once = False self.tried_once = False
atexit.register(shutil.rmtree, self.root) netplan_path = self.netplan_path
os.makedirs(os.path.join(self.root, 'etc/netplan')) netplan_dir = os.path.dirname(netplan_path)
with open(os.path.join(self.root, 'etc/netplan', netplan_config_file_name), 'w') as fp: if os.path.exists(netplan_dir):
import shutil
shutil.rmtree(netplan_dir)
os.makedirs(netplan_dir)
with open(netplan_path, 'w') as fp:
fp.write(default_netplan) fp.write(default_netplan)
self.model = NetworkModel(self.root) self.model = NetworkModel(self.root)
@ -357,10 +357,18 @@ class NetworkController(BaseController):
self.ui.set_footer(footer, 20) self.ui.set_footer(footer, 20)
self.ui.set_body(NetworkView(self.model, self)) self.ui.set_body(NetworkView(self.model, self))
@property
def netplan_path(self):
if self.opts.project == "subiquity":
netplan_config_file_name = '00-installer-config.yaml'
else:
netplan_config_file_name = '00-snapd-config.yaml'
return os.path.join(self.root, 'etc/netplan', netplan_config_file_name)
def network_finish(self, config): def network_finish(self, config):
log.debug("network config: \n%s", yaml.dump(sanitize_config(config), default_flow_style=False)) log.debug("network config: \n%s", yaml.dump(sanitize_config(config), default_flow_style=False))
netplan_path = os.path.join(self.root, 'etc/netplan', netplan_config_file_name) netplan_path = self.netplan_path
while True: while True:
try: try:
tmppath = '%s.%s' % (netplan_path, random.randrange(0, 1000)) tmppath = '%s.%s' % (netplan_path, random.randrange(0, 1000))
@ -371,7 +379,7 @@ class NetworkController(BaseController):
break break
w = os.fdopen(fd, 'w') w = os.fdopen(fd, 'w')
with w: with w:
w.write("# This is the network config written by 'console-conf'\n") w.write("# This is the network config written by '{}'\n".format(self.opts.project))
w.write(yaml.dump(config)) w.write(yaml.dump(config))
os.rename(tmppath, netplan_path) os.rename(tmppath, netplan_path)
self.model.parse_netplan_configs() self.model.parse_netplan_configs()
@ -413,9 +421,9 @@ class NetworkController(BaseController):
self.ui.frame.body.show_network_error(stage, info) self.ui.frame.body.show_network_error(stage, info)
def tasks_finished(self): def tasks_finished(self):
self.signal.emit_signal('network-config-written', self.netplan_path)
self.signal.emit_signal('next-screen') self.signal.emit_signal('next-screen')
@view @view
def set_default_v4_route(self): def set_default_v4_route(self):
self.ui.set_header("Default route") self.ui.set_header("Default route")

View File

@ -56,6 +56,8 @@ class Application:
log.exception(err) log.exception(err)
raise ApplicationError(err) raise ApplicationError(err)
opts.project = self.project
self.common = { self.common = {
"ui": ui, "ui": ui,
"opts": opts, "opts": opts,