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`` ...@@ -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 QEMU option): combined the use of ``discard`` mount option, this minimizes
the used space on disk. 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 Options
~~~~~~~ ~~~~~~~
...@@ -690,6 +686,27 @@ ISO sections ...@@ -690,6 +686,27 @@ ISO sections
<arch>.initrd <arch>.initrd
Path to initrd image inside the ISO. 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 Example
~~~~~~~ ~~~~~~~
...@@ -765,6 +782,9 @@ stop-ssh ...@@ -765,6 +782,9 @@ stop-ssh
Tell `reboot` function how to stop SSH (see Helpers_). Tell `reboot` function how to stop SSH (see Helpers_).
Default: systemctl stop ssh Default: systemctl stop ssh
user
SSH connects with this user. Default: slapos
wait-ssh wait-ssh
Time to wait for (re)boot. The recipe fails if it can't connect to the 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 server after this number of seconds. Default: 60
...@@ -815,9 +835,9 @@ Example ...@@ -815,9 +835,9 @@ Example
<= vm-run-base <= vm-run-base
repository = `map ${userhosts-repository:location}` repository = `map ${userhosts-repository:location}`
command = command =
git clone -s ${:repository} /userhosts git clone -s ${:repository} userhosts
cd /userhosts cd userhosts
mk-build-deps -irt 'apt-get -y' mk-build-deps -irs sudo -t 'apt-get -y'
dpkg-buildpackage -uc -b -jauto dpkg-buildpackage -uc -b -jauto
cd .. cd ..
mv *.changes *.deb $PARTDIR mv *.changes *.deb $PARTDIR
......
...@@ -29,10 +29,11 @@ import base64, os, select, shutil, socket ...@@ -29,10 +29,11 @@ import base64, os, select, shutil, socket
import subprocess, sys, tempfile, threading, time import subprocess, sys, tempfile, threading, time
from contextlib import contextmanager from contextlib import contextmanager
from os.path import join 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 from zc.buildout import UserError
ARCH = os.uname()[4] ARCH = os.uname()[4]
USER = 'slapos'
@contextmanager @contextmanager
def building_directory(directory): def building_directory(directory):
...@@ -115,12 +116,14 @@ class InstallDebianRecipe(BaseRecipe): ...@@ -115,12 +116,14 @@ class InstallDebianRecipe(BaseRecipe):
finish-install/reboot_in_progress = note finish-install/reboot_in_progress = note
preseed/url = file:///dev/null preseed/url = file:///dev/null
passwd/make-user = true
passwd/root-login = false
clock-setup/ntp = false clock-setup/ntp = false
time/zone = UTC time/zone = UTC
language = C language = C
country = FR country = FR
keymap = us keymap = us
passwd/make-user = false
partman-auto/method = regular 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{ } . 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): ...@@ -176,11 +179,16 @@ class InstallDebianRecipe(BaseRecipe):
packages = options.get('packages', 'ssh').split() packages = options.get('packages', 'ssh').split()
if packages: if packages:
cmdline['pkgsel/include'] = ','.join(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: else:
cmdline['passwd/root-password'] = root_password = \ user = None
cmdline['passwd/root-password-again'] = generatePassword()
env = self.environ env = self.environ
location = self.vm location = self.vm
...@@ -192,8 +200,12 @@ class InstallDebianRecipe(BaseRecipe): ...@@ -192,8 +200,12 @@ class InstallDebianRecipe(BaseRecipe):
with open(key) as f: with open(key) as f:
os.remove(key) os.remove(key)
key = f.read().strip() 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( 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: if self.late_command:
cmdline['preseed/late_command'] = ( cmdline['preseed/late_command'] = (
'cd /target && echo %s|usr/bin/base64 -d|chroot . sh' 'cd /target && echo %s|usr/bin/base64 -d|chroot . sh'
...@@ -227,23 +239,17 @@ class InstallDebianRecipe(BaseRecipe): ...@@ -227,23 +239,17 @@ class InstallDebianRecipe(BaseRecipe):
'DOS/MBR boot sector'): 'DOS/MBR boot sector'):
raise Exception('non bootable image') 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] return [location]
class RunRecipe(BaseRecipe): class RunRecipe(BaseRecipe):
command = """set -e command = """set -e
[ "$USER" = root ] || SUDO=sudo
reboot() { reboot() {
unset -f reboot unset -f reboot
%s $SUDO %s
(while pgrep -x sshd; do sleep 1; done >/dev/null; reboot (while pgrep -x sshd; do sleep 1; done >/dev/null; exec $SUDO reboot
) >/dev/null 2>&1 & ) >/dev/null 2>&1 &
exit exit
} }
...@@ -252,9 +258,9 @@ map() { ...@@ -252,9 +258,9 @@ map() {
echo /mnt/buildout$x echo /mnt/buildout$x
} }
PARTDIR=`map %s` 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 mount -t 9p -o trans=virtio,version=9p2000.L,noatime $tag $tag
done) done'
""" """
def __init__(self, buildout, name, options): def __init__(self, buildout, name, options):
...@@ -285,6 +291,7 @@ PARTDIR=`map %s` ...@@ -285,6 +291,7 @@ PARTDIR=`map %s`
location, ' '.join(self.mount_dict)) location, ' '.join(self.mount_dict))
commands = map(options.__getitem__, commands = map(options.__getitem__,
options.get('commands', 'command').split()) options.get('commands', 'command').split())
user = options.get('user', USER)
hostfwd_retries = 9 hostfwd_retries = 9
wait_ssh = int(options.get('wait-ssh') or 60) wait_ssh = int(options.get('wait-ssh') or 60)
with building_directory(location): with building_directory(location):
...@@ -336,7 +343,8 @@ PARTDIR=`map %s` ...@@ -336,7 +343,8 @@ PARTDIR=`map %s`
'-o', 'BatchMode=yes', '-o', 'BatchMode=yes',
'-o', 'UserKnownHostsFile=' + os.devnull, '-o', 'UserKnownHostsFile=' + os.devnull,
'-o', 'StrictHostKeyChecking=no', '-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: finally:
p.stop() p.stop()
break 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