Drop maas
This commit is contained in:
parent
f9b9414de1
commit
6df3f5c2af
|
@ -17,7 +17,7 @@ import logging
|
||||||
|
|
||||||
from subiquitycore.controller import BaseController
|
from subiquitycore.controller import BaseController
|
||||||
|
|
||||||
from subiquity.ui.views import InstallpathView, MAASView
|
from subiquity.ui.views import InstallpathView
|
||||||
|
|
||||||
log = logging.getLogger('subiquity.controller.installpath')
|
log = logging.getLogger('subiquity.controller.installpath')
|
||||||
|
|
||||||
|
@ -65,33 +65,3 @@ class InstallpathController(BaseController):
|
||||||
def install_cmdline(self):
|
def install_cmdline(self):
|
||||||
log.debug("Installing from command line sources.")
|
log.debug("Installing from command line sources.")
|
||||||
self.signal.emit_signal('next-screen')
|
self.signal.emit_signal('next-screen')
|
||||||
|
|
||||||
def install_maas_region(self):
|
|
||||||
# show region questions, seed model
|
|
||||||
title = "MAAS Region Controller Setup"
|
|
||||||
excerpt = _(
|
|
||||||
"MAAS is Metal As A Service. Running on Ubuntu, it lets you "
|
|
||||||
"treat physical servers like virtual machines (instances) "
|
|
||||||
"in the cloud. Rather than having to manage each server "
|
|
||||||
"individually, MAAS turns your bare metal into an elastic "
|
|
||||||
"cloud-like resource. \n\n"
|
|
||||||
"For further details, see https://maas.io/."
|
|
||||||
)
|
|
||||||
self.ui.set_body(MAASView(self.model, self, title, excerpt))
|
|
||||||
|
|
||||||
def install_maas_rack(self):
|
|
||||||
# show cack questions, seed model
|
|
||||||
title = "MAAS Rack Controller Setup"
|
|
||||||
excerpt = _(
|
|
||||||
"A MAAS rack controller provides services to machines provisioned "
|
|
||||||
"by MAAS in the fabric (group of trunked switches) it is attached "
|
|
||||||
"to. The rack controller requires the accessible URL of a MAAS "
|
|
||||||
"region controller."
|
|
||||||
)
|
|
||||||
|
|
||||||
self.ui.set_body(MAASView(self.model, self, title, excerpt))
|
|
||||||
|
|
||||||
def setup_maas(self, result):
|
|
||||||
log.debug("InstallpathController.setup_mass next-screen")
|
|
||||||
self.model.update(result)
|
|
||||||
self.signal.emit_signal('next-screen')
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger("subiquity.models.installpath")
|
log = logging.getLogger("subiquity.models.installpath")
|
||||||
|
@ -39,9 +38,7 @@ class InstallpathModel(object):
|
||||||
if self.cmdline_sources:
|
if self.cmdline_sources:
|
||||||
cmdline = [(_('Install from cli provided sources'), 'cmdline')]
|
cmdline = [(_('Install from cli provided sources'), 'cmdline')]
|
||||||
return cmdline + [
|
return cmdline + [
|
||||||
(_('Install Ubuntu'), 'ubuntu'),
|
(_('Install Ubuntu'), 'ubuntu'),
|
||||||
(_('Install MAAS bare-metal cloud (region)'), 'maas_region'),
|
|
||||||
(_('Install MAAS bare-metal cloud (rack)'), 'maas_rack'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def update(self, results):
|
def update(self, results):
|
||||||
|
@ -50,8 +47,6 @@ class InstallpathModel(object):
|
||||||
def render(self):
|
def render(self):
|
||||||
src_map = {
|
src_map = {
|
||||||
'ubuntu': ['cp:///media/filesystem'],
|
'ubuntu': ['cp:///media/filesystem'],
|
||||||
'maas_region': ['cp:///media/region'],
|
|
||||||
'maas_rack': ['cp:///media/rack'],
|
|
||||||
'cmdline': self.cmdline_sources,
|
'cmdline': self.cmdline_sources,
|
||||||
}
|
}
|
||||||
src_list = src_map[self.path]
|
src_list = src_map[self.path]
|
||||||
|
@ -64,96 +59,4 @@ class InstallpathModel(object):
|
||||||
'sources': self.sources,
|
'sources': self.sources,
|
||||||
}
|
}
|
||||||
|
|
||||||
def t(path):
|
|
||||||
return os.path.join(self.target, path)
|
|
||||||
|
|
||||||
if self.path == 'maas_region':
|
|
||||||
config['debconf_selections'] = {
|
|
||||||
'maas-username': ('maas-region-controller maas/username '
|
|
||||||
'string %s' % self.results['username']),
|
|
||||||
'maas-password': ('maas-region-controller maas/password '
|
|
||||||
'password %s' % self.results['password']),
|
|
||||||
}
|
|
||||||
config['late_commands'] = {
|
|
||||||
# Maintainer scripts cache self.results, from config files, if
|
|
||||||
# they # exist. These shouldn't exist, since this was fixed in
|
|
||||||
# livecd-rootfs but remove these, just to be sure.
|
|
||||||
'900-maas': ['rm', '-f', t('etc/maas/rackd.conf')],
|
|
||||||
'901-maas': ['rm', '-f', t('etc/maas/region.conf')],
|
|
||||||
# All the crazy things are workarounds for maas maintainer
|
|
||||||
# scripts deficiencies see:
|
|
||||||
# LP: #1766209
|
|
||||||
# LP: #1766211
|
|
||||||
# LP: #1766214
|
|
||||||
# LP: #1766218
|
|
||||||
# LP: #1766241
|
|
||||||
#
|
|
||||||
# uuid is not initialized by reconfigure, maybe it should,
|
|
||||||
# if it is at all used make it so, to make it match the
|
|
||||||
# udeb/deb installs
|
|
||||||
'902-maas': ['curtin', 'in-target', '--',
|
|
||||||
'maas-rack', 'config', '--init'],
|
|
||||||
# this should do setups of maas-url for the rack controller,
|
|
||||||
# and secret if needed.
|
|
||||||
'903-maas': ['curtin', 'in-target', '--', 'dpkg-reconfigure',
|
|
||||||
'-u', '-fnoninteractive', 'maas-rack-controller'],
|
|
||||||
# Below are workaround to make postgresql database running,
|
|
||||||
# and invoke-rc.d --force to not faill and a running postgresql
|
|
||||||
# is needed, to change the role password and to create an admin
|
|
||||||
# user.
|
|
||||||
'904-maas': ['mount', '-o', 'bind', '/proc', t('proc')],
|
|
||||||
'905-maas': ['mount', '-o', 'bind', '/sys', t('sys')],
|
|
||||||
'906-maas': ['mount', '-o', 'bind', '/dev', t('dev')],
|
|
||||||
'907-maas': ['mount', '-o', 'bind', '/dev/shm', t('dev/shm')],
|
|
||||||
'908-maas': ['mount', '-o', 'bind', t('bin/true'),
|
|
||||||
t('usr/sbin/invoke-rc.d')],
|
|
||||||
'909-maas': ['chroot', self.target, 'sh', '-c',
|
|
||||||
'pg_ctlcluster --skip-systemctl-redirect '
|
|
||||||
'$(/bin/ls /var/lib/postgresql/) main start'],
|
|
||||||
# These are called like this, because reconfigure doesn't
|
|
||||||
# create nor change an admin user account, nor regens the
|
|
||||||
# semi-autogenerated maas-url
|
|
||||||
'910-maas':
|
|
||||||
['chroot', self.target, 'sh', '-c', (
|
|
||||||
'debconf -fnoninteractive -omaas-region-controller '
|
|
||||||
'/var/lib/dpkg/info/maas-region-controller.config '
|
|
||||||
'configure')],
|
|
||||||
'911-maas':
|
|
||||||
['chroot', self.target, 'sh', '-c', (
|
|
||||||
'debconf -fnoninteractive -omaas-region-controller '
|
|
||||||
'/var/lib/dpkg/info/maas-region-controller.postinst '
|
|
||||||
'configure')],
|
|
||||||
'912-maas': ['chroot', self.target, 'sh', '-c', (
|
|
||||||
'pg_ctlcluster --skip-systemctl-redirect '
|
|
||||||
'$(/bin/ls /var/lib/postgresql/) main stop')],
|
|
||||||
'913-maas': ['umount', t('usr/sbin/invoke-rc.d')],
|
|
||||||
'914-maas': ['umount', t('dev/shm')],
|
|
||||||
'915-maas': ['umount', t('dev')],
|
|
||||||
'916-maas': ['umount', t('sys')],
|
|
||||||
'917-maas': ['umount', t('proc')],
|
|
||||||
}
|
|
||||||
elif self.path == 'maas_rack':
|
|
||||||
config['debconf_selections'] = {
|
|
||||||
'maas-url': ('maas-rack-controller '
|
|
||||||
'maas-rack-controller/maas-url '
|
|
||||||
'string %s' % self.results['url']),
|
|
||||||
'maas-secret': ('maas-rack-controller '
|
|
||||||
'maas-rack-controller/shared-secret '
|
|
||||||
'password %s' % self.results['secret']),
|
|
||||||
}
|
|
||||||
config['late_commands'] = {
|
|
||||||
'90-maas': ['rm', '-f', t('etc/maas/rackd.conf')],
|
|
||||||
'91-maas': ['curtin', 'in-target', '--', 'maas-rack',
|
|
||||||
'config', '--init'],
|
|
||||||
# maas-rack-controller is broken, and does db_input & go on
|
|
||||||
# the password question in the postinst... when it should have
|
|
||||||
# been done in .config and it doesn't gracefully handle the
|
|
||||||
# case of db_go returning 30 skipped
|
|
||||||
'93-maas': ['curtin', 'in-target', '--', 'sh', '-c',
|
|
||||||
('debconf -fnoninteractive -omaas-rack-controller '
|
|
||||||
'/var/lib/dpkg/info/maas-rack-controller.postinst'
|
|
||||||
' configure || :')],
|
|
||||||
}
|
|
||||||
elif self.path != "ubuntu":
|
|
||||||
raise ValueError("invalid Installpath %s" % self.path)
|
|
||||||
return config
|
return config
|
||||||
|
|
|
@ -22,7 +22,7 @@ from .bcache import BcacheView
|
||||||
from .ceph import CephDiskView
|
from .ceph import CephDiskView
|
||||||
from .iscsi import IscsiDiskView
|
from .iscsi import IscsiDiskView
|
||||||
from .identity import IdentityView
|
from .identity import IdentityView
|
||||||
from .installpath import InstallpathView, MAASView
|
from .installpath import InstallpathView
|
||||||
from .installprogress import ProgressView
|
from .installprogress import ProgressView
|
||||||
from .keyboard import KeyboardView
|
from .keyboard import KeyboardView
|
||||||
from .welcome import WelcomeView
|
from .welcome import WelcomeView
|
||||||
|
|
|
@ -18,29 +18,13 @@
|
||||||
Provides high level options for Ubuntu install
|
Provides high level options for Ubuntu install
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import binascii
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
|
|
||||||
from urwid import connect_signal, Text
|
from urwid import Text
|
||||||
|
|
||||||
from subiquitycore.ui.buttons import back_btn, forward_btn
|
from subiquitycore.ui.buttons import back_btn, forward_btn
|
||||||
from subiquitycore.ui.utils import button_pile, screen
|
from subiquitycore.ui.utils import button_pile, screen
|
||||||
from subiquitycore.view import BaseView
|
from subiquitycore.view import BaseView
|
||||||
from subiquitycore.ui.interactive import (
|
|
||||||
PasswordEditor,
|
|
||||||
)
|
|
||||||
from subiquity.ui.views.identity import (
|
|
||||||
UsernameField,
|
|
||||||
PasswordField,
|
|
||||||
USERNAME_MAXLEN,
|
|
||||||
)
|
|
||||||
from subiquitycore.ui.form import (
|
|
||||||
Form,
|
|
||||||
simple_field,
|
|
||||||
URLField,
|
|
||||||
WantsToKnowFormField,
|
|
||||||
)
|
|
||||||
|
|
||||||
from subiquitycore.lsb_release import lsb_release
|
from subiquitycore.lsb_release import lsb_release
|
||||||
|
|
||||||
|
@ -87,113 +71,3 @@ class InstallpathView(BaseView):
|
||||||
|
|
||||||
def cancel(self, button=None):
|
def cancel(self, button=None):
|
||||||
self.controller.cancel()
|
self.controller.cancel()
|
||||||
|
|
||||||
|
|
||||||
class RegionForm(Form):
|
|
||||||
|
|
||||||
cancel_label = _("Back")
|
|
||||||
|
|
||||||
username = UsernameField(
|
|
||||||
_("Pick a username for the admin account:"),
|
|
||||||
help=_("Enter the administrative username."))
|
|
||||||
password = PasswordField(
|
|
||||||
_("Choose a password:"),
|
|
||||||
help=_("Please enter the password for this account."))
|
|
||||||
|
|
||||||
def validate_username(self):
|
|
||||||
if len(self.username.value) < 1:
|
|
||||||
return _("Username missing")
|
|
||||||
|
|
||||||
if len(self.username.value) > USERNAME_MAXLEN:
|
|
||||||
return _("Username too long, must be < ") + str(USERNAME_MAXLEN)
|
|
||||||
|
|
||||||
if not re.match(r'[a-z_][a-z0-9_-]*', self.username.value):
|
|
||||||
return _("Username must match NAME_REGEX, i.e. [a-z_][a-z0-9_-]*")
|
|
||||||
|
|
||||||
def validate_password(self):
|
|
||||||
if len(self.password.value) < 1:
|
|
||||||
return _("Password must be set")
|
|
||||||
|
|
||||||
|
|
||||||
# Copied from MAAS:
|
|
||||||
def to_bin(u):
|
|
||||||
"""Convert ASCII-only unicode string to hex encoding."""
|
|
||||||
assert isinstance(u, str), "%r is not a unicode string" % (u,)
|
|
||||||
# Strip ASCII whitespace from u before converting.
|
|
||||||
return binascii.a2b_hex(u.encode("ascii").strip())
|
|
||||||
|
|
||||||
|
|
||||||
class RackSecretEditor(PasswordEditor, WantsToKnowFormField):
|
|
||||||
def __init__(self):
|
|
||||||
self.valid_char_pat = r'[a-fA-F0-9]'
|
|
||||||
self.error_invalid_char = _("The secret can only contain hexadecimal "
|
|
||||||
"characters, i.e. 0-9, a-f, A-F.")
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def valid_char(self, ch):
|
|
||||||
if len(ch) == 1 and not re.match(self.valid_char_pat, ch):
|
|
||||||
self.bff.in_error = True
|
|
||||||
self.bff.show_extra(("info_error", self.error_invalid_char))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return super().valid_char(ch)
|
|
||||||
|
|
||||||
|
|
||||||
RackSecretField = simple_field(RackSecretEditor)
|
|
||||||
|
|
||||||
|
|
||||||
class RackForm(Form):
|
|
||||||
|
|
||||||
cancel_label = _("Back")
|
|
||||||
|
|
||||||
url = URLField(
|
|
||||||
_("Ubuntu MAAS Region API address:"),
|
|
||||||
help=_("e.g. \"http://192.168.1.1:5240/MAAS\". "
|
|
||||||
"localhost or 127.0.0.1 are not useful values here."))
|
|
||||||
|
|
||||||
secret = RackSecretField(
|
|
||||||
_("MAAS shared secret:"),
|
|
||||||
help=_("The secret can be found in /var/lib/maas/secret "
|
|
||||||
"on the region controller. "))
|
|
||||||
|
|
||||||
def validate_url(self):
|
|
||||||
if len(self.url.value) < 1:
|
|
||||||
return _("API address must be set")
|
|
||||||
|
|
||||||
def validate_secret(self):
|
|
||||||
if len(self.secret.value) < 1:
|
|
||||||
return _("Secret must be set")
|
|
||||||
try:
|
|
||||||
to_bin(self.secret.value)
|
|
||||||
except binascii.Error as error:
|
|
||||||
return _("Secret could not be decoded: %s") % (error,)
|
|
||||||
|
|
||||||
|
|
||||||
class MAASView(BaseView):
|
|
||||||
|
|
||||||
def __init__(self, model, controller, title, excerpt):
|
|
||||||
self.model = model
|
|
||||||
self.controller = controller
|
|
||||||
self.signal = controller.signal
|
|
||||||
self.items = []
|
|
||||||
self.title = title
|
|
||||||
|
|
||||||
if self.model.path == "maas_region":
|
|
||||||
self.form = RegionForm(initial=self.model.results)
|
|
||||||
elif self.model.path == "maas_rack":
|
|
||||||
self.form = RackForm(initial=self.model.results)
|
|
||||||
else:
|
|
||||||
raise ValueError("invalid MAAS form %s" % self.model.path)
|
|
||||||
|
|
||||||
connect_signal(self.form, 'submit', self.done)
|
|
||||||
connect_signal(self.form, 'cancel', self.cancel)
|
|
||||||
|
|
||||||
super().__init__(self.form.as_screen(focus_buttons=False,
|
|
||||||
excerpt=excerpt))
|
|
||||||
|
|
||||||
def done(self, result):
|
|
||||||
log.debug("User input: {}".format(result.as_data()))
|
|
||||||
self.controller.setup_maas(result.as_data())
|
|
||||||
|
|
||||||
def cancel(self, result=None):
|
|
||||||
self.controller.default()
|
|
||||||
|
|
Loading…
Reference in New Issue