コード例 #1
0
 def create(self, **kwargs):
     self.create_gke_cluster = (kwargs.get('create_gke_cluster',
                                           'false').lower() != 'false')
     if self.create_gke_cluster and 'GKE_NUM_NODES' not in kwargs:
         raise base_environment.VitessEnvironmentError(
             'Must specify GKE_NUM_NODES')
     if 'GKE_CLUSTER_NAME' not in kwargs:
         kwargs['GKE_CLUSTER_NAME'] = getpass.getuser()
     if 'VITESS_NAME' not in kwargs:
         kwargs['VITESS_NAME'] = getpass.getuser()
     kwargs['TEST_MODE'] = '1'
     self.script_dir = os.path.join(os.environ['VTTOP'],
                                    'examples/kubernetes')
     try:
         subprocess.check_output(['gcloud', 'config', 'list'])
     except OSError:
         raise base_environment.VitessEnvironmentError(
             'gcloud not found, please install by visiting cloud.google.com'
         )
     if 'project' in kwargs:
         logging.info('Setting project to %s', kwargs['project'])
         subprocess.check_output(
             ['gcloud', 'config', 'set', 'project', kwargs['project']])
     project_name_json = json.loads(
         subprocess.check_output(
             ['gcloud', 'config', 'list', 'project', '--format', 'json']))
     project_name = project_name_json['core']['project']
     logging.info('Current project name: %s', project_name)
     for k, v in kwargs.iteritems():
         os.environ[k] = v
     if self.create_gke_cluster:
         cluster_up_txt = subprocess.check_output(
             [os.path.join(self.script_dir, 'cluster-up.sh')],
             cwd=self.script_dir,
             stderr=subprocess.STDOUT)
         logging.info(cluster_up_txt)
     vitess_up_output = subprocess.check_output(
         [os.path.join(self.script_dir, 'vitess-up.sh')],
         cwd=self.script_dir,
         stderr=subprocess.STDOUT)
     logging.info(vitess_up_output)
     self.use_named(kwargs['VITESS_NAME'])
コード例 #2
0
    def poll_for_varz(self,
                      tablet_name,
                      varz,
                      timeout=60.0,
                      condition_fn=None,
                      converter=str,
                      condition_msg=None):
        """Polls for varz to exist, or match specific conditions, within a timeout.

    Args:
      tablet_name: the name of the process that we're trying to poll vars from.
      varz: name of the vars to fetch from varz
      timeout: number of seconds that we should attempt to poll for.
      condition_fn: a function that takes the var as input, and returns a truthy
        value if it matches the success conditions.
      converter: function to convert varz value
      condition_msg: string describing the conditions that we're polling for,
        used for error messaging.

    Raises:
      VitessEnvironmentError: Raised if the varz conditions aren't met within
        the given timeout.

    Returns:
      dict of requested varz.
    """
        start_time = time.time()
        while True:
            if (time.time() - start_time) >= timeout:
                timeout_error_msg = 'Timed out polling for varz.'
                if condition_fn and condition_msg:
                    timeout_error_msg += ' Condition "%s" not met.' % condition_msg
                raise base_environment.VitessEnvironmentError(
                    timeout_error_msg)
            hostname = self.get_tablet_ip_port(tablet_name)
            host_varz = subprocess.check_output([
                'kubectl', 'exec', '-ti',
                self.get_tablet_pod_name(tablet_name),
                '--namespace=%s' % self.cluster_name, 'curl',
                '%s/debug/vars' % hostname
            ])
            if not host_varz:
                continue
            host_varz = json.loads(host_varz)
            if condition_fn is None or condition_fn(host_varz):
                return host_varz
コード例 #3
0
    def use_named(self, instance_name):
        # Check to make sure kubectl exists
        try:
            subprocess.check_output(['kubectl'])
        except OSError:
            raise base_environment.VitessEnvironmentError(
                'kubectl not found, please install by visiting kubernetes.io or '
                'running gcloud components update kubectl if using compute engine.'
            )

        get_address_template = (
            '{{if ge (len .status.loadBalancer) 1}}'
            '{{index (index .status.loadBalancer.ingress 0) "ip"}}'
            '{{end}}')

        get_address_params = [
            'kubectl', 'get', '-o', 'template', '--template',
            get_address_template, 'service', '--namespace', instance_name
        ]

        start_time = time.time()
        vtctld_addr = ''
        while time.time() - start_time < 60 and not vtctld_addr:
            vtctld_addr = subprocess.check_output(get_address_params +
                                                  ['vtctld'],
                                                  stderr=subprocess.STDOUT)
        self.vtctl_addr = '%s:15999' % vtctld_addr

        self.vtctl_helper = vtctl_helper.VtctlHelper('grpc', self.vtctl_addr)
        self.cluster_name = instance_name

        keyspaces = self.vtctl_helper.execute_vtctl_command(['GetKeyspaces'])
        self.mobs = filter(None, keyspaces.split('\n'))
        self.keyspaces = self.mobs

        if not self.keyspaces:
            raise base_environment.VitessEnvironmentError(
                'Invalid environment, no keyspaces found')

        self.num_shards = []

        for keyspace in self.keyspaces:
            keyspace_info = json.loads(
                self.vtctl_helper.execute_vtctl_command(
                    ['GetKeyspace', keyspace]))
            if not keyspace_info:
                self.num_shards.append(1)
            else:
                self.num_shards.append(keyspace_info['split_shard_count'])

        # This assumes that all keyspaces use the same set of cells
        self.cells = json.loads(
            self.vtctl_helper.execute_vtctl_command([
                'GetShard',
                '%s/%s' % (self.keyspaces[0],
                           utils.get_shard_name(0, self.num_shards[0]))
            ]))['cells']

        self.primary_cells = self.cells
        self.replica_instances = []
        self.rdonly_instances = []

        # This assumes that all cells are equivalent for k8s environments.
        all_tablets_in_a_cell = self.vtctl_helper.execute_vtctl_command(
            ['ListAllTablets', self.cells[0]])
        all_tablets_in_a_cell = [
            x.split(' ')
            for x in filter(None, all_tablets_in_a_cell.split('\n'))
        ]

        for index, keyspace in enumerate(self.keyspaces):
            keyspace_tablets_in_cell = [
                tablet for tablet in all_tablets_in_a_cell
                if tablet[1] == keyspace
            ]
            replica_tablets_in_cell = [
                tablet for tablet in keyspace_tablets_in_cell
                if tablet[3] == 'master' or tablet[3] == 'replica'
            ]
            replica_instances = len(
                replica_tablets_in_cell) / self.num_shards[index]
            self.replica_instances.append(replica_instances)
            self.rdonly_instances.append((len(keyspace_tablets_in_cell) /
                                          self.num_shards[index]) -
                                         replica_instances)

        # Converts keyspace name and alias to number of instances
        self.keyspace_alias_to_num_instances_dict = {}
        for index, keyspace in enumerate(self.keyspaces):
            self.keyspace_alias_to_num_instances_dict[keyspace] = {
                'replica': int(self.replica_instances[index]),
                'rdonly': int(self.rdonly_instances[index])
            }

        start_time = time.time()
        self.vtgate_addrs = {}
        self.vtgate_conns = {}
        for cell in self.cells:
            self.vtgate_addr = ''
            while time.time() - start_time < 60 and not self.vtgate_addr:
                vtgate_addr = subprocess.check_output(get_address_params +
                                                      ['vtgate-%s' % cell],
                                                      stderr=subprocess.STDOUT)
            self.vtgate_addrs[cell] = '%s:15001' % vtgate_addr
            self.vtgate_conns[cell] = vtgate_client.connect(
                protocols_flavor.protocols_flavor().vtgate_python_protocol(),
                self.vtgate_addrs[cell], 60)
コード例 #4
0
    def use_named(self, instance_name):
        # Check to make sure kubectl exists
        try:
            subprocess.check_output(['kubectl'])
        except OSError:
            raise base_environment.VitessEnvironmentError(
                'kubectl not found, please install by visiting kubernetes.io or '
                'running gcloud components update kubectl if using compute engine.'
            )

        vtctld_ip = kubernetes_components.get_forwarded_ip(
            'vtctld', instance_name)
        self.vtctl_addr = '%s:15999' % vtctld_ip

        self.vtctl_helper = vtctl_helper.VtctlHelper('grpc', self.vtctl_addr)
        self.cluster_name = instance_name

        keyspaces = self.vtctl_helper.execute_vtctl_command(['GetKeyspaces'])
        self.mobs = filter(None, keyspaces.split('\n'))
        self.keyspaces = self.mobs

        if not self.keyspaces:
            raise base_environment.VitessEnvironmentError(
                'Invalid environment, no keyspaces found')

        self.num_shards = []
        self.shards = []

        for keyspace in self.keyspaces:
            shards = json.loads(
                self.vtctl_helper.execute_vtctl_command(
                    ['FindAllShardsInKeyspace', keyspace]))
            self.shards.append(shards)
            self.num_shards.append(len(shards))

        # This assumes that all keyspaces use the same set of cells
        self.cells = json.loads(
            self.vtctl_helper.execute_vtctl_command([
                'GetShard',
                '%s/%s' % (self.keyspaces[0], self.shards[0].keys()[0])
            ]))['cells']

        self.primary_cells = self.cells
        self.replica_instances = []
        self.rdonly_instances = []

        # This assumes that all cells are equivalent for k8s environments.
        all_tablets_in_a_cell = self.vtctl_helper.execute_vtctl_command(
            ['ListAllTablets', self.cells[0]])
        all_tablets_in_a_cell = [
            x.split(' ')
            for x in filter(None, all_tablets_in_a_cell.split('\n'))
        ]

        for index, keyspace in enumerate(self.keyspaces):
            keyspace_tablets_in_cell = [
                tablet for tablet in all_tablets_in_a_cell
                if tablet[1] == keyspace
            ]
            replica_tablets_in_cell = [
                tablet for tablet in keyspace_tablets_in_cell
                if tablet[3] == 'master' or tablet[3] == 'replica'
            ]
            replica_instances = len(
                replica_tablets_in_cell) / self.num_shards[index]
            self.replica_instances.append(replica_instances)
            self.rdonly_instances.append((len(keyspace_tablets_in_cell) /
                                          self.num_shards[index]) -
                                         replica_instances)

        # Converts keyspace name and alias to number of instances
        self.keyspace_alias_to_num_instances_dict = {}
        for index, keyspace in enumerate(self.keyspaces):
            self.keyspace_alias_to_num_instances_dict[keyspace] = {
                'replica': int(self.replica_instances[index]),
                'rdonly': int(self.rdonly_instances[index])
            }

        self.vtgate_addrs = {}
        for cell in self.cells:
            vtgate_ip = kubernetes_components.get_forwarded_ip(
                'vtgate-%s' % cell, instance_name)
            self.vtgate_addrs[cell] = '%s:15991' % vtgate_ip
        super(K8sEnvironment, self).use_named(instance_name)