def do_enable_debugger(self, args): if self._report_not_running(): return if not args: debugger_password = raw_input( "Please enter the password to be used for remote debugger " "access from the modeler, or leave blank to auto-generate " "a password: "******"This action is not available in the Mendix Runtime " "version you are currently using.") logger.error("It was implemented in Mendix 4.3.0") return m2eeresp.display_error() if not m2eeresp.has_error(): logger.info("The remote debugger is now enabled, the password to " "use is %s" % debugger_password) logger.info("You can use the remote debugger option in the Mendix " "Business Modeler to connect to the /debugger/ sub " "url on your application (e.g. " "https://app.example.com/debugger/). ")
def do_unpack(self, args): if not args: logger.error("unpack needs the name of a model upload zipfile in " "%s as argument" % self.m2ee.config.get_model_upload_path()) return (pid_alive, m2ee_alive) = self.m2ee.check_alive() if pid_alive or m2ee_alive: logger.error("The application process is still running, refusing " "to unpack a new application model right now.") return if mdautil.unpack( self.m2ee.config.get_model_upload_path(), args, self.m2ee.config.get_app_base(), ): self.m2ee.reload_config() post_unpack_hook = self.m2ee.config.get_post_unpack_hook() if post_unpack_hook: if os.path.isfile(post_unpack_hook): if os.access(post_unpack_hook, os.X_OK): logger.info("Running post-unpack-hook...") retcode = subprocess.call((post_unpack_hook,)) if retcode != 0: logger.error("The post-unpack-hook returned a " "non-zero exit code: %d" % retcode) else: logger.error("post-unpack-hook script %s is not " "executable." % post_unpack_hook) else: logger.error("post-unpack-hook script %s does not exist." % post_unpack_hook)
def _set_log_level(self, subscriber, node, level): level = level.upper() response = self.m2ee.set_log_level(subscriber, node, level) if response.has_error(): response.display_error() print("Remember, all parameters are case sensitive") else: logger.info("Loglevel for %s set to %s" % (node, level))
def __init__(self, yamlfiles=None): cmd.Cmd.__init__(self) self.m2ee = M2EE(yamlfiles) self.do_status(None) username = pwd.getpwuid(os.getuid())[0] self._default_prompt = "m2ee(%s): " % username self.prompt = self._default_prompt logger.info("Application Name: %s" % self.m2ee.config.get_app_name())
def do_show_critical_log_messages(self, args): if self._report_not_running(): return critlist = self.m2ee.client.get_critical_log_messages() if len(critlist) == 0: logger.info("No messages were logged to a critical loglevel since " "starting the application.") return print("\n".join(critlist))
def _who(self, limitint=None): limit = {} if limitint is not None: limit = {"limit": limitint} m2eeresp = self.m2ee.client.get_logged_in_user_names(limit) m2eeresp.display_error() if not m2eeresp.has_error(): feedback = m2eeresp.get_feedback() logger.info("Logged in users: (%s) %s" % (feedback['count'], feedback['users'])) return feedback['count'] return 0
def do_disable_debugger(self, args): if self._report_not_running(): return m2eeresp = self.m2ee.client.disable_debugger() if m2eeresp.get_result() == m2eeresp.ERR_ACTION_NOT_FOUND: logger.error("This action is not available in the Mendix Runtime " "version you are currently using.") logger.error("It was implemented in Mendix 4.3.0") return if not m2eeresp.has_error(): logger.info("The remote debugger is now disabled.") else: m2eeresp.display_error()
def do_check_health(self, args): if self._report_not_running(): return health_response = self.m2ee.client.check_health() if not health_response.has_error(): feedback = health_response.get_feedback() if feedback['health'] == 'healthy': logger.info("Health check microflow says the application is " "healthy.") elif feedback['health'] == 'sick': logger.warning("Health check microflow says the application " "is sick: %s" % feedback['diagnosis']) elif feedback['health'] == 'unknown': logger.info("Health check microflow is not configured, no " "health information available.") else: logger.error("Unexpected health check status: %s" % feedback['health']) else: if (health_response.get_result() == 3 and health_response.get_cause() == "java.lang.IllegalArgument" "Exception: Action should not be null"): # Because of an incomplete implementation, in Mendix 2.5.4 or # 2.5.5 this means that the runtime is health-check # capable, but no health check microflow is defined. logger.info("Health check microflow is probably not " "configured, no health information available.") elif (health_response.get_result() == health_response.ERR_ACTION_NOT_FOUND): logger.info("The Mendix version you are running does not yet " "support health check functionality.") else: health_response.display_error()
def do_show_current_runtime_requests(self, args): if self._report_not_running(): return m2eeresp = self.m2ee.client.get_current_runtime_requests() if m2eeresp.get_result() == m2eeresp.ERR_ACTION_NOT_FOUND: logger.error("This action is not available in the Mendix Runtime " "version you are currently using.") logger.error("It was implemented in Mendix 2.5.8 and 3.1.0") return m2eeresp.display_error() if not m2eeresp.has_error(): feedback = m2eeresp.get_feedback() if not feedback: logger.info("There are no currently running runtime requests.") else: print("Current running Runtime Requests:") print(yaml.safe_dump(feedback))
def do_status(self, args): if self._report_not_running(): return feedback = self.m2ee.client.runtime_status().get_feedback() logger.info("The application process is running, the MxRuntime has " "status: %s" % feedback['status']) critlist = self.m2ee.client.get_critical_log_messages() if len(critlist) > 0: logger.error("%d critical error(s) were logged. Use show_critical" "_log_messages to view them." % len(critlist)) max_show_users = 10 total_users = self._who(max_show_users) if total_users > max_show_users: logger.info("Only showing %s logged in users. Use who to see a " "complete list." % max_show_users)
def _report_not_running(self): """ To be used by actions to see whether m2ee is available for executing requests. Also prints a line when the application is not running. if self._report_not_running(): return do_things_that_communicate_using_m2ee_client() returns True when m2ee is not available for requests, else False """ (pid_alive, m2ee_alive) = self.m2ee.check_alive() if not pid_alive and not m2ee_alive: logger.info("The application process is not running.") return True # if pid is alive, but m2ee does not respond, errors are already # printed by check_alive if pid_alive and not m2ee_alive: return True return False
def do_interrupt_request(self, args): if self._report_not_running(): return if args == "": logger.error("This function needs a request id as parameter") logger.error("Use show_current_runtime_requests to view currently " "running requests") return m2eeresp = self.m2ee.client.interrupt_request({"request_id": args}) if m2eeresp.get_result() == m2eeresp.ERR_ACTION_NOT_FOUND: logger.error("This action is not available in the Mendix Runtime " "version you are currently using.") logger.error("It was implemented in Mendix 2.5.8 and 3.1.0") return m2eeresp.display_error() if not m2eeresp.has_error(): feedback = m2eeresp.get_feedback() if feedback["result"] is False: logger.error("A request with ID %s was not found" % args) else: logger.info("An attempt to cancel the running action was " "made.")
def do_show_debugger_status(self, args): if self._report_not_running(): return m2eeresp = self.m2ee.client.get_debugger_status() if m2eeresp.get_result() == m2eeresp.ERR_ACTION_NOT_FOUND: logger.error("This action is not available in the Mendix Runtime " "version you are currently using.") logger.error("It was implemented in Mendix 4.3.0") return if not m2eeresp.has_error(): enabled = m2eeresp.get_feedback()['enabled'] connected = m2eeresp.get_feedback()['client_connected'] paused = m2eeresp.get_feedback()['number_of_paused_microflows'] logger.info("The remote debugger is currently %s." % ("enabled" if enabled else "disabled")) if connected: logger.info("A debugger session is connected.") elif enabled: logger.info("There is no connected debugger session.") if enabled and paused == 0: logger.info("There are no paused microflows.") elif paused == 1: logger.info("There is 1 paused microflow.") elif paused > 1: logger.info("There are %s paused microflows." % paused) else: m2eeresp.display_error()
def _stop(self): (pid_alive, m2ee_alive) = self.m2ee.check_alive() if not pid_alive and not m2ee_alive: logger.info("Nothing to stop, the application is not running.") return True logger.debug("Trying to stop the application.") stopped = False logger.info("Waiting for the application to shutdown...") stopped = self.m2ee.runner.stop(timeout=10) if stopped: logger.info("The application has been stopped successfully.") return True logger.warn("The application did not shutdown by itself yet...") answer = None while not answer in ('y', 'n'): answer = raw_input("Do you want to try to signal the JVM " "process to stop immediately? (y)es, (n)o? ") if answer == 'y': logger.info("Waiting for the JVM process to disappear...") stopped = self.m2ee.runner.terminate(timeout=10) if stopped: logger.info("The JVM process has been stopped.") return True elif answer == 'n': logger.info("Doing nothing, use stop again to check if the " "process finally disappeared...") return False else: print("Unknown option %s" % answer) logger.warn("The application process seems not to respond to any " "command or signal.") answer = None while not answer in ('y', 'n'): answer = raw_input("Do you want to kill the JVM process? (y)es," "(n)o? ") if answer == 'y': logger.info("Waiting for the JVM process to disappear...") stopped = self.m2ee.runner.kill(timeout=10) if stopped: logger.info("The JVM process has been destroyed.") return True elif answer == 'n': logger.info("Doing nothing, use stop again to check if the " "process finally disappeared...") return False else: print("Unknown option %s" % answer) logger.error("Stopping the application process failed thorougly.") return False
def do_nagios(self, args): import m2ee.nagios logger.info("The nagios plugin will exit m2ee after running, this is " "by design, don't report it as bug.") # TODO: implement as separate program after libraryfying m2ee sys.exit(m2ee.nagios.check(self.m2ee.runner, self.m2ee.client))
def _start_runtime(self): """ This function deals with the start-up sequence of the Mendix Runtime. After a fixup of the mxclientsystem symlink, which needs to point to the right version of the mxclientsystem code, and submitting runtime configuration settings, the start action is called. Starting the Mendix Runtime can fail in both a temporary or permanent way. Known error codes are: 2: Database to be used does not exist 3: Database structure is out of sync with the application domain model, DDL commands need to be run to synchronize the database. 4: Constant definitions used in the application model are missing from the configuration. 5: In the application database, a user account was detected which has the administrative role (as specified in the modeler) and has password '1'. 6: The Mendix Runtime has reached an invalid state and cannot start. 7,8,9: Mandatory configuration items are missing. By using startresponse.display_error() the error message sent by the Mendix Runtime is printed. Temporary failures need to be resolved, often interactively. """ self.m2ee.fix_mxclientsystem_symlink() if not self.m2ee.send_runtime_config(): return abort = False fully_started = False params = {} while not (fully_started or abort): startresponse = self.m2ee.client.start(params) result = startresponse.get_result() if result == 0: fully_started = True logger.info("The MxRuntime is fully started now.") else: startresponse.display_error() if result == 2: answer = self._ask_user_whether_to_create_db() if answer == 'a': abort = True elif self.m2ee.config._dirty_hack_is_25 and answer == 'c': params["autocreatedb"] = True elif result == 3: answer = self._handle_ddl_commands() if answer == 'a': abort = True elif result == 4: answer = self._ask_user_to_fix_constants() if answer == 'a': abort = True elif result == 5: answer = self._handle_admin_1( startresponse.get_feedback()['users']) if answer == 'a': abort = True elif result == 6: abort = True elif result == 7 or result == 8 or result == 9: logger.error("You'll have to fix the configuration and " "run start again... (or ask for help..)") abort = True else: abort = True if abort: self._stop()