def ssh_copy_id(cls, # pylint: disable=too-many-arguments instance: object, name: str, user: str, key_file: str, comment: str = "test@local") -> None: container = cls.get_container(instance, name) pub_key = pub_key_from_private_key_file(key_file) shell_command = f"umask 077 && echo 'ssh-rsa {pub_key} {comment}' >> ~/.ssh/authorized_keys" res = container.exec_run(["sh", "-c", shell_command], user=user) if res.exit_code: raise DockerException(f"{container}: {res.output.decode('utf-8')}")
def _create_instance(self, node_index, dc_idx, spot=False): # if size of disk is larget than 80G, then # change the timeout of job completion to default * 3. gce_job_default_timeout = None if self._gce_image_size and int(self._gce_image_size) > 80: gce_job_default_timeout = self._gce_services[ dc_idx].connection.timeout self._gce_services[ dc_idx].connection.timeout = gce_job_default_timeout * 3 self.log.info("Job complete timeout is set to %ss" % self._gce_services[dc_idx].connection.timeout) name = f"{self.node_prefix}-{dc_idx}-{node_index}".lower() gce_disk_struct = self._get_disks_struct(name=name, dc_idx=dc_idx) # Name must start with a lowercase letter followed by up to 63 # lowercase letters, numbers, or hyphens, and cannot end with a hyphen assert len(name) <= 63, "Max length of instance name is 63" startup_script = self.test_config.get_startup_script() if self.params.get("scylla_linux_distro") in ( "ubuntu-bionic", "ubuntu-xenial", "ubuntu-focal", ): # we need to disable sshguard to prevent blocking connections from the builder startup_script += dedent(""" sudo systemctl disable sshguard sudo systemctl stop sshguard """) username = self.params.get("gce_image_username") public_key = pub_key_from_private_key_file( self.params.get("user_credentials_path")) create_node_params = dict( name=name, size=self._gce_instance_type, image=self._gce_image, ex_network=self._gce_network, ex_disks_gce_struct=gce_disk_struct, ex_metadata={ **self.tags, "Name": name, "NodeIndex": node_index, "startup-script": startup_script, "user-data": json.dumps( dict(scylla_yaml=dict(cluster_name=self.name), start_scylla_on_first_boot=False)), "block-project-ssh-keys": "true", "ssh-keys": f"{username}:ssh-rsa {public_key}", }, ex_service_accounts=self._service_accounts, ex_preemptible=spot) instance = self._create_node_with_retries( name=name, dc_idx=dc_idx, create_node_params=create_node_params, spot=spot) self.log.info('Created %s instance %s', 'spot' if spot else 'on-demand', instance) if gce_job_default_timeout: self.log.info('Restore default job timeout %s' % gce_job_default_timeout) self._gce_services[ dc_idx].connection.timeout = gce_job_default_timeout return instance
def _create_instance(self, node_index, dc_idx, spot=False): # if size of disk is larget than 80G, then # change the timeout of job completion to default * 3. gce_job_default_timeout = None if self._gce_image_size and int(self._gce_image_size) > 80: gce_job_default_timeout = self._gce_services[ dc_idx].connection.timeout self._gce_services[ dc_idx].connection.timeout = gce_job_default_timeout * 3 self.log.info("Job complete timeout is set to %ss" % self._gce_services[dc_idx].connection.timeout) name = f"{self.node_prefix}-{dc_idx}-{node_index}".lower() gce_disk_struct = list() gce_disk_struct.append( self._get_root_disk_struct(name=name, disk_type=self._gce_image_type, dc_idx=dc_idx)) for i in range(self._gce_n_local_ssd): gce_disk_struct.append( self._get_local_ssd_disk_struct(name=name, index=i, dc_idx=dc_idx)) if self._add_disks: for disk_type, disk_size in self._add_disks.items(): disk_size = int(disk_size) if disk_size: gce_disk_struct.append( self._get_persistent_disk_struct(name=name, disk_size=disk_size, disk_type=disk_type, dc_idx=dc_idx)) self.log.info(gce_disk_struct) # Name must start with a lowercase letter followed by up to 63 # lowercase letters, numbers, or hyphens, and cannot end with a hyphen assert len(name) <= 63, "Max length of instance name is 63" startup_script = cluster.Setup.get_startup_script() if self.params.get("scylla_linux_distro") in ( "ubuntu-bionic", "ubuntu-xenial", "ubuntu-focal", ): # we need to disable sshguard to prevent blocking connections from the builder startup_script += dedent(""" sudo systemctl disable sshguard sudo systemctl stop sshguard """) username = self.params.get("gce_image_username") public_key = pub_key_from_private_key_file( self.params.get("user_credentials_path")) create_node_params = dict( name=name, size=self._gce_instance_type, image=self._gce_image, ex_network=self._gce_network, ex_disks_gce_struct=gce_disk_struct, ex_metadata={ **self.tags, "Name": name, "NodeIndex": node_index, "startup-script": startup_script, "user-data": json.dumps( dict(scylla_yaml=dict(cluster_name=self.name), start_scylla_on_first_boot=False)), "block-project-ssh-keys": "true", "ssh-keys": f"{username}:ssh-rsa {public_key}", }, ex_service_accounts=self._service_accounts, ex_preemptible=spot) try: instance = self._gce_services[dc_idx].create_node( **create_node_params) except GoogleBaseError as details: if not spot: raise self.log.warning( 'Unable to create a spot instance, try to create an on-demand one: %s', details) # May happen that spot instance was preempted during instance creating. This instance won't be # destroyed but stopped and stays with the name in the instances pool. In this case we should destroy this # instance before creating new one if "Instance failed to start due to preemption" in str(details) and \ (failed_instance := self._get_instances_by_name(dc_idx=dc_idx, name=name)): self._gce_services[dc_idx].destroy_node(node=failed_instance, destroy_boot_disk=True) create_node_params['ex_preemptible'] = spot = False instance = self._gce_services[dc_idx].create_node( **create_node_params)