mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00

Up until now I didn't see the point of using spaces for indentation. However, the previous commit (a18bec3) was quite eye opening. Given that python is an indentation aware language, the amount of mistakes that went unnoticed because tabs and spaces were used at the same time (tabs for indentation and spaces for alignment) were unacceptable. E101,W191 have been re-enable in the tox flake8 checker and the documentation has been modified accordingly. The following files have been left as-is: * bootstrapvz/common/assets/extlinux/extlinux.conf * bootstrapvz/common/assets/init.d/expand-root * bootstrapvz/common/assets/init.d/generate-ssh-hostkeys * bootstrapvz/common/assets/init.d/squeeze/generate-ssh-hostkeys * bootstrapvz/plugins/docker_daemon/assets/init.d/docker * bootstrapvz/providers/ec2/assets/bin/growpart * bootstrapvz/providers/ec2/assets/grub.d/40_custom * bootstrapvz/providers/ec2/assets/init.d/ec2-get-credentials * bootstrapvz/providers/ec2/assets/init.d/ec2-run-user-data * docs/_static/taskoverview.coffee * docs/_static/taskoverview.less * tests/unit/subprocess.sh
112 lines
4.4 KiB
Python
112 lines
4.4 KiB
Python
from bootstrapvz.base import Task
|
|
from bootstrapvz.common import phases
|
|
from bootstrapvz.common.tasks.initd import InstallInitScripts
|
|
from bootstrapvz.providers.ec2.tasks.initd import AddEC2InitScripts
|
|
|
|
import os
|
|
import logging
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class AddSudoPackage(Task):
|
|
description = 'Adding `sudo\' to the image packages'
|
|
phase = phases.preparation
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
info.packages.add('sudo')
|
|
|
|
|
|
class CreateAdminUser(Task):
|
|
description = 'Creating the admin user'
|
|
phase = phases.system_modification
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
from bootstrapvz.common.tools import log_check_call
|
|
log_check_call(['chroot', info.root,
|
|
'useradd',
|
|
'--create-home', '--shell', '/bin/bash',
|
|
info.manifest.plugins['admin_user']['username']])
|
|
|
|
|
|
class PasswordlessSudo(Task):
|
|
description = 'Allowing the admin user to use sudo without a password'
|
|
phase = phases.system_modification
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
sudo_admin_path = os.path.join(info.root, 'etc/sudoers.d/99_admin')
|
|
username = info.manifest.plugins['admin_user']['username']
|
|
with open(sudo_admin_path, 'w') as sudo_admin:
|
|
sudo_admin.write('{username} ALL=(ALL) NOPASSWD:ALL'.format(username=username))
|
|
import stat
|
|
ug_read_only = (stat.S_IRUSR | stat.S_IRGRP)
|
|
os.chmod(sudo_admin_path, ug_read_only)
|
|
|
|
|
|
class AdminUserPassword(Task):
|
|
description = 'Setting the admin user password'
|
|
phase = phases.system_modification
|
|
predecessors = [InstallInitScripts, CreateAdminUser]
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
from bootstrapvz.common.tools import log_check_call
|
|
log_check_call(['chroot', info.root, 'chpasswd'],
|
|
info.manifest.plugins['admin_user']['username'] +
|
|
':' + info.manifest.plugins['admin_user']['password'])
|
|
|
|
|
|
class AdminUserPublicKey(Task):
|
|
description = 'Installing the public key for the admin user'
|
|
phase = phases.system_modification
|
|
predecessors = [AddEC2InitScripts, CreateAdminUser]
|
|
successors = [InstallInitScripts]
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
if 'ec2-get-credentials' in info.initd['install']:
|
|
log.warn('You are using a static public key for the admin account.'
|
|
'This will conflict with the ec2 public key injection mechanism.'
|
|
'The ec2-get-credentials startup script will therefore not be enabled.')
|
|
del info.initd['install']['ec2-get-credentials']
|
|
|
|
# Get the stuff we need (username & public key)
|
|
username = info.manifest.plugins['admin_user']['username']
|
|
with open(info.manifest.plugins['admin_user']['pubkey']) as pubkey_handle:
|
|
pubkey = pubkey_handle.read()
|
|
|
|
# paths
|
|
ssh_dir_rel = os.path.join('home', username, '.ssh')
|
|
auth_keys_rel = os.path.join(ssh_dir_rel, 'authorized_keys')
|
|
ssh_dir_abs = os.path.join(info.root, ssh_dir_rel)
|
|
auth_keys_abs = os.path.join(info.root, auth_keys_rel)
|
|
# Create the ssh dir if nobody has created it yet
|
|
if not os.path.exists(ssh_dir_abs):
|
|
os.mkdir(ssh_dir_abs, 0700)
|
|
|
|
# Create (or append to) the authorized keys file (and chmod u=rw,go=)
|
|
import stat
|
|
with open(auth_keys_abs, 'a') as auth_keys_handle:
|
|
auth_keys_handle.write(pubkey + '\n')
|
|
os.chmod(auth_keys_abs, (stat.S_IRUSR | stat.S_IWUSR))
|
|
|
|
# Set the owner of the authorized keys file
|
|
# (must be through chroot, the host system doesn't know about the user)
|
|
from bootstrapvz.common.tools import log_check_call
|
|
log_check_call(['chroot', info.root,
|
|
'chown', '-R', (username + ':' + username), ssh_dir_rel])
|
|
|
|
|
|
class AdminUserPublicKeyEC2(Task):
|
|
description = 'Modifying ec2-get-credentials to copy the ssh public key to the admin user'
|
|
phase = phases.system_modification
|
|
predecessors = [InstallInitScripts, CreateAdminUser]
|
|
|
|
@classmethod
|
|
def run(cls, info):
|
|
from bootstrapvz.common.tools import sed_i
|
|
getcreds_path = os.path.join(info.root, 'etc/init.d/ec2-get-credentials')
|
|
username = info.manifest.plugins['admin_user']['username']
|
|
sed_i(getcreds_path, "username='root'", "username='{username}'".format(username=username))
|