def put(self, id): data = request.get_json()["database_user"] u = databases.get_users(id) if not id or not u: abort(404) elif not data.get("operation"): abort(400) u.chperm(data["operation"], databases.get(data["database"])) return jsonify(database_user=u.serialized)
def delete(self, id): u = databases.get_users(id) if not id or not u: abort(404) try: u.remove() except errors.InvalidConfigError as e: logger.error("Databases", str(e)) return jsonify(errors={"msg": str(e)}), 422 return Response(status=204)
def get(self, id): if request.args.get("rescan", None): databases.scan_users() u = databases.get_users(id) if id and not u: abort(404) if isinstance(u, databases.DatabaseUser): return jsonify(database_user=u.serialized, database_type=u.manager.serialized) else: db_types = (x.manager.serialized for x in u) db_types = list({v['id']: v for v in db_types}.values()) return jsonify(database_users=[x.serialized for x in u], database_types=db_types)
def list_users(): """List all database users.""" try: dbs = databases.get_users() if not dbs: logger.info('ctl:dbusr:list', 'No database users found') return llen = len(sorted(dbs, key=lambda x: len(x.id))[-1].id) for x in sorted(dbs, key=lambda x: x.id): click.echo( click.style('{name: <{fill}}'.format(name=x.id, fill=llen + 3), fg="white", bold=True) + click.style(x.manager.name, fg="yellow")) except Exception as e: raise CLIException(str(e))
def _remove(self, nthread): nthread.title = "Removing website" # Call site type's pre-removal hook msg = "Running pre-removal. This may take a few minutes..." nthread.update(Notification("info", "Webs", msg)) self.pre_remove() # Remove source directories msg = "Cleaning directories..." nthread.update(Notification("info", "Webs", msg)) if os.path.islink(self.path): os.unlink(self.path) else: shutil.rmtree(self.path) # If there's a database, get rid of that too if self.db: msg = "Removing database..." nthread.update(Notification("info", "Webs", msg)) if self.db.manager.meta.database_multiuser: db_user = databases.get_users(self.db.id) if db_user: db_user.remove() self.db.remove() self.nginx_disable(reload=True) try: os.unlink(os.path.join("/etc/nginx/sites-available", self.id)) except: pass # Call site type's post-removal hook msg = "Running post-removal..." nthread.update(Notification("info", "Webs", msg)) self.post_remove() create_acme_dummy(self.domain) if self.id in storage.websites: del storage.websites[self.id] signals.emit("websites", "site_removed", self) msg = "{0} site removed successfully".format(self.app.name) nthread.complete(Notification("success", "Webs", msg))
def clean_up(self): """Clean up after a failed installation.""" try: shutil.rmtree(self.path, True) except: pass if self.db: try: self.db.remove() except: pass db_user = databases.get_users(self.id) if db_user: try: db_user.remove() except: pass try: os.unlink(os.path.join("/etc/nginx/sites-available", self.id)) except: pass
def restore(self, backup, data=True, nthread=NotificationThread()): """ Restore an associated arkOS app backup. :param Backup backup: backup to restore :param bool data: Restore backed up data files too? :param NotificationThread nthread: notification thread to use :returns: ``Backup`` :rtype: dict """ nthread.title = "Restoring backup" # Trigger pre-restore hook for the app/site signals.emit("backups", "pre_restore", self) msg = "Running pre-restore for {0}...".format(backup["pid"]) nthread.update(Notification("info", "Backup", msg)) self.pre_restore() # Extract all files in archive sitename = "" nthread.update(Notification("info", "Backup", "Extracting files...")) with tarfile.open(backup["path"], "r:gz") as t: for x in t.getnames(): if x.startswith("etc/nginx/sites-available"): sitename = os.path.basename(x) t.extractall("/") # If it's a website that had a database, restore DB via SQL file too dbpasswd = "" if self.ctype == "site" and sitename: self.site = websites.get(sitename) if not self.site: websites.scan() self.site = websites.get(sitename) meta = configparser.SafeConfigParser() meta.read(os.path.join(self.site.path, ".arkos")) sql_path = "/{0}.sql".format(sitename) if meta.get("website", "dbengine", fallback=None) \ and os.path.exists(sql_path): nthread.update( Notification("info", "Backup", "Restoring database...")) dbmgr = databases.get_managers(meta.get("website", "dbengine")) if databases.get(sitename): databases.get(sitename).remove() db = dbmgr.add_db(sitename) with open(sql_path, "r") as f: db.execute(f.read()) os.unlink(sql_path) if dbmgr.meta.database_multiuser: dbpasswd = random_string(16) dbuser = databases.get_users(sitename) if dbuser: dbuser.remove() db_user = dbmgr.add_user(sitename, dbpasswd) db_user.chperm("grant", db) # Trigger post-restore hook for the app/site msg = "Running post-restore for {0}...".format(backup["pid"]) nthread.update(Notification("info", "Backup", msg)) if self.ctype == "site": self.post_restore(self.site, dbpasswd) self.site.nginx_enable() else: self.post_restore() signals.emit("backups", "post_restore", self) backup["is_ready"] = True msg = "{0} restored successfully.".format(backup["pid"]) nthread.complete(Notification("info", "Backup", msg)) return backup