Merge branch 'mwhudson/demo'
This commit is contained in:
commit
d3c0bb95d7
|
@ -18,7 +18,7 @@ import argparse
|
|||
import sys
|
||||
import logging
|
||||
import signal
|
||||
from subiquitycore.log import setup_logger, LOGFILE
|
||||
from subiquitycore.log import setup_logger
|
||||
from subiquitycore import __version__ as VERSION
|
||||
from console_conf.core import ConsoleConf
|
||||
from subiquitycore.core import ApplicationError
|
||||
|
@ -70,10 +70,14 @@ def parse_options(argv):
|
|||
def control_c_handler(signum, frame):
|
||||
sys.exit(1)
|
||||
|
||||
LOGDIR = "/writable/.subiquity"
|
||||
|
||||
def main():
|
||||
opts = parse_options(sys.argv[1:])
|
||||
setup_logger()
|
||||
global LOGDIR
|
||||
if opts.dry_run:
|
||||
LOGDIR = ".subiquity"
|
||||
LOGFILE = setup_logger(dir=LOGDIR)
|
||||
logger = logging.getLogger('console_conf')
|
||||
logger.info("Starting console-conf v{}".format(VERSION))
|
||||
logger.info("Arguments passed: {}".format(sys.argv))
|
||||
|
|
|
@ -16,8 +16,32 @@
|
|||
|
||||
from subiquitycore.controllers.identity import BaseIdentityController
|
||||
|
||||
from console_conf.ui.views import IdentityView
|
||||
from console_conf.ui.views import IdentityView, LoginView
|
||||
|
||||
|
||||
class IdentityController(BaseIdentityController):
|
||||
identity_view = IdentityView
|
||||
|
||||
def identity(self):
|
||||
title = "Profile setup"
|
||||
excerpt = "Enter an email address from your account in the store."
|
||||
footer = ""
|
||||
self.ui.set_header(title, excerpt)
|
||||
self.ui.set_footer(footer, 40)
|
||||
self.ui.set_body(self.identity_view(self.model, self.signal, self.opts, self.loop))
|
||||
|
||||
def login(self):
|
||||
title = "Configuration Complete"
|
||||
footer = "View configured user and device access methods"
|
||||
self.ui.set_header(title)
|
||||
self.ui.set_footer(footer)
|
||||
|
||||
net_model = self.controllers['Network'].model
|
||||
configured_ifaces = net_model.get_configured_interfaces()
|
||||
login_view = LoginView(self.opts,
|
||||
self.model,
|
||||
self.signal,
|
||||
self.model.user,
|
||||
configured_ifaces)
|
||||
|
||||
self.ui.set_body(login_view)
|
||||
|
|
|
@ -16,4 +16,5 @@
|
|||
""" ConsoleConf UI Views """
|
||||
|
||||
from .identity import IdentityView # NOQA
|
||||
from .login import LoginView # NOQA
|
||||
from .welcome import WelcomeView # NOQA
|
||||
|
|
|
@ -14,19 +14,130 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import pwd
|
||||
|
||||
from subiquitycore.ui.views.identity import BaseIdentityView
|
||||
from subiquitycore.user import create_user
|
||||
from urwid import (Pile, Columns, Text, ListBox)
|
||||
from subiquitycore.ui.buttons import done_btn, cancel_btn
|
||||
from subiquitycore.ui.interactive import EmailEditor
|
||||
from subiquitycore.ui.utils import Padding, Color
|
||||
from subiquitycore.utils import run_command
|
||||
from subiquitycore.view import BaseView
|
||||
|
||||
log = logging.getLogger("console_conf.views.identity")
|
||||
|
||||
|
||||
class IdentityView(BaseIdentityView):
|
||||
def create_user(self, result):
|
||||
try:
|
||||
create_user(
|
||||
result, dryrun=self.opts.dry_run, extra_args=['--extrausers'])
|
||||
except PermissionError:
|
||||
# XXX do something here
|
||||
log.exception('Failed to create user.')
|
||||
return None
|
||||
'''
|
||||
+---------------------------------------------------+
|
||||
| |
|
||||
| Enter the email address of the account in the |
|
||||
| store |
|
||||
| |
|
||||
| +-------------------------+ |
|
||||
| Email address: | | |
|
||||
| +-------------------------+ |
|
||||
| |
|
||||
| |
|
||||
| +--------+ |
|
||||
| | Done | |
|
||||
| +--------+ |
|
||||
| | Cancel | |
|
||||
| +--------+ |
|
||||
| |
|
||||
+---------------------------------------------------+
|
||||
'''
|
||||
|
||||
class IdentityView(BaseView):
|
||||
|
||||
def __init__(self, model, signal, opts, loop):
|
||||
self.model = model
|
||||
self.signal = signal
|
||||
self.opts = opts
|
||||
self.loop = loop
|
||||
self.items = []
|
||||
self.email = EmailEditor(caption="")
|
||||
self.error = Text("", align="center")
|
||||
self.progress = Text("", align="center")
|
||||
|
||||
body = [
|
||||
Padding.center_90(self._build_model_inputs()),
|
||||
Padding.line_break(""),
|
||||
Padding.center_90(Color.info_error(self.error)),
|
||||
Padding.center_90(self.progress),
|
||||
Padding.line_break(""),
|
||||
Padding.fixed_10(self._build_buttons()),
|
||||
]
|
||||
super().__init__(ListBox(body))
|
||||
|
||||
def _build_model_inputs(self):
|
||||
sl = [
|
||||
Columns(
|
||||
[
|
||||
("weight", 0.2, Text("Email address:", align="right")),
|
||||
("weight", 0.3,
|
||||
Color.string_input(self.email,
|
||||
focus_map="string_input focus"))
|
||||
],
|
||||
dividechars=4
|
||||
),
|
||||
]
|
||||
return Pile(sl)
|
||||
|
||||
def _build_buttons(self):
|
||||
cancel = cancel_btn(on_press=self.cancel)
|
||||
done = done_btn(on_press=self.done)
|
||||
|
||||
buttons = [
|
||||
Color.button(done, focus_map='button focus'),
|
||||
Color.button(cancel, focus_map='button focus')
|
||||
]
|
||||
return Pile(buttons)
|
||||
|
||||
def cancel(self, button):
|
||||
self.signal.prev_signal()
|
||||
|
||||
def done(self, button):
|
||||
if len(self.email.value) < 1:
|
||||
self.error.set_text("Please enter an email address.")
|
||||
return
|
||||
if not self.opts.dry_run:
|
||||
self.progress.set_text("Contacting store...")
|
||||
self.loop.draw_screen()
|
||||
users_before = users()
|
||||
result = run_command(["snap", "create-user", self.email.value])
|
||||
self.progress.set_text("")
|
||||
if result['status'] != 0:
|
||||
self.error.set_text("Creating user failed:\n" + result['err'])
|
||||
return
|
||||
else:
|
||||
users_after = users()
|
||||
new_users = users_after - users_before
|
||||
if len(new_users) != 1:
|
||||
self.error.set_text("uhh")
|
||||
return
|
||||
new_user = pwd.getpwnam(new_users.pop())
|
||||
# Use email for realname until
|
||||
# https://bugs.launchpad.net/snappy/+bug/1607121 is resolved.
|
||||
result = {
|
||||
'realname': self.email.value, #new_user.pw_gecos.split(",")[0]
|
||||
'username': new_user.pw_name,
|
||||
'passwod': '',
|
||||
'confirm_password': ''
|
||||
}
|
||||
# Work around https://bugs.launchpad.net/snappy/+bug/1606815
|
||||
run_command(["chown", "{}:{}".format(new_user.pw_uid, new_user.pw_gid), "-R", new_user.pw_dir])
|
||||
self.model.add_user(result)
|
||||
else:
|
||||
result = {
|
||||
'realname': self.email.value,
|
||||
'username': self.email.value,
|
||||
'passwod': '',
|
||||
'confirm_password': '',
|
||||
}
|
||||
self.model.add_user(result)
|
||||
self.signal.emit_signal('menu:identity:login:main')
|
||||
|
||||
def users():
|
||||
r = set()
|
||||
for pw in pwd.getpwall():
|
||||
r.add(pw.pw_name)
|
||||
return r
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
subiquity (0.0.6~cy3) UNRELEASED; urgency=medium
|
||||
subiquity (0.0.7~1) UNRELEASED; urgency=medium
|
||||
|
||||
* Release 0.0.6 snapshot: port for yakkety:
|
||||
- Build separate subiquitycore, subiquity, and console-conf packages.
|
||||
[ Michael Hudson-Doyle ]
|
||||
* Demo-ware.
|
||||
* Install systemd units for console-conf.
|
||||
|
||||
[ Mathieu Trudel-Lapierre ]
|
||||
* Release 0.0.7 snapshot
|
||||
* debian/control: move Depends on curtin from subiquitycore to subiquity.
|
||||
|
||||
-- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Fri, 08 Jul 2016 16:44:55 -0400
|
||||
|
|
|
@ -7,7 +7,7 @@ ExecStop=systemctl start getty@%I
|
|||
Before=getty.target
|
||||
IgnoreOnIsolate=yes
|
||||
ConditionPathExists=/dev/tty0
|
||||
ConditionPathExists=!/var/lib/firstboot/firstboot-complete
|
||||
ConditionPathExists=!/writable/firstboot-complete
|
||||
|
||||
[Service]
|
||||
Environment=PYTHONPATH=/usr/share/subiquity
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
systemctl enable console-conf@tty1.service
|
||||
systemctl enable serial-console-conf@ttyS1.service
|
|
@ -4,7 +4,7 @@ BindsTo=dev-%i.device
|
|||
#After=getty@tty.service
|
||||
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
|
||||
After=rc-local.service
|
||||
ConditionPathExists=!/var/lib/firstboot/firstboot-complete
|
||||
ConditionPathExists=!/writable/firstboot-complete
|
||||
|
||||
[Service]
|
||||
Environment=PYTHONPATH=/usr/share/subiquity
|
||||
|
|
|
@ -18,14 +18,15 @@ import os
|
|||
import sys
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
LOGDIR = ".subiquity"
|
||||
LOGDIR = "/writable/.subiquity"
|
||||
LOGFILE = os.path.join(LOGDIR, "subiquity-debug.log")
|
||||
|
||||
|
||||
def setup_logger(name=__name__):
|
||||
def setup_logger(name=__name__, dir=LOGDIR):
|
||||
LOGFILE = os.path.join(dir, "subiquity-debug.log")
|
||||
try:
|
||||
if not os.path.isdir(LOGDIR):
|
||||
os.makedirs(LOGDIR)
|
||||
if not os.path.isdir(dir):
|
||||
os.makedirs(dir)
|
||||
log = TimedRotatingFileHandler(LOGFILE,
|
||||
when='D',
|
||||
interval=1,
|
||||
|
@ -46,4 +47,4 @@ def setup_logger(name=__name__):
|
|||
logger = logging.getLogger('')
|
||||
logger.setLevel('DEBUG')
|
||||
logger.addHandler(log)
|
||||
return logger
|
||||
return LOGFILE
|
||||
|
|
|
@ -74,6 +74,20 @@ class RealnameEditor(StringEditor):
|
|||
return super().keypress(size, key)
|
||||
|
||||
|
||||
class EmailEditor(StringEditor):
|
||||
""" Email input prompt with input rules
|
||||
"""
|
||||
|
||||
def keypress(self, size, key):
|
||||
''' restrict what chars we allow for username '''
|
||||
|
||||
realname = r'[-a-zA-Z0-9_.@]'
|
||||
if re.match(realname, key) is None:
|
||||
return False
|
||||
|
||||
return super().keypress(size, key)
|
||||
|
||||
|
||||
class UsernameEditor(StringEditor):
|
||||
""" Username input prompt with input rules
|
||||
"""
|
||||
|
|
|
@ -202,7 +202,7 @@ def sudo_user():
|
|||
def mark_firstboot_complete():
|
||||
""" Touch our firstboot-complete eyecatcher """
|
||||
log.info('marking firstboot service complete')
|
||||
firstboot = '/var/lib/firstboot/firstboot-complete'
|
||||
firstboot = '/writable/firstboot-complete'
|
||||
if not os.path.exists(os.path.dirname(firstboot)):
|
||||
os.makedirs(os.path.dirname(firstboot))
|
||||
with open(firstboot, 'w') as fp:
|
||||
|
|
Loading…
Reference in New Issue