reserve_g5k.py 3.91 KB
Newer Older
1 2 3 4 5
#!/usr/bin/env python
import yaml


class G5kReservation:
6 7
    def _g5k_deploy(self, g5k_config, force_deploy=False, discover=True):
        from enoslib.api import discover_networks
8
        from enoslib.infra.enos_g5k.provider import G5k
9
        from enoslib.infra.enos_g5k.configuration import Configuration
Maverick Chardet's avatar
Maverick Chardet committed
10 11
        self._g5k_job = G5k(Configuration.from_dictionnary(g5k_config))
        self._roles, self._networks = self._g5k_job.init(force_deploy=force_deploy)
12 13
        if discover:
            discover_networks(self._roles, self._networks)
Maverick Chardet's avatar
Maverick Chardet committed
14 15
        # logging.info('Wait 30 seconds for iface to be ready...')
        # time.sleep(30)
16

17
    def _allocate(self, conf, force_deployment=False, discover_networks=True):
18 19 20 21 22 23 24 25 26
        if isinstance(conf, str):
            with open(conf) as f:
                config = yaml.load(f)
        elif isinstance(conf, dict):
            config = conf
        else:
            raise Exception(
                'conf is type {!r} while it should be a yaml file or a dict'.format(type(conf)))

Maverick Chardet's avatar
Maverick Chardet committed
27
        self._config = config
28 29

        # Claim resources on Grid'5000
Maverick Chardet's avatar
Maverick Chardet committed
30 31
        if 'g5k' not in config:
            raise Exception("'g5k' key missing in configuration!")
32
        self._g5k_deploy(config['g5k'], force_deploy=force_deployment, discover=discover_networks)
33

Maverick Chardet's avatar
Maverick Chardet committed
34 35 36 37 38
    def generate_inventory(self, path):
        from enoslib.api import generate_inventory as el_generate_inventory
        el_generate_inventory(self._roles, self._networks, path)
        self._inventory_path = path

39 40 41 42 43 44 45 46 47 48
    @staticmethod
    def _get_ip(g5k_address):
        from subprocess import run, PIPE
        ip = run("dig +short %s" % g5k_address, shell=True, stdout=PIPE).stdout.decode('utf-8').strip(' \r\n')
        return ip

    @staticmethod
    def _get_host_dict(g5k_address):
        return {"address": g5k_address, "ip": G5kReservation._get_ip(g5k_address)}

Maverick Chardet's avatar
Maverick Chardet committed
49
    def __init__(self, conf, force_deployment=True, destroy=False, discover_networks=True, inventory_path=None):
Maverick Chardet's avatar
Maverick Chardet committed
50 51 52 53
        self._config = None
        self._g5k_job = None
        self._roles = None
        self._networks = None
54
        self._destroy = destroy
55
        self._allocate(conf, force_deployment, discover_networks)
56
        self._alive = True
Maverick Chardet's avatar
Maverick Chardet committed
57
        self._inventory_path = inventory_path
58 59 60 61

    def get_roles(self):
        if not self._alive:
            raise Exception("G5k reservation not alive!")
Maverick Chardet's avatar
Maverick Chardet committed
62
        return self._roles.keys()
63 64 65 66

    def get_hosts_info(self, role):
        if not self._alive:
            raise Exception("G5k reservation not alive!")
Maverick Chardet's avatar
Maverick Chardet committed
67
        return [G5kReservation._get_host_dict(host.address) for host in self._roles[role]]
68 69 70 71 72 73 74 75

    def terminate(self):
        if not self._alive:
            raise Exception("G5k reservation not alive!")
        if self._destroy:
            self._g5k_job.destroy()
        self._alive = False

76 77 78 79 80 81 82 83 84
    def ansible_to(self, pattern_hosts="all"):
        """
        Args:
            pattern_hosts (str): pattern to describe ansible hosts to target.
                see https://docs.ansible.com/ansible/latest/intro_patterns.html
        """
        from enoslib.api import play_on
        return play_on(roles=self._roles, pattern_hosts=pattern_hosts)

85 86 87
    def run_ansible(
            self,
            playbooks,
Maverick Chardet's avatar
Maverick Chardet committed
88
            inventory_path_override=None,
89 90 91 92 93 94
            extra_vars=None,
            tags=None,
            on_error_continue=False,
            basedir="."
    ):
        from enoslib.api import run_ansible as enoslib_run_ansible
Maverick Chardet's avatar
Maverick Chardet committed
95
        inventory_path = inventory_path_override if inventory_path_override else self._inventory_path
96 97 98 99 100 101 102 103 104 105
        enoslib_run_ansible(
            playbooks,
            inventory_path=inventory_path,
            roles=self._roles,
            extra_vars=extra_vars,
            tags=tags,
            on_error_continue=on_error_continue,
            basedir=basedir
        )

106 107 108 109 110 111
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self._alive:
            self.terminate()