Beispiel #1
0
class UCSInstallation(object):
    def __init__(self, args):
        # see https://github.com/tesseract-ocr/tesseract/issues/2611
        os.environ['OMP_THREAD_LIMIT'] = '1'
        init_logger('info')
        self.args = args
        self.config = OCRConfig()
        self.config.update(lang=self.args.language)
        self.timeout = 120
        self.setup_finish_sleep = 900
        self.connect()

    def _clear_input(self):
        self.client.keyPress('end')
        time.sleep(0.1)
        for i in range(100):
            self.client.keyPress('bsp')
            time.sleep(0.1)

    def screenshot(self, filename):
        if not os.path.isdir(self.args.screenshot_dir):
            os.mkdir(self.args.screenshot_dir)
        screenshot_file = os.path.join(self.args.screenshot_dir, filename)
        self.client.captureScreen(screenshot_file)

    def click(self, text):
        self.client.waitForText(text, timeout=self.timeout)
        self.client.mouseClickOnText(text)

    def connect(self):
        self.conn = VNCConnection(self.args.vnc)
        self.client = self.conn.__enter__()
        self.client.updateOCRConfig(self.config)

    def text_is_visible(self, text, timeout=120):
        try:
            self.client.waitForText(text, timeout=timeout)
            return True
        except VNCDoException:
            self.connect()
            return False

    def move_to_next_and_click(self):
        time.sleep(1)
        self.client.mouseMove(910, 700)
        time.sleep(1)
        logging.info('clicking next')
        self.client.mousePress(1)

    def installer(self):
        # language
        for i in range(3):
            self.client.waitForText('Select a language',
                                    timeout=self.timeout + 120,
                                    prevent_screen_saver=True)
            self.client.enterText(self._['english_language_name'])
            self.click('Continue')
            try:
                self.client.waitForText(self._['select_location'],
                                        timeout=self.timeout)
                break
            except VNCDoException:
                self.connect()
                self.click('Go Back')
        self.client.enterText(self._['location'])
        self.client.keyPress('enter')
        self.client.waitForText(self._['select_keyboard'],
                                timeout=self.timeout)
        self.client.enterText(self._['us_keyboard_layout'])
        self.client.keyPress('enter')

        if not self.network_setup():
            self.client.mouseMove(100, 320)
            self.client.mousePress(1)
            time.sleep(1)

        # root
        self.client.waitForText(self._['user_and_password'],
                                timeout=self.timeout)
        self.client.enterText(self.args.password)
        self.client.keyPress('tab')
        self.client.keyPress('tab')
        self.client.enterText(self.args.password)
        self.client.keyPress('enter')
        if self.args.language == 'eng':
            self.client.waitForText(self._['configure_clock'],
                                    timeout=self.timeout)
            #self.client.enterText(self._['clock'])
            time.sleep(1)
            self.client.keyPress('enter')
        # hd
        time.sleep(60)
        self.client.waitForText(self._['partition_disks'],
                                timeout=self.timeout)
        if self.args.role == 'applianceLVM':
            self.click(self._['entire_disk_with_lvm'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('enter')
            self.click(self._['all_files_on_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('down')
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
        elif self.args.role == 'applianceEC2':
            # Manuel
            self.click(self._['manual'])
            self.client.keyPress('enter')
            time.sleep(3)
            # Virtuelle Festplatte 1
            self.click(self._['virtual_disk_1'])
            time.sleep(3)
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('down')
            time.sleep(3)
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['free_space'])
            self.client.keyPress('enter')
            time.sleep(3)
            # neue partition erstellen
            self.client.keyPress('enter')
            time.sleep(3)
            # enter: ganze festplattengröße ist eingetragen
            self.client.keyPress('enter')
            time.sleep(3)
            # enter: primär
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['boot_flag'])
            # enter: boot-flag aktivieren
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['finish_create_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['finish_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            # Nein (kein swap speicher)
            self.click(self._['no'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
            self.client.keyPress('enter')
        else:
            self.click(self._['entire_disk'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('enter')
            self.click(self._['finish_partition'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
        time.sleep(600)
        self.client.waitForText(self._['finish_installation'], timeout=1300)
        self.client.keyPress('enter')
        time.sleep(30)

    def network_setup(self):
        time.sleep(60)
        # we may not see this because the only interface is configured via dhcp
        if not self.text_is_visible(self._['configure_network'], timeout=120):
            return False
        self.client.waitForText(self._['configure_network'],
                                timeout=self.timeout)
        if not self.text_is_visible(self._['ip_address'],
                                    timeout=self.timeout):
            # always use first interface
            self.click(self._['continue'])
            time.sleep(60)
        if self.args.ip:
            if self.text_is_visible(self._['not_using_dhcp'],
                                    timeout=self.timeout):
                self.client.waitForText(self._['not_using_dhcp'],
                                        timeout=self.timeout)
                self.client.keyPress('enter')
                self.client.waitForText(self._['manual_network_config'],
                                        timeout=self.timeout)
                self.client.mouseClickOnText(self._['manual_network_config'])
                self.client.keyPress('enter')
            self.client.waitForText(self._['ip_address'], timeout=self.timeout)
            self.client.enterText(self.args.ip)
            self.client.keyPress('enter')
            self.client.waitForText(self._['netmask'], timeout=self.timeout)
            if self.args.netmask:
                self.client.enterText(self.args.netmask)
            self.client.keyPress('enter')
            self.client.waitForText(self._['gateway'], timeout=self.timeout)
            if self.args.gateway:
                self.client.enterText(self.args.gateway)
            self.client.keyPress('enter')
            self.client.waitForText(self._['name_server'],
                                    timeout=self.timeout)
            if self.args.dns:
                self.client.enterText(self.args.dns)
            self.client.keyPress('enter')
        return True

    def configure_kvm_network(self):
        if 'all' in self.args.components or 'kde' in self.args.components:
            time.sleep(10)
            self.client.keyDown('alt')
            self.client.keyDown('ctrl')
            self.client.keyPress('f1')
            self.client.keyUp('alt')
            self.client.keyUp('ctrl')
        elif self.args.role == 'basesystem':
            time.sleep(3)
        else:
            self.client.waitForText('corporate server')
            self.client.keyPress('enter')
        time.sleep(3)
        self.client.enterText('root')
        self.client.keyPress('enter')
        time.sleep(5)
        self.client.enterText(self.args.password)
        self.client.keyPress('enter')
        self.client.enterText('ucr set interfaces-ens6-tzpe`manual')
        self.client.keyPress('enter')
        time.sleep(30)
        self.client.enterText('ifconfig ens6 up')
        self.client.keyPress('enter')
        self.client.enterText('echo ')
        self.client.keyDown('shift')
        self.client.enterText('2')  # @
        self.client.keyUp('shift')
        self.client.enterText('reboot -sbin-ifconfig ens6 up ')
        self.client.keyDown('shift')
        self.client.enterText("'")  # |
        self.client.keyUp('shift')
        self.client.enterText(' crontab')
        self.client.keyPress('enter')

    def setup(self):
        self.client.waitForText(self._['domain_setup'],
                                timeout=self.timeout + 900)
        if self.args.role == 'master':
            self.click(self._['new_domain'])
            self.move_to_next_and_click()
            self.client.waitForText(self._['account_information'],
                                    timeout=self.timeout)
            self.client.enterText('home')
            self.move_to_next_and_click()
        elif self.args.role in ['slave', 'backup', 'member']:
            self.click(self._['join_domain'])
            self.move_to_next_and_click()
            if self.text_is_visible(self._['no_dc_dns']):
                self.client.keyPress('enter')
                self.click(self._['preferred_dns'])
                self.client.enterText(self.args.dns)
                self.client.keyPress('enter')
                time.sleep(120)
                if self.text_is_visible(self._['repositories_not_reachable']):
                    self.client.keyPress('enter')
                    time.sleep(30)
                self.click(self._['join_domain'])
                self.move_to_next_and_click()
            self.client.waitForText(self._['role'])
            if self.args.role == 'backup':
                self.click('Backup Directory Node')
                self.move_to_next_and_click()
            if self.args.role == 'slave':
                self.click('Replica Directory Node')
                self.move_to_next_and_click()
            if self.args.role == 'member':
                self.click('Managed Node')
                self.move_to_next_and_click()
        elif self.args.role == 'admember':
            self.click(self._['ad_domain'])
            self.move_to_next_and_click()
            self.client.waitForText(self._['no_dc_dns'], timeout=self.timeout)
            self.client.keyPress('enter')
            self.click(self._['preferred_dns'])
            time.sleep(1)
            self.client.enterText(self.args.dns)
            self.client.keyPress('enter')
            time.sleep(120)
            if self.text_is_visible(self._['repositories_not_reachable']):
                self.client.keyPress('enter')
                time.sleep(30)
            if self.text_is_visible('APIPA', timeout=self.timeout):
                self.client.keyPress('enter')
                time.sleep(60)
            self.move_to_next_and_click()
            self.move_to_next_and_click()
        elif self.args.role == 'basesystem':
            self.click(self._['no_domain'])
            self.click(self._['next'])
            self.client.waitForText(self._['warning_no_domain'],
                                    timeout=self.timeout)
            self.click(self._['next'])
        elif self.args.role == 'applianceEC2' or self.args.role == 'applianceLVM':
            self.client.keyDown('ctrl')
            self.client.keyPress('q')
            self.client.keyUp('ctrl')
            time.sleep(60)
            sys.exit(0)
        else:
            raise NotImplementedError

    def joinpass(self):
        if self.args.role not in ['slave', 'backup', 'member']:
            return
        self.client.waitForText(self._['start_join'], timeout=self.timeout)
        for i in range(2):
            self.click(self._['hostname_primary'])
            self.client.keyPress('tab')
            self._clear_input()
            self.client.enterText(self.args.join_user)
            self.client.keyPress('tab')
            self._clear_input()
            self.client.enterText(self.args.join_password)
            self.move_to_next_and_click()
            try:
                self.client.waitForText(self._['error'], timeout=self.timeout)
                self.client.keyPress('enter')
                self.client.keyPress('caplk')
            except VNCDoException:
                self.connect()
                break

    def joinpass_ad(self):
        if self.args.role not in ['admember']:
            return
        # join/ad password and user
        self.client.waitForText(self._['ad_account_information'],
                                timeout=self.timeout)
        for i in range(2):
            self.click(self._['address_ad'])
            self.client.keyPress('tab')
            self._clear_input()
            self.client.enterText(self.args.join_user)
            self.client.keyPress('tab')
            self._clear_input()
            self.client.enterText(self.args.join_password)
            self.move_to_next_and_click()
            try:
                self.client.waitForText(self._['error'], timeout=self.timeout)
                self.client.keyPress('enter')
                self.client.keyPress('caplk')
            except VNCDoException:
                self.connect()
                break

    def hostname(self):
        # name hostname
        if self.args.role == 'master':
            self.client.waitForText(self._['host_settings'],
                                    timeout=self.timeout)
        else:
            self.client.waitForText(self._['system_name'])
        self._clear_input()
        self.client.enterText(self.args.fqdn)
        if self.args.role == 'master':
            self.client.keyPress('tab')
        self.move_to_next_and_click()

    def finish(self):
        self.client.waitForText(self._['confirm_config'], timeout=self.timeout)
        self.client.keyPress('enter')
        time.sleep(self.setup_finish_sleep)
        self.client.waitForText(self._['setup_successful'], timeout=2100)
        self.client.keyPress('tab')
        self.client.keyPress('enter')
        time.sleep(10)
        self.client.waitForText('univention', timeout=self.timeout)

    def ucsschool(self):
        # ucs@school role
        if self.args.school_dep:
            self.client.waitForText(self._['school_role'],
                                    timeout=self.timeout)
            if self.args.school_dep == 'adm':
                self.click(self._['school_adm'])
            elif self.args.school_dep == 'edu':
                self.click(self._['school_edu'])
            elif self.args.school_dep == 'central':
                self.click(self._['school_central'])
            else:
                raise NotImplementedError()
            self.click(self._['next'])

    def bootmenu(self):
        if self.text_is_visible('Univention Corporate Server Installer',
                                timeout=120):
            if self.args.ip:
                self.client.keyPress('down')
            self.client.keyPress('enter')

    def installation(self):
        if self.args.language == 'eng':
            self._ = english.strings
        elif self.args.language == 'fra':
            self._ = french.strings
        else:
            self._ = german.strings

        try:
            self.bootmenu()
            self.installer()
            self.setup()
            self.joinpass_ad()
            self.joinpass()
            self.hostname()
            self.ucsschool()
            self.finish()
            if not self.args.no_second_interface:
                # TODO activate ens6 so that ucs-kvm-create can connect to instance
                # this is done via login and setting interfaces/eth0/type, is there a better way?
                self.configure_kvm_network()
        except Exception:
            self.connect()
            self.screenshot('error.png')
            raise
Beispiel #2
0
class UCSInstallation(object):
    def __init__(self, args):
        init_logger('info')
        self.args = args
        self.config = OCRConfig()
        self.config.update(lang=self.args.language)
        self.timeout = 60
        self.connect()

    def screenshot(self, filename):
        if not os.path.isdir(self.args.screenshot_dir):
            os.mkdir(self.args.screenshot_dir)
        screenshot_file = os.path.join(self.args.screenshot_dir, filename)
        self.client.captureScreen(screenshot_file)

    def click(self, text):
        self.client.waitForText(text, timeout=self.timeout)
        self.client.mouseClickOnText(text)

    def connect(self):
        self.conn = VNCConnection(self.args.vnc)
        self.client = self.conn.__enter__()
        self.client.updateOCRConfig(self.config)

    def text_is_visible(self, text, timeout=30):
        try:
            self.client.waitForText(text, timeout=timeout)
            return True
        except VNCDoException:
            self.connect()
            return False

    def installer(self):
        # language
        self.client.waitForText('Select a language',
                                timeout=self.timeout,
                                prevent_screen_saver=True)
        self.client.enterText(self._['english_language_name'])
        self.click('Continue')
        self.client.waitForText(self._['select_location'],
                                timeout=self.timeout)
        self.client.enterText(self._['location'])
        self.client.keyPress('enter')
        self.client.waitForText(self._['select_keyboard'],
                                timeout=self.timeout)
        self.client.enterText(self._['us_keyboard_layout'])
        self.client.keyPress('enter')

        self.network_setup()

        # root
        self.client.waitForText(self._['user_and_password'],
                                timeout=self.timeout)
        self.client.enterText(self.args.password)
        self.client.keyPress('tab')
        self.client.keyPress('tab')
        self.client.enterText(self.args.password)
        self.client.keyPress('enter')
        if self.args.language == 'eng':
            self.client.waitForText(self._['configure_clock'],
                                    timeout=self.timeout)
            self.client.enterText(self._['clock'])
            self.client.keyPress('enter')
        # hd
        time.sleep(60)
        self.client.waitForText(self._['partition_disks'],
                                timeout=self.timeout)
        if self.args.role == 'applianceLVM':
            self.click(self._['entire_disk_with_lvm'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('enter')
            self.click(self._['all_files_on_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('down')
            self.client.keyPress('enter')
            self.click(self._['finish_partition'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
        elif self.args.role == 'applianceEC2':
            # Manuel
            self.click(self._['manual'])
            self.client.keyPress('enter')
            time.sleep(3)
            # Virtuelle Festplatte 1
            self.click(self._['virtual_disk_1'])
            time.sleep(3)
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('down')
            time.sleep(3)
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['free_space'])
            self.client.keyPress('enter')
            time.sleep(3)
            # neue partition erstellen
            self.client.keyPress('enter')
            time.sleep(3)
            # enter: ganze festplattengröße ist eingetragen
            self.client.keyPress('enter')
            time.sleep(3)
            # enter: primär
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['boot_flag'])
            # enter: boot-flag aktivieren
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['finish_create_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.click(self._['finish_partition'])
            self.client.keyPress('enter')
            time.sleep(3)
            # Nein (kein swap speicher)
            self.click(self._['no'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
            self.client.keyPress('enter')
        else:
            self.click(self._['entire_disk'])
            self.client.keyPress('enter')
            time.sleep(3)
            self.client.keyPress('enter')
            self.click(self._['all_files_on_partition'])
            self.client.keyPress('enter')
            self.click(self._['finish_partition'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['continue_partition'],
                                    timeout=self.timeout)
            self.client.keyPress('down')
            self.client.keyPress('enter')
        time.sleep(600)

    def network_setup(self):
        time.sleep(60)
        self.client.waitForText(self._['configure_network'],
                                timeout=self.timeout)
        # always use first interface
        self.click(self._['continue'])
        time.sleep(60)
        if self.args.ip:
            self.client.waitForText(self._['not_using_dhcp'],
                                    timeout=self.timeout)
            self.client.keyPress('enter')

            self.client.waitForText(self._['manual_network_config'],
                                    timeout=self.timeout)
            self.client.mouseClickOnText(self._['manual_network_config'])
            self.client.keyPress('enter')
            self.client.waitForText(self._['ip_address'], timeout=self.timeout)
            self.client.enterText(self.args.ip)
            self.client.keyPress('enter')

            self.client.waitForText(self._['netmask'], timeout=self.timeout)
            self.client.keyPress('enter')

            self.client.waitForText(self._['gateway'], timeout=self.timeout)
            self.client.keyPress('enter')

            self.client.waitForText(self._['name_server'],
                                    timeout=self.timeout)
            if self.args.dns:
                self.client.enterText(self.args.dns)
            self.client.keyPress('enter')

    def configure_kvm_network(self):
        if 'all' in self.args.components or 'kde' in self.args.components:
            time.sleep(10)
            self.client.keyDown('alt')
            self.client.keyDown('ctrl')
            self.client.keyPress('f1')
            self.client.keyUp('alt')
            self.client.keyUp('ctrl')
        elif self.args.role == 'basesystem':
            time.sleep(3)
        else:
            self.client.waitForText('corporate server')
            self.client.keyPress('enter')
        time.sleep(3)
        self.client.enterText('root')
        self.client.keyPress('enter')
        time.sleep(5)
        self.client.enterText(self.args.password)
        self.client.keyPress('enter')
        self.client.enterText('ifconfig ens6 up')
        self.client.keyPress('enter')
        self.client.enterText('echo ')
        self.client.keyDown('shift')
        self.client.enterText('2')  # @
        self.client.keyUp('shift')
        self.client.enterText('reboot -sbin-ifconfig ens6 up ')
        self.client.keyDown('shift')
        self.client.enterText("'")  # |
        self.client.keyUp('shift')
        self.client.enterText(' crontab')
        self.client.keyPress('enter')

    def setup(self):
        self.client.waitForText(self._['domain_setup'], timeout=self.timeout)
        if self.args.role == 'master':
            self.click(self._['new_domain'])
            self.click(self._['next'])
            self.client.waitForText(self._['account_information'],
                                    timeout=self.timeout)
            self.client.enterText('home')
            self.click(self._['next'])
        elif self.args.role in ['slave', 'backup', 'member']:
            self.click(self._['join_domain'])
            self.click(self._['next'])
            self.client.waitForText(self._['no_dc_dns'])
            self.click(self._['no_dc_dns_adapt'])
            self.click(self._['preferred_dns'])
            self.client.enterText(self.args.dns)
            self.client.keyPress('enter')
            time.sleep(120)
            if self.text_is_visible(self._['repositories_not_reachable']):
                self.client.keyPress('enter')
                time.sleep(30)
            self.click(self._['join_domain'])
            self.click(self._['next'])
            time.sleep(10)
            if self.args.role == 'backup':
                self.click(self._['next'])
            if self.args.role == 'slave':
                self.client.keyPress('down')
                self.click(self._['next'])
            if self.args.role == 'member':
                self.client.keyPress('down')
                self.client.keyPress('down')
                self.click(self._['next'])
            self.client.waitForText(self._['start_join'], timeout=self.timeout)
            self.client.keyPress('tab')
            self.client.keyPress('tab')
            self.client.enterText(self.args.join_user)
            self.client.keyPress('tab')
            self.client.enterText(self.args.join_password)
            self.client.keyPress('enter')
        elif self.args.role == 'admember':
            self.click(self._['ad_domain'])
            self.click(self._['next'])
            self.client.waitForText(self._['no_dc_dns'], timeout=self.timeout)
            self.client.keyPress('enter')
            self.click(self._['preferred_dns'])
            self.client.enterText(self.args.dns)
            self.client.keyPress('enter')
            time.sleep(120)
            if self.text_is_visible(self._['repositories_not_reachable']):
                self.client.keyPress('enter')
                time.sleep(30)
            if self.text_is_visible('APIPA', timeout=self.timeout):
                self.client.keyPress('enter')
                time.sleep(60)
            self.click(self._['next'])
            self.client.waitForText(self._['ad_account_information'],
                                    timeout=self.timeout)
            self.client.keyPress('tab')
            self.client.enterText(self.args.join_user)
            self.client.keyPress('tab')
            self.client.enterText(self.args.join_password)
            self.click(self._['next'])
        elif self.args.role == 'basesystem':
            self.click(self._['no_domain'])
            self.click(self._['next'])
            self.client.waitForText(self._['warning_no_domain'],
                                    timeout=self.timeout)
            self.click(self._['next'])
        elif self.args.role == 'applianceEC2' or self.args.role == 'applianceLVM':
            self.client.keyDown('ctrl')
            self.client.keyPress('q')
            self.client.keyUp('ctrl')
            time.sleep(300)
            self.client.waitForText(self._['appliance_modus'],
                                    timeout=self.timeout)
            self.click(self._['continue'])
            time.sleep(60)
            sys.exit(0)
        else:
            raise NotImplemented

    def hostname(self):
        # name hostname
        if self.args.role == 'master':
            self.client.waitForText(self._['host_settings'],
                                    timeout=self.timeout)
        else:
            self.client.waitForText(self._['system_name'])
        self.client.keyPress('end')
        for i in range(1, 200):
            self.client.keyPress('bsp')
        self.client.enterText(self.args.fqdn)
        self.client.keyPress('tab')
        self.click(self._['next'])

    def finish(self):
        self.client.waitForText(self._['setup_successful'], timeout=2400)
        self.click(self._['finish'])
        time.sleep(200)

    def software_configuration(self):
        # software configuration
        if self.args.role != 'basesystem':
            if self.args.role == 'master':
                self.client.waitForText(self._['software_configuration'],
                                        timeout=self.timeout)
            else:
                self.client.waitForText(
                    self._['software_configuration_non_master'],
                    timeout=self.timeout)
            self.select_components()
            self.click(self._['next'])
        time.sleep(5)
        self.client.keyPress('enter')
        time.sleep(800)

    def select_components(self):
        # this is needed to make the down button work
        if 'all' in self.args.components:
            self.client.mouseMove(320, 215)
            self.client.mousePress(1)
        else:
            self.client.mouseMove(420, 270)
            self.client.mousePress(1)
            self.client.mousePress(1)
            for name, steps in components.iteritems():
                if name in self.args.components:
                    # go to the top
                    for step in range(1, 20):
                        self.client.keyPress('up')
                        time.sleep(0.2)
                    for step in range(1, steps):
                        self.client.keyPress('down')
                        time.sleep(0.2)
                    self.click(self._[name])

    def bootmenu(self):
        if self.text_is_visible('Univention Corporate Server Installer',
                                timeout=120):
            self.client.keyPress('enter')

    def installation(self):
        if self.args.language == 'eng':
            self._ = english.strings
        elif self.args.language == 'fra':
            self._ = french.strings
        else:
            self._ = german.strings

        try:
            self.bootmenu()
            self.installer()
            self.setup()
            self.hostname()
            self.software_configuration()
            self.finish()
            # TODO activate ens6 so that ucs-kvm-create can connect to instance
            # this is done via login and setting interfaces/eth0/type, is there a better way?
            self.configure_kvm_network()
        except Exception:
            self.connect()
            self.screenshot('error.png')
            raise
class UCSSetup(UCSInstallation):

	def __init__(self, args):
		init_logger('info')
		self.args = args
		self.config = OCRConfig()
		self.config.update(lang='eng')
		self.timeout = 40
		self.connect()

	def click(self, text):
		self.client.waitForText(text, timeout=self.timeout)
		self.client.mouseClickOnText(text)

	def screenshot(self, filename):
		if not os.path.isdir(self.args.screenshot_dir):
			os.mkdir(self.args.screenshot_dir)
		screenshot_file = os.path.join(self.args.screenshot_dir, filename)
		self.client.captureScreen(screenshot_file)

	def __next__(self):
		self.client.waitForText('NEXT', timeout=self.timeout)
		self.client.mouseClickOnText('NEXT')

	next = __next__  # Python 2

	def language(self, language):
		if self.text_is_visible('Notification', timeout=self.timeout):
			self.screenshot('notification.png')
			self.mouseClickOnText('OK')
		try:
			self.client.waitForText('English', timeout=self.timeout, prevent_screen_saver=True)
		except VNCDoException:
			self.connect()
		self.screenshot('language-setup.png')
		self.next()
		self.client.waitForText('Default system locale', timeout=self.timeout)
		self.next()

	def network(self):
		try:
			self.client.waitForText('IP address', timeout=self.timeout)
		except VNCDoException:
			self.connect()
			self.client.waitForText('Domain and network', timeout=self.timeout)
		self.screenshot('network-setup.png')
		if self.args.role in ['admember', 'slave']:
			self.click('Preferred DNS')
			self.client.enterText(self.args.dns)
		self.next()
		time.sleep(60)
		# check APIPA warning (automatic private address for eth0 if no dhcp answer)
		try:
			self.client.waitForText('APIPA', timeout=self.timeout)
			self.client.keyPress('enter')
			time.sleep(60)
		except VNCDoException:
			self.connect()
		try:
			self.client.waitForText('No gateway has been', timeout=self.timeout)
			self.client.keyPress('enter')
			time.sleep(60)
		except VNCDoException:
			self.connect()
		try:
			self.client.waitForText('continue without access', timeout=self.timeout)
			self.client.keyPress('enter')
			time.sleep(60)
		except VNCDoException:
			self.connect()
		time.sleep(120)

	def domain(self, role):
		text = 'Manage users and permissions'
		if self.args.ucs is True:
			text = 'Create a new UCS domain'
		if role == 'admember':
			text = 'Join into an existing Microsoft Active'
		elif role in ['join', 'slave']:
			text = 'Join into an existing UCS domain'
		elif role == 'fast':
			text = 'Fast demo'
		self.client.waitForText(text, timeout=self.timeout)
		self.client.mouseClickOnText(text, timeout=self.timeout)
		self.screenshot('domain-setup.png')
		self.next()
		time.sleep(10)
		if role == 'slave':
			self.client.keyPress('down')
			self.next()
			self.click('Username')
			self.client.enterText(self.args.join_user)
			self.click('Password')
			self.client.enterText(self.args.join_password)
			self.next()
		if role == 'admember':
			self.client.waitForText('Active Directory join', timeout=self.timeout)
			self.click('Username')
			self.client.enterText(self.args.join_user)
			self.click('Password')
			self.client.enterText(self.args.join_password)
			self.next()

	def orga(self, orga, password):
		self.client.waitForText('Account information', timeout=self.timeout)
		self.screenshot('organisation-setup.png')
		self.client.enterText('home')
		self.client.keyPress('tab')
		self.client.keyPress('tab')
		self.client.keyPress('tab')
		self.client.enterText(password)
		self.client.keyPress('tab')
		self.client.enterText(password)
		self.next()

	def hostname(self, hostname):
		self.client.waitForText('Host settings', timeout=self.timeout)
		self.screenshot('hostname-setup.png')
		# delete the pre-filled hostname
		self.client.keyPress('end')
		for i in range(1, 200):
			self.client.keyPress('bsp')
		time.sleep(3)
		self.client.enterText(hostname)
		self.client.keyPress('tab')
		if self.args.role in ['admember', 'slave']:
			self.client.keyPress('tab')
			self.client.enterText(self.args.password)
			self.client.keyPress('tab')
			self.client.enterText(self.args.password)
		self.next()

	def start(self):
		self.client.waitForText('confirm configuration', timeout=self.timeout)
		self.screenshot('start-setup.png')
		found = False
		try:
			self.client.mouseClickOnText('configuresystem')
			found = True
		except VNCDoException:
			self.connect()
		if not found:
			self.client.mouseClickOnText('configure system')

	def finish(self):
		self.client.waitForText('Setup successful', timeout=3600, prevent_screen_saver=True)
		self.screenshot('finished-setup.png')
		self.client.keyPress('tab')
		self.client.keyPress('enter')
		# except welcome screen
		found = False
		try:
			self.client.waitForText('www', timeout=self.timeout)
			found = True
		except VNCDoException:
			self.connect()
		if not found:
			self.client.waitForText('press any key', timeout=self.timeout)
		self.screenshot('welcome-screen.png')

	def connect(self):
		self.conn = VNCConnection(self.args.vnc)
		self.client = self.conn.__enter__()
		self.client.updateOCRConfig(self.config)

	def setup(self):
		try:
			self.language('English')
			self.network()
			self.domain(self.args.role)
			if self.args.role == 'master':
				self.orga(self.args.organisation, self.args.password)
			if not self.args.role == 'fast':
				self.hostname(self.args.fqdn)
			try:
				self.client.waitForText('Software configuration', timeout=self.timeout)
				self.next()
			except VNCDoException:
				self.connect()
			self.start()
			self.finish()
		except Exception:
			self.connect()
			self.screenshot('error.png')
			raise