<commit_before># Copyright 2014 CloudFounders NV
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Module for SetupController
"""

import os
import re
import sys
import time
import ConfigParser
import urllib2
import base64
from string import digits

from ovs.extensions.generic.sshclient import SSHClient
from ovs.extensions.generic.interactive import Interactive
from ovs.extensions.db.arakoon.ArakoonManagement import ArakoonManagement
from ovs.log.logHandler import LogHandler

logger = LogHandler('lib', name='setup')

# @TODO: Make the setup_node idempotent
# @TODO: Make it possible to run as a non-privileged user
# @TODO: Node password identical for all nodes


class SetupController(object):
    """
    This class contains all logic for setting up an environment, installed with system-native packages
    """

    @staticmethod
    def setup_node(ip=None, force_type=None, verbose=False):
        """
        Sets up a node, post installation
        """

        default_hypervisor_username = 'root'

        try:
            print Interactive.boxed_message(['Open vStorage Setup'])
            logger.info('Starting Open vStorage Setup')

            # Prepare variables
            target_password = None
            join_cluster = False
            cluster_name = None
            cluster_ip = ''
            master_ip = None
            node_type = None  # in ['master', 'extra']
            nodes = []
            extra_hdd_storage = ''
            extra_hdd_mountpoint = ''
            use_hdd_io_ssd = ''
            ssd_mountpoint = ''
            hypervisor_type = ''
            hypervisor_name = ''
            hypervisor_ip = ''
            hypervisor_username = ''
            hypervisor_password = ''
            arakoon_mountpoint = ''
            rabbitmq_server_config = """
[
   {rabbit, [{tcp_listeners, [%(broker_port)s]},
             {default_user, <<"%(broker_username)s">>},
             {default_pass, <<"%(broker_<PASSWORD>">>},
             {cluster_nodes, {[], disc}}]}
].
"""
            # Support non-interactive setup
            preconfig = '/tmp/openvstorage_preconfig.cfg'
            if os.path.exists(preconfig):
                config = ConfigParser.ConfigParser()
                config.read(preconfig)
                ip = config.get('setup', 'target_ip')
                target_password = config.get('setup', 'target_password')
                cluster_ip = config.get('setup', 'cluster_ip')
                cluster_name = str(config.get('setup', 'cluster_name'))
                join_cluster = config.getboolean('setup', 'join_cluster')
                master_ip = config.get('setup', 'master_ip')
                extra_hdd_storage = config.getboolean('setup', 'extra_hdd_storage')
                extra_hdd_mountpoint = config.get('setup', 'extra_hdd_mountpoint')
                use_hdd_io_ssd = config.get('setup', 'use_hdd_io_ssd')
                ssd_mountpoint = config.get('setup', 'ssd_mountpoint')
                hypervisor_type = config.get('setup', 'hypervisor_type')
                hypervisor_name = config.get('setup', 'hypervisor_name')
                hypervisor_ip = config.get('setup', 'hypervisor_ip')
                hypervisor_username = config.get('setup', 'hypervisor_username')
                hypervisor_password = config.get('setup', 'hypervisor_password')
                arakoon_mountpoint = config.get('setup', 'arakoon_mountpoint')
                verbose = config.getboolean('setup', 'verbose')

            if force_type is not None:
                force_type = force_type.lower()
                if force_type not in ['master', 'extra']:
                    raise ValueError("The force_type parameter should be 'master' or 'extra'.")
                node_type = force_type

            # Create connection to target node
            print '\n+++ Setting up connections +++\n'
            logger.info('Setting up connections')
            if ip is None:
                ip = '127.0.0.1'
            if target_password is None:
                node_string = 'this node' if ip == '127.0.0.1' else ip
                target_node_password = Interactive.ask_password('Enter the root password for {0}'.format(node_string))
            else:
                target_node_password = target_password
            target_client = SSHClient.load(ip, target_node_password)
            if verbose:
                logger.debug('Verbose mode')
                from ovs.plugin.provider.remote import Remote
                Remote.cuisine.fabric.output['running'] = True
            logger.debug('Target client loaded')

            # Collect information about the cluster to join
            print '\n+++ Collecting cluster information +++\n'
            current_cluster_names = []
            clusters = []
            discovery_result = SetupController._discover_nodes(target_client)
            if discovery_result:
                clusters = discovery_result.keys()
                current_cluster_names = clusters[:]
                logger.debug('Cluster names: {0}'.format(current_cluster_names))
            else:
                print 'No existing Open vStorage clusters are found.'
                logger.debug('No clusters found')

            node_name = target_client.run('hostname')
            logger.debug('Current host: {0}'.format(node_name))
            if cluster_name is None:
                if len(clusters) > 0:
                    dont_join = "Don't join any of these clusters."
                    if force_type in [None, 'master']:
                        clusters.append(dont_join)
                    print 'Following Open vStorage clusters are found.'
                    cluster_name = Interactive.ask_choice(clusters, 'Select a cluster to join')
                    if cluster_name != dont_join:
                        logger.debug('Cluster {0} selected'.format(cluster_name))
                        nodes = [node_property['ip'] for node_property in discovery_result[cluster_name].values()]
                        if node_name in discovery_result[cluster_name].keys():
                            continue_install = Interactive.ask_yesno(
                                '{0} already exists in cluster {1}. Do you want to continue?'.format(
                                    node_name, cluster_name
                                ), default_value=True
                            )
                            if continue_install is False:
                                raise ValueError('Duplicate node name found.')
                        master_nodes = [this_node_name for this_node_name, node_properties in discovery_result[cluster_name].iteritems()
                                        if node_properties.get('type', None) == 'master']
                        if len(master_nodes) == 0:
                            raise RuntimeError('No master node could be found in cluster {0}'.format(cluster_name))
                        master_ip = discovery_result[cluster_name][master_nodes[0]]['ip']
                        join_cluster = True
                    else:
                        cluster_name = None
                        logger.debug('No cluster will be joined')
                elif force_type != 'master':
                    raise RuntimeError('No clusters were found. Only a Master node can be setup.')

                if join_cluster is False and cluster_name is None:
                    while True:
                        cluster_name = Interactive.ask_string('Please enter the cluster name')
                        if cluster_name in current_cluster_names:
                            print 'The new cluster name should be unique.'
                        elif '_' in cluster_name:
                            print "The new cluster name should not contain '_'."
                        else:
                            break

            else:  # Automated install
                logger.debug('Automated installation')
                if cluster_name in discovery_result:
                    nodes = [node_property['ip'] for node_property in discovery_result[cluster_name].values()]

            # Creating filesystems
            print '\n+++ Creating filesystems +++\n'
            logger.info('Creating filesystems')
            if extra_hdd_storage == '' or extra_hdd_storage is None:
                extra_hdd_storage = Interactive.ask_yesno('Do you want to configure an additional HDD for data storage?', default_value=False)
                if extra_hdd_storage:
                    logger.debug('Extra HDD should be configured')
            SetupController._create_filesystems(target_client, extra_hdd_storage, extra_hdd_mountpoint, use_hdd_io_ssd, ssd_mountpoint)

            # Get target grid ip
            print '\n+++ Collecting generic information +++\n'<commit_msg>OVS-925 - Fixed issue on installation when no clusters were found<commit_after># Copyright 2014 CloudFounders NV
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Module for SetupController
"""

import os
import re
import sys
import time
import ConfigParser
import urllib2
import base64
from string import digits

from ovs.extensions.generic.sshclient import SSHClient
from ovs.extensions.generic.interactive import Interactive
from ovs.extensions.db.arakoon.ArakoonManagement import ArakoonManagement
from ovs.log.logHandler import LogHandler

logger = LogHandler('lib', name='setup')

# @TODO: Make the setup_node idempotent
# @TODO: Make it possible to run as a non-privileged user
# @TODO: Node password identical for all nodes


class SetupController(object):
    """
    This class contains all logic for setting up an environment, installed with system-native packages
    """

    @staticmethod
    def setup_node(ip=None, force_type=None, verbose=False):
        """
        Sets up a node, post installation
        """

        default_hypervisor_username = 'root'

        try:
            print Interactive.boxed_message(['Open vStorage Setup'])
            logger.info('Starting Open vStorage Setup')

            # Prepare variables
            target_password = None
            join_cluster = False
            cluster_name = None
            cluster_ip = ''
            master_ip = None
            node_type = None  # in ['master', 'extra']
            nodes = []
            extra_hdd_storage = ''
            extra_hdd_mountpoint = ''
            use_hdd_io_ssd = ''
            ssd_mountpoint = ''
            hypervisor_type = ''
            hypervisor_name = ''
            hypervisor_ip = ''
            hypervisor_username = ''
            hypervisor_password = ''
            arakoon_mountpoint = ''
            rabbitmq_server_config = """
[
   {rabbit, [{tcp_listeners, [%(broker_port)s]},
             {default_user, <<"%(broker_username)s">>},
             {default_pass, <<"%(broker_password)s">>},
             {cluster_nodes, {[], disc}}]}
].
"""
            # Support non-interactive setup
            preconfig = '/tmp/openvstorage_preconfig.cfg'
            if os.path.exists(preconfig):
                config = ConfigParser.ConfigParser()
                config.read(preconfig)
                ip = config.get('setup', 'target_ip')
                target_password = config.get('setup', 'target_password')
                cluster_ip = config.get('setup', 'cluster_ip')
                cluster_name = str(config.get('setup', 'cluster_name'))
                join_cluster = config.getboolean('setup', 'join_cluster')
                master_ip = config.get('setup', 'master_ip')
                extra_hdd_storage = config.getboolean('setup', 'extra_hdd_storage')
                extra_hdd_mountpoint = config.get('setup', 'extra_hdd_mountpoint')
                use_hdd_io_ssd = config.get('setup', 'use_hdd_io_ssd')
                ssd_mountpoint = config.get('setup', 'ssd_mountpoint')
                hypervisor_type = config.get('setup', 'hypervisor_type')
                hypervisor_name = config.get('setup', 'hypervisor_name')
                hypervisor_ip = config.get('setup', 'hypervisor_ip')
                hypervisor_username = config.get('setup', 'hypervisor_username')
                hypervisor_password = config.get('setup', 'hypervisor_password')
                arakoon_mountpoint = config.get('setup', 'arakoon_mountpoint')
                verbose = config.getboolean('setup', 'verbose')

            if force_type is not None:
                force_type = force_type.lower()
                if force_type not in ['master', 'extra']:
                    raise ValueError("The force_type parameter should be 'master' or 'extra'.")
                node_type = force_type

            # Create connection to target node
            print '\n+++ Setting up connections +++\n'
            logger.info('Setting up connections')
            if ip is None:
                ip = '127.0.0.1'
            if target_password is None:
                node_string = 'this node' if ip == '127.0.0.1' else ip
                target_node_password = Interactive.ask_password('Enter the root password for {0}'.format(node_string))
            else:
                target_node_password = target_password
            target_client = SSHClient.load(ip, target_node_password)
            if verbose:
                logger.debug('Verbose mode')
                from ovs.plugin.provider.remote import Remote
                Remote.cuisine.fabric.output['running'] = True
            logger.debug('Target client loaded')

            # Collect information about the cluster to join
            print '\n+++ Collecting cluster information +++\n'
            current_cluster_names = []
            clusters = []
            discovery_result = SetupController._discover_nodes(target_client)
            if discovery_result:
                clusters = discovery_result.keys()
                current_cluster_names = clusters[:]
                logger.debug('Cluster names: {0}'.format(current_cluster_names))
            else:
                print 'No existing Open vStorage clusters are found.'
                logger.debug('No clusters found')

            node_name = target_client.run('hostname')
            logger.debug('Current host: {0}'.format(node_name))
            if cluster_name is None:
                if len(clusters) > 0:
                    dont_join = "Don't join any of these clusters."
                    if force_type in [None, 'master']:
                        clusters.append(dont_join)
                    print 'Following Open vStorage clusters are found.'
                    cluster_name = Interactive.ask_choice(clusters, 'Select a cluster to join')
                    if cluster_name != dont_join:
                        logger.debug('Cluster {0} selected'.format(cluster_name))
                        nodes = [node_property['ip'] for node_property in discovery_result[cluster_name].values()]
                        if node_name in discovery_result[cluster_name].keys():
                            continue_install = Interactive.ask_yesno(
                                '{0} already exists in cluster {1}. Do you want to continue?'.format(
                                    node_name, cluster_name
                                ), default_value=True
                            )
                            if continue_install is False:
                                raise ValueError('Duplicate node name found.')
                        master_nodes = [this_node_name for this_node_name, node_properties in discovery_result[cluster_name].iteritems()
                                        if node_properties.get('type', None) == 'master']
                        if len(master_nodes) == 0:
                            raise RuntimeError('No master node could be found in cluster {0}'.format(cluster_name))
                        master_ip = discovery_result[cluster_name][master_nodes[0]]['ip']
                        join_cluster = True
                    else:
                        cluster_name = None
                        logger.debug('No cluster will be joined')
                elif force_type is not None and force_type != 'master':
                    raise RuntimeError('No clusters were found. Only a Master node can be set up.')

                if join_cluster is False and cluster_name is None:
                    while True:
                        cluster_name = Interactive.ask_string('Please enter the cluster name')
                        if cluster_name in current_cluster_names:
                            print 'The new cluster name should be unique.'
                        elif '_' in cluster_name:
                            print "The new cluster name should not contain '_'."
                        else:
                            break

            else:  # Automated install
                logger.debug('Automated installation')
                if cluster_name in discovery_result:
                    nodes = [node_property['ip'] for node_property in discovery_result[cluster_name].values()]

            # Creating filesystems
            print '\n+++ Creating filesystems +++\n'
            logger.info('Creating filesystems')
            if extra_hdd_storage == '' or extra_hdd_storage is None:
                extra_hdd_storage = Interactive.ask_yesno('Do you want to configure an additional HDD for data storage?', default_value=False)
                if extra_hdd_storage:
                    logger.debug('Extra HDD should be configured')
            SetupController._create_filesystems(target_client, extra_hdd_storage, extra_hdd_mountpoint, use_hdd_io_ssd, ssd_mountpoint)

            # Get target grid ip
            print '\n+++ Collecting generic information +++\n'
{'fraction_non_alphanumeric': 0.08657338175603503, 'fraction_numerical': 0.003685110019226661, 'mean_word_length': 1.908060257804007, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6152851', 'n_tokens_mistral': 4732, 'n_tokens_neox': 4516, 'n_words': 1290}