示例#1
0
def download_with_curl(url, output, curl_opts=None):
    interactive = sys.stderr.isatty()
    command = ['curl']
    if interactive:
        command.append('-#')
    else:
        command.append('--silent')
    if curl_opts is not None:
        command.extend([str(opt) for opt in curl_opts])
    command.extend(['--fail', '--output', output, url])

    logger.trace("Executing %s" % command)
    try:
        subprocess.check_call(
            command,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=None if sys.stderr.isatty() else subprocess.PIPE,
            close_fds=True)
    except subprocess.CalledProcessError as cpe:
        if interactive and cpe.returncode == 22:
            # curl error to stderr is already printed on the screen of the user
            raise M2EEException("Failed to download %s" % url,
                                errno=M2EEException.ERR_DOWNLOAD_FAILED)
        else:
            raise M2EEException("Failed to download %s, curl returncode %s" %
                                (url, cpe.returncode),
                                cause=cpe,
                                errno=M2EEException.ERR_DOWNLOAD_FAILED)
示例#2
0
def unpack(config, mda_name):

    mda_file_name = os.path.join(config.get_model_upload_path(), mda_name)
    if not os.path.isfile(mda_file_name):
        raise M2EEException("File %s does not exist." % mda_file_name)

    logger.debug("Testing archive...")
    cmd = ("unzip", "-tqq", mda_file_name)
    logger.trace("Executing %s" % str(cmd))
    try:
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()

        logger.trace("stdout: %s" % stdout)
        logger.trace("stderr: %s" % stderr)
        if proc.returncode != 0:
            raise M2EEException("\n".join([
                "An error occured while testing archive consistency:",
                "stdout: %s" % stdout,
                "stderr: %s" % stderr,
            ]))
    except OSError, ose:
        import errno
        if ose.errno == errno.ENOENT:
            raise M2EEException("The unzip program could not be found", ose)
        else:
            raise M2EEException(
                "An error occured while executing unzip: %s " % ose, ose)
示例#3
0
def dumpdb(config, name=None):
    env = os.environ.copy()
    env.update(config.get_pg_environment())

    if name is None:
        name = ("%s_%s.backup" %
                (env['PGDATABASE'], time.strftime("%Y%m%d_%H%M%S")))

    db_dump_file_name = os.path.join(config.get_database_dump_path(), name)

    logger.info("Writing database dump to %s" % db_dump_file_name)
    cmd = (config.get_pg_dump_binary(), "-O", "-x", "-F", "c")
    logger.trace("Executing %s" % str(cmd))
    try:
        proc = subprocess.Popen(cmd,
                                env=env,
                                stdout=open(db_dump_file_name, 'w+'),
                                stderr=subprocess.PIPE)
        (_, stderr) = proc.communicate()

        if stderr != '':
            raise M2EEException(
                "An error occured while creating database dump: %s" %
                stderr.strip())
    except OSError as e:
        raise M2EEException("Database dump failed, cmd: %s" % cmd, e)
示例#4
0
    def write_felix_config(self):
        felix_config_file = self.get_felix_config_file()
        felix_config_path = os.path.dirname(felix_config_file)
        if not os.access(felix_config_path, os.W_OK):
            raise M2EEException(
                "felix_config_file is not in a writable location: %s" %
                felix_config_path,
                errno=M2EEException.ERR_INVALID_OSGI_CONFIG)

        project_bundles_path = os.path.join(self._conf['m2ee']['app_base'],
                                            'model', 'bundles')
        osgi_storage_path = os.path.join(self._conf['m2ee']['app_base'],
                                         'data', 'tmp', 'felixcache')
        felix_template_file = os.path.join(self._runtime_path, 'runtime',
                                           'felixconfig.properties.template')
        if os.path.exists(felix_template_file):
            logger.debug("writing felix configuration template from %s "
                         "to %s" % (felix_template_file, felix_config_file))
            try:
                input_file = open(felix_template_file)
                template = input_file.read()
            except IOError, e:
                raise M2EEException(
                    "felix configuration template could not be read: %s", e)
            try:
                output_file = open(felix_config_file, 'w')
                render = template.format(
                    ProjectBundlesDir=project_bundles_path,
                    InstallDir=self._runtime_path,
                    FrameworkStorage=osgi_storage_path)
                output_file.write(render)
            except IOError, e:
                raise M2EEException(
                    "felix configuration file could not be written: %s", e)
示例#5
0
def pg_stat_activity(config):
    env = os.environ.copy()
    env.update(config.get_pg_environment())
    datname = env['PGDATABASE']
    usename = env['PGUSER']

    cmd = (config.get_psql_binary(), "-At", "-c",
           "SELECT count(*), state FROM pg_stat_activity "
           "WHERE datname = '%s' AND usename = '%s' GROUP BY 2" %
           (datname, usename))
    try:
        proc = subprocess.Popen(cmd,
                                env=env,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()
        if stderr != '':
            raise M2EEException("Retrieving pg_stat_activity info failed: %s" %
                                stderr.strip())
    except OSError as e:
        raise M2EEException(
            "Retrieving pg_stat_activity info failed, cmd: %s" % cmd, e)

    # e.g. {'idle': 19, 'active': 2, 'idle in transaction': 1}
    return {
        state: int(count)
        for line in stdout.splitlines() for count, state in [line.split('|')]
    }
示例#6
0
    def start_appcontainer(self):
        logger.debug("Checking if the runtime is already alive...")
        (pid_alive, m2ee_alive) = self.check_alive()
        if pid_alive is True or m2ee_alive is True:
            raise M2EEException(
                "There's already a MxRuntime process running, aborting start. "
                "If the application is not functional, or failed to start "
                "earlier, try stop or restart first.",
                errno=M2EEException.ERR_START_ALREADY_RUNNING)

        if not self.config.all_systems_are_go():  # TODO: Exception later
            raise M2EEException(
                "Cannot start MxRuntime due to previous critical errors.",
                errno=M2EEException.ERR_MISSING_CONFIG)

        version = self.config.get_runtime_version()

        if version // 5 or version // 6:
            self.config.write_felix_config()

        if self.config.get_symlink_mxclientsystem():
            util.fix_mxclientsystem_symlink(self.config)

        logger.info("Trying to start the MxRuntime...")
        self.runner.start()
        logger.debug("MxRuntime status: %s" %
                     self.client.runtime_status()['status'])

        # go do startup sequence
        self._configure_logging()
        self._send_mime_types()

        hybrid = self.config.use_hybrid_appcontainer()

        if version < 5 and not hybrid:
            self._send_jetty_config()
        elif version < 5 and hybrid:
            self._send_jetty_config()
            self._connect_xmpp()
            self.client.create_runtime({
                "runtime_path":
                os.path.join(self.config.get_runtime_path(), 'runtime'),
                "port":
                self.config.get_runtime_port(),
                "application_base_path":
                self.config.get_app_base(),
                "use_blocking_connector":
                self.config.get_runtime_blocking_connector(),
            })
        elif version >= 5:
            self.client.update_appcontainer_configuration({
                "runtime_port":
                self.config.get_runtime_port(),
                "runtime_listen_addresses":
                self.config.get_runtime_listen_addresses(),
                "runtime_jetty_options":
                self.config.get_jetty_options()
            })
            self._connect_xmpp()
示例#7
0
def unpack_runtime(version, tempdir, temptgz, runtimes_path):
    try:
        subprocess.check_call(['tar', 'xz', '-C', tempdir, '-f', temptgz])
    except subprocess.CalledProcessError as cpe:
        raise M2EEException("Corrupt runtime archive, extracting failed: %s" % cpe.message, cpe)
    extracted_runtime_dir = os.path.join(tempdir, str(version))
    if not os.path.isdir(extracted_runtime_dir):
        raise M2EEException("Corrupt runtime archive, version %s not found inside!" % version)
    os.rename(extracted_runtime_dir, os.path.join(runtimes_path, str(version)))
示例#8
0
    def start(self, detach=True, timeout=60, step=0.25):
        if self.check_pid():
            logger.error("The application process is already started!")
            return

        if detach:
            try:
                logger.trace("[%s] Forking now..." % os.getpid())
                pid = os.fork()
                if pid > 0:
                    self._pid = None
                    logger.trace("[%s] Waiting for intermediate process to exit..." % os.getpid())
                    # prevent zombie process
                    (pid, result) = os.waitpid(pid, 0)
                    exitcode = result >> 8
                    self._handle_jvm_start_result(exitcode)
                    return
            except OSError, e:
                raise M2EEException("Forking subprocess failed: %d (%s)\n" % (e.errno, e.strerror))
            logger.trace("[%s] Now in intermediate forked process..." % os.getpid())
            # decouple from parent environment
            os.chdir("/")
            os.setsid()
            os.umask(0022)
            exitcode = self._start_jvm(detach, timeout, step)
            logger.trace("[%s] Exiting intermediate process with exit code %s" %
                         (os.getpid(), exitcode))
            os._exit(exitcode)
示例#9
0
 def _handle_jvm_start_result(self, exitcode, output=None):
     if exitcode == 0:
         logger.debug("The JVM process has been started.")
     elif exitcode == 2:
         logger.error("The java binary cannot be found in the default search path!")
         logger.error("By default, when starting the JVM, the environment is not "
                      "preserved. If you don't set preserve_environment to true or "
                      "specify PATH in preserve_environment or custom_environment in "
                      "the m2ee section of your m2ee.yaml configuration file, the "
                      "search path is likely a very basic default list like "
                      "'/bin:/usr/bin'")
         raise M2EEException("Starting the JVM process did not succeed: JVM binary not found",
                             errno=M2EEException.ERR_JVM_BINARY_NOT_FOUND)
     elif exitcode == 3:
         raise M2EEException("Starting the JVM process (fork/exec) did not succeed.",
                             errno=M2EEException.ERR_JVM_FORKEXEC)
     elif exitcode == 4:
         if self.check_pid():
             stopped = self.terminate(5)
         if not stopped and self.check_pid():
             logger.error("Unable to terminate JVM process...")
             stopped = self.kill(5)
         if not stopped:
             logger.error("Unable to kill JVM process!")
         raise M2EEException("Starting the JVM process takes too long.",
                             errno=M2EEException.ERR_JVM_TIMEOUT,
                             output=output)
     elif exitcode == 0x20:
         raise M2EEException("JVM process disappeared with a clean exit code.",
                             errno=M2EEException.ERR_APPCONTAINER_EXIT_ZERO,
                             output=output)
     elif exitcode == 0x21:
         raise M2EEException("JVM process terminated without reason.",
                             errno=M2EEException.ERR_APPCONTAINER_UNKNOWN_ERROR,
                             output=output)
     elif exitcode == 0x22:
         raise M2EEException("JVM process terminated: could not bind admin port.",
                             errno=M2EEException.ERR_APPCONTAINER_ADMIN_PORT_IN_USE,
                             output=output)
     elif exitcode == 0x23:
         raise M2EEException("JVM process terminated: could not bind runtime port.",
                             errno=M2EEException.ERR_APPCONTAINER_RUNTIME_PORT_IN_USE,
                             output=output)
     elif exitcode == 0x24:
         raise M2EEException("JVM process terminated: incompatible JVM version.",
                             errno=M2EEException.ERR_APPCONTAINER_INVALID_JDK_VERSION,
                             output=output)
     else:
         raise M2EEException("Starting the JVM process failed, reason unknown (%s)." %
                             exitcode, errno=M2EEException.ERR_JVM_UNKNOWN,
                             output=output)
     return
示例#10
0
    def _check_appcontainer_config(self):
        # did we load any configuration at all?
        if not self._conf:
            raise M2EEException(
                "No configuration present. Please put a m2ee.yaml "
                "configuration file at the default location "
                "~/.m2ee/m2ee.yaml or specify an alternate "
                "configuration file using the -c option.")

        # m2ee
        for option in ['app_base', 'admin_port', 'admin_pass']:
            if not self._conf['m2ee'].get(option, None):
                raise M2EEException(
                    "Option %s in configuration section m2ee is "
                    "not defined!" % option)

        # force admin_pass to a string, prevent TypeError when base64-ing it
        # before sending to m2ee api
        self._conf['m2ee']['admin_pass'] = str(
            self._conf['m2ee']['admin_pass'])

        # Mendix >= 4.3: admin and runtime port only bind to localhost by
        # default
        self._conf['m2ee']['admin_listen_addresses'] = (self._conf['m2ee'].get(
            'admin_listen_addresses', ""))
        self._conf['m2ee']['runtime_listen_addresses'] = (
            self._conf['m2ee'].get('runtime_listen_addresses', ""))

        # check admin_pass 1 or password... refuse to accept when users don't
        # change default passwords
        if (self._conf['m2ee']['admin_pass'] == '1'
                or self._conf['m2ee']['admin_pass'] == 'password'):
            raise M2EEException(
                "Using admin_pass '1' or 'password' is not "
                "allowed. Please put a long, random password into "
                "the admin_pass configuration option. At least "
                "change the default!")

        # database_dump_path
        if 'database_dump_path' not in self._conf['m2ee']:
            self._conf['m2ee']['database_dump_path'] = os.path.join(
                self._conf['m2ee']['app_base'], 'data', 'database')
        if not os.path.isdir(self._conf['m2ee']['database_dump_path']):
            logger.warn("Database dump path %s is not a directory" %
                        self._conf['m2ee']['database_dump_path'])
示例#11
0
def psql(config):
    env = os.environ.copy()
    env.update(config.get_pg_environment())
    cmd = (config.get_psql_binary(), )
    logger.trace("Executing %s" % str(cmd))
    try:
        subprocess.call(cmd, env=env)
    except OSError as e:
        raise M2EEException(
            "An error occured while calling psql, cmd: %s" % cmd, e)
示例#12
0
 def download_and_unpack_runtime(self, version, curl_opts=None):
     mxversion = MXVersion(version)
     url = self.config.get_runtime_download_url(mxversion)
     path = self.config.get_first_writable_mxjar_repo()
     if path is None:
         raise M2EEException(
             "None of the locations specified in the mxjar_repo "
             "configuration option are writable by the current "
             "user account.")
     util.download_and_unpack_runtime_curl(version, url, path, curl_opts)
     self.reload_config()
示例#13
0
    def start(self, detach=True, timeout=60, step=0.25):
        if self.check_pid():
            logger.error("The application process is already started!")
            return

        if detach:
            pipe_r, pipe_w = os.pipe()
            try:
                logger.trace("[%s] Forking now..." % os.getpid())
                pid = os.fork()
            except OSError as e:
                raise M2EEException("Forking subprocess failed: %d (%s)\n" % (e.errno, e.strerror))
            if pid > 0:
                self._pid = None
                os.close(pipe_w)
                fcntl.fcntl(pipe_r, fcntl.F_SETFL,
                            fcntl.fcntl(pipe_r, fcntl.F_GETFL) | os.O_NONBLOCK)
                logger.trace("[%s] Waiting for intermediate process to exit..." % os.getpid())
                interactive = sys.stderr.isatty()
                pipe_fragments = []
                child, result = 0, 0
                while child == 0:
                    sleep(step)
                    child, result = os.waitpid(pid, os.WNOHANG)
                    if child != 0:
                        os.close(pipe_r)
                    while True:
                        try:
                            pipe_fragment = os.read(pipe_r, 1024)
                            if interactive:
                                os.write(2, pipe_fragment)
                            pipe_fragments.append(pipe_fragment)
                        except OSError:
                            break
                pipe_bytes = b''.join(pipe_fragments)
                output = pipe_bytes.decode('utf-8')
                exitcode = result >> 8
                self._handle_jvm_start_result(exitcode, output)
                return
            logger.trace("[%s] Now in intermediate forked process..." % os.getpid())
            os.close(pipe_r)
            # decouple from parent environment
            os.chdir("/")
            os.setsid()
            os.umask(0o0022)
            exitcode = self._start_jvm(detach, timeout, step, pipe_w)
            os.close(pipe_w)
            logger.trace("[%s] Exiting intermediate process with exit code %s" %
                         (os.getpid(), exitcode))
            os._exit(exitcode)
        else:
            exitcode = self._start_jvm(detach, timeout, step)
            self._handle_jvm_start_result(exitcode)
示例#14
0
 def get_default_dotm2ee_directory(self):
     dotm2ee = os.path.join(pwd.getpwuid(os.getuid())[5], ".m2ee")
     if not os.path.isdir(dotm2ee):
         try:
             os.mkdir(dotm2ee)
         except OSError as e:
             raise M2EEException(
                 "Directory %s does not exist, and cannot be created: %s. "
                 "If you do not want to use .m2ee in your home "
                 "directory, you have to specify pidfile and "
                 "munin config_cache in your configuration file explicitly."
                 % (dotm2ee, e))
     return dotm2ee
示例#15
0
def restoredb(config, dump_name):
    env = os.environ.copy()
    env.update(config.get_pg_environment())

    db_dump_file_name = os.path.join(config.get_database_dump_path(),
                                     dump_name)
    logger.debug("Restoring %s" % db_dump_file_name)
    cmd = (config.get_pg_restore_binary(), "-d", env['PGDATABASE'], "-O", "-n",
           "public", "-x", db_dump_file_name)
    logger.trace("Executing %s" % str(cmd))
    try:
        proc = subprocess.Popen(cmd,
                                env=env,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()

        if stderr != '':
            raise M2EEException(
                "An error occured while doing database restore: %s " %
                stderr.strip())
    except OSError as e:
        raise M2EEException("Database restore failed, cmd: %s" % cmd, e)
示例#16
0
 def __init__(self, version):
     if isinstance(version, (int, long, float, MXVersion)):
         version = str(version)
     parsed = re.match(
         "(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?(?:-(.*))?", version)
     if parsed is None:
         raise M2EEException(
             "The provided runtime version string, '%s' is not a "
             "valid Mendix Runtime version number. Try using "
             "the format x.y.z, e.g. 4.7.1" % version)
     groups = parsed.groups()
     self.major, self.minor, self.patch, self.hotfix = map(
         lambda x: int(x) if x else None, groups[:-1])
     self.addendum = groups[-1]
示例#17
0
def unpack(config, mda_name):

    mda_file_name = os.path.join(config.get_model_upload_path(), mda_name)
    if not os.path.isfile(mda_file_name):
        raise M2EEException("File %s does not exist." % mda_file_name)

    logger.debug("Removing everything in model/ and web/ locations...")
    # TODO: error handling. removing model/ and web/ itself should not be
    # possible (parent dir is root owned), all errors ignored for now
    app_base = config.get_app_base()
    shutil.rmtree(os.path.join(app_base, 'model'), ignore_errors=True)
    shutil.rmtree(os.path.join(app_base, 'web'), ignore_errors=True)

    logger.info("Extracting archive '%s'..." % mda_name)
    try:
        z = zipfile.ZipFile(mda_file_name, 'r')
        z.extractall(
            path=app_base,
            members=[info for info in z.infolist()
                     if info.filename.startswith(('model/', 'web/'))]
        )
    except Exception as e:
        raise M2EEException("Error extracting archive '%s'" % mda_name, e)
示例#18
0
def pg_stat_database(config):
    env = os.environ.copy()
    env.update(config.get_pg_environment())
    datname = env['PGDATABASE']

    cmd = (
        config.get_psql_binary(), "-At", "-c",
        "SELECT xact_commit, xact_rollback, tup_inserted, tup_updated, tup_deleted "
        "FROM pg_stat_database where datname = '%s'" % datname)
    try:
        proc = subprocess.Popen(cmd,
                                env=env,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()
        if stderr != '':
            raise M2EEException("Retrieving pg_stat_database info failed: %s" %
                                stderr.strip())
    except OSError as e:
        raise M2EEException(
            "Retrieving pg_stat_database info failed, cmd: %s" % cmd, e)

    return [int(x) for x in stdout.split('|')]
示例#19
0
    def _check_runtime_config(self):
        # ensure mxjar_repo is a list, multiple locations are allowed for searching
        if not self._conf.get('mxnode', {}).get('mxjar_repo', None):
            self._conf['mxnode']['mxjar_repo'] = []
        elif not type(self._conf.get('mxnode', {})['mxjar_repo']) == list:
            self._conf['mxnode']['mxjar_repo'] = [
                self._conf['mxnode']['mxjar_repo']
            ]
        # m2ee
        for option in ['app_name', 'app_base', 'runtime_port']:
            if not self._conf['m2ee'].get(option, None):
                logger.warn("Option %s in configuration section m2ee is not "
                            "defined!" % option)
        # check some locations for existance and permissions
        basepath = self._conf['m2ee']['app_base']
        if not os.path.exists(basepath):
            raise M2EEException(
                "Application base directory %s does not exist!" % basepath)

        # model_upload_path
        if 'model_upload_path' not in self._conf['m2ee']:
            self._conf['m2ee']['model_upload_path'] = os.path.join(
                self._conf['m2ee']['app_base'], 'data', 'model-upload')
        if not os.path.isdir(self._conf['m2ee']['model_upload_path']):
            logger.warn("Model upload path %s is not a directory" %
                        self._conf['m2ee']['model_upload_path'])

        # magically add app_base/runtimes to mxjar_repo when it's present
        magic_runtimes = os.path.join(self._conf['m2ee']['app_base'],
                                      'runtimes')
        if ((magic_runtimes not in self._conf['mxnode']['mxjar_repo']
             and os.path.isdir(magic_runtimes))):
            self._conf['mxnode']['mxjar_repo'].insert(0, magic_runtimes)

        if 'DatabasePassword' not in self._conf['mxruntime']:
            logger.warn(
                "There is no database password present in the configuration. Either add "
                "it to the configuration, or use the set_database_password command to "
                "set it before trying to start the application!")

        if len(self._conf['logging']) == 0:
            logger.warn(
                "No logging settings found, this is probably not what you want."
            )
示例#20
0
def emptydb(config):
    env = os.environ.copy()
    env.update(config.get_pg_environment())

    logger.info("Removing all tables...")
    # get list of drop table commands
    cmd1 = (
        config.get_psql_binary(), "-t", "-c",
        "SELECT 'DROP TABLE ' || n.nspname || '.\"' || c.relname || '\" CASCADE;' "
        "FROM pg_catalog.pg_class AS c LEFT JOIN pg_catalog.pg_namespace AS n "
        "ON n.oid = c.relnamespace WHERE relkind = 'r' AND n.nspname NOT IN "
        "('pg_catalog', 'pg_toast') AND pg_catalog.pg_table_is_visible(c.oid)")
    logger.trace("Executing %s, creating pipe for stdout,stderr" % str(cmd1))
    try:
        proc1 = subprocess.Popen(cmd1,
                                 env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        (stdout1, stderr1) = proc1.communicate()

        if stderr1 != '':
            raise M2EEException("Emptying database (step 1) failed: %s" %
                                stderr1.strip())
    except OSError as e:
        raise M2EEException(
            "Emptying database (step 1) failed, cmd: %s" % cmd1, e)

    stdin2 = stdout1
    cmd2 = (config.get_psql_binary(), )
    logger.trace("Piping stdout,stderr to %s" % str(cmd2))
    try:
        proc2 = subprocess.Popen(cmd2,
                                 env=env,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        (stdout2, stderr2) = proc2.communicate(stdin2)

        if stderr2 != '':
            raise M2EEException("Emptying database (step 2) failed: %s" %
                                stderr2.strip())
    except OSError as e:
        raise M2EEException(
            "Emptying database (step 2) failed, cmd: %s" % cmd2, e)

    logger.info("Removing all sequences...")
    # get list of drop sequence commands
    cmd3 = (
        config.get_psql_binary(), "-t", "-c",
        "SELECT 'DROP SEQUENCE ' || n.nspname || '.\"' || c.relname || '\" "
        "CASCADE;' FROM pg_catalog.pg_class AS c LEFT JOIN "
        "pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace WHERE "
        "relkind = 'S' AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND "
        "pg_catalog.pg_table_is_visible(c.oid)")
    logger.trace("Executing %s, creating pipe for stdout,stderr" % str(cmd3))
    try:
        proc3 = subprocess.Popen(cmd3,
                                 env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        (stdout3, stderr3) = proc3.communicate()

        if stderr3 != '':
            raise M2EEException("Emptying database (step 3) failed: %s" %
                                stderr3.strip())
    except OSError as e:
        raise M2EEException(
            "Emptying database (step 3) failed, cmd: %s" % cmd3, e)

    stdin4 = stdout3
    cmd4 = (config.get_psql_binary(), )
    logger.trace("Piping stdout,stderr to %s" % str(cmd4))
    try:
        proc4 = subprocess.Popen(cmd4,
                                 env=env,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        (stdout4, stderr4) = proc4.communicate(stdin4)

        if stderr4 != '':
            raise M2EEException("Emptying database (step 4) failed: %s" %
                                stderr4.strip())
    except OSError as e:
        raise M2EEException(
            "Emptying database (step 4) failed, cmd: %s" % cmd4, e)
示例#21
0
    shutil.rmtree(os.path.join(app_base, 'web'), ignore_errors=True)

    logger.debug("Extracting archive...")
    cmd = ("unzip", "-oq", mda_file_name, "web/*", "model/*", "-d", app_base)
    logger.trace("Executing %s" % str(cmd))
    proc = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    (stdout, stderr) = proc.communicate()

    logger.trace("stdout: %s" % stdout)
    logger.trace("stderr: %s" % stderr)
    if proc.returncode != 0:
        raise M2EEException("\n".join([
            "An error occured while extracting archive:",
            "stdout: %s" % stdout,
            "stderr: %s" % stderr,
        ]))

    # XXX: reset permissions on web/ model/ to be sure after executing this
    # function


def fix_mxclientsystem_symlink(config):
    logger.debug("Running fix_mxclientsystem_symlink...")
    mxclient_symlink = os.path.join(config.get_public_webroot_path(),
                                    'mxclientsystem')
    logger.trace("mxclient_symlink: %s" % mxclient_symlink)
    real_mxclientsystem_path = config.get_real_mxclientsystem_path()
    logger.trace("real_mxclientsystem_path: %s" % real_mxclientsystem_path)
    if os.path.islink(mxclient_symlink):
示例#22
0
    def start(self, timeout=60, step=0.25):
        if self.check_pid():
            logger.error("The application process is already started!")
            return

        env = self._config.get_java_env()
        cmd = self._config.get_java_cmd()

        try:
            logger.trace("[%s] Forking now..." % os.getpid())
            pid = os.fork()
            if pid > 0:
                self._pid = None
                logger.trace("[%s] Waiting for intermediate process to "
                             "exit..." % os.getpid())
                # prevent zombie process
                (pid, result) = os.waitpid(pid, 0)
                exitcode = result >> 8
                if exitcode == 0:
                    logger.debug("The JVM process has been started.")
                elif exitcode == 2:
                    logger.error(
                        "The java binary cannot be found in the default search path!"
                    )
                    logger.error(
                        "By default, when starting the JVM, the environment is not "
                        "preserved. If you don't set preserve_environment to true or "
                        "specify PATH in preserve_environment or custom_environment in "
                        "the m2ee section of your m2ee.yaml configuration file, the "
                        "search path is likely a very basic default list like "
                        "'/bin:/usr/bin'")
                    raise M2EEException(
                        "Starting the JVM process did not succeed: "
                        "JVM binary not found",
                        errno=M2EEException.ERR_JVM_BINARY_NOT_FOUND)
                elif exitcode == 3:
                    raise M2EEException(
                        "Starting the JVM process (fork/exec) did not succeed.",
                        errno=M2EEException.ERR_JVM_FORKEXEC)
                elif exitcode == 4:
                    raise M2EEException(
                        "Starting the JVM process takes too long.",
                        errno=M2EEException.ERR_JVM_TIMEOUT)
                elif exitcode == 0x20:
                    raise M2EEException(
                        "JVM process disappeared with a clean exit code.",
                        errno=M2EEException.ERR_APPCONTAINER_EXIT_ZERO)
                elif exitcode == 0x21:
                    raise M2EEException(
                        "JVM process terminated without reason.",
                        errno=M2EEException.ERR_APPCONTAINER_UNKNOWN_ERROR)
                elif exitcode == 0x22:
                    raise M2EEException(
                        "JVM process terminated: could not bind admin port.",
                        errno=M2EEException.ERR_APPCONTAINER_ADMIN_PORT_IN_USE)
                elif exitcode == 0x23:
                    raise M2EEException(
                        "JVM process terminated: could not bind runtime port.",
                        errno=M2EEException.
                        ERR_APPCONTAINER_RUNTIME_PORT_IN_USE)
                elif exitcode == 0x24:
                    raise M2EEException(
                        "JVM process terminated: incompatible JVM version.",
                        errno=M2EEException.
                        ERR_APPCONTAINER_INVALID_JDK_VERSION)
                else:
                    raise M2EEException(
                        "Starting the JVM process failed, reason unknown (%s)."
                        % exitcode,
                        errno=M2EEException.ERR_JVM_UNKNOWN)
                return
        except OSError, e:
            raise M2EEException("Forking subprocess failed: %d (%s)\n" %
                                (e.errno, e.strerror))
示例#23
0
                input_file = open(felix_template_file)
                template = input_file.read()
            except IOError, e:
                raise M2EEException("felix configuration template could not be read: %s", e)
            try:
                output_file = open(felix_config_file, 'w')
                render = template.format(
                    ProjectBundlesDir=project_bundles_path,
                    InstallDir=self._runtime_path,
                    FrameworkStorage=osgi_storage_path
                )
                output_file.write(render)
            except IOError, e:
                raise M2EEException("felix configuration file could not be written: %s", e)
        else:
            raise M2EEException("felix configuration template is not a readable file: %s" %
                                felix_template_file)

    def get_app_name(self):
        return self._conf['m2ee']['app_name']

    def get_app_base(self):
        return self._conf['m2ee']['app_base']

    def get_default_dotm2ee_directory(self):
        dotm2ee = os.path.join(pwd.getpwuid(os.getuid())[5], ".m2ee")
        if not os.path.isdir(dotm2ee):
            try:
                os.mkdir(dotm2ee)
            except OSError, e:
                logger.debug("Got %s: %s" % (type(e), e))
                import traceback