예제 #1
0
def verify_server_version(host, expected_server_version, cbs_ssl=False):
    """ Verifies that the version of a running Couchbase Server is the 'expected_server_version' """

    running_server_version = get_server_version(host, cbs_ssl=cbs_ssl)
    expected_server_version_parts = expected_server_version.split("-")

    # Check both version parts if expected version contains a build
    if len(expected_server_version_parts) == 2:
        # 4.1.1-5487
        log_info("Expected Server Version: {}".format(expected_server_version))
        log_info("Running Server Version: {}".format(running_server_version))
        if running_server_version != expected_server_version:
            raise ProvisioningError(
                "Unexpected server version!! Expected: {} Actual: {}".format(
                    expected_server_version, running_server_version))
    elif len(expected_server_version_parts) == 1:
        # 4.1.1
        running_server_version_parts = running_server_version.split("-")
        log_info("Expected Server Version: {}".format(expected_server_version))
        log_info("Running Server Version: {}".format(
            running_server_version_parts[0]))
        if expected_server_version != running_server_version_parts[0]:
            raise ProvisioningError(
                "Unexpected server version!! Expected: {} Actual: {}".format(
                    expected_server_version, running_server_version_parts[0]))
    else:
        raise ProvisioningError("Unsupported version format")
    def is_valid(self):
        if self._version_number is not None and self._build_number is not None:
            if self.commit is not None:
                raise ProvisioningError(
                    "Commit should be empty when provisioning with a binary")
        elif self.commit is not None:
            if self._version_number is not None:
                raise ProvisioningError(
                    "Do not specify a version number when provisioning via a commit."
                )
            if self._build_number is not None:
                raise ProvisioningError(
                    "Do not specify a build number when provisioning via a commit."
                )
        else:
            log_info(
                "You must provide a (version and build number) or (dev url and dev build number) or commit to build for sync_gateway"
            )
            return False

        if not os.path.isfile(self.config_path):
            log_info("Could not find sync_gateway config file: {}".format(
                self.config_path))
            log_info("Try to use an absolute path.")
            return False

        return True
예제 #3
0
def verify_sync_gateway_version(host, expected_sync_gateway_version):
    running_sg_version, running_sg_vendor_version = get_sync_gateway_version(
        host)

    log_info("Expected sync_gateway Version: {}".format(
        expected_sync_gateway_version))
    log_info("Running sync_gateway Version: {}".format(running_sg_version))
    log_info("Running sync_gateway Vendor Version: {}".format(
        running_sg_vendor_version))

    if version_is_binary(expected_sync_gateway_version):
        # Example, 1.2.1-4
        if running_sg_version != expected_sync_gateway_version:
            raise ProvisioningError(
                "Unexpected sync_gateway version!! Expected: {} Actual: {}".
                format(expected_sync_gateway_version, running_sg_version))
        # Running vendor version: ex. '1.2', check that the expected version start with the vendor version
        if not expected_sync_gateway_version.startswith(
                running_sg_vendor_version):
            raise ProvisioningError(
                "Unexpected sync_gateway vendor version!! Expected: {} Actual: {}"
                .format(expected_sync_gateway_version,
                        running_sg_vendor_version))
    else:
        # Since sync_gateway does not return the full commit, verify the prefix
        if running_sg_version != expected_sync_gateway_version[:7]:
            raise ProvisioningError(
                "Unexpected sync_gateway version!! Expected: {} Actual: {}".
                format(expected_sync_gateway_version, running_sg_version))
예제 #4
0
    def start_sync_gateways(self, cluster_config, url=None, config=None):
        """ Start sync gateways in a cluster. If url is passed,
        start the sync gateway at that url
        """

        if config is None:
            raise ProvisioningError(
                "Starting a Sync Gateway requires a config")

        ansible_runner = AnsibleRunner(cluster_config)
        config_path = os.path.abspath(config)
        couchbase_server_primary_node = add_cbs_to_sg_config_server_field(
            cluster_config)
        if is_cbs_ssl_enabled(cluster_config):
            self.server_port = 18091
            self.server_scheme = "https"

        playbook_vars = {
            "sync_gateway_config_filepath": config_path,
            "server_port": self.server_port,
            "server_scheme": self.server_scheme,
            "autoimport": "",
            "xattrs": "",
            "no_conflicts": "",
            "revs_limit": "",
            "couchbase_server_primary_node": couchbase_server_primary_node
        }

        if is_xattrs_enabled(cluster_config):
            playbook_vars["autoimport"] = '"import_docs": "continuous",'
            playbook_vars["xattrs"] = '"enable_shared_bucket_access": true,'

        if no_conflicts_enabled(cluster_config):
            playbook_vars["no_conflicts"] = '"allow_conflicts": false,'
        try:
            revs_limit = get_revs_limit(cluster_config)
            playbook_vars["revs_limit"] = '"revs_limit": {},'.format(
                revs_limit)
        except KeyError as ex:
            log_info("Keyerror in getting revs_limit{}".format(ex.message))
        if url is not None:
            target = hostname_for_url(cluster_config, url)
            log_info("Starting {} sync_gateway.".format(target))
            status = ansible_runner.run_ansible_playbook(
                "start-sync-gateway.yml",
                extra_vars=playbook_vars,
                subset=target)
        else:
            log_info("Starting all sync_gateways.")
            status = ansible_runner.run_ansible_playbook(
                "start-sync-gateway.yml", extra_vars=playbook_vars)
        if status != 0:
            raise ProvisioningError("Could not start sync_gateway")
예제 #5
0
    def provision_cluster(self, cluster_config, server_version, sync_gateway_version, sync_gateway_config, race_enabled=False, sg_ce=False, cbs_platform="centos7", sg_platform="centos", sa_platform="centos"):
        if server_version is None or sync_gateway_version is None or sync_gateway_version is None:
            raise ProvisioningError("Please make sure you have server_version, sync_gateway_version, and sync_gateway_config are set")

        # Dirty hack -- these have to be put here in order to avoid circular imports
        from libraries.provision.install_couchbase_server import CouchbaseServerConfig
        from libraries.provision.provision_cluster import provision_cluster
        from libraries.provision.install_sync_gateway import SyncGatewayConfig

        cbs_config = CouchbaseServerConfig(server_version)

        if version_is_binary(sync_gateway_version):

            if race_enabled:
                raise ProvisioningError("Race should only be enabled for source builds")

            version, build = version_and_build(sync_gateway_version)
            sg_config = SyncGatewayConfig(
                commit=None,
                version_number=version,
                build_number=build,
                config_path=sync_gateway_config,
                build_flags="",
                skip_bucketcreation=False
            )
        else:

            build_flags = ""
            if race_enabled:
                build_flags = "-race"

            sg_config = SyncGatewayConfig(
                commit=sync_gateway_version,
                version_number=None,
                build_number=None,
                config_path=sync_gateway_config,
                build_flags=build_flags,
                skip_bucketcreation=False
            )

        provision_cluster(
            cluster_config=cluster_config,
            couchbase_server_config=cbs_config,
            sync_gateway_config=sg_config,
            sg_ce=sg_ce,
            cbs_platform=cbs_platform,
            sg_platform=sg_platform,
            sa_platform=sa_platform
        )

        # verify running services are the expected versions
        self.verify_cluster_versions(cluster_config, server_version, sync_gateway_version)
예제 #6
0
def install_deps(cluster_config):

    log_info("Installing dependencies for cluster_config: {}".format(
        cluster_config))

    ansible_runner = AnsibleRunner(config=cluster_config)
    status = ansible_runner.run_ansible_playbook("os-level-modifications.yml")
    if status != 0:
        raise ProvisioningError("Failed to make os modifications")

    status = ansible_runner.run_ansible_playbook("install-common-tools.yml")
    if status != 0:
        raise ProvisioningError("Failed to install dependencies")
예제 #7
0
def clean_cluster(cluster_config):

    log_info("Cleaning cluster: {}".format(cluster_config))

    ansible_runner = AnsibleRunner(config=cluster_config)
    status = ansible_runner.run_ansible_playbook(
        "remove-previous-installs.yml")
    if status != 0:
        raise ProvisioningError("Failed to removed previous installs")

    # Clear firewall rules
    status = ansible_runner.run_ansible_playbook("flush-firewall.yml")
    if status != 0:
        raise ProvisioningError("Failed to flush firewall")
    def sync_gateway_base_url_and_package(self,
                                          sg_ce=False,
                                          sg_platform="centos",
                                          sa_platform="centos"):
        platform_extension = {
            "centos": "rpm",
            "ubuntu": "deb",
            "windows": "exe"
        }

        if self._version_number == "1.1.0" or self._build_number == "1.1.1":
            log_info("Version unsupported in provisioning.")
            raise ProvisioningError("Unsupport version of sync_gateway")
            # http://latestbuilds.service.couchbase.com/couchbase-sync-gateway/release/1.1.1/1.1.1-10/couchbase-sync-gateway-enterprise_1.1.1-10_x86_64.rpm
            # base_url = "http://latestbuilds.service.couchbase.com/couchbase-sync-gateway/release/{0}/{1}-{2}".format(version, version, build)
            # sg_package_name  = "couchbase-sync-gateway-enterprise_{0}-{1}_x86_64.rpm".format(version, build)
        else:
            # http://latestbuilds.service.couchbase.com/builds/latestbuilds/sync_gateway/1.3.1.5/2/couchbase-sync-gateway-enterprise_1.2.0-6_x86_64.rpm
            base_url = "http://latestbuilds.service.couchbase.com/builds/latestbuilds/sync_gateway/{0}/{1}".format(
                self._version_number, self._build_number)

            sg_type = "enterprise"

            if sg_ce:
                sg_type = "community"

            sg_package_name = "couchbase-sync-gateway-{0}_{1}-{2}_x86_64.{3}".format(
                sg_type, self._version_number, self._build_number,
                platform_extension[sg_platform])
            accel_package_name = "couchbase-sg-accel-enterprise_{0}-{1}_x86_64.{2}".format(
                self._version_number, self._build_number,
                platform_extension[sa_platform])

        return base_url, sg_package_name, accel_package_name
def install_couchbase_server(cluster_config,
                             couchbase_server_config,
                             cbs_platform="centos7"):

    log_info(cluster_config)
    log_info(couchbase_server_config)

    ansible_runner = AnsibleRunner(cluster_config)
    cluster_keywords = ClusterKeywords()
    cluster_topology = cluster_keywords.get_cluster_topology(cluster_config)
    server_url = cluster_topology["couchbase_servers"][0]
    cb_server = CouchbaseServer(server_url)

    log_info(">>> Installing Couchbase Server")
    # Install Server
    server_baseurl, server_package_name = couchbase_server_config.get_baseurl_package(
        cb_server, cbs_platform)
    status = ansible_runner.run_ansible_playbook(
        "install-couchbase-server-package.yml",
        extra_vars={
            "couchbase_server_package_base_url": server_baseurl,
            "couchbase_server_package_name": server_package_name
        })
    if status != 0:
        raise ProvisioningError("Failed to install Couchbase Server")

    # Wait for server to be in 'healthy state'
    print(">>> Waiting for server to be in 'healthy' state")
    cb_server.wait_for_ready_state()
예제 #10
0
    def set_cluster_config(self, name):
        """Sets CLUSTER_CONFIG environment variable for provisioning

        Checks if CLUSTER_CONFIG is set, will fail if it is.
        Checks if cluster configuration file exists, will fail if it does not
        """

        if "CLUSTER_CONFIG" in os.environ:
            raise ProvisioningError("CLUSTER_CONFIG will be set by suite setup. Make sure it is unset.")

        path = "{}/{}".format(CLUSTER_CONFIGS_DIR, name)
        if not os.path.isfile(path):
            raise ProvisioningError("{} not found. Make sure you have generated your cluster configurations.")

        log_info("Setting CLUSTER_CONFIG: {}".format(path))
        os.environ["CLUSTER_CONFIG"] = path
예제 #11
0
def build_sgload(ansible_runner):

    ansible_status = ansible_runner.run_ansible_playbook(
        "build-sgload.yml",
        extra_vars={},
    )
    if ansible_status != 0:
        raise ProvisioningError("Failed to build sgload")
예제 #12
0
def verify_sg_accel_version(host, expected_sg_accel_version):
    running_ac_version = get_sg_accel_version(host)

    log_info("Expected sg_accel Version: {}".format(expected_sg_accel_version))
    log_info("Running sg_accel Version: {}".format(running_ac_version))

    if version_is_binary(expected_sg_accel_version):
        # Example, 1.2.1-4
        if running_ac_version != expected_sg_accel_version:
            raise ProvisioningError(
                "Unexpected sync_gateway version!! Expected: {} Actual: {}".
                format(expected_sg_accel_version, running_ac_version))
    else:
        # Since sync_gateway does not return the full commit, verify the prefix
        if running_ac_version != expected_sg_accel_version[:7]:
            raise ProvisioningError(
                "Unexpected sync_gateway version!! Expected: {} Actual: {}".
                format(expected_sg_accel_version, running_ac_version))
예제 #13
0
    def upgrade_server(self,
                       cluster_config,
                       server_version_build,
                       cbs_platform,
                       target=None,
                       toy_build=None):
        ansible_runner = AnsibleRunner(cluster_config)

        log_info(">>> Upgrading Couchbase Server")
        # Install Server
        if toy_build:
            # http://server.jenkins.couchbase.com/view/All/job/watson-toy/1770/artifact/couchbase-server-enterprise-5.0.0-9900-centos7.x86_64.rpm
            toy_build_url_parts = toy_build.split('/')
            toy_build_url_len = len(toy_build_url_parts)
            server_package_name = toy_build_url_parts[-1]
            server_baseurl = "/".join(
                toy_build_url_parts[0:(toy_build_url_len - 1)])
        else:
            version_build = server_version_build.split("-")
            server_verion = version_build[0]
            if len(version_build) == 2:
                # Build number is included
                server_build = version_build[1]
            else:
                server_build = None

            if server_build is None:
                server_baseurl, server_package_name = self.resolve_cb_mobile_url(
                    server_verion, cbs_platform)
            else:
                server_baseurl, server_package_name = self.resolve_cb_nas_url(
                    server_verion, server_build, cbs_platform)

        if target is not None:
            target = hostname_for_url(cluster_config, target)
            log_info("Upgrading Couchbase server on {} ...".format(target))
            status = ansible_runner.run_ansible_playbook(
                "upgrade-couchbase-server-package.yml",
                subset=target,
                extra_vars={
                    "couchbase_server_package_base_url": server_baseurl,
                    "couchbase_server_package_name": server_package_name
                })
        else:
            log_info("Upgrading Couchbase server on all nodes")
            status = ansible_runner.run_ansible_playbook(
                "upgrade-couchbase-server-package.yml",
                extra_vars={
                    "couchbase_server_package_base_url": server_baseurl,
                    "couchbase_server_package_name": server_package_name
                })

        if status != 0:
            raise ProvisioningError("Failed to install Couchbase Server")

        self.wait_for_ready_state()
def generate_cluster_configs_from_vagrant(private_network, public_network,
                                          public_network_ethernet):
    """
    1. Gets the status for a running vagrant vm set.
    2. Uses the host name to look up the ip allocated to each vagrant vm instance
    3. Uses this IP list to build a pool.json file and generate the cluster configurations
    """

    check_network_options(private_network, public_network,
                          public_network_ethernet)

    cwd = os.getcwd()

    # Change directory to where the appropriate Vagrantfile lives
    if private_network:
        os.chdir("vagrant/private_network")
    elif public_network:
        os.chdir("vagrant/public_network")
    else:
        os.chdir("vagrant/public_network_ethernet")

    v = vagrant.Vagrant()
    status = v.status()

    # Get vagrant ips
    vagrant_ips = []
    print("Getting ip addresses from running vagrant vms ...")
    for stat in status:
        name = stat.name
        # Expected output: '10.0.2.15 192.168.0.61 2605:e000:9092:200:a00:27ff:fe7b:9bbf \r\n'
        # where second ip is the publicly routable ip
        output = subprocess.check_output(
            'vagrant ssh {} -c "hostname -I"'.format(name), shell=True)
        cleaned_output = output.strip()
        ip_addresses = cleaned_output.split()
        if len(ip_addresses) < 2:
            raise ProvisioningError(
                "Expected at least 2 ip addresses hostname -I result: {}".
                format(ip_addresses))
        public_ip = ip_addresses[1]
        print("host: {} ip: {}".format(name, public_ip))
        vagrant_ips.append(public_ip)

    # Restore previous directory
    os.chdir(cwd)

    # Write pool.json
    pool_file = "resources/pool.json"
    pool_def = {"ips": vagrant_ips}
    with open(pool_file, "w") as f:
        print("Writing 'resources/pool.json' ...")
        f.write(json.dumps(pool_def, indent=4))

    # Generate cluster configs
    print("Generating cluster_configs ...")
    generate_clusters_from_pool(pool_file)
예제 #15
0
    def unset_cluster_config(self):
        """Will unset the CLUSTER_CONFIG environment variable if it is set.

        Will fail if CLUSTER_CONFIG is not set
        """

        if "CLUSTER_CONFIG" not in os.environ:
            raise ProvisioningError("Trying to unset CLUSTER_CONFIG but it is not defined")

        log_info("Unsetting CLUSTER_CONFIG")
        del os.environ["CLUSTER_CONFIG"]
def check_network_options(private_network, public_network,
                          public_network_ethernet):
    # Check if only one of the options is set, private_network or public_network or public_network_ethernet
    if private_network and (public_network or public_network_ethernet):
        raise ProvisioningError(
            "Invalid private_network and public_network/public_network_ethernet flags"
        )
    elif public_network and (private_network or public_network_ethernet):
        raise ProvisioningError(
            "Invalid public_network and private_network/public_network_ethernet flags"
        )
    elif public_network_ethernet and (public_network or private_network):
        raise ProvisioningError(
            "Invalid public_network_ethernet and public_network/private_network flags"
        )

    # Check if none of the options are set
    if not private_network and not public_network and not public_network_ethernet:
        raise ProvisioningError(
            "Invalid private_network, public_network and public_network_ethernet flags"
        )
def get_load_balancer_ip(cluster_config):
    """ Loads cluster config to fetch load balancer ip """
    cluster = load_cluster_config_json(cluster_config)

    num_lbs = len(cluster["load_balancers"])
    if num_lbs != 1:
        raise ProvisioningError(
            "Expecting exactly 1 load balancer IP in {}".format(
                cluster_config))

    lb_ip = cluster["load_balancers"][0]["ip"]
    return lb_ip
예제 #18
0
def verify_sync_gateway_product_info(host):
    """ Get the product information from host and verify for Sync Gateway:
    - vendor name in GET / request
    - Server header in response
    """

    resp = requests.get("http://{}:4984".format(host))
    log_r(resp)
    resp.raise_for_status()
    resp_obj = resp.json()

    server_header = resp.headers["server"]
    log_info("'server' header: {}".format(server_header))
    if not server_header.startswith("Couchbase Sync Gateway"):
        raise ProvisioningError(
            "Wrong product info. Expected 'Couchbase Sync Gateway'")

    vendor_name = resp_obj["vendor"]["name"]
    log_info("vendor name: {}".format(vendor_name))
    if vendor_name != "Couchbase Sync Gateway":
        raise ProvisioningError(
            "Wrong vendor name. Expected 'Couchbase Sync Gateway'")
예제 #19
0
    def collect_packet_capture(self, cluster_config, test_name):
        ansible_runner = AnsibleRunner(config=cluster_config)
        status = ansible_runner.run_ansible_playbook("collect-ngrep.yml")
        if status != 0:
            raise ProvisioningError("Failed to collect packet capture")

        # zip logs and timestamp
        if os.path.isdir("/tmp/sys-logs"):
            date_time = time.strftime("%Y-%m-%d-%H-%M-%S")
            name = "/tmp/ngrep-{}-{}-output".format(test_name, date_time)
            shutil.make_archive(name, "zip", "/tmp/sys-logs")
            shutil.rmtree("/tmp/sys-logs")
            print("ngrep logs copied here {}.zip\n".format(name))
def install_aws_credentials(cluster_config, aws_access_key_id, aws_secret_access_key):

    log_info("Installing aws credentials for cluster_config: {}".format(cluster_config))

    ansible_runner = AnsibleRunner(config=cluster_config)

    status = ansible_runner.run_ansible_playbook(
        "install-aws-credentials.yml",
        extra_vars={
            "aws_access_key_id": aws_access_key_id,
            "aws_secret_access_key": aws_secret_access_key,
        },
    )
    if status != 0:
        raise ProvisioningError("Failed to aws credentials")
예제 #21
0
    def restart_sync_gateways(self, cluster_config, url=None):
        """ Restart sync gateways in a cluster. If url is passed, restart
         the sync gateway at that url
        """
        ansible_runner = AnsibleRunner(cluster_config)

        if url is not None:
            target = hostname_for_url(cluster_config, url)
            log_info("Restarting sync_gateway on {} ...".format(target))
            status = ansible_runner.run_ansible_playbook(
                "restart-sync-gateway.yml", subset=target)
        else:
            log_info("Restarting all sync_gateways")
            status = ansible_runner.run_ansible_playbook(
                "restart-sync-gateway.yml", )
        if status != 0:
            raise ProvisioningError("Could not restart sync_gateway")
def persist_cluster_config_environment_prop(cluster_config,
                                            property_name,
                                            value,
                                            property_name_check=True):
    """ Loads the cluster_config and sets

    [environment]
    property_name=value

    for cluster_config and

    "property_name": value

    for cluster_config.json
    """

    if property_name_check is True:
        valid_props = [
            "cbs_ssl_enabled", "xattrs_enabled", "sg_lb_enabled",
            "sync_gateway_version", "server_version", "no_conflicts_enabled"
        ]
        if property_name not in valid_props:
            raise ProvisioningError(
                "Make sure the property you are trying to change is one of: {}"
                .format(valid_props))

    # Write property = value in the cluster_config.json
    cluster_config_json = "{}.json".format(cluster_config)
    with open(cluster_config_json) as f:
        cluster = json.loads(f.read())

    cluster["environment"][property_name] = value
    with open(cluster_config_json, "w") as f:
        json.dump(cluster, f, indent=4)

    # Write [section] property = value in the cluster_config
    config = CustomConfigParser()
    config.read(cluster_config)
    config.set('environment', property_name, str(value))

    with open(cluster_config, 'w') as f:
        config.write(f)
예제 #23
0
    def _get_mem_total_lowest(self, server_info):
        # Workaround for https://github.com/couchbaselabs/mobile-testkit/issues/709
        # Later updated for https://github.com/couchbaselabs/mobile-testkit/issues/1038
        # where some node report mem_total = 0. Loop over all the nodes and find the smallest non-zero val
        mem_total_lowest = None
        for node in server_info["nodes"]:
            mem_total = node["systemStats"]["mem_total"]
            if mem_total == 0:
                # ignore nodes that report mem_total = 0
                continue
            if mem_total_lowest is None:
                # no previous value for mem_total_lowest, use non-zero value we got back from node
                mem_total_lowest = mem_total
            elif mem_total < mem_total_lowest:
                # only use it if it's lower than previous low
                mem_total_lowest = mem_total

        if mem_total_lowest is None:
            raise ProvisioningError("All nodes reported 0MB of RAM available")

        return mem_total_lowest
예제 #24
0
def run_sgload_perf_test(cluster_config, sgload_arg_list_main,
                         skip_build_sgload):

    print(
        "Running sgload perf test against cluster: {}".format(cluster_config))
    main_ansible_runner = AnsibleRunner(cluster_config)

    print(">>> Starting profile collection scripts")
    status = main_ansible_runner.run_ansible_playbook(
        "start-profile-collection.yml",
        extra_vars={
            "stats_run_time": 3600,
            "delay_profiling_secs": 60
        },
    )
    assert status == 0, "Could not start profiling collection scripts"

    # Install + configure telegraf
    status = main_ansible_runner.run_ansible_playbook("install-telegraf.yml")
    if status != 0:
        raise ProvisioningError("Failed to install telegraf")

    # build_sgload (ansible)
    if not skip_build_sgload:
        build_sgload(main_ansible_runner)

    # get load generator and sg hostnames
    lg_hosts_main = get_load_generators_hosts(cluster_config)
    sg_hosts_main = get_sync_gateways_hosts(cluster_config)

    # Get the first SG host from the list of SG hosts
    sg_host_main = sg_hosts_main[0]

    run_sgload_on_single_loadgenerator(lg_hosts_main, sgload_arg_list_main,
                                       sg_host_main)

    log_info("Finished")
예제 #25
0
    def reset(self, sg_config_path):

        ansible_runner = AnsibleRunner(self._cluster_config)

        log_info(">>> Reseting cluster ...")
        log_info(">>> CBS SSL enabled: {}".format(self.cbs_ssl))
        log_info(">>> Using xattrs: {}".format(self.xattrs))

        # Stop sync_gateways
        log_info(">>> Stopping sync_gateway")
        status = ansible_runner.run_ansible_playbook("stop-sync-gateway.yml")
        assert status == 0, "Failed to stop sync gateway"

        # Stop sync_gateway accels
        log_info(">>> Stopping sg_accel")
        status = ansible_runner.run_ansible_playbook("stop-sg-accel.yml")
        assert status == 0, "Failed to stop sg_accel"

        # Deleting sync_gateway artifacts
        log_info(">>> Deleting sync_gateway artifacts")
        status = ansible_runner.run_ansible_playbook(
            "delete-sync-gateway-artifacts.yml")
        assert status == 0, "Failed to delete sync_gateway artifacts"

        # Deleting sg_accel artifacts
        log_info(">>> Deleting sg_accel artifacts")
        status = ansible_runner.run_ansible_playbook(
            "delete-sg-accel-artifacts.yml")
        assert status == 0, "Failed to delete sg_accel artifacts"

        # Delete buckets
        log_info(">>> Deleting buckets on: {}".format(self.servers[0].url))
        self.servers[0].delete_buckets()

        # Parse config and grab bucket names
        config_path_full = os.path.abspath(sg_config_path)
        config = Config(config_path_full)
        mode = config.get_mode()
        bucket_name_set = config.get_bucket_name_set()

        self.sync_gateway_config = config

        is_valid, reason = validate_cluster(self.sync_gateways, self.sg_accels,
                                            config)
        if not is_valid:
            raise ProvisioningError(reason)

        log_info(">>> Creating buckets on: {}".format(self.servers[0].url))
        log_info(">>> Creating buckets {}".format(bucket_name_set))
        self.servers[0].create_buckets(bucket_name_set)

        # Wait for server to be in a warmup state to work around
        # https://github.com/couchbase/sync_gateway/issues/1745
        log_info(">>> Waiting for Server: {} to be in a healthy state".format(
            self.servers[0].url))
        self.servers[0].wait_for_ready_state()

        log_info(">>> Starting sync_gateway with configuration: {}".format(
            config_path_full))

        server_port = 8091
        server_scheme = "http"
        couchbase_server_primary_node = add_cbs_to_sg_config_server_field(
            self._cluster_config)
        if self.cbs_ssl:
            server_port = 18091
            server_scheme = "https"

        # Start sync-gateway
        playbook_vars = {
            "sync_gateway_config_filepath": config_path_full,
            "server_port": server_port,
            "server_scheme": server_scheme,
            "autoimport": "",
            "xattrs": "",
            "no_conflicts": "",
            "revs_limit": "",
            "couchbase_server_primary_node": couchbase_server_primary_node
        }

        # Add configuration to run with xattrs
        if self.xattrs:
            playbook_vars["autoimport"] = '"import_docs": "continuous",'
            playbook_vars["xattrs"] = '"enable_shared_bucket_access": true,'

        if no_conflicts_enabled(self._cluster_config):
            playbook_vars["no_conflicts"] = '"allow_conflicts": false,'
        try:
            revs_limit = get_revs_limit(self._cluster_config)
            playbook_vars["revs_limit"] = '"revs_limit": {},'.format(
                revs_limit)
        except KeyError as ex:
            log_info("Keyerror in getting revs_limit{}".format(ex.message))
        status = ansible_runner.run_ansible_playbook("start-sync-gateway.yml",
                                                     extra_vars=playbook_vars)
        assert status == 0, "Failed to start to Sync Gateway"

        # HACK - only enable sg_accel for distributed index tests
        # revise this with https://github.com/couchbaselabs/sync-gateway-testcluster/issues/222
        if mode == "di":
            # Start sg-accel
            status = ansible_runner.run_ansible_playbook(
                "start-sg-accel.yml", extra_vars=playbook_vars)
            assert status == 0, "Failed to start sg_accel"

        # Validate CBGT
        if mode == "di":
            if not self.validate_cbgt_pindex_distribution_retry(
                    len(self.sg_accels)):
                self.save_cbgt_diagnostics()
                raise Exception("Failed to validate CBGT Pindex distribution")
            log_info(">>> Detected valid CBGT Pindex distribution")
        else:
            log_info(">>> Running in channel cache")

        return mode
def provision_cluster(cluster_config, couchbase_server_config, sync_gateway_config, sg_ce=False, cbs_platform="centos7", sg_platform="centos", sa_platform="centos"):

    log_info("\n>>> Cluster info:\n")
    server_version = "{}-{}".format(couchbase_server_config.version, couchbase_server_config.build)
    sg_version = "{}-{}".format(sync_gateway_config._version_number, sync_gateway_config._build_number)

    try:
        server_version
    except NameError:
        log_info("Server version is not provided")
        persist_cluster_config_environment_prop(cluster_config, 'server_version', "")
    else:
        log_info("Running test with server version {}".format(server_version))
        persist_cluster_config_environment_prop(cluster_config, 'server_version', server_version)

    try:
        sg_version
    except NameError:
        log_info("Sync gateway version is not provided")
        persist_cluster_config_environment_prop(cluster_config, 'sync_gateway_version', "")
    else:
        log_info("Running test with sync_gateway version {}".format(sg_version))
        persist_cluster_config_environment_prop(cluster_config, 'sync_gateway_version', sg_version)

    with open(cluster_config, "r") as ansible_hosts:
        log_info(ansible_hosts.read())

    log_info(couchbase_server_config)
    log_info(sync_gateway_config)

    if not sync_gateway_config.is_valid():
        log_info("Invalid sync_gateway provisioning configuration. Exiting ...")
        sys.exit(1)

    cluster = Cluster(config=cluster_config)
    config_path_full = os.path.abspath(sync_gateway_config.config_path)
    config = Config(config_path_full)

    is_valid, reason = validate_cluster(
        cluster.sync_gateways,
        cluster.sg_accels,
        config,
    )
    if not is_valid:
        raise ProvisioningError(reason)

    log_info(">>> Provisioning cluster...")

    # Get server base url and package name
    cluster_keywords = ClusterKeywords()
    cluster_topology = cluster_keywords.get_cluster_topology(cluster_config)
    server_url = cluster_topology["couchbase_servers"][0]
    cb_server = CouchbaseServer(server_url)
    server_baseurl, server_package_name = couchbase_server_config.get_baseurl_package(cb_server, cbs_platform)

    log_info(">>> Server package: {0}/{1}".format(server_baseurl, server_package_name))
    log_info(">>> Using sync_gateway config: {}".format(sync_gateway_config.config_path))

    # Reset previous installs
    clean_cluster(cluster_config)

    # Install server package
    log_info("Installing Couchbase Server")
    install_couchbase_server.install_couchbase_server(
        cluster_config=cluster_config,
        couchbase_server_config=couchbase_server_config,
        cbs_platform=cbs_platform
    )

    # Install sync_gateway
    log_info("Installing Sync Gateway")
    install_sync_gateway.install_sync_gateway(
        cluster_config=cluster_config,
        sync_gateway_config=sync_gateway_config,
        sg_platform=sg_platform,
        sa_platform=sa_platform,
        sg_ce=sg_ce
    )

    # Install nginx
    install_nginx(cluster_config)

    log_info(">>> Done provisioning cluster...")
                      action="store", dest="delay_expvar_collect_secs",
                      default=None,
                      help="The delay time between expvar collection")

    arg_parameters = sys.argv[1:]

    (opts, args) = parser.parse_args(arg_parameters)

    if opts.test_id is None:
        print("You must provide a test identifier to run the test")
        sys.exit(1)

    # Validate feed_type
    valid_feed_types = ["continuous", "longpoll"]
    if opts.feed_type not in valid_feed_types:
        raise ProvisioningError("Make sure you provide a valid feed type!")

    # Wrap gateload params into a named tuple
    gateload_params_from_args = GateloadParams(
        number_pullers=opts.number_pullers,
        number_pushers=opts.number_pushers,
        doc_size=opts.doc_size,
        runtime_ms=opts.runtime_ms,
        rampup_interval_ms=opts.rampup_interval_ms,
        feed_type=opts.feed_type,
        sleep_time_ms=opts.sleep_time_ms,
        channel_active_users=opts.channel_active_users,
        channel_concurrent_users=opts.channel_concurrent_users
    )

    # Start load generator
def run_gateload_perf_test(gen_gateload_config, test_id, gateload_params, delay_profiling_secs, delay_expvar_collect_secs):

    try:
        cluster_config = os.environ["CLUSTER_CONFIG"]
    except KeyError:
        print ("Make sure CLUSTER_CONFIG is defined and pointing to the configuration you would like to provision")
        sys.exit(1)

    print("Running perf test against cluster: {}".format(cluster_config))
    ansible_runner = AnsibleRunner(cluster_config)

    # Install + configure telegraf
    status = ansible_runner.run_ansible_playbook("install-telegraf.yml")
    if status != 0:
        raise ProvisioningError("Failed to install telegraf")

    test_run_id = "{}_{}".format(test_id, time.strftime("%Y-%m-%d-%H-%M-%S"))

    # Create test results directory
    os.makedirs("testsuites/syncgateway/performance/results/{}".format(test_run_id))

    # Copy provisioning_config to performance_results/ folder
    shutil.copy("{}".format(cluster_config), "testsuites/syncgateway/performance/results/{}".format(test_run_id))

    if int(gateload_params.number_pullers) > 0 and not gen_gateload_config:
        raise Exception("You specified --num-pullers but did not set --gen-gateload-config")

    # Build gateload
    print(">>> Building gateload")
    status = ansible_runner.run_ansible_playbook(
        "build-gateload.yml",
        extra_vars={},
    )
    assert status == 0, "Could not build gateload"

    # Generate gateload config
    print(">>> Generate gateload configs")
    if gen_gateload_config:
        generate_gateload_configs.main(
            cluster_config=cluster_config,
            test_id=test_run_id,
            gateload_params=gateload_params
        )

    print(">>> Starting profile collection scripts")
    runtime_s = int(gateload_params.runtime_ms) // 1000
    status = ansible_runner.run_ansible_playbook(
        "start-profile-collection.yml",
        extra_vars={
            "stats_run_time": runtime_s,
            "delay_profiling_secs": int(delay_profiling_secs)
        },
    )
    assert status == 0, "Could not start profiling collection scripts"

    # Start gateload
    print(">>> Starting gateload with {0} pullers and {1} pushers".format(
        gateload_params.number_pullers, gateload_params.number_pushers
    ))
    status = ansible_runner.run_ansible_playbook(
        "start-gateload.yml",
        extra_vars={
            "delay_expvar_collect_secs": int(delay_expvar_collect_secs)
        },
    )
    assert status == 0, "Could not start gateload"

    # write expvars to file, will exit when gateload scenario is done
    print(">>> Logging expvars")
    gateload_finished_successfully = log_expvars(cluster_config, test_run_id)

    print(">>> Fetch Sync Gateway profile")
    fetch_sync_gateway_profile(cluster_config, test_run_id)

    print(">>> Shutdown gateload")
    kill_gateload()

    if not gateload_finished_successfully:
        raise RuntimeError("It appears that gateload did not finish successfully.  Check logs for details")
예제 #29
0
 def stop_packet_capture(self, cluster_config):
     ansible_runner = AnsibleRunner(config=cluster_config)
     status = ansible_runner.run_ansible_playbook("stop-ngrep.yml")
     if status != 0:
         raise ProvisioningError("Failed to stop packet capture")
def install_sync_gateway(cluster_config,
                         sync_gateway_config,
                         sg_ce=False,
                         sg_platform="centos",
                         sa_platform="centos"):

    log_info(sync_gateway_config)

    if sync_gateway_config.build_flags != "":
        log_warn(
            "\n\n!!! WARNING: You are building with flags: {} !!!\n\n".format(
                sync_gateway_config.build_flags))

    ansible_runner = AnsibleRunner(cluster_config)
    config_path = os.path.abspath(sync_gateway_config.config_path)
    couchbase_server_primary_node = add_cbs_to_sg_config_server_field(
        cluster_config)
    # Create buckets unless the user explicitly asked to skip this step
    if not sync_gateway_config.skip_bucketcreation:
        create_server_buckets(cluster_config, sync_gateway_config)

    server_port = 8091
    server_scheme = "http"

    if is_cbs_ssl_enabled(cluster_config):
        server_port = 18091
        server_scheme = "https"

    # Shared vars
    playbook_vars = {
        "sync_gateway_config_filepath": config_path,
        "server_port": server_port,
        "server_scheme": server_scheme,
        "autoimport": "",
        "xattrs": "",
        "no_conflicts": "",
        "couchbase_server_primary_node": couchbase_server_primary_node
    }

    if is_xattrs_enabled(cluster_config):
        playbook_vars["autoimport"] = '"import_docs": "continuous",'
        playbook_vars["xattrs"] = '"enable_shared_bucket_access": true,'

    if no_conflicts_enabled(cluster_config):
        playbook_vars["no_conflicts"] = '"allow_conflicts": false,'
    try:
        revs_limit = get_revs_limit(cluster_config)
        playbook_vars["revs_limit"] = '"revs_limit": {},'.format(revs_limit)
    except KeyError as ex:
        log_info("Keyerror in getting revs_limit{}".format(ex.message))
    # Install Sync Gateway via Source or Package
    if sync_gateway_config.commit is not None:
        # Install from source
        playbook_vars["commit"] = sync_gateway_config.commit
        playbook_vars["build_flags"] = sync_gateway_config.build_flags

        status = ansible_runner.run_ansible_playbook(
            "install-sync-gateway-source.yml", extra_vars=playbook_vars)
        if status != 0:
            raise ProvisioningError("Failed to install sync_gateway source")

    else:
        # Install from Package
        sync_gateway_base_url, sync_gateway_package_name, sg_accel_package_name = sync_gateway_config.sync_gateway_base_url_and_package(
            sg_ce=sg_ce, sg_platform=sg_platform, sa_platform=sa_platform)

        playbook_vars[
            "couchbase_sync_gateway_package_base_url"] = sync_gateway_base_url
        playbook_vars[
            "couchbase_sync_gateway_package"] = sync_gateway_package_name
        playbook_vars["couchbase_sg_accel_package"] = sg_accel_package_name

        if sg_platform == "windows":
            status = ansible_runner.run_ansible_playbook(
                "install-sync-gateway-package-windows.yml",
                extra_vars=playbook_vars)
        else:
            status = ansible_runner.run_ansible_playbook(
                "install-sync-gateway-package.yml", extra_vars=playbook_vars)

        if status != 0:
            raise ProvisioningError("Failed to install sync_gateway package")

        if sa_platform == "windows":
            status = ansible_runner.run_ansible_playbook(
                "install-sg-accel-package-windows.yml",
                extra_vars=playbook_vars)
        else:
            status = ansible_runner.run_ansible_playbook(
                "install-sg-accel-package.yml", extra_vars=playbook_vars)
        if status != 0:
            raise ProvisioningError("Failed to install sg_accel package")

    # Configure aws cloudwatch logs forwarder
    status = ansible_runner.run_ansible_playbook(
        "configure-sync-gateway-awslogs-forwarder.yml", extra_vars={})
    if status != 0:
        raise ProvisioningError(
            "Failed to configure sync_gateway awslogs forwarder")