예제 #1
0
파일: sites.py 프로젝트: aspc/piccolo
 def create(shortname, full_name):
     session = db.Session()
     if Site.get(shortname):
         raise Site.Exists
     elif shell.exists(shell.join(config.SITES_ROOT, shortname)):
         raise Site.Exists
     elif not config.NAME_REGEX.match(shortname) or len(shortname) > config.NAME_LIMIT:
         raise Site.BadName("Site names must be between 2 and {0} characters and be valid hostnames (only letters, numbers, and dashes)".format(config.NAME_LIMIT))
     elif Domain.get('.'.join([shortname, config.DEFAULT_DOMAIN])):
         existing = Domain.get('.'.join([shortname, config.DEFAULT_DOMAIN]))
         raise Site.BadName("There is already a domain {0} in piccolo, so adding this site would "\
             "create a name conflict. Remove {0} from {1} before "\
             "adding this site.".format(existing.domain_name, existing.site.shortname))
     else:
         logger.debug("site doesn't exist yet in db")
         new_site = Site(shortname, full_name)
     
     new_site.db_password = shell.generate_password(length=20)
     new_site.db_username = re.sub(r'[^\w\d]', '_', new_site.shortname)
     new_site.db_username_mysql = new_site.db_username[:16] # grrr
     
     if not shell.is_pretend():
         session.add(new_site)
         session.commit()
     try:
         new_site._shell_create()
         if not shell.is_pretend():
             Domain.create('.'.join([new_site.shortname, config.DEFAULT_DOMAIN]), new_site)
     except shell.ShellActionFailed as e:
         logger.exception("Shell action failed")
         raise
     else:
         do("service nginx reload")
         logger.info('Created site "{0}" [{1}]'.format(full_name, shortname))
예제 #2
0
파일: sites.py 프로젝트: aspc/piccolo
 def addUser(self, user, suppress_welcome=False):
     if shell.is_pretend():
         suppress_welcome = True
         logger.info("Pretending to add {0} to site {1}".format(user, self))
     
     session = db.Session()
     logger.debug('Users in {0}: {1}'.format(self.shortname, self.users))
     if user in self.users:
         raise Site.AlreadyHasUser
     if not shell.is_pretend():
         self.users.append(user)
         session.commit()
     try:
         do("gpasswd -a {0} {1}".format(user.username, self.shortname))
         do("ln -s {0} {1}".format(self._get_home(), shell.join(user._get_home(), self.shortname)))
     except shell.ShellActionFailed:
         if not shell.is_pretend():
             self.users.remove(user)
             session.commit()
         raise
     else:
         if not suppress_welcome:
             email_vars = {
                 "$FULL_NAME": user.full_name,
                 "$SITE_SHORTNAME": self.shortname,
             }
             
             email_message = shell.format(open(shell.join(config.TEMPLATE_ROOT, 'site_adduser_email.txt')).read(), email_vars)
             email_subject = "Peninsula Account Update: {0} added to site {1}".format(user.username, self.shortname)
             user.send_email(email_subject, email_message)
             logger.info("Sent adduser email to {0}".format(user.email))
         logger.info('Added {0} to {1}'.format(user.username, self.shortname))
예제 #3
0
파일: sites.py 프로젝트: aspc/piccolo
 def delete(shortname):
     session = db.Session()
     the_site = Site.get(shortname)
     if not the_site:
         raise Site.DoesNotExist("Cannot delete {0} because it does not exist in the DB".format(shortname))
     try:
         the_site._shell_delete()
     except shell.ShellActionFailed as e:
         logger.exception("Shell action failed")
         raise
     else:
         if not shell.is_pretend():
             session.delete(the_site)
             session.commit()
             do("service nginx reload")
         logger.info("Deleted {0} from the DB".format(shortname))
예제 #4
0
파일: sites.py 프로젝트: aspc/piccolo
    def removeUser(self, user):
        if shell.is_pretend():
            logger.info("Pretending to remove {0} from site {1}".format(user, self))

        session = db.Session()
        logger.debug('Users in {0}: {1}'.format(self.shortname, self.users))
        if not user in self.users:
            raise Site.NoSuchUser
        try:
            do("gpasswd -d {0} {1}".format(user.username, self.shortname))
            do("rm {0}".format(shell.join(user._get_home(), self.shortname)))
        except shell.ShellActionFailed:
            logger.exception("Removal failed; user is still member of site in DB.")
            raise
        else:
            if not shell.is_pretend():
                self.users.remove(user)
                session.commit()
            logger.info('Removed {0} from {1}'.format(user.username, self.shortname))
예제 #5
0
파일: users.py 프로젝트: aspc/piccolo
 def _shell_create(self):
     do("useradd -U -b {0} -m -s /bin/bash {1}".format(
         config.USERS_ROOT,
         self.username
     ))
     self._format_append("user_bash_profile.sh", shell.join(self._get_home(), ".profile"))
     tmppass = shell.join(self._get_home(), '.tmppass')
     with open(tmppass, 'w') as t:
         os.chmod(tmppass, stat.S_IRWXU)
         t.write("{0}\n{0}\n".format(self._temp_password))
         t.close()
     do("passwd {0} < {1}".format(self.username, tmppass), shell=True)
     do("passwd -e {0}".format(self.username))
     do("rm {0}".format(tmppass))
예제 #6
0
파일: sites.py 프로젝트: aspc/piccolo
 def _shell_delete(self):
     do("rm {0}".format(self._get_path()))
     do("service nginx reload")
예제 #7
0
파일: sites.py 프로젝트: aspc/piccolo
 def _shell_create(self):
     self._format_copy("site.nginx.domain.conf", self._get_path())
     do("service nginx reload")
예제 #8
0
파일: sites.py 프로젝트: aspc/piccolo
 def _shell_create(self, pretend=False):
     # Actual shell-level business of provisioning the site goes here
     
     # Set up siteuser and sitegroup
     do("useradd -U -b {0} -m -s /bin/bash {1}".format(
         config.SITES_ROOT,
         self.shortname
     ))
     
     # Set up template and permissions
     do("chmod u=rwX,g=rwXs,o=X {0}".format(self._get_home()))
     
     for path in glob.glob(shell.join(config.TEMPLATE_ROOT, 'site', '*')):
         do("cp -R {0} {1}".format(path, self._get_home()))
     
     for d in Site._additional_dirs:
         do("mkdir {0}".format(shell.join(self._get_home(), d)))
     
     do("chown -R {0}:{0} {1}".format(self.shortname, self._get_home()))
     
     for p in Site._permissions:
         do("chmod {0} {1}".format(p[1], shell.join(self._get_home(), p[0])))
     
     # Do variable substitution in template files
     
     for root, dirs, files in os.walk(self._get_home()):
         for name in files:
             shell.format_file(shell.join(root, name), self._vars())
     
     for root, dirs, files in os.walk(shell.join(self._get_home(), "bin")):
         for name in files:
             do("chmod u=rwx,g=rx,o= {0}".format(shell.join(root, name)))
     
     for root, dirs, files in os.walk(shell.join(self._get_home(), "config")):
         for name in files:
             do("chmod u=rw,g=rw,o= {0}".format(shell.join(root, name)))
     
     # Install crontab from temp file
     
     crontab_path = shell.join(self._get_home(), 'crontab')
     self._format_copy('site.crontab', crontab_path)
     
     do("crontab -u {0} {1}".format(self.shortname, crontab_path))
     do("rm {0}".format(crontab_path))
     
     # Install sudoers
     sudoers_dest = '/etc/sudoers.d/{0}'.format(self.shortname)
     if shell.exists(sudoers_dest):
         raise shell.ShellActionFailed("{0} exists. Abort!".format(sudoers_dest))
     self._format_copy('site.sudoers', sudoers_dest)
     do("chmod u=r,g=r,o= {0}".format(sudoers_dest))
     do("chown root:root {0}".format(sudoers_dest))
     
     # Install nginx config
     nginx_dest = shell.join(config.NGINX_CONF_ROOT, "{0}.conf".format(self.shortname))
     if shell.exists(nginx_dest):
         raise shell.ShellActionFailed("{0} exists. Abort!".format(nginx_dest))
     self._format_copy('site.nginx.conf', nginx_dest)
     do("chmod u=rw,g=rw,o=r {0}".format(nginx_dest))
     do("chown root:admin {0}".format(nginx_dest))
     
     do("mkdir {0}".format(shell.join(config.NGINX_CONF_ROOT, "{0}_domains".format(self.shortname))))
     
     # Set up db users
     self._create_db_accounts()
     
     # Start site
     for service in ("httpd.sh", "php.sh"):
         do("sudo -u {0} {1} start".format(self.shortname, shell.join(self._get_home(), "bin", service)))
예제 #9
0
파일: sites.py 프로젝트: aspc/piccolo
 def _shell_delete(self):
     for service in ("httpd.sh", "php.sh"):
         do("sudo -u {0} {1} stop".format(self.shortname, shell.join(self._get_home(), "bin", service)))
     do("pkill -u {0}".format(self.shortname), ignore_errors=True)
     
     wait("Waiting for services to be removed from process list")
     
     try:
         self._drop_db_accounts()
     except:
         if not shell.is_forced():
             raise
     
     do("rm /etc/sudoers.d/{0}".format(self.shortname))
     do("rm /etc/piccolo/nginx/{0}.conf".format(self.shortname))
     do("rm -rf /etc/piccolo/nginx/{0}_domains".format(self.shortname))
     do("userdel -r {0}".format(self.shortname))
     do("groupdel {0}".format(self.shortname), ignore_errors=True)
예제 #10
0
파일: users.py 프로젝트: aspc/piccolo
 def _shell_delete(self):
     do("pkill -u {0}".format(self.username), ignore_errors=True)
     wait("Waiting for user's processes to exit")
     do("userdel -r {0}".format(self.username))