Merge pull request #794 from mwhudson/lp-1881588

use snapd apis to check for users
This commit is contained in:
Michael Hudson-Doyle 2020-07-10 08:37:51 +12:00 committed by GitHub
commit 317648aec4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 44 deletions

View File

@ -16,11 +16,13 @@
import json
import logging
import os
import pwd
import shlex
import sys
from subiquitycore.controller import BaseController
from subiquitycore.ssh import host_key_info, get_ips_standalone
from subiquitycore.snapd import SnapdConnection
from subiquitycore.utils import disable_console_conf, run_command
from console_conf.ui.views import IdentityView, LoginView
@ -50,24 +52,34 @@ def get_core_version():
return version
def get_device_owner():
""" Check if device is owned """
def get_managed():
""" Check if device is managed """
con = SnapdConnection('', '/run/snapd.socket')
return con.get('v2/system-info').json()['result']['managed']
# TODO: use proper snap APIs.
def get_realname(username):
try:
extrausers_fp = open('/var/lib/extrausers/passwd', 'r')
except FileNotFoundError:
return None
with extrausers_fp:
passwd_line = extrausers_fp.readline()
if passwd_line and len(passwd_line) > 0:
passwd = passwd_line.split(':')
result = {
'realname': passwd[4].split(',')[0],
'username': passwd[0],
'homedir': passwd[5],
info = pwd.getpwnam(username)
except KeyError:
return ''
return info.pw_gecos.split(',', 1)[0]
def get_device_owner():
""" Get device owner, if any """
con = SnapdConnection('', '/run/snapd.socket')
for user in con.get('v2/users').json()['result']:
if 'username' not in user:
continue
username = user['username']
homedir = '/home/' + username
if os.path.isdir(homedir):
return {
'username': username,
'realname': get_realname(username),
'homedir': homedir,
}
return result
return None
@ -111,17 +123,21 @@ def write_login_details(fp, username, ips):
def write_login_details_standalone():
owner = get_device_owner()
if owner is None:
print("No device owner details found.")
return 0
ips = get_ips_standalone()
if len(ips) == 0:
tty_name = os.ttyname(0)[5:]
version = get_core_version() or "16"
print(login_details_tmpl_no_ip.format(tty_name=tty_name,
version=version))
return 2
write_login_details(sys.stdout, owner['username'], ips)
if owner is None:
print("device managed without user")
return 2
else:
tty_name = os.ttyname(0)[5:]
version = get_core_version() or "16"
print(login_details_tmpl_no_ip.format(
tty_name=tty_name, version=version))
return 2
if owner is None:
print("device managed without user @ {}".format(', '.join(ips)))
else:
write_login_details(sys.stdout, owner['username'], ips)
return 0
@ -133,14 +149,15 @@ class IdentityController(BaseController):
def start_ui(self):
self.ui.set_body(IdentityView(self.model, self))
device_owner = get_device_owner()
if device_owner is not None:
self.model.add_user(device_owner)
key_file = os.path.join(device_owner['homedir'],
".ssh/authorized_keys")
self.model.user.fingerprints = (
run_command(['ssh-keygen', '-lf',
key_file]).stdout.replace('\r', '').splitlines())
if get_managed():
device_owner = get_device_owner()
if device_owner:
self.model.add_user(device_owner)
key_file = os.path.join(device_owner['homedir'],
".ssh/authorized_keys")
cp = run_command(['ssh-keygen', '-lf', key_file])
self.model.user.fingerprints = (
cp.stdout.replace('\r', '').splitlines())
self.login()
def identity_done(self, email):

View File

@ -57,6 +57,17 @@ class LoginView(BaseView):
]
def _build_model_inputs(self):
user = self.model.user
ips = []
for dev in self.netdevs:
for addr in dev.actual_global_ip_addresses:
ips.append(addr)
if not user:
sl = []
sl.append(Text("no owner"))
return sl
local_tpl = (
"This device is registered to {realname}.")
@ -67,17 +78,12 @@ class LoginView(BaseView):
"device via SSH:")
sl = []
user = self.model.user
login_info = {
'realname': user.realname,
'username': user.username,
}
login_text = local_tpl.format(**login_info)
login_text += remote_tpl.format(**login_info)
ips = []
for dev in self.netdevs:
for addr in dev.actual_global_ip_addresses:
ips.append(addr)
sl += [Text(login_text), Padding.line_break("")]
for ip in ips:

2
debian/control vendored
View File

@ -23,6 +23,8 @@ Depends: probert-network,
python3-urwid (>= 1.2.1),
python3-attr,
python3-yaml,
python3-requests,
python3-requests-unixsocket,
${misc:Depends},
${python3:Depends}
Description: Ubuntu Server Installer - core libraries

View File

@ -49,6 +49,7 @@ subiquitycore/ui/stretchy.py
subiquitycore/ui/container.py
subiquitycore/ui/frame.py
subiquitycore/file_util.py
subiquitycore/snapd.py
subiquitycore/view.py
subiquity/controllers/identity.py
subiquity/controllers/package.py
@ -76,7 +77,6 @@ subiquity/cmd/__init__.py
subiquity/cmd/tui.py
subiquity/cmd/schema.py
subiquity/journald.py
subiquity/snapd.py
subiquity/lockfile.py
subiquity/models/identity.py
subiquity/models/locale.py

View File

@ -35,6 +35,11 @@ from subiquitycore.async_helpers import (
)
from subiquitycore.controller import Skip
from subiquitycore.core import Application
from subiquitycore.snapd import (
AsyncSnapd,
FakeSnapdConnection,
SnapdConnection,
)
from subiquitycore.view import BaseView
from subiquity.controllers.error import (
@ -43,11 +48,6 @@ from subiquity.controllers.error import (
from subiquity.journald import journald_listener
from subiquity.lockfile import Lockfile
from subiquity.models.subiquity import SubiquityModel
from subiquity.snapd import (
AsyncSnapd,
FakeSnapdConnection,
SnapdConnection,
)
from subiquity.ui.frame import SubiquityUI
from subiquity.ui.views.error import ErrorReportStretchy
from subiquity.ui.views.help import HelpMenu

View File

@ -31,7 +31,7 @@ from subiquitycore.utils import run_command
import requests_unixsocket
log = logging.getLogger('subiquity.snapd')
log = logging.getLogger('subiquitycore.snapd')
# Every method in this module blocks. Do not call them from the main thread!