Example #1
0
 def _add_box(path, name):
     box = h.VagrantBox(name, path=path)
     logger.info("Adding vagrant box '{}'".format(name))
     h.Vagrant().box("add --provider virtualbox --name", box.name,
                     '--force', "'{}'".format(box.path))
     return box
Example #2
0
    def vagrant_box(request, base_env, project_path):
        def _get_user_vars():
            res = {'base_env': base_env}

            if env_level == 'base':
                p_machine = request.getfixturevalue('vbox_seed_machine')
                res['seed_vm_name'] = p_machine.name
            else:
                env_spec = ENV_LEVELS_HIERARCHY[env_level]
                if type(env_spec) is dict:
                    p_env = env_spec['parent']
                    # add pytest session level vars from config
                    for vname in env_spec.get('vars', []):
                        res[vname] = request.config.getoption(vname)
                else:
                    p_env = env_spec

                if type(p_env) is not str:
                    raise RuntimeError("{} is not a string: {}".format(
                        type(p_env), p_env))

                p_box = request.getfixturevalue("vagrant_box_{}".format(
                    env_fixture_suffix(os_name, p_env)))
                res['parent_source'] = res['parent_box_name'] = p_box.name
                res['skip_add'] = 'true'

            return res

        def _check_box_added(box_name):
            vagrant_rows = h.Vagrant().box("list", parse=True)
            for row in vagrant_rows:
                if (row.data_type == 'box-name') and (row.data[0] == box_name):
                    return True
            return False

        def _add_box(path, name):
            box = h.VagrantBox(name, path=path)
            logger.info("Adding vagrant box '{}'".format(name))
            h.Vagrant().box("add --provider virtualbox --name", box.name,
                            '--force', "'{}'".format(box.path))
            return box

        user_vars = _get_user_vars()

        # TODO separator ???
        box_name = '_'.join([VAGRANT_VMS_PREFIX, base_env, env_level])
        box_path = (project_path / '.boxes' / base_env / env_level /
                    'package.box')

        # TODO for now always rebuild the base box if box file is missed
        #  until smarter logic of boxes rebuild is implemented,
        #  should be triggered when any of the following is true:
        #  - parent env is changed
        #  - input user variables set is changed
        #  - provisioning scripts and other related sources are changed
        if _check_box_added(box_name) and False:
            logger.info("Vagrant box for env '{}:{}' already added".format(
                base_env, env_level))
            # TODO ??? do not specify package.box here since we don't
            # know whether it exists or not and how it is really related
            # to the box
            return h.VagrantBox(box_name)

        if not box_path.exists():
            pf_name = "packer.{}.json".format(env_level)
            packerfile = project_path / 'images' / 'vagrant' / pf_name
            packer = h.Packer(packerfile)

            logger.info("Building vagrant env '{}' for base env '{}'".format(
                env_level, base_env))
            # TODO pytest options to turn on packer debug
            packer.build('--force {}'.format(' '.join(
                ['-var {}={}'.format(k, v) for k, v in user_vars.items()])))

        if not box_path.exists():
            raise RuntimeError(
                "Vagrant box file {} hasn't been created".format(box_path))

        return _add_box(box_path, box_name)