コード例 #1
0
def removeApacheConf(self, domain):
    if os.path.isfile("/etc/apache2/sites-available/{0}.conf".format(domain)):
        Log.debug(self, "Removing Apache configuration")
        SSSFileUtils.rm(self, "/etc/apache2/sites-enabled/{0}.conf".format(domain))
        SSSFileUtils.rm(self, "/etc/apache2/sites-available/{0}.conf".format(domain))
        SSSService.reload_service(self, "apache2")
        SSSGit.add(self, ["/etc/apache2"], msg="Deleted {0} ".format(domain))
コード例 #2
0
ファイル: site.py プロジェクト: serversetup/SetupServer
    def enable(self):
        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    self.app.pargs.site_name = (input('Enter site name : ')
                                                .strip())
            except IOError as e:
                Log.error(self, 'could not input site name')

        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        # validate domain name
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)

        # check if site exists
        if not check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} does not exist".format(sss_domain))
        if os.path.isfile('/etc/apache2/sites-available/{0}.conf'
                          .format(sss_domain)):
            Log.info(self, "Enable domain {0:10} \t".format(sss_domain), end='')
            SSSFileUtils.create_symlink(self,
                                       ['/etc/apache2/sites-available/{0}.conf'
                                        .format(sss_domain),
                                        '/etc/apache2/sites-enabled/{0}.conf'
                                        .format(sss_domain)])
            SSSGit.add(self, ["/etc/apache2"],
                      msg="Enabled {0} "
                      .format(sss_domain))
            updateSiteInfo(self, sss_domain, enabled=True)
            Log.info(self, "[" + Log.ENDC + "OK" + Log.OKGREEN + "]")
            if not SSSService.reload_service(self, 'apache2'):
                Log.error(self, "service Apache2 reload failed. "
                          "check issues with `apachectl configtest` command")
        else:
            Log.error(self, "Apache configuration file does not exist"
                      .format(sss_domain))
コード例 #3
0
ファイル: site.py プロジェクト: serversetup/SetupServer
    def default(self):
        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    self.app.pargs.site_name = (input('Enter site name : ')
                                                .strip())
            except IOError as e:
                Log.error(self, 'Unable to read input, Please try again')

        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)

        if not check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} does not exist".format(sss_domain))

        sss_site_webroot = SSSVariables.sss_webroot + sss_domain

        if os.path.isfile('/etc/apache2/sites-available/{0}.conf'
                              .format(sss_domain)):
                try:
                    SSSShellExec.invoke_editor(self, '/etc/apache2/sites-availa'
                                              'ble/{0}.conf'.format(sss_domain))
                except CommandExecutionError as e:
                    Log.error(self, "Failed invoke editor")
                if (SSSGit.checkfilestatus(self, "/etc/apache2",
                   '/etc/apache2/sites-available/{0}.conf'.format(sss_domain))):
                    SSSGit.add(self, ["/etc/apache2"], msg="Edit website: {0}"
                              .format(sss_domain))
                    # Reload Apache
                    if not SSSService.reload_service(self, 'apache2'):
                        Log.error(self, "service apache2 reload failed. "
                                  "check issues with `service apache2 reload` command")
        else:
            Log.error(self, "Apache configuration file does not exists"
                          .format(sss_domain))
コード例 #4
0
 def secure_auth(self):
     """This function Secures authentication"""
     passwd = ''.join([random.choice
                      (string.ascii_letters + string.digits)
                      for n in range(6)])
     if not self.app.pargs.user_input:
         username = input("Provide HTTP authentication user "
                          "name [{0}] :".format(SSSVariables.sss_user))
         self.app.pargs.user_input = username
         if username == "":
             self.app.pargs.user_input = SSSVariables.sss_user
     if not self.app.pargs.user_pass:
         password = getpass.getpass("Provide HTTP authentication "
                                    "password [{0}] :".format(passwd))
         self.app.pargs.user_pass = password
         if password == "":
             self.app.pargs.user_pass = passwd
     Log.debug(self, "printf username:"******"$(openssl passwd -crypt "
               "password 2> /dev/null)\n\""
               "> /etc/apache2/htpasswd-sss 2>/dev/null")
     SSSShellExec.cmd_exec(self, "printf \"{username}:"
                          "$(openssl passwd -crypt "
                          "{password} 2> /dev/null)\n\""
                          "> /etc/apache2/htpasswd-sss 2>/dev/null"
                          .format(username=self.app.pargs.user_input,
                                  password=self.app.pargs.user_pass),
                          log=False)
     SSSGit.add(self, ["/etc/apache2"],
               msg="Adding changed secure auth into Git")
コード例 #5
0
 def secure_auth(self):
     """This function Secures authentication"""
     passwd = ''.join([
         random.choice(string.ascii_letters + string.digits)
         for n in range(6)
     ])
     if not self.app.pargs.user_input:
         username = input("Provide HTTP authentication user "
                          "name [{0}] :".format(SSSVariables.sss_user))
         self.app.pargs.user_input = username
         if username == "":
             self.app.pargs.user_input = SSSVariables.sss_user
     if not self.app.pargs.user_pass:
         password = getpass.getpass("Provide HTTP authentication "
                                    "password [{0}] :".format(passwd))
         self.app.pargs.user_pass = password
         if password == "":
             self.app.pargs.user_pass = passwd
     Log.debug(
         self, "printf username:"******"$(openssl passwd -crypt "
         "password 2> /dev/null)\n\""
         "> /etc/apache2/htpasswd-sss 2>/dev/null")
     SSSShellExec.cmd_exec(self,
                           "printf \"{username}:"
                           "$(openssl passwd -crypt "
                           "{password} 2> /dev/null)\n\""
                           "> /etc/apache2/htpasswd-sss 2>/dev/null".format(
                               username=self.app.pargs.user_input,
                               password=self.app.pargs.user_pass),
                           log=False)
     SSSGit.add(self, ["/etc/apache2"],
                msg="Adding changed secure auth into Git")
コード例 #6
0
def removeApacheConf(self, domain):
    if os.path.isfile('/etc/apache2/sites-available/{0}.conf'.format(domain)):
        Log.debug(self, "Removing Apache configuration")
        SSSFileUtils.rm(self,
                        '/etc/apache2/sites-enabled/{0}.conf'.format(domain))
        SSSFileUtils.rm(self,
                        '/etc/apache2/sites-available/{0}.conf'.format(domain))
        SSSService.reload_service(self, 'apache2')
        SSSGit.add(self, ["/etc/apache2"], msg="Deleted {0} ".format(domain))
コード例 #7
0
    def disable(self):
        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    self.app.pargs.site_name = (
                        input('Enter site name : ').strip())

            except IOError as e:
                Log.error(self, 'could not input site name')
        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)
        # check if site exists
        if not check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} does not exist".format(sss_domain))

        if os.path.isfile(
                '/etc/apache2/sites-available/{0}.conf'.format(sss_domain)):
            Log.info(self,
                     "Disable domain {0:10} \t".format(sss_domain),
                     end='')
            if not os.path.isfile(
                    '/etc/apache2/sites-enabled/{0}.conf'.format(sss_domain)):
                Log.info(self, "[" + Log.FAIL + "Failed" + Log.OKGREEN + "]")
                Log.info(self, "Site {0} already disabled".format(sss_domain))
            else:
                SSSFileUtils.remove_symlink(
                    self,
                    '/etc/apache2/sites-enabled/{0}.conf'.format(sss_domain))
                SSSGit.add(self, ["/etc/apache2"],
                           msg="Disabled {0} ".format(sss_domain))
                updateSiteInfo(self, sss_domain, enabled=False)
                Log.info(self, "[" + Log.ENDC + "OK" + Log.OKGREEN + "]")
                if not SSSService.reload_service(self, 'apache2'):
                    Log.error(
                        self, "service apache2 reload failed. "
                        "check issues with `apachectl configtest` command")
        else:
            Log.error(
                self,
                "Apache configuration file does not exist".format(sss_domain))
コード例 #8
0
    def default(self):
        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    self.app.pargs.site_name = (
                        input('Enter site name : ').strip())
            except IOError as e:
                Log.error(self, 'Unable to read input, Please try again')

        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)

        if not check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} does not exist".format(sss_domain))

        sss_site_webroot = SSSVariables.sss_webroot + sss_domain

        if os.path.isfile(
                '/etc/apache2/sites-available/{0}.conf'.format(sss_domain)):
            try:
                SSSShellExec.invoke_editor(
                    self, '/etc/apache2/sites-availa'
                    'ble/{0}.conf'.format(sss_domain))
            except CommandExecutionError as e:
                Log.error(self, "Failed invoke editor")
            if (SSSGit.checkfilestatus(
                    self, "/etc/apache2",
                    '/etc/apache2/sites-available/{0}.conf'.format(sss_domain))
                ):
                SSSGit.add(self, ["/etc/apache2"],
                           msg="Edit website: {0}".format(sss_domain))
                # Reload Apache
                if not SSSService.reload_service(self, 'apache2'):
                    Log.error(
                        self, "service apache2 reload failed. "
                        "check issues with `service apache2 reload` command")
        else:
            Log.error(
                self,
                "Apache configuration file does not exists".format(sss_domain))
コード例 #9
0
    def default(self):
        # self.app.render((data), 'default.mustache')
        # Check domain name validation
        data = dict()
        host, port = None, None
        try:
            stype, cache = detSitePar(vars(self.app.pargs))
        except RuntimeError as e:
            Log.debug(self, str(e))
            Log.error(self, "Please provide valid options to creating site")

        if stype is None and self.app.pargs.proxy:
            stype, cache = 'proxy', ''
            proxyinfo = self.app.pargs.proxy[0].strip()
            if not proxyinfo:
                Log.error(self, "Please provide proxy server host information")
            proxyinfo = proxyinfo.split(':')
            host = proxyinfo[0].strip()
            port = '80' if len(proxyinfo) < 2 else proxyinfo[1].strip()
        elif stype is None and not self.app.pargs.proxy:
            stype, cache = 'html', 'basic'
        elif stype and self.app.pargs.proxy:
            Log.error(self, "proxy should not be used with other site types")
        if (self.app.pargs.proxy
                and (self.app.pargs.pagespeed or self.app.pargs.hhvm)):
            Log.error(self, "Proxy site can not run on pagespeed or hhvm")

        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    # preprocessing before finalize site name
                    self.app.pargs.site_name = (
                        input('Enter site name : ').strip())
            except IOError as e:
                Log.debug(self, str(e))
                Log.error(self, "Unable to input site name, Please try again!")

        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)

        if not sss_domain.strip():
            Log.error("Invalid domain name, " "Provide valid domain name")

        sss_site_webroot = SSSVariables.sss_webroot + sss_domain

        if check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} already exists".format(sss_domain))
        elif os.path.isfile(
                '/etc/apache2/sites-available/{0}.conf'.format(sss_domain)):
            Log.error(
                self, "Apache configuration /etc/apache2/sites-available/"
                "{0} already exists".format(sss_domain))

        if stype in ['html', 'php']:
            data = dict(site_name=sss_domain,
                        www_domain=sss_www_domain,
                        static=True,
                        basic=False,
                        webroot=sss_site_webroot)

            if stype == 'php':
                data['static'] = False
                data['basic'] = True

        elif stype in ['mysql', 'wp']:
            data = dict(site_name=sss_domain,
                        www_domain=sss_www_domain,
                        static=False,
                        basic=True,
                        wp=False,
                        w3tc=False,
                        wpfc=False,
                        wpsc=False,
                        wpredis=False,
                        multisite=False,
                        wpsubdir=False,
                        webroot=sss_site_webroot,
                        sss_db_name='',
                        sss_db_user='',
                        sss_db_pass='',
                        sss_db_host='')

        else:
            pass

        # Check rerequired packages are installed or not
        sss_auth = site_package_check(self, stype)

        try:
            pre_run_checks(self)
        except SiteError as e:
            Log.debug(self, str(e))
            Log.error(self, "Apache configuration check failed.")

        try:
            try:
                # setup Apache configuration, and webroot
                setupdomain(self, data)
            except SiteError as e:
                # call cleanup actions on failure
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self,
                                domain=sss_domain,
                                webroot=data['webroot'])
                Log.debug(self, str(e))
                Log.error(
                    self, "Check logs for reason "
                    "`tail /var/log/sss/sss.log` & Try Again!!!")

            addNewSite(self, sss_domain, stype, cache, sss_site_webroot)

            # Setup Database for MySQL site
            if 'sss_db_name' in data.keys() and not data['wp']:
                try:
                    data = setupdatabase(self, data)
                    # Add database information for site into database
                    updateSiteInfo(self,
                                   sss_domain,
                                   db_name=data['sss_db_name'],
                                   db_user=data['sss_db_user'],
                                   db_password=data['sss_db_pass'],
                                   db_host=data['sss_db_host'])

                except SiteError as e:
                    # call cleanup actions on failure
                    Log.debug(self, str(e))
                    Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                    Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                    doCleanupAction(self,
                                    domain=sss_domain,
                                    webroot=data['webroot'],
                                    dbname=data['sss_db_name'],
                                    dbuser=data['sss_db_user'],
                                    dbhost=data['sss_db_host'])
                    deleteSiteInfo(self, sss_domain)
                    Log.error(
                        self, "Check logs for reason "
                        "`tail /var/log/sss/sss.log` & Try Again!!!")

                try:
                    sssdbconfig = open(
                        "{0}/sss-config.php".format(sss_site_webroot),
                        encoding='utf-8',
                        mode='w')
                    sssdbconfig.write("<?php \ndefine('DB_NAME', '{0}');"
                                      "\ndefine('DB_USER', '{1}'); "
                                      "\ndefine('DB_PASSWORD', '{2}');"
                                      "\ndefine('DB_HOST', '{3}');\n?>".format(
                                          data['sss_db_name'],
                                          data['sss_db_user'],
                                          data['sss_db_pass'],
                                          data['sss_db_host']))

                    sssdbconfig.close()
                    stype = 'mysql'
                except IOError as e:
                    Log.debug(self.str(e))
                    Log.debug(
                        self, "Error occured while generating "
                        "sss-config.php")
                    Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                    Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                    doCleanupAction(self,
                                    domain=sss_domain,
                                    webroot=data['webroot'],
                                    dbname=data['sss_db_name'],
                                    dbuser=data['sss_db_user'],
                                    dbhost=data['sss_db_host'])
                    deleteSiteInfo(self, sss_domain)
                    Log.error(
                        self, "Check logs for reason "
                        "`tail /var/log/sss/sss.log` & Try Again!!!")

            if not SSSService.reload_service(self, 'apache2'):
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self,
                                domain=sss_domain,
                                webroot=data['webroot'])
                deleteSiteInfo(self, sss_domain)
                Log.info(
                    self, Log.FAIL + "service Apache reload failed."
                    "check issues with `apachectl configtest` command")
                Log.error(
                    self, "Check logs for reason "
                    "`tail /var/log/sss/sss.log` & Try Again!!!")

            SSSGit.add(self, ["/etc/apache2"],
                       msg="{0} created with {1} {2}".format(
                           sss_www_domain, stype, cache))

            # Setup Permissions for webroot
            try:
                setwebrootpermissions(self, data['webroot'])
                #fix for log permission

                Log.debug(self, "Fixing Log file Permissions")
                if os.path.isfile(
                        '/var/log/apache2/{0}.access.log'.format(sss_domain)):
                    SSSFileUtils.chown(
                        self,
                        '/var/log/apache2/{0}.access.log'.format(sss_domain),
                        "root", "root")
                if os.path.isfile(
                        '/var/log/apache2/{0}.error.log'.format(sss_domain)):
                    SSSFileUtils.chown(
                        self,
                        '/var/log/apache2/{0}.error.log'.format(sss_domain),
                        "root", "root")

            except SiteError as e:
                Log.debug(self, str(e))
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self,
                                domain=sss_domain,
                                webroot=data['webroot'])
                deleteSiteInfo(self, sss_domain)
                Log.error(
                    self, "Check logs for reason "
                    "`tail /var/log/sss/sss.log` & Try Again!!!")

            if sss_auth and len(sss_auth):
                for msg in sss_auth:
                    Log.info(self, Log.ENDC + msg, log=False)

            Log.info(
                self, "Successfully created site"
                " http://{0}".format(sss_domain))
        except SiteError as e:
            Log.error(
                self, "Check logs for reason "
                "`tail /var/log/sss/sss.log` & Try Again!!!")
コード例 #10
0
ファイル: site.py プロジェクト: serversetup/SetupServer
    def default(self):
        # self.app.render((data), 'default.mustache')
        # Check domain name validation
        data = dict()
        host,port = None, None
        try:
            stype, cache = detSitePar(vars(self.app.pargs))
        except RuntimeError as e:
            Log.debug(self, str(e))
            Log.error(self, "Please provide valid options to creating site")

        if stype is None and self.app.pargs.proxy:
            stype, cache = 'proxy', ''
            proxyinfo = self.app.pargs.proxy[0].strip()
            if not proxyinfo:
                Log.error(self, "Please provide proxy server host information")
            proxyinfo = proxyinfo.split(':')
            host = proxyinfo[0].strip()
            port = '80' if len(proxyinfo) < 2 else proxyinfo[1].strip()
        elif stype is None and not self.app.pargs.proxy:
            stype, cache = 'html', 'basic'
        elif stype and self.app.pargs.proxy:
            Log.error(self, "proxy should not be used with other site types")
        if (self.app.pargs.proxy and (self.app.pargs.pagespeed
           or self.app.pargs.hhvm)):
            Log.error(self, "Proxy site can not run on pagespeed or hhvm")

        if not self.app.pargs.site_name:
            try:
                while not self.app.pargs.site_name:
                    # preprocessing before finalize site name
                    self.app.pargs.site_name = (input('Enter site name : ')
                                                .strip())
            except IOError as e:
                Log.debug(self, str(e))
                Log.error(self, "Unable to input site name, Please try again!")

        self.app.pargs.site_name = self.app.pargs.site_name.strip()
        (sss_domain, sss_www_domain) = ValidateDomain(self.app.pargs.site_name)

        if not sss_domain.strip():
            Log.error("Invalid domain name, "
                      "Provide valid domain name")

        sss_site_webroot = SSSVariables.sss_webroot + sss_domain

        if check_domain_exists(self, sss_domain):
            Log.error(self, "site {0} already exists".format(sss_domain))
        elif os.path.isfile('/etc/apache2/sites-available/{0}.conf'
                            .format(sss_domain)):
            Log.error(self, "Apache configuration /etc/apache2/sites-available/"
                      "{0} already exists".format(sss_domain))

        if stype in ['html', 'php']:
            data = dict(site_name=sss_domain, www_domain=sss_www_domain,
                        static=True,  basic=False,webroot=sss_site_webroot)

            if stype == 'php':
                data['static'] = False
                data['basic'] = True

        elif stype in ['mysql', 'wp']:
            data = dict(site_name=sss_domain, www_domain=sss_www_domain,
                        static=False,  basic=True, wp=False, w3tc=False,
                        wpfc=False, wpsc=False, wpredis=False, multisite=False,
                        wpsubdir=False, webroot=sss_site_webroot,
                        sss_db_name='', sss_db_user='', sss_db_pass='',
                        sss_db_host='')

        else:
            pass

         # Check rerequired packages are installed or not
        sss_auth = site_package_check(self, stype)

        try:
            pre_run_checks(self)
        except SiteError as e:
            Log.debug(self, str(e))
            Log.error(self, "Apache configuration check failed.")

        try:
            try:
                # setup Apache configuration, and webroot
                setupdomain(self, data)
            except SiteError as e:
                # call cleanup actions on failure
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self, domain=sss_domain,
                                webroot=data['webroot'])
                Log.debug(self, str(e))
                Log.error(self, "Check logs for reason "
                          "`tail /var/log/sss/sss.log` & Try Again!!!")

            addNewSite(self, sss_domain, stype, cache, sss_site_webroot)

            # Setup Database for MySQL site
            if 'sss_db_name' in data.keys() and not data['wp']:
                try:
                    data=setupdatabase(self,data)
                    # Add database information for site into database
                    updateSiteInfo(self, sss_domain, db_name=data['sss_db_name'],
                               db_user=data['sss_db_user'],
                               db_password=data['sss_db_pass'],
                               db_host=data['sss_db_host'])

                except SiteError as e:
                    # call cleanup actions on failure
                    Log.debug(self, str(e))
                    Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                    Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                    doCleanupAction(self, domain=sss_domain,
                                    webroot=data['webroot'],
                                    dbname=data['sss_db_name'],
                                    dbuser=data['sss_db_user'],
                                    dbhost=data['sss_db_host'])
                    deleteSiteInfo(self, sss_domain)
                    Log.error(self, "Check logs for reason "
                              "`tail /var/log/sss/sss.log` & Try Again!!!")

                try:
                    sssdbconfig = open("{0}/sss-config.php"
                                  .format(sss_site_webroot),
                                  encoding='utf-8', mode='w')
                    sssdbconfig.write("<?php \ndefine('DB_NAME', '{0}');"
                                     "\ndefine('DB_USER', '{1}'); "
                                     "\ndefine('DB_PASSWORD', '{2}');"
                                     "\ndefine('DB_HOST', '{3}');\n?>"
                                     .format(data['sss_db_name'],
                                             data['sss_db_user'],
                                             data['sss_db_pass'],
                                             data['sss_db_host']))

                    sssdbconfig.close()
                    stype = 'mysql'
                except IOError as e:
                    Log.debug(self.str(e))
                    Log.debug(self, "Error occured while generating "
                              "sss-config.php")
                    Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                    Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                    doCleanupAction(self, domain=sss_domain,
                                    webroot=data['webroot'],
                                    dbname=data['sss_db_name'],
                                    dbuser=data['sss_db_user'],
                                    dbhost=data['sss_db_host'])
                    deleteSiteInfo(self, sss_domain)
                    Log.error(self, "Check logs for reason "
                              "`tail /var/log/sss/sss.log` & Try Again!!!")

            if not SSSService.reload_service(self, 'apache2'):
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self, domain=sss_domain,
                                webroot=data['webroot'])
                deleteSiteInfo(self, sss_domain)
                Log.info(self, Log.FAIL + "service Apache reload failed."
                         "check issues with `apachectl configtest` command")
                Log.error(self, "Check logs for reason "
                          "`tail /var/log/sss/sss.log` & Try Again!!!")

            SSSGit.add(self, ["/etc/apache2"],
                      msg="{0} created with {1} {2}"
                      .format(sss_www_domain, stype, cache))

            # Setup Permissions for webroot
            try:
                setwebrootpermissions(self, data['webroot'])
                #fix for log permission

                Log.debug(self,"Fixing Log file Permissions")
                if os.path.isfile('/var/log/apache2/{0}.access.log'
                                          .format(sss_domain)):
                    SSSFileUtils.chown(self,'/var/log/apache2/{0}.access.log'
                                          .format(sss_domain),"root","root")
                if os.path.isfile('/var/log/apache2/{0}.error.log'
                                          .format(sss_domain)):
                    SSSFileUtils.chown(self,'/var/log/apache2/{0}.error.log'
                                          .format(sss_domain),"root","root")

            except SiteError as e:
                Log.debug(self, str(e))
                Log.info(self, Log.FAIL + "Oops Something went wrong !!")
                Log.info(self, Log.FAIL + "Calling cleanup actions ...")
                doCleanupAction(self, domain=sss_domain,
                                webroot=data['webroot'])
                deleteSiteInfo(self, sss_domain)
                Log.error(self, "Check logs for reason "
                          "`tail /var/log/sss/sss.log` & Try Again!!!")

            if sss_auth and len(sss_auth):
                for msg in sss_auth:
                    Log.info(self, Log.ENDC + msg, log=False)

            Log.info(self, "Successfully created site"
                     " http://{0}".format(sss_domain))
        except SiteError as e:
            Log.error(self, "Check logs for reason "
                      "`tail /var/log/sss/sss.log` & Try Again!!!")
コード例 #11
0
ファイル: stack.py プロジェクト: serversetup/SetupServer
    def post_pref(self, apt_packages, packages):
        """Post activity after installation of packages"""
        if len(apt_packages):
            if set(SSSVariables.sss_apache).issubset(set(apt_packages)):
                if not (os.path.isfile('/etc/apache2/conf-available/acl.conf')):
                    data = dict(webroot=SSSVariables.sss_webroot)
                    Log.debug(self, 'Writting the Apache configuration to '
                              'file /etc/apache2/conf-available/acl.conf')
                    sss_apache = open('/etc/apache2/conf-available/acl.conf',
                                    encoding='utf-8', mode='w')
                    self.app.render((data), 'acl.mustache',
                                    out=sss_apache)
                    sss_apache.close()

                    # 22222 port setting

                    Log.debug(self, 'Writting the Apache configuration to '
                              'file /etc/apache2/sites-available/'
                              '22222')

                    sss_apache = open('/etc/apache2/sites-available/22222.conf',encoding='utf-8', mode='w')
                    self.app.render((data), '22222.mustache',
                                    out=sss_apache)
                    sss_apache.close()

                    passwd = ''.join([random.choice
                                     (string.ascii_letters + string.digits)
                                     for n in range(6)])

                    try:
                        SSSShellExec.cmd_exec(self, "printf \"SSS:"
                                             "$(openssl passwd -crypt "
                                             "{password} 2> /dev/null)\n\""
                                             "> /etc/apache2/htpasswd-sss "
                                             "2>/dev/null"
                                             .format(password=passwd))
                    except CommandExecutionError as e:
                        Log.error(self, "Failed to save HTTP Auth")

                    # Create Symbolic link for 22222
                    SSSFileUtils.create_symlink(self, ['/etc/apache2/'
                                                      'sites-available/'
                                                      '22222.conf',
                                                      '/etc/apache2/'
                                                      'sites-enabled/'
                                                      '22222.conf'])

                    # Create htdocs folder
                    if not os.path.exists('{0}22222/htdocs'
                                          .format(SSSVariables.sss_webroot)):
                        Log.debug(self, "Creating directory "
                                  "{0}22222/htdocs "
                                  .format(SSSVariables.sss_webroot))
                        os.makedirs('{0}22222/htdocs'
                                    .format(SSSVariables.sss_webroot))

                    if not os.path.exists('/etc/apache2/ssl'):
                        Log.debug(self, "Creating directory "
                                  "/etc/apache2/ssl/")
                        os.makedirs('/etc/apache2/ssl')

                    try:
                        SSSShellExec.cmd_exec(self, "openssl genrsa -out "
                                             "/etc/apache2/ssl/22222.key 2048")
                        SSSShellExec.cmd_exec(self, "openssl req -new -batch  "
                                             "-subj /commonName=127.0.0.1/ "
                                             "-key /etc/apache2/ssl/22222.key "
                                             "-out /etc/apache2/ssl/"
                                             "22222.csr")

                        SSSFileUtils.mvfile(self, "/etc/apache2/ssl/22222.key",
                                           "/etc/apache2/ssl/"
                                           "22222.key.org")

                        SSSShellExec.cmd_exec(self, "openssl rsa -in "
                                             "/etc/apache2/ssl/"
                                             "22222.key.org -out "
                                             "/etc/apache2/ssl/22222.key")

                        SSSShellExec.cmd_exec(self, "openssl x509 -req -days "
                                             "3652 -in /etc/apache2/ssl/"
                                             "22222.csr -signkey "
                                             "/etc/apache2/ssl/22222.key -out "
                                             "/etc/apache2/ssl/22222.crt")

                    except CommandExecutionError as e:
                        Log.error(self, "Failed to generate SSL for 22222")

                    # Apache Configation into GIT
                    SSSGit.add(self,
                              ["/etc/apache2"], msg="Adding Apache into Git")
                    SSSService.restart_service(self, 'apache2')

                    self.msg = (self.msg + ["HTTP Auth User Name: SSS"]
                                + ["HTTP Auth Password : {0}".format(passwd)])

            if set(SSSVariables.sss_php).issubset(set(apt_packages)):
                # Create log directories
                if not os.path.exists('/var/log/php/7.0/'):
                    Log.debug(self, 'Creating directory /var/log/php/7.0/')
                    os.makedirs('/var/log/php/7.0/')

                # TOD : xdebug

                # Parse etc/php5/fpm/php.ini
                config = configparser.ConfigParser()
                Log.debug(self, "configuring php file /etc/php/7.0/fpm/php.ini")
                config.read('/etc/php/7.0/fpm/php.ini')
                config['PHP']['expose_php'] = 'Off'
                config['PHP']['post_max_size'] = '100M'
                config['PHP']['upload_max_filesize'] = '100M'
                config['PHP']['max_execution_time'] = '300'
                config['PHP']['date.timezone'] = SSSVariables.sss_timezone
                with open('/etc/php/7.0/fpm/php.ini',
                          encoding='utf-8', mode='w') as configfile:
                    Log.debug(self, "Writting php configuration into "
                              "/etc/php/7.0/fpm/php.ini")
                    config.write(configfile)

                # Prase /etc/php/7.0/fpm/php-fpm.conf
                config = configparser.ConfigParser()
                Log.debug(self, "configuring php file"
                          "/etc/php/7.0/fpm/php-fpm.conf")
                config.read_file(codecs.open("/etc/php/7.0/fpm/php-fpm.conf",
                                             "r", "utf8"))
                config['global']['error_log'] = '/var/log/php/7.0/fpm.log'
                config.remove_option('global', 'include')
                config['global']['log_level'] = 'notice'
                config['global']['include'] = '/etc/php/7.0/fpm/pool.d/*.conf'
                with codecs.open('/etc/php/7.0/fpm/php-fpm.conf',
                                 encoding='utf-8', mode='w') as configfile:
                    Log.debug(self, "writting php7 configuration into "
                              "/etc/php/7.0/fpm/php-fpm.conf")
                    config.write(configfile)

                # Parse /etc/php/7.0/fpm/pool.d/www.conf
                config = configparser.ConfigParser()
                config.read_file(codecs.open('/etc/php/7.0/fpm/pool.d/www.conf',
                                             "r", "utf8"))
                config['www']['ping.path'] = '/ping'
                config['www']['pm.status_path'] = '/status'
                config['www']['pm.max_requests'] = '500'
                config['www']['pm.max_children'] = '100'
                config['www']['pm.start_servers'] = '20'
                config['www']['pm.min_spare_servers'] = '10'
                config['www']['pm.max_spare_servers'] = '30'
                config['www']['request_terminate_timeout'] = '300'
                config['www']['pm'] = 'ondemand'
                config['www']['listen'] = '127.0.0.1:9000'
                with codecs.open('/etc/php/7.0/fpm/pool.d/www.conf',
                                 encoding='utf-8', mode='w') as configfile:
                    Log.debug(self, "writting PHP5 configuration into "
                              "/etc/php/7.0/fpm/pool.d/www.conf")
                    config.write(configfile)

                #TODO : Debug Config
                #TODO : Disable xdebug

                # PHP and Debug pull configuration
                if not os.path.exists('{0}22222/htdocs/fpm/status/'
                                      .format(SSSVariables.sss_webroot)):
                    Log.debug(self, 'Creating directory '
                              '{0}22222/htdocs/fpm/status/ '
                              .format(SSSVariables.sss_webroot))
                    os.makedirs('{0}22222/htdocs/fpm/status/'
                                .format(SSSVariables.sss_webroot))
                open('{0}22222/htdocs/fpm/status/debug'
                     .format(SSSVariables.sss_webroot),
                     encoding='utf-8', mode='a').close()
                open('{0}22222/htdocs/fpm/status/php'
                     .format(SSSVariables.sss_webroot),
                     encoding='utf-8', mode='a').close()

                # Write info.php
                if not os.path.exists('{0}22222/htdocs/php/'
                                      .format(SSSVariables.sss_webroot)):
                    Log.debug(self, 'Creating directory '
                              '{0}22222/htdocs/php/ '
                              .format(SSSVariables.sss_webroot))
                    os.makedirs('{0}22222/htdocs/php'
                                .format(SSSVariables.sss_webroot))

                with open("{0}22222/htdocs/php/info.php"
                          .format(SSSVariables.sss_webroot),
                          encoding='utf-8', mode='w') as myfile:
                    myfile.write("<?php\nphpinfo();\n?>")

                SSSFileUtils.chown(self, "{0}22222"
                                  .format(SSSVariables.sss_webroot),
                                  SSSVariables.sss_php_user,
                                  SSSVariables.sss_php_user, recursive=True)

                SSSGit.add(self, ["/etc/php/"], msg="Adding PHP into Git")
                SSSService.restart_service(self, 'php7.0-fpm')

            if set(SSSVariables.sss_mysql).issubset(set(apt_packages)):
                if not os.path.isfile("/etc/mysql/my.cnf"):
                    config = ("[mysqld]\nwait_timeout = 30\n"
                              "interactive_timeout=60\nperformance_schema = 0"
                              "\nquery_cache_type = 1")
                    config_file = open("/etc/mysql/my.cnf",
                                       encoding='utf-8', mode='w')
                    config_file.write(config)
                    config_file.close()
                else:
                    try:
                        SSSShellExec.cmd_exec(self, "sed -i \"/#max_conn"
                                             "ections/a wait_timeout = 30 \\n"
                                             "interactive_timeout = 60 \\n"
                                             "performance_schema = 0\\n"
                                             "query_cache_type = 1 \" "
                                             "/etc/mysql/my.cnf")
                    except CommandExecutionError as e:
                        Log.error(self, "Unable to update MySQL file")

                 # Set MySQL Tuning Primer permission
                SSSFileUtils.chmod(self, "/usr/bin/tuning-primer", 0o775)

                SSSGit.add(self, ["/etc/mysql"], msg="Adding MySQL into Git")
                SSSService.reload_service(self, 'mysql')

        if len(packages):
            if any('/tmp/pma.tar.gz' == x[1]
                    for x in packages):
                SSSExtract.extract(self, '/tmp/pma.tar.gz', '/tmp/')
                Log.debug(self, 'Extracting file /tmp/pma.tar.gz to '
                          'location /tmp/')
                if not os.path.exists('{0}22222/htdocs/db'
                                      .format(SSSVariables.sss_webroot)):
                    Log.debug(self, "Creating new  directory "
                              "{0}22222/htdocs/db"
                              .format(SSSVariables.sss_webroot))
                    os.makedirs('{0}22222/htdocs/db'
                                .format(SSSVariables.sss_webroot))
                shutil.move('/tmp/phpmyadmin-STABLE/',
                            '{0}22222/htdocs/db/pma/'
                            .format(SSSVariables.sss_webroot))
                shutil.copyfile('{0}22222/htdocs/db/pma/config.sample.inc.php'
                                .format(SSSVariables.sss_webroot),
                                '{0}22222/htdocs/db/pma/config.inc.php'
                                .format(SSSVariables.sss_webroot))
                Log.debug(self, 'Setting Blowfish Secret Key FOR COOKIE AUTH to  '
                          '{0}22222/htdocs/db/pma/config.inc.php file '
                          .format(SSSVariables.sss_webroot))
                blowfish_key = ''.join([random.choice
                         (string.ascii_letters + string.digits)
                         for n in range(10)])
                SSSFileUtils.searchreplace(self,
                                          '{0}22222/htdocs/db/pma/config.inc.php'
                                          .format(SSSVariables.sss_webroot),
                                          "$cfg[\'blowfish_secret\'] = \'\';","$cfg[\'blowfish_secret\'] = \'{0}\';"
                                          .format(blowfish_key))
                Log.debug(self, 'Setting HOST Server For Mysql to  '
                          '{0}22222/htdocs/db/pma/config.inc.php file '
                          .format(SSSVariables.sss_webroot))
                SSSFileUtils.searchreplace(self,
                                          '{0}22222/htdocs/db/pma/config.inc.php'
                                          .format(SSSVariables.sss_webroot),
                                          "$cfg[\'Servers\'][$i][\'host\'] = \'localhost\';","$cfg[\'Servers\'][$i][\'host\'] = \'{0}\';"
                                          .format(SSSVariables.sss_mysql_host))
                Log.debug(self, 'Setting Privileges of webroot permission to  '
                          '{0}22222/htdocs/db/pma file '
                          .format(SSSVariables.sss_webroot))
                SSSFileUtils.chown(self, '{0}22222'
                                  .format(SSSVariables.sss_webroot),
                                  SSSVariables.sss_php_user,
                                  SSSVariables.sss_php_user,
                recursive=True) 
コード例 #12
0
    def post_pref(self, apt_packages, packages):
        """Post activity after installation of packages"""
        if len(apt_packages):
            if set(SSSVariables.sss_apache).issubset(set(apt_packages)):
                if not (os.path.isfile('/etc/apache2/conf-available/acl.conf')
                        ):
                    data = dict(webroot=SSSVariables.sss_webroot)
                    Log.debug(
                        self, 'Writting the Apache configuration to '
                        'file /etc/apache2/conf-available/acl.conf')
                    sss_apache = open('/etc/apache2/conf-available/acl.conf',
                                      encoding='utf-8',
                                      mode='w')
                    self.app.render((data), 'acl.mustache', out=sss_apache)
                    sss_apache.close()

                    # 22222 port setting

                    Log.debug(
                        self, 'Writting the Apache configuration to '
                        'file /etc/apache2/sites-available/'
                        '22222')

                    sss_apache = open(
                        '/etc/apache2/sites-available/22222.conf',
                        encoding='utf-8',
                        mode='w')
                    self.app.render((data), '22222.mustache', out=sss_apache)
                    sss_apache.close()

                    passwd = ''.join([
                        random.choice(string.ascii_letters + string.digits +
                                      string.punctuation) for n in range(10)
                    ])

                    try:
                        SSSShellExec.cmd_exec(
                            self, "printf \"SSS:"
                            "$(openssl passwd -crypt "
                            "{password} 2> /dev/null)\n\""
                            "> /etc/apache2/htpasswd-sss "
                            "2>/dev/null".format(password=passwd))
                    except CommandExecutionError as e:
                        Log.error(self, "Failed to save HTTP Auth")

                    # Create Symbolic link for 22222
                    SSSFileUtils.create_symlink(self, [
                        '/etc/apache2/'
                        'sites-available/'
                        '22222.conf', '/etc/apache2/'
                        'sites-enabled/'
                        '22222.conf'
                    ])

                    # Create htdocs folder
                    if not os.path.exists('{0}22222/htdocs'.format(
                            SSSVariables.sss_webroot)):
                        Log.debug(
                            self, "Creating directory "
                            "{0}22222/htdocs ".format(
                                SSSVariables.sss_webroot))
                        os.makedirs('{0}22222/htdocs'.format(
                            SSSVariables.sss_webroot))

                    if not os.path.exists('/etc/apache2/ssl'):
                        Log.debug(self, "Creating directory "
                                  "/etc/apache2/ssl/")
                        os.makedirs('/etc/apache2/ssl')

                    try:
                        SSSShellExec.cmd_exec(
                            self, "openssl genrsa -out "
                            "/etc/apache2/ssl/22222.key 2048")
                        SSSShellExec.cmd_exec(
                            self, "openssl req -new -batch  "
                            "-subj /commonName=127.0.0.1/ "
                            "-key /etc/apache2/ssl/22222.key "
                            "-out /etc/apache2/ssl/"
                            "22222.csr")

                        SSSFileUtils.mvfile(
                            self, "/etc/apache2/ssl/22222.key",
                            "/etc/apache2/ssl/"
                            "22222.key.org")

                        SSSShellExec.cmd_exec(
                            self, "openssl rsa -in "
                            "/etc/apache2/ssl/"
                            "22222.key.org -out "
                            "/etc/apache2/ssl/22222.key")

                        SSSShellExec.cmd_exec(
                            self, "openssl x509 -req -days "
                            "3652 -in /etc/apache2/ssl/"
                            "22222.csr -signkey "
                            "/etc/apache2/ssl/22222.key -out "
                            "/etc/apache2/ssl/22222.crt")

                    except CommandExecutionError as e:
                        Log.error(self, "Failed to generate SSL for 22222")

                    # Apache Configation into GIT
                    SSSGit.add(self, ["/etc/apache2"],
                               msg="Adding Apache into Git")
                    SSSService.restart_service(self, 'apache2')

                    self.msg = (self.msg + ["HTTP Auth User Name: SSS"] +
                                ["HTTP Auth Password : {0}".format(passwd)])

            #phpmyadmin config
            if set(SSSVariables.sss_pma).issubset(set(apt_packages)):
                php_conf = ("Include /etc/phpmyadmin/apache.conf")
                with open('/etc/apache2/apache2.conf', 'a') as php_conf_file:
                    php_conf_file.write(php_conf)
                """SSSFileUtils.create_symlink(self, ['/etc/phpmyadmin/apache.conf','/etc/apache2/apache2.conf'])"""
                """sss_php = open('/etc/apache2/apache2.conf',encoding='utf-8', mode='a')
                self.app.render((data), 'Include /etc/phpmyadmin/apache.conf',
                                out=sss_php)
                sss_php.close()
                """
            if set(SSSVariables.sss_php).issubset(set(apt_packages)):
                # Create log directories
                if not os.path.exists('/var/log/php/7.0/'):
                    Log.debug(self, 'Creating directory /var/log/php/7.0/')
                    os.makedirs('/var/log/php/7.0/')

                # TOD : xdebug

                # Parse etc/php5/fpm/php.ini
                config = configparser.ConfigParser()
                Log.debug(self,
                          "configuring php file /etc/php/7.0/fpm/php.ini")
                config.read('/etc/php/7.0/fpm/php.ini')
                config['PHP']['expose_php'] = 'Off'
                config['PHP']['post_max_size'] = '100M'
                config['PHP']['upload_max_filesize'] = '100M'
                config['PHP']['max_execution_time'] = '300'
                config['PHP']['date.timezone'] = SSSVariables.sss_timezone
                with open('/etc/php/7.0/fpm/php.ini',
                          encoding='utf-8',
                          mode='w') as configfile:
                    Log.debug(
                        self, "Writting php configuration into "
                        "/etc/php/7.0/fpm/php.ini")
                    config.write(configfile)

                # Prase /etc/php/7.0/fpm/php-fpm.conf
                config = configparser.ConfigParser()
                Log.debug(
                    self, "configuring php file"
                    "/etc/php/7.0/fpm/php-fpm.conf")
                config.read_file(
                    codecs.open("/etc/php/7.0/fpm/php-fpm.conf", "r", "utf8"))
                config['global']['error_log'] = '/var/log/php/7.0/fpm.log'
                config.remove_option('global', 'include')
                config['global']['log_level'] = 'notice'
                config['global']['include'] = '/etc/php/7.0/fpm/pool.d/*.conf'
                with codecs.open('/etc/php/7.0/fpm/php-fpm.conf',
                                 encoding='utf-8',
                                 mode='w') as configfile:
                    Log.debug(
                        self, "writting php7 configuration into "
                        "/etc/php/7.0/fpm/php-fpm.conf")
                    config.write(configfile)

                # Parse /etc/php/7.0/fpm/pool.d/www.conf
                config = configparser.ConfigParser()
                config.read_file(
                    codecs.open('/etc/php/7.0/fpm/pool.d/www.conf', "r",
                                "utf8"))
                config['www']['ping.path'] = '/ping'
                config['www']['pm.status_path'] = '/status'
                config['www']['pm.max_requests'] = '500'
                config['www']['pm.max_children'] = '100'
                config['www']['pm.start_servers'] = '20'
                config['www']['pm.min_spare_servers'] = '10'
                config['www']['pm.max_spare_servers'] = '30'
                config['www']['request_terminate_timeout'] = '300'
                config['www']['pm'] = 'ondemand'
                config['www']['listen'] = '127.0.0.1:9000'
                with codecs.open('/etc/php/7.0/fpm/pool.d/www.conf',
                                 encoding='utf-8',
                                 mode='w') as configfile:
                    Log.debug(
                        self, "writting PHP5 configuration into "
                        "/etc/php/7.0/fpm/pool.d/www.conf")
                    config.write(configfile)

                #TODO : Debug Config
                #TODO : Disable xdebug

                # PHP and Debug pull configuration
                if not os.path.exists('{0}22222/htdocs/fpm/status/'.format(
                        SSSVariables.sss_webroot)):
                    Log.debug(
                        self, 'Creating directory '
                        '{0}22222/htdocs/fpm/status/ '.format(
                            SSSVariables.sss_webroot))
                    os.makedirs('{0}22222/htdocs/fpm/status/'.format(
                        SSSVariables.sss_webroot))
                open('{0}22222/htdocs/fpm/status/debug'.format(
                    SSSVariables.sss_webroot),
                     encoding='utf-8',
                     mode='a').close()
                open('{0}22222/htdocs/fpm/status/php'.format(
                    SSSVariables.sss_webroot),
                     encoding='utf-8',
                     mode='a').close()

                # Write info.php
                if not os.path.exists('{0}22222/htdocs/php/'.format(
                        SSSVariables.sss_webroot)):
                    Log.debug(
                        self, 'Creating directory '
                        '{0}22222/htdocs/php/ '.format(
                            SSSVariables.sss_webroot))
                    os.makedirs('{0}22222/htdocs/php'.format(
                        SSSVariables.sss_webroot))

                with open("{0}22222/htdocs/php/info.php".format(
                        SSSVariables.sss_webroot),
                          encoding='utf-8',
                          mode='w') as myfile:
                    myfile.write("<?php\nphpinfo();\n?>")

                SSSFileUtils.chown(self,
                                   "{0}22222".format(SSSVariables.sss_webroot),
                                   SSSVariables.sss_php_user,
                                   SSSVariables.sss_php_user,
                                   recursive=True)

                SSSGit.add(self, ["/etc/php/"], msg="Adding PHP into Git")
                SSSService.restart_service(self, 'php7.0-fpm')

            if set(SSSVariables.sss_mysql).issubset(set(apt_packages)):
                if not os.path.isfile("/etc/mysql/my.cnf"):
                    config = ("[mysqld]\nwait_timeout = 30\n"
                              "interactive_timeout=60\nperformance_schema = 0"
                              "\nquery_cache_type = 1")
                    config_file = open("/etc/mysql/my.cnf",
                                       encoding='utf-8',
                                       mode='w')
                    config_file.write(config)
                    config_file.close()
                else:
                    try:
                        SSSShellExec.cmd_exec(
                            self, "sed -i \"/#max_conn"
                            "ections/a wait_timeout = 30 \\n"
                            "interactive_timeout = 60 \\n"
                            "performance_schema = 0\\n"
                            "query_cache_type = 1 \" "
                            "/etc/mysql/my.cnf")
                    except CommandExecutionError as e:
                        Log.error(self, "Unable to update MySQL file")

                # Set MySQL Tuning Primer permission
                SSSFileUtils.chmod(self, "/usr/bin/tuning-primer", 0o775)

                SSSGit.add(self, ["/etc/mysql"], msg="Adding MySQL into Git")
                SSSService.reload_service(self, 'mysql')