_modules/vm_create.py
author Paul Tonelli <paul.tonelli@logilab.fr>
Mon, 25 Mar 2013 11:32:52 +0100
changeset 94 4a2b15de9ec9
parent 84 40a8790380af
child 101 8b47c42308c4
permissions -rw-r--r--
changed parameter name from chroot_dir to path in module for easier call in sls files

#!/usr/bin/env python
'''
translation of a bash script to create a flavored virtual machine
'''

PROXY_ADDRESS = 'http://proxy.logilab.priv:3142/'
DEFAULT_PATH = '/mnt'
APT_PROXY_FILENAME = '/etc/apt/apt.conf.d/01proxy'
POLICY_FILENAME = '/usr/sbin/policy-rc.d'
POLICY_CONTENT =  'exit 101'
DEFAULT_MOUNT_DIR = 'variation'
DEFAULT_VARIATION_NAME = DEFAULT_MOUNT_DIR + '.sls'

from os import listdir, remove, stat, environ
import shutil
import salt.utils
import logging

log = logging.getLogger(__name__)

def update_image(path):
    '''
    update image using apt-get. Doing so, it creates a few files.
    In order to be executed in chroot, you should use is with
    create_proxy=True unless you have /run mounted

    CLI Example::

        salt '*' vm_create.update_image /mnt/variation
    '''
    _print_if_error(_chroot_exec(path, 'apt-get update'))
    _print_if_error(_chroot_exec(path, 'apt-get --force-yes -y install salt-minion'))
    return True

def variate_image(path, variation_filename=DEFAULT_VARIATION_NAME):
    '''
    do all code relevant to personalizing the machine here
    salt-minion should be available

    CLI Example::

        salt '*' vm_create.variate_image /mnt/variation

    '''
    log.info(_chroot_exec(path, 'salt-call  --local state.highstate'))
    return True

def create_variation(path=DEFAULT_PATH):
    '''
    complete function to create the new variation from a virtual machine

    CLI Example::

        salt '*' vm_create.create_variation
    '''
    image_dirname = DEFAULT_MOUNT_DIR
    ### Exec pre state here ###
    log.info(__salt__['state.sls']('ami_pre'))
    update_image(path + '/' + image_dirname)
    variate_image(path + '/' + image_dirname)
    log.info(__salt__['state.sls']('ami_post'))

    if __salt__['grains.item']('keystone.user'): #true only if len>0
        upload_to_glance(path)
    else:
        log.info('Image Not uploaded to glance !')
    return True

def upload_to_glance(path):
    log.info('will now try to upload to glance server')
    ami_name = __salt__['grains.item']('ami.name')
    if not ami_name:
        ami_name = "variation"
    object_id = {}
    object_types = {'kernel':'aki','ramdisk':'ari'}
    ok_for_image = True
    for o_type in object_types:
        object_id[o_type] = __salt__['grains.item'](o_type + '_id')
        if object_id[o_type]:
            object_id[o_type] = object_id[o_type].values()[0]
        else:
            o_path = _find_objects(path, o_type)
            if len(o_path) == 1:
                object_id[o_type] = __salt__['openstack_client.upload_to_glance'](
                        o_path[0], object_types[o_type], image_name=o_type + '_' + ami_name)
            else:
                log.error('no ' + o_type + ' found in ' + path)
                ok_for_image = False
    if ok_for_image:
        o_path = _find_objects(path,'.img')
        if len(o_path) == 1:
            image_id = __salt__['openstack_client.upload_to_glance'](
                 o_path[0], 'ami', 'kernel_id=' + object_id['kernel'] +
                 ' ramdisk_id=' + object_id['ramdisk'], image_name=ami_name)
        return image_id
    return False

def _chroot_exec(chroot_path, command):
    return __salt__['cmd.run_all']('chroot ' + chroot_path + ' ' + command)

def _print_if_error(ret):
    if ret['retcode'] != 0:
        log.error(ret['stderr'])

def _find_objects(path, substring):
    object_names = [element for element in listdir(path)
            if substring in element]
    return [path + '/' + element for element in object_names]