예제 #1
0
    def do_deploy_async(self, values, sender=None):
        log.debug9("TRACE do_deploy_async(databaseserver)")
        # Do the magic
        #
        # In case of error raise an exception

        first_instance = True

        # Check whether this is the first instance of the database
        for value in self._parent.get_instances().values():
            if ('databaseserver' == value.get_type()
                    and self.get_name() != value.get_name()
                    and self.get_state() in deployed_states):
                first_instance = False
                break

        # If the database name wasn't specified
        if 'database' not in values:
            # Use the instance name if it was manually specified
            if self.get_name()[0].isalpha():
                values['database'] = self.get_name()
            else:
                # Either it was autogenerated or begins with a
                # non-alphabetic character; prefix it with db_
                values['database'] = "db_%s" % self.get_name()

        if 'owner' not in values:
            # We'll default to db_owner
            values['owner'] = "db_owner"

        # We will assume the owner is new until adding them fails
        new_owner = True

        # Determine if a password was passed in, so we know whether to
        # suppress it from the settings list later.
        if 'password' in values:
            password_provided = True
        else:
            password_provided = False

        if 'postgresql_conf' not in values:
            values['postgresql_conf'] = self._settings['postgresql_conf']

        if 'pg_hba_conf' not in values:
            values['pg_hba_conf'] = self._settings['pg_hba_conf']

        # Get the UID and GID of the 'postgres' user
        try:
            self.pg_uid = pwd.getpwnam('postgres').pw_uid
        except KeyError:
            raise RolekitError(MISSING_ID,
                               "Could not retrieve UID for postgres user")

        try:
            self.pg_gid = grp.getgrnam('postgres').gr_gid
        except KeyError:
            raise RolekitError(MISSING_ID,
                               "Could not retrieve GID for postgres group")

        if first_instance:
            # Initialize the database on the filesystem
            initdb_args = ["/usr/bin/postgresql-setup", "--initdb"]

            log.debug2("TRACE: Initializing database")
            result = yield async .subprocess_future(initdb_args)
            if result.status:
                # If this fails, it may be just that the filesystem
                # has already been initialized. We'll log the message
                # and continue.
                log.debug1("INITDB: %s" % result.stdout)

        # Now we have to start the service to set everything else up
        # It's safe to start an already-running service, so we'll
        # just always make this call, particularly in case other instances
        # exist but aren't running.
        log.debug2("TRACE: Starting postgresql.service unit")
        try:
            with SystemdJobHandler() as job_handler:
                job_path = job_handler.manager.StartUnit(
                    "postgresql.service", "replace")
                job_handler.register_job(job_path)
                log.debug2("TRACE: unit start job registered")

                job_results = yield job_handler.all_jobs_done_future()

                log.debug2("TRACE: unit start job concluded")

                if any([
                        x for x in job_results.values()
                        if x not in ("skipped", "done")
                ]):
                    details = ", ".join(
                        ["%s: %s" % item for item in job_results.items()])
                    log.error("Starting services failed: {}".format(details))
                    raise RolekitError(
                        COMMAND_FAILED,
                        "Starting services failed: %s" % details)
        except Exception as e:
            log.error("Error received starting unit: {}".format(e))
            raise

        # Next we create the owner
        log.debug2("TRACE: Creating owner of new database")
        createuser_args = ["/usr/bin/createuser", values['owner']]
        result = yield async .subprocess_future(createuser_args,
                                                uid=self.pg_uid,
                                                gid=self.pg_gid)

        if result.status:
            # If the subprocess returned non-zero, the user probably already exists
            # (such as when we're using db_owner). If the caller was trying to set
            # a password, they probably didn't realize this, so we need to throw
            # an exception.
            log.info1("User {} already exists in the database".format(
                values['owner']))

            if password_provided:
                raise RolekitError(INVALID_SETTING,
                                   "Cannot set password on pre-existing user")

            # If no password was specified, we'll continue
            new_owner = False

        # If no password was requested, generate a random one here
        if not password_provided:
            values['password'] = generate_password()

        log.debug2("TRACE: Creating new database")
        createdb_args = [
            "/usr/bin/createdb", values['database'], "-O", values['owner']
        ]
        result = yield async .subprocess_future(createdb_args,
                                                uid=self.pg_uid,
                                                gid=self.pg_gid)
        if result.status:
            # If the subprocess returned non-zero, raise an exception
            raise RolekitError(COMMAND_FAILED,
                               "Creating database failed: %d" % result.status)

        # Next, set the password on the owner
        # We'll skip this phase if the the user already existed
        if new_owner:
            log.debug2("TRACE: Setting password for database owner")
            pwd_args = [
                ROLEKIT_ROLES + "/databaseserver/tools/rk_db_setpwd.py",
                "--database", values['database'], "--user", values['owner']
            ]
            result = yield async .subprocess_future(pwd_args,
                                                    stdin=values['password'],
                                                    uid=self.pg_uid,
                                                    gid=self.pg_gid)

            if result.status:
                # If the subprocess returned non-zero, raise an exception
                log.error("Setting owner password failed: {}".format(
                    result.status))
                raise RolekitError(
                    COMMAND_FAILED,
                    "Setting owner password failed: %d" % result.status)

            # If this password was provided by the user, don't save it to
            # the settings for later retrieval. That could be a security
            # issue
            if password_provided:
                values.pop("password", None)
        else:  # Not a new owner
            # Never save the password to settings for an existing owner
            log.debug2("TRACE: Owner already exists, not setting password")
            values.pop("password", None)

        if first_instance:
            # Then update the server configuration to accept network
            # connections.
            log.debug2("TRACE: Opening access to external addresses")

            # edit postgresql.conf to add listen_addresses = '*'
            conffile = values['postgresql_conf']
            bakfile = conffile + ".rksave"

            try:
                linkfile(conffile, bakfile)

                with open(conffile) as f:
                    conflines = f.readlines()

                tweaking_rules = [{
                    'regex': r"^\s*#?\s*listen_addresses\s*=.*",
                    'replace': r"listen_addresses = '*'",
                    'append_if_missing': True
                }]

                overwrite_safely(
                    conffile, "".join(_tweak_lines(conflines, tweaking_rules)))
            except Exception as e:
                log.fatal("Couldn't write {!r}: {}".format(conffile, e))
                # At this point, conffile is unmodified, otherwise
                # overwrite_safely() would have succeeded
                try:
                    os.unlink(bakfile)
                except Exception as x:
                    if not (isinstance(x, OSError)
                            and x.errno == errno.ENOENT):
                        log.error("Couldn't remove {!r}: {}".format(
                            bakfile, x))

                raise RolekitError(
                    COMMAND_FAILED,
                    "Opening access to external addresses in '{}'"
                    "failed: {}".format(conffile, e))

            # Edit pg_hba.conf to allow 'md5' auth on IPv4 and
            # IPv6 interfaces.
            conffile = values['pg_hba_conf']
            bakfile = conffile + ".rksave"

            try:
                linkfile(conffile, bakfile)

                with open(conffile) as f:
                    conflines = f.readlines()

                tweaking_rules = [{
                    'regex': r"^\s*host((?:\s.*)$)",
                    'replace': r"#host\1"
                }, {
                    'regex':
                    r"^\s*local(?:\s.*|)$",
                    'append':
                    "# Use md5 method for all connections\nhost    all             all             all                     md5"
                }]

                overwrite_safely(
                    conffile, "".join(_tweak_lines(conflines, tweaking_rules)))
            except Exception as e:
                log.fatal("Couldn't write {!r}: {}".format(conffile, e))
                # At this point, conffile is unmodified, otherwise
                # overwrite_safely() would have succeeded
                try:
                    os.unlink(bakfile)
                except Exception as x:
                    if not (isinstance(x, OSError)
                            and x.errno == errno.ENOENT):
                        log.error("Couldn't remove {!r}: {}".format(
                            bakfile, x))

                # Restore previous postgresql.conf from the backup
                conffile = values['postgresql_conf']
                bakfile = conffile + ".rksave"
                try:
                    os.rename(bakfile, conffile)
                except Exception as x:
                    log.error(
                        "Couldn't restore {!r} from backup {!r}: {}".format(
                            conffile, bakfile, x))

                raise RolekitError(
                    COMMAND_FAILED,
                    "Changing all connections to use md5 method in '{}'"
                    "failed: {}".format(values['pg_hba_conf'], e))

            # Restart the postgresql server to accept the new configuration
            log.debug2("TRACE: Restarting postgresql.service unit")
            with SystemdJobHandler() as job_handler:
                job_path = job_handler.manager.RestartUnit(
                    "postgresql.service", "replace")
                job_handler.register_job(job_path)

                job_results = yield job_handler.all_jobs_done_future()
                if any([
                        x for x in job_results.values()
                        if x not in ("skipped", "done")
                ]):
                    details = ", ".join(
                        ["%s: %s" % item for item in job_results.items()])
                    raise RolekitError(
                        COMMAND_FAILED,
                        "Restarting service failed: %s" % details)

        # Create the systemd target definition
        target = RoleDeploymentValues(self.get_type(), self.get_name(),
                                      "Database Server")
        target.add_required_units(['postgresql.service'])

        log.debug2("TRACE: Database server deployed")

        yield target
예제 #2
0
    def writeNtpConfig (self, ntpServers, ntpBroadcastClient, ntpLocalTimeSource, ntpIburst):
        broadcastclientFound = False
        ntpFileList = []

        servers = []
        for server in ntpServers:
            if server not in servers:
                servers.append (server)
        if ntpLocalTimeSource and "127.127.1.0" not in servers:
            servers.append ("127.127.1.0")

        serversfound = []

        # Write /etc/ntp.conf file, default to template if it was missing or
        # empty
        if self.ntpFile and len (self.ntpFile) > 0:
            lines = self.ntpFile
        else:
            fd = open("/usr/share/system-config-date/ntp.conf.template", "r")
            lines = fd.readlines()
            fd.close ()

        for line in lines:
            tokens = line.split ()
            if len (tokens) == 0 or tokens[0][0] == "#":
                # empty line or comment, copy verbatim
                ntpFileList.append (line)

            elif tokens[0] == "server":
                # server line
                if len(tokens) > 1:
                    host = tokens[1]
                    if host in servers:
                        line = self.addRemoveIburst(line, ntpIburst)
                        ntpFileList.append (line)
                        serversfound.append (host)
                else:
                    # What do we do here? server without an address isn't
                    # described in the documentation. Barring any problems
                    # we'll leave the line as it is.
                    ntpFileList.append (line)
            elif tokens[0] in ("broadcastclient", "#broadcastclient") or len (tokens) > 1 and tokens[0] == "#" and tokens[1] == "broadcastclient":
                # if 'broadcastclient' is found in the line
                if not broadcastclientFound:
                    if not ntpBroadcastClient:
                        ntpFileList.append("#")
                    ntpFileList.append ("broadcastclient\n")
                    broadcastclientFound = 1
                else:
                    ntpFileList.append(line)
            else:
                #This is not the server line, so just add it to the list
                ntpFileList.append(line)

        for server in servers:
            if not server in serversfound:
                if ntpIburst:
                    ntpFileList.append ("server %s iburst\n" % (server))
                else:
                    ntpFileList.append ("server %s\n" % (server))

        if not broadcastclientFound and ntpBroadcastClient:
            ntpFileList.append("broadcastclient\n")

        #Now that we've got the list of data, open the file and write it out
        try:
            overwrite_safely("/etc/ntp.conf", "".join(ntpFileList))
        except Exception, e:
            print >>sys.stderr, e
            return
예제 #3
0
파일: role.py 프로젝트: whitel/rolekit
    def do_deploy_async(self, values, sender=None):
        log.debug9("TRACE do_deploy_async(databaseserver)")
        # Do the magic
        #
        # In case of error raise an exception

        first_instance = True

        # Check whether this is the first instance of the database
        for value in self._parent.get_instances().values():
            if (
                "databaseserver" == value.get_type()
                and self.get_name() != value.get_name()
                and self.get_state() in deployed_states
            ):
                first_instance = False
                break

        # If the database name wasn't specified
        if "database" not in values:
            # Use the instance name if it was manually specified
            if self.get_name()[0].isalpha():
                values["database"] = self.get_name()
            else:
                # Either it was autogenerated or begins with a
                # non-alphabetic character; prefix it with db_
                values["database"] = "db_%s" % self.get_name()

        if "owner" not in values:
            # We'll default to db_owner
            values["owner"] = "db_owner"

        # We will assume the owner is new until adding them fails
        new_owner = True

        # Determine if a password was passed in, so we know whether to
        # suppress it from the settings list later.
        if "password" in values:
            password_provided = True
        else:
            password_provided = False

        if "postgresql_conf" not in values:
            values["postgresql_conf"] = self._settings["postgresql_conf"]

        if "pg_hba_conf" not in values:
            values["pg_hba_conf"] = self._settings["pg_hba_conf"]

        # Get the UID and GID of the 'postgres' user
        try:
            self.pg_uid = pwd.getpwnam("postgres").pw_uid
        except KeyError:
            raise RolekitError(MISSING_ID, "Could not retrieve UID for postgres user")

        try:
            self.pg_gid = grp.getgrnam("postgres").gr_gid
        except KeyError:
            raise RolekitError(MISSING_ID, "Could not retrieve GID for postgres group")

        if first_instance:
            # Initialize the database on the filesystem
            initdb_args = ["/usr/bin/postgresql-setup", "--initdb"]

            log.debug2("TRACE: Initializing database")
            result = yield async.subprocess_future(initdb_args)
            if result.status:
                # If this fails, it may be just that the filesystem
                # has already been initialized. We'll log the message
                # and continue.
                log.debug1("INITDB: %s" % result.stdout)

        # Now we have to start the service to set everything else up
        # It's safe to start an already-running service, so we'll
        # just always make this call, particularly in case other instances
        # exist but aren't running.
        log.debug2("TRACE: Starting postgresql.service unit")
        try:
            with SystemdJobHandler() as job_handler:
                job_path = job_handler.manager.StartUnit("postgresql.service", "replace")
                job_handler.register_job(job_path)
                log.debug2("TRACE: unit start job registered")

                job_results = yield job_handler.all_jobs_done_future()

                log.debug2("TRACE: unit start job concluded")

                if any([x for x in job_results.values() if x not in ("skipped", "done")]):
                    details = ", ".join(["%s: %s" % item for item in job_results.items()])
                    log.error("Starting services failed: {}".format(details))
                    raise RolekitError(COMMAND_FAILED, "Starting services failed: %s" % details)
        except Exception as e:
            log.error("Error received starting unit: {}".format(e))
            raise

        # Next we create the owner
        log.debug2("TRACE: Creating owner of new database")
        createuser_args = ["/usr/bin/createuser", values["owner"]]
        result = yield async.subprocess_future(createuser_args, uid=self.pg_uid, gid=self.pg_gid)

        if result.status:
            # If the subprocess returned non-zero, the user probably already exists
            # (such as when we're using db_owner). If the caller was trying to set
            # a password, they probably didn't realize this, so we need to throw
            # an exception.
            log.info1("User {} already exists in the database".format(values["owner"]))

            if password_provided:
                raise RolekitError(INVALID_SETTING, "Cannot set password on pre-existing user")

            # If no password was specified, we'll continue
            new_owner = False

        # If no password was requested, generate a random one here
        if not password_provided:
            values["password"] = generate_password()

        log.debug2("TRACE: Creating new database")
        createdb_args = ["/usr/bin/createdb", values["database"], "-O", values["owner"]]
        result = yield async.subprocess_future(createdb_args, uid=self.pg_uid, gid=self.pg_gid)
        if result.status:
            # If the subprocess returned non-zero, raise an exception
            raise RolekitError(COMMAND_FAILED, "Creating database failed: %d" % result.status)

        # Next, set the password on the owner
        # We'll skip this phase if the the user already existed
        if new_owner:
            log.debug2("TRACE: Setting password for database owner")
            pwd_args = [
                ROLEKIT_ROLES + "/databaseserver/tools/rk_db_setpwd.py",
                "--database",
                values["database"],
                "--user",
                values["owner"],
            ]
            result = yield async.subprocess_future(pwd_args, stdin=values["password"], uid=self.pg_uid, gid=self.pg_gid)

            if result.status:
                # If the subprocess returned non-zero, raise an exception
                log.error("Setting owner password failed: {}".format(result.status))
                raise RolekitError(COMMAND_FAILED, "Setting owner password failed: %d" % result.status)

            # If this password was provided by the user, don't save it to
            # the settings for later retrieval. That could be a security
            # issue
            if password_provided:
                values.pop("password", None)
        else:  # Not a new owner
            # Never save the password to settings for an existing owner
            log.debug2("TRACE: Owner already exists, not setting password")
            values.pop("password", None)

        if first_instance:
            # Then update the server configuration to accept network
            # connections.
            log.debug2("TRACE: Opening access to external addresses")

            # edit postgresql.conf to add listen_addresses = '*'
            conffile = values["postgresql_conf"]
            bakfile = conffile + ".rksave"

            try:
                linkfile(conffile, bakfile)

                with open(conffile) as f:
                    conflines = f.readlines()

                tweaking_rules = [
                    {
                        "regex": r"^\s*#?\s*listen_addresses\s*=.*",
                        "replace": r"listen_addresses = '*'",
                        "append_if_missing": True,
                    }
                ]

                overwrite_safely(conffile, "".join(_tweak_lines(conflines, tweaking_rules)))
            except Exception as e:
                log.fatal("Couldn't write {!r}: {}".format(conffile, e))
                # At this point, conffile is unmodified, otherwise
                # overwrite_safely() would have succeeded
                try:
                    os.unlink(bakfile)
                except Exception as x:
                    if not (isinstance(x, OSError) and x.errno == errno.ENOENT):
                        log.error("Couldn't remove {!r}: {}".format(bakfile, x))

                raise RolekitError(
                    COMMAND_FAILED, "Opening access to external addresses in '{}'" "failed: {}".format(conffile, e)
                )

            # Edit pg_hba.conf to allow 'md5' auth on IPv4 and
            # IPv6 interfaces.
            conffile = values["pg_hba_conf"]
            bakfile = conffile + ".rksave"

            try:
                linkfile(conffile, bakfile)

                with open(conffile) as f:
                    conflines = f.readlines()

                tweaking_rules = [
                    {"regex": r"^\s*host((?:\s.*)$)", "replace": r"#host\1"},
                    {
                        "regex": r"^\s*local(?:\s.*|)$",
                        "append": "# Use md5 method for all connections\nhost    all             all             all                     md5",
                    },
                ]

                overwrite_safely(conffile, "".join(_tweak_lines(conflines, tweaking_rules)))
            except Exception as e:
                log.fatal("Couldn't write {!r}: {}".format(conffile, e))
                # At this point, conffile is unmodified, otherwise
                # overwrite_safely() would have succeeded
                try:
                    os.unlink(bakfile)
                except Exception as x:
                    if not (isinstance(x, OSError) and x.errno == errno.ENOENT):
                        log.error("Couldn't remove {!r}: {}".format(bakfile, x))

                # Restore previous postgresql.conf from the backup
                conffile = values["postgresql_conf"]
                bakfile = conffile + ".rksave"
                try:
                    os.rename(bakfile, conffile)
                except Exception as x:
                    log.error("Couldn't restore {!r} from backup {!r}: {}".format(conffile, bakfile, x))

                raise RolekitError(
                    COMMAND_FAILED,
                    "Changing all connections to use md5 method in '{}'" "failed: {}".format(values["pg_hba_conf"], e),
                )

            # Restart the postgresql server to accept the new configuration
            log.debug2("TRACE: Restarting postgresql.service unit")
            with SystemdJobHandler() as job_handler:
                job_path = job_handler.manager.RestartUnit("postgresql.service", "replace")
                job_handler.register_job(job_path)

                job_results = yield job_handler.all_jobs_done_future()
                if any([x for x in job_results.values() if x not in ("skipped", "done")]):
                    details = ", ".join(["%s: %s" % item for item in job_results.items()])
                    raise RolekitError(COMMAND_FAILED, "Restarting service failed: %s" % details)

        # Create the systemd target definition
        target = RoleDeploymentValues(self.get_type(), self.get_name(), "Database Server")
        target.add_required_units(["postgresql.service"])

        log.debug2("TRACE: Database server deployed")

        yield target
예제 #4
0
class dateBackend(object):

    def __init__(self):
        self.ntpFile = None
        self.ntpServers = None
        self.ntpBroadcastClient = False
        self.ntpLocalTimeSource = False
        self.readNtpConf()
        self.getNtpServers()
        pass

    def getDate (self):
        times = time.localtime(time.time())
        return times

    def writeDateConfig (self, sysDate, sysTime):
        year, month, day = sysDate
        hour, min, sec = sysTime

        #--cal.get_date starts counting months at 0 for Jan.  We need to start counting at 1
        month = month + 1
        cmd = '/bin/date -s %d/%d/%d\ %s:%s:%s' % (year, month, day, hour, min, sec)
        fd = os.popen(cmd, 'r')
        lines = fd.readlines()
        return not fd.close()

    def syncHardwareClock(self):
        # sync hardware clock.  Will use either localtime or utc
        # according to value in /etc/adjtime (recorded last time hwclock
        # was run).
        if os.access("/sbin/hwclock", os.F_OK) == 1:
            #The S390 has no hwclock binary, so don't try to run it if it isn't there
            return not os.system("/sbin/hwclock --systohc")
        return True

    def writeNtpConfig (self, ntpServers, ntpBroadcastClient, ntpLocalTimeSource, ntpIburst):
        broadcastclientFound = False
        ntpFileList = []

        servers = []
        for server in ntpServers:
            if server not in servers:
                servers.append (server)
        if ntpLocalTimeSource and "127.127.1.0" not in servers:
            servers.append ("127.127.1.0")

        serversfound = []

        # Write /etc/ntp.conf file, default to template if it was missing or
        # empty
        if self.ntpFile and len (self.ntpFile) > 0:
            lines = self.ntpFile
        else:
            fd = open("/usr/share/system-config-date/ntp.conf.template", "r")
            lines = fd.readlines()
            fd.close ()

        for line in lines:
            tokens = line.split ()
            if len (tokens) == 0 or tokens[0][0] == "#":
                # empty line or comment, copy verbatim
                ntpFileList.append (line)

            elif tokens[0] == "server":
                # server line
                if len(tokens) > 1:
                    host = tokens[1]
                    if host in servers:
                        line = self.addRemoveIburst(line, ntpIburst)
                        ntpFileList.append (line)
                        serversfound.append (host)
                else:
                    # What do we do here? server without an address isn't
                    # described in the documentation. Barring any problems
                    # we'll leave the line as it is.
                    ntpFileList.append (line)
            elif tokens[0] in ("broadcastclient", "#broadcastclient") or len (tokens) > 1 and tokens[0] == "#" and tokens[1] == "broadcastclient":
                # if 'broadcastclient' is found in the line
                if not broadcastclientFound:
                    if not ntpBroadcastClient:
                        ntpFileList.append("#")
                    ntpFileList.append ("broadcastclient\n")
                    broadcastclientFound = 1
                else:
                    ntpFileList.append(line)
            else:
                #This is not the server line, so just add it to the list
                ntpFileList.append(line)

        for server in servers:
            if not server in serversfound:
                if ntpIburst:
                    ntpFileList.append ("server %s iburst\n" % (server))
                else:
                    ntpFileList.append ("server %s\n" % (server))

        if not broadcastclientFound and ntpBroadcastClient:
            ntpFileList.append("broadcastclient\n")

        #Now that we've got the list of data, open the file and write it out
        try:
            overwrite_safely("/etc/ntp.conf", "".join(ntpFileList))
        except Exception, e:
            print >>sys.stderr, e
            return

        self.ntpFile = ntpFileList

        # Add or remove iburst to NTPSERVERARGS in /etc/sysconfig/network
        try:
            f = open("/etc/sysconfig/network", "r")
            lines = f.readlines()
            f.close()
        except:
            return

        lines_new = []
        found = False
        for line in lines:
            # parsing shell is hard
            start, x, end = line.partition("=")
            if start.lstrip() == "NTPSERVERARGS" and end == end.lstrip() and \
                    len(end) > 0:
                end_tokens = shlex.split(end)
                tokens = end_tokens[0].split()
                if "iburst" in tokens:
                    found = True
                    if not ntpIburst:
                        # rebuild changed NTPSERVERARGS line, not optimal
                        tokens = filter(lambda x: x != "iburst", tokens)
                        if len(tokens) > 0:
                            if len(tokens) > 1:
                                end_tokens[0] = "\"%s\"" % (" ".join(tokens))
                            elif len(tokens) == 1:
                                end_tokens[0] = tokens[0]
                            line = start + x + " ".join(end_tokens) + "\n"
                        else:
                            line = ""

            lines_new.append(line)
        if ntpIburst and not found:
            lines_new.append("NTPSERVERARGS=iburst\n")

        try:
            overwrite_safely("/etc/sysconfig/network", "".join(lines_new))
        except Exception, e:
            print e
            return