PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
# -*- coding: utf-8 -*- # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT from __future__ import print_function from __future__ import absolute_import from __future__ import division import os import pwd import requests import requests.packages.urllib3.exceptions as urllib_exceptions # pylint: disable=E0401 import shutil from requests.exceptions import ConnectionError from future.utils import iteritems from past.builtins import basestring from . import clpassenger from . import clselectctl from . import utils from clcommon.cpapi import userdomains from clcommon.utils import mod_makedirs from .clselectexcept import ClSelectExcept from .clselectnodejs.apps_manager import ApplicationsManager from .clselectnodejsuser import environments, interpreters from .baseclselect import APP_STARTED_CONST, APP_STOPPED_CONST from .clselectprint import clprint DEFAULT_STARTUP_FILE = "app.js" DEFAULT_APP_STATE = APP_STARTED_CONST def _create_environment(user, directory, version, env_name=None, destroy_first=False): prefix = _get_prefix(user, directory) if not env_name: env_name = version environment = environments.Environment(env_name, user, prefix) if not environment.exists() or destroy_first: try: interpreter = interpreters.interpreters(key="version")[version] except KeyError: raise ClSelectExcept.NoSuchAlternativeVersion(version) environment.create(interpreter, destroy_first=destroy_first) return environment def _get_environment(user, directory, app_summary=None): prefix = _get_prefix(user, directory) if app_summary is None: user_summary = clpassenger.summary(user) try: app_summary = utils.get_using_realpath_keys(user, directory, user_summary) except KeyError: raise ClSelectExcept.NoSuchApplication( 'No such application (or application not configured) "%s"' % directory ) binary = app_summary["binary"] env_name = os.path.basename(os.path.dirname(os.path.dirname(binary))) environment = environments.Environment(env_name, user, prefix) return environment def _get_prefix(user, directory): _, rel_dir = utils.get_abs_rel(user, directory) return os.path.join(environments.DEFAULT_PREFIX, rel_dir) def _ensure_version_enabled(version, user): """ Check whether particular interpreter version is enabled and raises exception if not :param user: user to include in exception """ from .clselectnodejs import node_manager if not node_manager.NodeManager().is_version_enabled(version): raise ClSelectExcept.UnableToSetAlternative(user, version, "version is not enabled") def _get_existing_nesting_app_for(new_app_directory, user, apps_manager=None): """ Return None if new_app_directory is not nested inside an existing user application, and the name of conflicting application otherwise """ if apps_manager is None: apps_manager = ApplicationsManager() abs_app_path, _ = utils.get_abs_rel(user, new_app_directory) full_config = apps_manager.get_user_config_data(user) for existing_app in full_config.keys(): # In case home directory was symlinked after config was written existing_app_abs_path, _ = utils.get_abs_rel(user, existing_app) if (abs_app_path + os.sep).startswith(existing_app_abs_path + os.sep): return existing_app return None def create( user, directory, alias, version=None, doc_root=None, app_mode=None, env_vars=None, startup_file=None, domain_name=None, apps_manager=None, passenger_log_file=None, ): """ Create application :param user: unix user name :param directory: application path in user's home (app-root) :param alias: alias (app-uri) :param version: version of interpreter :param doc_root: doc_root :param app_mode: application mode for nodejs :param env_vars: dict with enviroment variables :param startup_file: main application file :param domain_name: domain name :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :param passenger_log_file: Passenger log filename to write to app's .htaccess :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() if version is None: raise ClSelectExcept.WrongData("Not passed version as argument") _ensure_version_enabled(version, user) if startup_file is None: startup_file = DEFAULT_STARTUP_FILE if env_vars is None: env_vars = {} if app_mode is None: app_mode = "production" conflicting_app = _get_existing_nesting_app_for(directory, user, apps_manager) if conflicting_app is not None: raise ClSelectExcept.BusyApplicationRoot(conflicting_app) alias = clselectctl.get_alias(alias) environment = _create_environment(user, directory, version) binary = environment.interpreter().binary clpassenger.configure( user, directory, alias, apps_manager.INTERPRETER, binary, doc_root=doc_root, startup_file=startup_file, passenger_log_file=passenger_log_file, ) # webapp was started clpassenger.restart(user, directory) if not domain_name: # if domain name not defined - try to detemine it summary_data = clpassenger.summary(user) app_summary = utils.get_using_realpath_keys(user, directory, summary_data) domain_name = app_summary["domain"] app_data = { "nodejs_version": version, "domain": domain_name, "app_uri": alias, "app_status": DEFAULT_APP_STATE, "startup_file": startup_file, "app_mode": app_mode, "config_files": [], "env_vars": env_vars, } if passenger_log_file: app_data["passenger_log_file"] = passenger_log_file apps_manager.add_app_to_config(user, directory, app_data) try: apps_manager.add_env_vars_for_htaccess(user, directory, env_vars, doc_root) except Exception as err: clprint.print_diag("text", {"status": "ERROR", "message": str(err)}) def _create_symlink_to_node_modules(username, environment_path, app_root): """ Creates symlink to app's node_modules in app_root :param username: user name :param environment_path: Path to app's virtual environment :param app_root: Application root :return: None """ # This function logic is duplicated in npm wrapper, but we still need it here too. See commit # message of LVEMAN-1335 message = ( "Cloudlinux NodeJS Selector demands to store node modules for application " "in separate folder (virtual environment) pointed by symlink " 'called "node_modules". That`s why application should not contain folder/file ' "with such name in application root" ) link_name = os.path.join(pwd.getpwnam(username).pw_dir, app_root, "node_modules") if os.path.islink(link_name): try: os.remove(link_name) except OSError: raise ClSelectExcept.RemoveSymlinkError("Can`t remove symlink %(link_name)s" % {"link_name": link_name}) elif os.path.exists(link_name): # link_name not a old symlink, but exists raise ClSelectExcept.SymlinkError(message) link_to = os.path.join(environment_path, "lib/node_modules") if not os.path.exists(link_to): mod_makedirs(link_to, 0o775) try: os.symlink(link_to, link_name) except OSError: raise ClSelectExcept.CreateSymlinkError("Error creating symlink. " + message) def destroy(user, app_directory, doc_root, apps_manager=None): """ Destroy web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() # get app state app_config = apps_manager.get_app_config(user, app_directory) # remove env from htaccess try: # if domain is already removed we shouldn't do anything if doc_root is not None: apps_manager.add_env_vars_for_htaccess(user, app_directory, None, doc_root) except Exception as err: clprint.print_diag("text", {"status": "ERROR", "message": str(err)}) if app_config.get("app_status") == APP_STOPPED_CONST: # stopped app user_home = pwd.getpwnam(user).pw_dir # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app nodevenv_path = "/".join([user_home, "nodevenv", app_directory]) try: # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app shutil.rmtree(nodevenv_path) except OSError: pass # if domain is already removed we shouldn't do anything if doc_root is not None: # Remove NodeJS lines from .htaccess htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root) clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename) # remove app from node-selector.json file apps_manager.remove_app_from_config(user, app_directory) # Update application status in passenger try: clpassenger.restart(user, app_directory) except ClSelectExcept.MissingApprootDirectory: pass return # Moved before removing an app from node-selector.json because in case if # app_root is absent we still want to remove venv dir of an application. # The method didn't anyhing if app_root is absent and skip other commands # including removal of a venv dir prefix = _get_prefix(user, app_directory) abs_dir, _ = utils.get_abs_rel(user, prefix) try: # Remove app's nodenv, e.g. /home/cltest1/nodevenv/test_app shutil.rmtree(abs_dir) except OSError: pass user_summary = clpassenger.summary(user) # remove app from node-selector.json file app_in_config = apps_manager.remove_app_from_config(user, app_directory) try: utils.get_using_realpath_keys(user, app_directory, user_summary) except KeyError: # if app was existed and app's dir is not exists, we skip all further actions if app_in_config: return None else: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # remove app from passenger clpassenger.unconfigure(user, app_directory) # Clear .htaccess try: clpassenger.restart(user, app_directory) except ClSelectExcept.MissingApprootDirectory: pass def start(user, app_directory, doc_root, apps_manager=None): """ Starts web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # Do nothing if application already started if app_config.get("app_status") == APP_STARTED_CONST: return # Create .htaccess file for the application apps_manager.update_htaccess_file(user, app_directory, doc_root) # Save new application status in user's config apps_manager.set_app_status(user, app_directory, APP_STARTED_CONST) # Update application status in passenger clpassenger.restart(user, app_directory) def restart(user, app_directory, doc_root, apps_manager=None): """ Restarts web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # If application was stopped - start it if app_config.get("app_status") == APP_STOPPED_CONST: start(user, app_directory, doc_root) else: clpassenger.restart(user, app_directory) def stop(user, app_directory, doc_root, apps_manager=None): """ Stops web app with specified directory for specified user :param user: username :param app_directory: application directory :param doc_root: Document root for selected domain :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() app_config = apps_manager.get_app_config(user, app_directory) if app_config is None: raise ClSelectExcept.WrongData('No such application (or application not configured) "%s"' % app_directory) # Do nothing if application is not started if app_config.get("app_status") == APP_STOPPED_CONST: return htaccess_filename = apps_manager.get_htaccess_by_appdir(user, app_directory, doc_root, app_config) # Remove NodeJS lines from .htaccess clpassenger.remove_passenger_lines_from_htaccess(htaccess_filename) # Save new application status in user's config apps_manager.set_app_status(user, app_directory, APP_STOPPED_CONST) # Update application status in passenger clpassenger.restart(user, app_directory) def check_response_from_webapp(domain, alias, action=None): """ Check response from user's webapp before and after calling action. Also compare both responses :param domain: domain associated with webapp :param alias: URI associated with webapp :param action: called action, that make something with webapp: install modules, transit it, etc :return: None """ app_is_inaccessible_before = 'Web application is inaccessible by its address "%s". The operation wasn\'t performed.' app_is_inaccessible_after = ( "The operation was performed, but check availability of application has failed. " 'Web application is inaccessible by its address "%s" after the operation.' ) app_is_broken = ( "The operation was performed, but check availability of application has failed. " 'Web application responds, but its return code "%s" or ' 'content type before operation "%s" doesn\'t equal to contet type after operation "%s".' ) requests.packages.urllib3.disable_warnings(urllib_exceptions.InsecureRequestWarning) # pylint: disable=E1101 if not callable(action): raise ClSelectExcept.WrongData("Wrong action for calling in checking webapp") webapp_url = "https://{domain}/{alias}".format( domain=domain, alias=alias, ) # for hiding from the module of Apache `mod_security` headers = { "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) " "Gecko/20101209 CentOS/3.6-2.el5.centos Firefox/3.6.13" } try: # Applies only to wildcard domains because '*' allows accessing URLs like # Example: http://{anything}.domain/nodejs_app. webapp_url = utils.transform_wildcard_url(webapp_url) request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: # site is not available by https protocol webapp_url = webapp_url.replace("https://", "http://") try: request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: raise ClSelectExcept.WebAppError(app_is_inaccessible_before % webapp_url) before_mime_type = request.headers.get("Content-Type") before_status = request.headers.get("Status") action() try: request = requests.get(webapp_url, verify=False, headers=headers) except ConnectionError: raise ClSelectExcept.WebAppError(app_is_inaccessible_after % webapp_url) after_mime_type = request.headers.get("Content-Type") after_status = request.headers.get("Status") # assume that app is broken if: # it's response Content-Type or Status code (if first code wasn't 500) changed # if last Status code was 500 (internal error) if ( before_mime_type.lower() != after_mime_type.lower() or (before_status != after_status and before_status is not None and before_status[:3] != "500") or (after_status is not None and after_status[:3] == "500") ): raise ClSelectExcept.WebAppError(app_is_broken % (after_status, before_mime_type, after_mime_type)) def _get_info_about_webapp(app_summary=None, user=None): """ Get info (alias and domain) about user's web application :param app_summary: dict -> summary info about user's web application :param user: str -> name of unix user :return: tuple -> (alias, domain) """ if app_summary is None: raise ClSelectExcept.WrongData("Was passed incorrect summary info about application") if user is None: raise ClSelectExcept.WrongData("Was passed incorrect name of user") alias = app_summary["alias"] user_domains = userdomains(user) found_domains = [ domain for domain, doc_root in user_domains if utils.realpaths_are_equal(user, doc_root, app_summary["docroot"]) ] if len(found_domains) == 0: raise ClSelectExcept.WrongData("Can not found suitable domain for application") app_domain = found_domains[0] return alias, app_domain def install(user, directory, extension="-", skip_web_check=False, apps_manager=None): """ Install nodejs extension to user's webapp :param user: name os unix user :param directory: directory with webapp (app-root) :param extension: name and version of extension :param skip_web_check: skip check web application after change it's properties :param apps_manager: Application Manager. Class that responsible for gathering and writing information about applications :return: None """ if apps_manager is None: apps_manager = ApplicationsManager() user_config = apps_manager.get_user_config_data(user) try: app_data = utils.get_using_realpath_keys(user, directory, user_config) except KeyError: raise ClSelectExcept.WrongData("Record about application {} is absent".format(directory)) if app_data["app_status"] != APP_STARTED_CONST: skip_web_check = True else: alias = app_data["app_uri"] app_domain = app_data["domain"] nodejs_version = app_data["nodejs_version"] cwd, _ = utils.get_abs_rel(user, directory) environment = _create_environment(user, directory, nodejs_version) def action(): # npm install environment.extension_install(extension=extension, cwd=cwd) clpassenger.restart(user, directory) if not skip_web_check: try: check_response_from_webapp( domain=app_domain, alias=alias, action=action, ) except ClSelectExcept.WebAppError as err: raise ClSelectExcept.WebAppError("An error occured during installation of modules. %s" % err) else: action() def summary(user): summ = {} for directory, data in iteritems(clpassenger.summary(user)): if data["interpreter"] != ApplicationsManager.INTERPRETER: continue environment = _get_environment(user, directory, data).as_deepdict() summ[directory] = { "domain": data["domain"], "alias": data["alias"], "environment": environment["name"], "interpreter": environment["interpreter"], } # add only list with additions domains if "domains" in data and len(data["domains"]) > 1: summ[directory]["domains"] = data["domains"] return summ def validate_env_vars(env_vars): if type(env_vars) is not dict: raise TypeError for item in env_vars: if not isinstance(env_vars[item], basestring): raise TypeError return env_vars