def test_multi_step_deployment(self): msd = MultiStepDeployment() self.assertEqual(len(msd.steps), 0) msd.add(MockDeployment()) self.assertEqual(len(msd.steps), 1) self.assertEqual(self.node, msd.run(node=self.node, client=None))
def deploy_node(self, **kwargs): """ Create a new node, and start deployment. @keyword enable_root: If true, root password will be set to vnc_password (this will enable SSH access) and default 'toor' account will be deleted. @type enable_root: C{bool} For detailed description and keywords args, see L{NodeDriver.deploy_node}. """ image = kwargs['image'] vnc_password = kwargs.get('vnc_password', None) enable_root = kwargs.get('enable_root', False) if not vnc_password: raise ValueError('You need to provide vnc_password argument ' 'if you want to use deployment') if (image in STANDARD_DRIVES and STANDARD_DRIVES[image]['supports_deployment']): raise ValueError('Image %s does not support deployment' % (image.id)) if enable_root: script = ("unset HISTFILE;" "echo root:%s | chpasswd;" "sed -i '/^toor.*$/d' /etc/passwd /etc/shadow;" "history -c") % vnc_password root_enable_script = ScriptDeployment(script=script, delete=True) deploy = kwargs.get('deploy', None) if deploy: if (isinstance(deploy, ScriptDeployment) or isinstance(deploy, SSHKeyDeployment)): deployment = MultiStepDeployment([deploy, root_enable_script]) elif isinstance(deploy, MultiStepDeployment): deployment = deploy deployment.add(root_enable_script) else: deployment = root_enable_script kwargs['deploy'] = deployment if not kwargs.get('ssh_username', None): kwargs['ssh_username'] = '******' return super(ElasticHostsBaseNodeDriver, self).deploy_node(**kwargs)
def deploy_node(self, **kwargs): """ Create a new node, and start deployment. @keyword enable_root: If true, root password will be set to vnc_password (this will enable SSH access) and default 'toor' account will be deleted. @type enable_root: C{bool} For detailed description and keywords args, see L{NodeDriver.deploy_node}. """ image = kwargs['image'] vnc_password = kwargs.get('vnc_password', None) enable_root = kwargs.get('enable_root', False) if not vnc_password: raise ValueError('You need to provide vnc_password argument ' 'if you want to use deployment') if (image in self._standard_drives and not self._standard_drives[image]['supports_deployment']): raise ValueError('Image %s does not support deployment' % (image.id)) if enable_root: script = ("unset HISTFILE;" "echo root:%s | chpasswd;" "sed -i '/^toor.*$/d' /etc/passwd /etc/shadow;" "history -c") % vnc_password root_enable_script = ScriptDeployment(script=script, delete=True) deploy = kwargs.get('deploy', None) if deploy: if (isinstance(deploy, ScriptDeployment) or isinstance(deploy, SSHKeyDeployment)): deployment = MultiStepDeployment([deploy, root_enable_script]) elif isinstance(deploy, MultiStepDeployment): deployment = deploy deployment.add(root_enable_script) else: deployment = root_enable_script kwargs['deploy'] = deployment if not kwargs.get('ssh_username', None): kwargs['ssh_username'] = '******' return super(ElasticStackBaseNodeDriver, self).deploy_node(**kwargs)
def deploy_node(self, **kwargs): """ Create a new node, and start deployment. @inherits: :class:`NodeDriver.deploy_node` :keyword enable_root: If true, root password will be set to vnc_password (this will enable SSH access) and default 'toor' account will be deleted. :type enable_root: ``bool`` """ image = kwargs["image"] vnc_password = kwargs.get("vnc_password", None) enable_root = kwargs.get("enable_root", False) if not vnc_password: raise ValueError("You need to provide vnc_password argument " "if you want to use deployment") if (image in self._standard_drives and not self._standard_drives[image]["supports_deployment"]): raise ValueError("Image %s does not support deployment" % (image.id)) if enable_root: script = ("unset HISTFILE;" "echo root:%s | chpasswd;" "sed -i '/^toor.*$/d' /etc/passwd /etc/shadow;" "history -c") % vnc_password root_enable_script = ScriptDeployment(script=script, delete=True) deploy = kwargs.get("deploy", None) if deploy: if isinstance(deploy, ScriptDeployment) or isinstance( deploy, SSHKeyDeployment): deployment = MultiStepDeployment( [deploy, root_enable_script]) elif isinstance(deploy, MultiStepDeployment): deployment = deploy deployment.add(root_enable_script) else: deployment = root_enable_script kwargs["deploy"] = deployment if not kwargs.get("ssh_username", None): kwargs["ssh_username"] = "******" return super(ElasticStackBaseNodeDriver, self).deploy_node(**kwargs)
def _eval_deploy_template(self, node_temp, kwargs): #deploy_node params ssh_username = node_temp.getSshUsername() kwargs = get_property(self, ssh_username, 'ssh_username' , kwargs, lambda x : x) ssh_alternate_usernames = node_temp.getSshAlternateUsernames() kwargs = get_property_list(self, ssh_alternate_usernames, 'ssh_alternate_usernames' , kwargs, lambda x : x) ssh_port = node_temp.getSshPort() kwargs = get_property(self, ssh_port, 'ssh_port' , kwargs, lambda x : int(x)) ssh_timeout = node_temp.getSshTimeout() kwargs = get_property(self, ssh_timeout, 'ssh_timeout' , kwargs, lambda x : float(x)) ssh_key = node_temp.getSshKey() kwargs = get_property(self, ssh_key, 'ssh_key' , kwargs, lambda x : x) timeout = node_temp.getTimeout() kwargs = get_property(self, timeout, 'timeout' , kwargs, lambda x : int(x)) max_tries = node_temp.getMaxTries() kwargs = get_property(self, max_tries, 'max_tries' , kwargs, lambda x : int(x)) ssh_interface = node_temp.getSshInterface() kwargs = get_property(self, ssh_interface, 'ssh_interface' , kwargs, lambda x : x) #get the deployment classes deployments = node_temp.getDeploy() if deployments: msd = MultiStepDeployment() for deploy in deployments: if isinstance(deploy, SshKeyDeployment): msd.add(SSHKeyDeployment(str(deploy.getKey()))) elif isinstance(deploy, FileDeployment): msd.add(FileDeployment(deploy.getSource(), deploy.getTarget())) elif isinstance(deploy, ScriptDeployment): args = deploy.getArgs() arg_lst = self._parse_arg_list(args) msd.add(ScriptDeployment(deploy.getScriptContent(), arg_lst, deploy.getName(), deploy.getDelete())) elif isinstance(deploy, ScriptFileDeployment): args = deploy.getArgs() arg_lst = self._parse_arg_list(args) msd.add(ScriptFileDeployment(deploy.getScriptPath(), arg_lst, deploy.getName(), deploy.getDelete())) kwargs['deploy'] = msd return kwargs
def main( distro, test_type, from_version, to_version, python_package, installer_script_url, additional_packages=None, destroy_node=False, verbose=False, ): # type: (str, str, str, str, str, str, str, bool, bool) -> None # deployment objects for package files will be stored here. file_upload_steps = [] # We always upload all the mock test configs from tests/ami/configs/ directory to a remote # server. # Those configs are used during various checks and tests. Uploading the configs is much less # messy compared to manipulating the configs using sed on the server. file_names = os.listdir(MOCK_CONFIGS_DIRECTORY) for file_name in file_names: config_file_path = os.path.join(MOCK_CONFIGS_DIRECTORY, file_name) file_upload_step = _create_config_file_deployment_step( config_file_path) file_upload_steps.append(file_upload_step) # Upload auxiliary files from tests/ami/files/ file_names = os.listdir(TEST_FILES_DIRECTORY) for file_name in file_names: file_path = os.path.join(TEST_FILES_DIRECTORY, file_name) file_upload_step = _create_file_deployment_step(file_path, "ca_certs") file_upload_steps.append(file_upload_step) if test_type == "install": install_package_source = to_version else: # install package is specified in from-version in case of upgrade install_package_source = from_version # prepare data for install_package install_package_source_type = _get_source_type(install_package_source) if install_package_source_type == "file": # create install package file deployment object. file_upload_steps.append( _create_file_deployment_step(install_package_source, "install_package")) install_package_info = { "type": install_package_source_type, "source": install_package_source, } upgrade_package_info = None # prepare data for upgrade_package if it is specified. if test_type == "upgrade": upgrade_package_source = to_version upgrade_package_source_type = _get_source_type(upgrade_package_source) if upgrade_package_source_type == "file": # create install package file deployment object. file_upload_steps.append( _create_file_deployment_step(to_version, "upgrade_package")) upgrade_package_info = { "type": upgrade_package_source_type, "source": upgrade_package_source, } distro_details = EC2_DISTRO_DETAILS_MAP[distro] if distro.lower().startswith("windows"): package_type = "windows" script_extension = "ps1" else: package_type = ("deb" if distro.startswith("ubuntu") or distro.startswith("debian") else "rpm") script_extension = "sh" script_filename = "test_%s.%s.j2" % (package_type, script_extension) script_file_path = os.path.join(SCRIPTS_DIR, script_filename) with open(script_file_path, "r") as fp: script_content = fp.read() cat_logs_script_file_path = os.path.join( SCRIPTS_DIR, "cat_logs.%s" % (script_extension)) with open(cat_logs_script_file_path, "r") as fp: cat_logs_script_content = fp.read() installer_script_info = { "source": installer_script_url or DEFAULT_INSTALLER_SCRIPT_URL } if os.path.exists(installer_script_url): installer_script_info["type"] = "file" file_upload_steps.append( _create_file_deployment_step(installer_script_url, "install-scalyr-agent-2")) else: if not _verify_url_exists(installer_script_url): raise ValueError( 'Failed to retrieve installer script from "%s". Ensure that the URL is correct.' % (installer_script_url)) installer_script_info["type"] = "url" rendered_template = render_script_template( script_template=script_content, distro_name=distro, distro_details=distro_details, python_package=python_package, test_type=test_type, install_package=install_package_info, upgrade_package=upgrade_package_info, installer_script_url=installer_script_info, additional_packages=additional_packages, verbose=verbose, ) # TODO: Lower those timeouts when upstream yum related issues or similar start to stabilize. # All AMI tests should take less than 5 minutes, but in the last days (dec 1, 2020), they # started to take 10 minutes with multiple timeouts. if "windows" in distro.lower(): deploy_step_timeout = 440 # 320 deploy_overall_timeout = 460 # 320 cat_step_timeout = 10 max_tries = 3 else: deploy_step_timeout = 320 # 260 deploy_overall_timeout = 340 # 280 max_tries = 3 cat_step_timeout = 5 remote_script_name = "deploy.{0}".format(script_extension) test_package_step = ScriptDeployment(rendered_template, name=remote_script_name, timeout=deploy_step_timeout) if file_upload_steps: # Package files must be uploaded to the instance directly. file_upload_steps.append(test_package_step) # type: ignore deployment = MultiStepDeployment(add=file_upload_steps) # type: ignore else: deployment = MultiStepDeployment(add=test_package_step) # type: ignore # Add a step which always cats agent.log file at the end. This helps us troubleshoot failures. if "windows" not in distro.lower(): # NOTE: We don't add it on Windows since it tends to time out often cat_logs_step = ScriptDeployment(cat_logs_script_content, timeout=cat_step_timeout) deployment.add(cat_logs_step) else: cat_logs_step = None # type: ignore driver = get_libcloud_driver() size = NodeSize( distro_details["size_id"], distro_details["size_id"], 0, 0, 0, 0, driver, ) image = NodeImage(distro_details["image_id"], distro_details["image_name"], driver, None) circle_branch_name = compat.os_environ_unicode.get("CIRCLE_BRANCH", "unknown") circle_branch_name = circle_branch_name.replace("/", "_").replace("-", "_") circle_build_num = compat.os_environ_unicode.get("CIRCLE_BUILD_NUM", random.randint(0, 1000)) name = "%s-automated-agent-tests-%s-branch-%s-build-%s" % ( distro, test_type, circle_branch_name, circle_build_num, ) print("Starting node provisioning and tests...") start_time = int(time.time()) kwargs = {} if destroy_node: kwargs["at_exit_func"] = destroy_node_and_cleanup try: node = driver.deploy_node(name=name, image=image, size=size, ssh_key=PRIVATE_KEY_PATH, ex_keyname=KEY_NAME, ex_security_groups=SECURITY_GROUPS, ssh_username=distro_details["ssh_username"], ssh_timeout=20, max_tries=max_tries, wait_period=15, timeout=deploy_overall_timeout, deploy=deployment, **kwargs) except DeploymentError as e: print("Deployment failed: %s" % (str(e))) node = e.node success = False test_package_step.exit_status = 1 stdout = getattr(e.original_error, "stdout", None) stderr = getattr(e.original_error, "stderr", None) else: success = test_package_step.exit_status == 0 stdout = test_package_step.stdout stderr = test_package_step.stderr if cat_logs_step and cat_logs_step.stdout: stdout += "\n" + cat_logs_step.stdout if cat_logs_step and cat_logs_step.stderr: stdout += "\n" + cat_logs_step.stderr duration = int(time.time()) - start_time if success: print("Script successfully completed.") else: print("Script failed.") print(("stdout: %s" % (stdout))) print(("stderr: %s" % (stderr))) print(("exit_code: %s" % (test_package_step.exit_status))) print(("succeeded: %s" % (str(success)))) print(("duration: %s seconds" % (duration))) # We don't destroy node if destroy_node is False (e.g. to aid with troubleshooting on failure # and similar) if node and destroy_node: destroy_node_and_cleanup(driver=driver, node=node) if not success: sys.exit(1)