Commit d63a5883 authored by Julien Muchembled's avatar Julien Muchembled

vm: use a normal user account by default

parent f8c6faef
......@@ -626,10 +626,6 @@ Currently, it only produces `raw` images, in `discard` mode (see ``-drive``
QEMU option): combined the use of ``discard`` mount option, this minimizes
the used space on disk.
If the ``ssh`` package is installed, which is required for
`slapos.recipe.build:vm.run`_, an SSH key is automatically created with
``ssh-keygen``, and it will be used to connect as `root` user.
Options
~~~~~~~
......@@ -690,6 +686,27 @@ ISO sections
<arch>.initrd
Path to initrd image inside the ISO.
User setup
~~~~~~~~~~
This recipe comes with 2 specific rules:
- If the `ssh` package is installed, which is required for
`slapos.recipe.build:vm.run`_, an SSH key is automatically created with
``ssh-keygen``, and it can be used to connect as the normal user account,
or as `root` if ``passwd/make-user`` is ``false``.
- If the user account is locked and if ``sudo`` is installed, a sudo rule is
added to allow this account to become root without password.
By default, both SSH and sudo are installed, a `slapos` user account is created
and both root and user accounts are locked.
For more information about the ``passwd/*`` preseed values, you can look at
the ``user-setup-udeb`` package at
https://anonscm.debian.org/cgit/d-i/user-setup.git/tree/
and in particular the ``user-setup-ask`` and ``user-setup-apply`` scripts.
Example
~~~~~~~
......@@ -765,6 +782,9 @@ stop-ssh
Tell `reboot` function how to stop SSH (see Helpers_).
Default: systemctl stop ssh
user
SSH connects with this user. Default: slapos
wait-ssh
Time to wait for (re)boot. The recipe fails if it can't connect to the SSH
server after this number of seconds. Default: 60
......@@ -815,9 +835,9 @@ Example
<= vm-run-base
repository = `map ${userhosts-repository:location}`
command =
git clone -s ${:repository} /userhosts
cd /userhosts
mk-build-deps -irt 'apt-get -y'
git clone -s ${:repository} userhosts
cd userhosts
mk-build-deps -irs sudo -t 'apt-get -y'
dpkg-buildpackage -uc -b -jauto
cd ..
mv *.changes *.deb $PARTDIR
......
......@@ -29,10 +29,11 @@ import base64, os, select, shutil, socket
import subprocess, sys, tempfile, threading, time
from contextlib import contextmanager
from os.path import join
from slapos.recipe import EnvironMixin, generatePassword, logger, rmtree
from slapos.recipe import EnvironMixin, logger, rmtree
from zc.buildout import UserError
ARCH = os.uname()[4]
USER = 'slapos'
@contextmanager
def building_directory(directory):
......@@ -115,12 +116,14 @@ class InstallDebianRecipe(BaseRecipe):
finish-install/reboot_in_progress = note
preseed/url = file:///dev/null
passwd/make-user = true
passwd/root-login = false
clock-setup/ntp = false
time/zone = UTC
language = C
country = FR
keymap = us
passwd/make-user = false
partman-auto/method = regular
partman-auto/expert_recipe = : 1 1 -1 ext4 $primary{ } $bootable{ } method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ / } options/discard{ } options/noatime{ } .
"""
......@@ -176,11 +179,16 @@ class InstallDebianRecipe(BaseRecipe):
packages = options.get('packages', 'ssh').split()
if packages:
cmdline['pkgsel/include'] = ','.join(packages)
if 'passwd/root-password' in cmdline:
root_password = None
if ('false', 'true').index(cmdline['passwd/make-user']):
user = cmdline.setdefault('passwd/username', USER)
cmdline.setdefault('passwd/user-fullname', '')
if not (cmdline.get('passwd/user-password') or
cmdline.get('passwd/user-password-crypted')):
cmdline['passwd/user-password-crypted'] = '!'
else:
cmdline['passwd/root-password'] = root_password = \
cmdline['passwd/root-password-again'] = generatePassword()
user = None
env = self.environ
location = self.vm
......@@ -192,8 +200,12 @@ class InstallDebianRecipe(BaseRecipe):
with open(key) as f:
os.remove(key)
key = f.read().strip()
cmd = "mkdir -m 0700 ~/.ssh && echo %s > ~/.ssh/authorized_keys" % key
self.late_command.append("su -c '%s' %s" % (cmd, user) if user else cmd)
if user and cmdline.get('passwd/user-password-crypted') == '!':
self.late_command.append(
"mkdir -m 0700 ~/.ssh && echo %s > ~/.ssh/authorized_keys" % key)
"(cd /etc/sudoers.d && echo %s ALL=NOPASSWD: ALL >%s && chmod 440 %s)"
% (user, user, user))
if self.late_command:
cmdline['preseed/late_command'] = (
'cd /target && echo %s|usr/bin/base64 -d|chroot . sh'
......@@ -227,23 +239,17 @@ class InstallDebianRecipe(BaseRecipe):
'DOS/MBR boot sector'):
raise Exception('non bootable image')
if root_password:
fd = os.open(join(location, 'passwd'), open_flags, 0600)
try:
os.write(fd, "root:%s\n" % root_password)
finally:
os.close(fd)
return [location]
class RunRecipe(BaseRecipe):
command = """set -e
[ "$USER" = root ] || SUDO=sudo
reboot() {
unset -f reboot
%s
(while pgrep -x sshd; do sleep 1; done >/dev/null; reboot
$SUDO %s
(while pgrep -x sshd; do sleep 1; done >/dev/null; exec $SUDO reboot
) >/dev/null 2>&1 &
exit
}
......@@ -252,9 +258,9 @@ map() {
echo /mnt/buildout$x
}
PARTDIR=`map %s`
(cd /mnt; set %s; mkdir -p $*; for tag; do
$SUDO sh -c 'cd /mnt; set %s; mkdir -p $*; for tag; do
mount -t 9p -o trans=virtio,version=9p2000.L,noatime $tag $tag
done)
done'
"""
def __init__(self, buildout, name, options):
......@@ -285,6 +291,7 @@ PARTDIR=`map %s`
location, ' '.join(self.mount_dict))
commands = map(options.__getitem__,
options.get('commands', 'command').split())
user = options.get('user', USER)
hostfwd_retries = 9
wait_ssh = int(options.get('wait-ssh') or 60)
with building_directory(location):
......@@ -336,7 +343,8 @@ PARTDIR=`map %s`
'-o', 'BatchMode=yes',
'-o', 'UserKnownHostsFile=' + os.devnull,
'-o', 'StrictHostKeyChecking=no',
'-p', str(ssh[1]), 'root@' + ssh[0], init + command), env=env)
'-p', str(ssh[1]), user + '@' + ssh[0], init + command),
env=env)
finally:
p.stop()
break
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment