<commit_before>from lazy import lazy
from mr.awsome.common import BaseMaster
from mr.awsome.config import BooleanMassager, PathMassager
from mr.awsome.config import expand_path
from mr.awsome.plain import Instance as PlainInstance
import logging
import os
import re
import subprocess
import shlex
import sys
import time


log = logging.getLogger('mr.awsome.virtualbox')


class VirtualBoxError(Exception):
    pass


class Instance(PlainInstance):
    sectiongroupname = 'vb-instance'

    @lazy
    def _vmbasefolder(self):
        folder = self.config.get('basefolder')
        if folder is None:
            folder = self.master.master_config.get('basefolder')
        if folder is None:
            folder = self.vb.list.systemproperties().get('Default machine folder')
        if folder is None:
            raise VirtualBoxError("No basefolder configured for VM '%s'." % self.id)
        return folder

    @lazy
    def _vmfolder(self):
        return os.path.join(self._vmbasefolder, self.id)

    @lazy
    def vb(self):
        import vbox
        return vbox.pyVb.VirtualBox().cli.manage

    def _vminfo(self, group=None):
        info = self.vb.showvminfo(self.id)
        info = dict(self.vb.cli.util.parseMachineReadableFmt(info))
        if group is None:
            return info
        result = {}
        matcher = re.compile('%s(\D+)(\d+)' % group)
        for key, value in info.items():
            m = matcher.match(key)
            if m:
                name, index = m.groups()
                d = result.setdefault(index, {})
                d[name] = value
                if name == 'name':
                    result[value] = d
        for key in list(result):
            if key != result[key]['name']:
                del result[key]
        return result

    @property
    def _vmacpi(self):
        acpi = self.config.get('use-acpi-powerbutton')
        if acpi is None:
            acpi = self.master.master_config.get('use-acpi-powerbutton')
        if acpi is None:
            acpi = self._vminfo().get('acpi', '').lower() == 'on'
        return acpi

    @property
    def _vmheadless(self):
        acpi = self.config.get('headless')
        if acpi is None:
            acpi = self.master.master_config.get('headless', False)
        return acpi

    def _status(self, vms=None):
        if vms is None:
            vms = self.vb.list.vms()
        if self.id not in vms:
            return 'unavailable'
        status = self._vminfo()['VMState']
        if status == 'running':
            return 'running'
        elif status == 'poweroff':
            return 'stopped'
        raise VirtualBoxError("Don't know how to handle VM '%s' in state '%s'" % (self.id, status))

    def get_massagers(self):
        return get_instance_massagers()

    def get_host(self):
        raise NotImplementedError

    def status(self):
        vms = self.vb.list.vms()
        status = self._status(vms)
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status != 'running':
            log.info("Instance state: %s", status)
            return
        log.info("Instance running.")

    def stop(self):
        status = self._status()
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status != 'running':
            log.info("Instance state: %s", status)
            log.info("Instance not stopped")
            return
        log.info("Stopping instance '%s'", self.id)
        if self._vmacpi:
            log.info('Trying to stop instance with ACPI:')
            self.vb.controlvm(self.id, 'acpipowerbutton')
            count = 60
            while count > 0:
                status = self._status()
                sys.stdout.write('%3d\r' % count)
                sys.stdout.flush()
                time.sleep(1)
                count -= 1
                if status == 'stopped':
                    print
                    log.info("Instance stopped")
                    return
        print
        log.info("Stopping instance by sending 'poweroff'.")
        self.vb.controlvm(self.id, 'poweroff')
        log.info("Instance stopped")

    def terminate(self):
        status = self._status()
        if self.config.get('no-terminate', False):
            log.error("Instance '%s' is configured not to be terminated.", self.id)
            return
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status == 'running':
            log.info("Stopping instance '%s'", self.id)
            self.vb.controlvm(self.id, 'poweroff')
        if status != 'stopped':
            log.info('Waiting for instance to stop')
            while status != 'stopped':
                status = self._status()
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(1)
            print
        log.info("Terminating instance '%s'", self.id)
        self.vb.unregistervm(self.id, delete=True)
        log.info("Instance terminated")

    def start(self, overrides=None):
        config = self.get_config(overrides)
        status = self._status()
        if status == 'unavailable':
            log.info("Creating instance '%s'", self.id)
            try:
                self.vb.createvm(
                    name=self.id, basefolder=self._vmbasefolder, register=True)
            except subprocess.CalledProcessError as e:
                log.error("Failed to create VM '%s':\n%s" % (self.id, e))
                sys.exit(1)
            status = self._status()
        if status != 'stopped':
            log.info("Instance state: %s", status)
            log.info("Instance already started")
            return True
        # modify vm
        args = []
        for key, value in config.items():
            if not key.startswith('vm-'):
                continue
            args.extend(("--%s" % key[3:], value))<commit_msg>Set ostype when creating the vm, it doesn't work properly when changing with modifyvm.<commit_after>from lazy import lazy
from mr.awsome.common import BaseMaster
from mr.awsome.config import BooleanMassager, PathMassager
from mr.awsome.config import expand_path
from mr.awsome.plain import Instance as PlainInstance
import logging
import os
import re
import subprocess
import shlex
import sys
import time


log = logging.getLogger('mr.awsome.virtualbox')


class VirtualBoxError(Exception):
    pass


class Instance(PlainInstance):
    sectiongroupname = 'vb-instance'

    @lazy
    def _vmbasefolder(self):
        folder = self.config.get('basefolder')
        if folder is None:
            folder = self.master.master_config.get('basefolder')
        if folder is None:
            folder = self.vb.list.systemproperties().get('Default machine folder')
        if folder is None:
            raise VirtualBoxError("No basefolder configured for VM '%s'." % self.id)
        return folder

    @lazy
    def _vmfolder(self):
        return os.path.join(self._vmbasefolder, self.id)

    @lazy
    def vb(self):
        import vbox
        return vbox.pyVb.VirtualBox().cli.manage

    def _vminfo(self, group=None):
        info = self.vb.showvminfo(self.id)
        info = dict(self.vb.cli.util.parseMachineReadableFmt(info))
        if group is None:
            return info
        result = {}
        matcher = re.compile('%s(\D+)(\d+)' % group)
        for key, value in info.items():
            m = matcher.match(key)
            if m:
                name, index = m.groups()
                d = result.setdefault(index, {})
                d[name] = value
                if name == 'name':
                    result[value] = d
        for key in list(result):
            if key != result[key]['name']:
                del result[key]
        return result

    @property
    def _vmacpi(self):
        acpi = self.config.get('use-acpi-powerbutton')
        if acpi is None:
            acpi = self.master.master_config.get('use-acpi-powerbutton')
        if acpi is None:
            acpi = self._vminfo().get('acpi', '').lower() == 'on'
        return acpi

    @property
    def _vmheadless(self):
        acpi = self.config.get('headless')
        if acpi is None:
            acpi = self.master.master_config.get('headless', False)
        return acpi

    def _status(self, vms=None):
        if vms is None:
            vms = self.vb.list.vms()
        if self.id not in vms:
            return 'unavailable'
        status = self._vminfo()['VMState']
        if status == 'running':
            return 'running'
        elif status == 'poweroff':
            return 'stopped'
        raise VirtualBoxError("Don't know how to handle VM '%s' in state '%s'" % (self.id, status))

    def get_massagers(self):
        return get_instance_massagers()

    def get_host(self):
        raise NotImplementedError

    def status(self):
        vms = self.vb.list.vms()
        status = self._status(vms)
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status != 'running':
            log.info("Instance state: %s", status)
            return
        log.info("Instance running.")

    def stop(self):
        status = self._status()
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status != 'running':
            log.info("Instance state: %s", status)
            log.info("Instance not stopped")
            return
        log.info("Stopping instance '%s'", self.id)
        if self._vmacpi:
            log.info('Trying to stop instance with ACPI:')
            self.vb.controlvm(self.id, 'acpipowerbutton')
            count = 60
            while count > 0:
                status = self._status()
                sys.stdout.write('%3d\r' % count)
                sys.stdout.flush()
                time.sleep(1)
                count -= 1
                if status == 'stopped':
                    print
                    log.info("Instance stopped")
                    return
        print
        log.info("Stopping instance by sending 'poweroff'.")
        self.vb.controlvm(self.id, 'poweroff')
        log.info("Instance stopped")

    def terminate(self):
        status = self._status()
        if self.config.get('no-terminate', False):
            log.error("Instance '%s' is configured not to be terminated.", self.id)
            return
        if status == 'unavailable':
            log.info("Instance '%s' unavailable", self.id)
            return
        if status == 'running':
            log.info("Stopping instance '%s'", self.id)
            self.vb.controlvm(self.id, 'poweroff')
        if status != 'stopped':
            log.info('Waiting for instance to stop')
            while status != 'stopped':
                status = self._status()
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(1)
            print
        log.info("Terminating instance '%s'", self.id)
        self.vb.unregistervm(self.id, delete=True)
        log.info("Instance terminated")

    def start(self, overrides=None):
        config = self.get_config(overrides)
        status = self._status()
        if status == 'unavailable':
            log.info("Creating instance '%s'", self.id)
            try:
                self.vb.createvm(
                    name=self.id, basefolder=self._vmbasefolder,
                    ostype=config.get('vm-ostype'), register=True)
            except subprocess.CalledProcessError as e:
                log.error("Failed to create VM '%s':\n%s" % (self.id, e))
                sys.exit(1)
            status = self._status()
        if status != 'stopped':
            log.info("Instance state: %s", status)
            log.info("Instance already started")
            return True
        # modify vm
        args = []
        for key, value in config.items():
            if not key.startswith('vm-'):
                continue
            args.extend(("--%s" % key[3:], value))
{'fraction_non_alphanumeric': 0.11775823814610896, 'fraction_numerical': 0.001479168378667105, 'mean_word_length': 1.778538812785388, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3606678', 'n_tokens_mistral': 3490, 'n_tokens_neox': 3395, 'n_words': 883}