def run_daemon(environment, log_level, config_file): create_app(app, log_level, config_file, True) app.conf.set("enviro", "run", environment) app.logger.info('Environment: %s' % environment) for code in default_exceptions.iterkeys(): app.error_handler_spec[None][code] = make_json_error app.register_blueprint(auth.backend) app.register_blueprint(messages.backend) app.logger.info("Loading applications...") applications.get() # Load framework blueprints app.logger.info("Loading frameworks...") register_frameworks(app) app.logger.info("Initializing Genesis (if present)...") app.register_blueprint(genesis.backend) tracked_services.initialize() app.logger.info("Server is up and ready") try: app.run(host="0.0.0.0", port=8000) except KeyboardInterrupt: app.logger.info("Received interrupt")
def assign(self, assign): """ Assign a TLS certificate to a website or service. :param dict assign: ``Assign`` object to assign :returns: self """ signals.emit("certificates", "pre_assign", (self, assign)) nginx_reload = False if assign["type"] == "genesis": config.set("genesis", "cert_file", self.cert_path) config.set("genesis", "cert_key", self.key_path) config.set("genesis", "ssl", True) config.save() self.assigns.append(assign) elif assign["type"] == "website": w = websites.get(assign["id"]) w.cert = self w.ssl_enable() self.assigns.append(assign) nginx_reload = True else: d = applications.get(assign["aid"]).ssl_enable(self, assign["sid"]) self.assigns.append(d) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_assign", (self, assign)) return self
def assigns(): """List all apps/sites that can use certificates.""" click.echo("Apps/Sites that can use certificates:") try: assigns = [] assigns.append({ "type": "genesis", "id": "genesis", "name": "arkOS Genesis/API" }) for x in websites.get(): assigns.append({ "type": "website", "id": x.id, "name": x.id if x.app else x.name }) for x in applications.get(installed=True): if x.type == "app" and x.uses_ssl: for y in x.get_ssl_able(): assigns.append(y) for x in assigns: imsg = click.style("(" + x["type"].capitalize() + ")", fg="green") click.echo( click.style(x["name"], fg="white", bold=True) + " " + imsg) except Exception as e: raise CLIException(str(e))
def scan(): certs, assigns = [], {} if config.get("genesis", "ssl"): ssl = os.path.splitext(os.path.basename(config.get("genesis", "cert_file", "")))[0] if ssl and assigns.has_key(ssl): assigns[ssl].append({"type": "genesis", "id": "genesis", "name": "arkOS Genesis/API"}) elif ssl: assigns[ssl] = [{"type": "genesis", "id": "genesis", "name": "arkOS Genesis/API"}] for x in applications.get(installed=True): if hasattr(x, "ssl"): for ssl, data in x.ssl.get_ssl_assigned(): if assigns.has_key(ssl): assigns[ssl] += data else: assigns[ssl] = [] assigns[ssl].append(data) if not os.path.exists(config.get("certificates", "cert_dir")): os.makedirs(config.get("certificates", "cert_dir")) if not os.path.exists(config.get("certificates", "key_dir")): os.makedirs(config.get("certificates", "key_dir")) for x in glob.glob(os.path.join(config.get("certificates", "cert_dir"), "*.crt")): id = os.path.splitext(os.path.basename(x))[0] with open(x, "r") as f: crt = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read()) with open(os.path.join(config.get("certificates", "key_dir"), id+".key"), "r") as f: key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, f.read()) sha1, md5 = get_cert_hashes(crt) c = Certificate(id=id, cert_path=x, key_path=os.path.join(config.get("certificates", "key_dir"), id+".key"), keytype="RSA" if key.type() == OpenSSL.crypto.TYPE_RSA else ("DSA" if key.type() == OpenSSL.crypto.TYPE_DSA else "Unknown"), keylength=int(key.bits()), domain=crt.get_subject().CN, assigns=assigns.get(id) or [], expiry=crt.get_notAfter(), sha1=sha1, md5=md5) certs.append(c) storage.certs.set("certificates", certs) return certs
def scan_managers(): mgrs = [] for x in applications.get(type="database"): if x.installed and hasattr(x, "_database_mgr"): mgrs.append(x._database_mgr(id=x.id, name=x.name, meta=x)) storage.dbs.set("managers", mgrs) return mgrs
def info(id): """Get information about a certain application.""" try: x = applications.get(id).as_dict lines = { "Type:": x["type"].capitalize(), "By:": x["app_author"], "Description:": x["description"]["short"], "Website:": x["app_homepage"], "Installed:": "Yes" if x["installed"] else "No" } click.echo(click.style(x["name"], fg="white", bold=True)) click.echo(click.style(" * Version: ", fg="yellow") + x["version"]) if x["upgradable"]: click.echo( click.style(" * Upgradable to: ", fg="green") + x["upgradable"]) for key in sorted(lines.keys()): imsg = click.style(lines[key], fg="white") click.echo(click.style(" * " + key, fg="yellow") + " " + imsg) if [y for y in x["dependencies"] if y["type"] == "app"]: deps = [y["name"] for y in x["dependencies"] if y["type"] == "app"] click.echo( click.style(" * Depends on:", fg="yellow") + " " + click.style(", ".join(deps), fg="white")) except Exception as e: raise CLIException(str(e))
def dispatcher(id, path): a = applications.get(id) if not a or not hasattr(a, "_api"): abort(404) params = path.split("/") fn = getattr(a._api, params[0]) return fn(*params[1:])
def get_defense_rules(): """Get all defense rules from arkOS service objects.""" lst = [] remove = [] cfg = get_jail_config(jailconf) fcfg = configparser.SafeConfigParser() for c in applications.get(): if hasattr(c, "f2b") and hasattr(c, "f2b_name"): lst.append({"id": c.f2b_name, "icon": c.f2b_icon, "f2b": c.f2b}) elif hasattr(c, "f2b"): lst.append({"id": c.id, "icon": c.icon, "f2b": c.f2b}) for p in lst: for l in p["f2b"]: if "custom" not in l: try: jail_opts = cfg.items(l["id"]) except configparser.NoSectionError: remove.append(p) continue filter_name = cfg.get(l["id"], "filter") if "%(__name__)s" in filter_name: filter_name = filter_name.replace("%(__name__)s", l["id"]) c = fcfg.read([ "{0}/common.conf".format(filters), "{0}/{1}.conf".format(filters, filter_name) ]) filter_opts = fcfg.items("Definition") l["jail_opts"] = jail_opts l["filter_name"] = filter_name l["filter_opts"] = filter_opts else: conf_name = "{0}/{1}.conf".format(filters, l["filter_name"]) if not os.path.exists(conf_name): fcfg = configparser.SafeConfigParser() fcfg.add_section("Definition") for o in l["filter_opts"]: fcfg.set("Definition", o[0], o[1]) with open(conf_name, "w") as f: fcfg.write(f) if not l["id"] in cfg.sections(): cfg.add_section(l["id"]) for o in l["jail_opts"]: cfg.set(l["id"], o[0], o[1]) with open(jailconf, "w") as f: cfg.write(f) else: jail_opts = cfg.items(l["id"]) filter_name = cfg.get(l["id"], "filter") fcfg.read([ "{0}/common.conf".format(filters), "{0}/{1}.conf".format(filters, filter_name) ]) filter_opts = fcfg.items("Definition") l["jail_opts"] = jail_opts l["filter_name"] = filter_name l["filter_opts"] = filter_opts for x in remove: lst.remove(x) return lst
def restore(backup, data=True): controller = None if backup["type"] == "site": sites = websites.get() for x in sites: if x.id == backup["pid"]: controller = x.backup break else: app = applications.get(backup["site_type"]) controller = app._backup(backup["pid"], backup["icon"], True) else: app = applications.get(backup["pid"]) controller = app._backup() if not controller: raise Exception("No backup controller found") b = controller.restore(backup) return b
def list_apps(show_hidden): """List all applications.""" try: adata = applications.get() if not show_hidden: adata = [x for x in adata if x.type not in ["database"]] _list_applications(adata) except Exception as e: raise CLIException(str(e))
def available(show_hidden): """List all available applications.""" try: adata = applications.get(installed=False) if not show_hidden: adata = [x for x in adata if x.type not in ["database"]] _list_applications(adata) except Exception as e: raise CLIException(str(e))
def ssl_able(): assigns = [] for x in websites.get(): assigns.append({"type": "website", "id": x.id, "name": x.id if x.meta else x.name}) for x in applications.get(): if x.type == "app" and x.uses_ssl: for y in x.get_ssl_able(): assigns.append(y) return jsonify(certassigns=assigns)
def unassign(self, assign): signals.emit("certificates", "pre_unassign", (self, assign)) nginx_reload = False if assign["type"] == "website": websites.get(assign["id"]).ssl_disable() self.assigns.remove(assign) nginx_reload = True elif assign["type"] == "genesis": config.set("genesis", "cert_file", "") config.set("genesis", "cert_key", "") config.set("genesis", "ssl", False) config.save() self.assigns.remove(assign) else: applications.get(assign["aid"]).ssl_disable(assign["sid"]) self.assigns.remove(assign) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_unassign", (self, assign)) return None
def get(self, id): if request.args.get("rescan", None): applications.scan() apps = applications.get(id, type=request.args.get("type", None), loadable=request.args.get("loadable", None), installed=request.args.get("installed", None)) if id and not apps: abort(404) if type(apps) == list: return jsonify(apps=[x.as_dict() for x in apps]) else: return jsonify(app=apps.as_dict())
def scan_sharers(): """ Retrieve a list of all file share systems registered with arkOS. :return: Sharer(s) :rtype: Sharer or list thereof """ storage.share_engines.clear() for x in applications.get(type="fileshare"): if x.installed and hasattr(x, "_share_mgr"): storage.share_engines[x.id] = x._share_mgr(id=x.id, icon=x.icon) return storage.share_engines
def scan(): """ Search proper directory for certificates, load them and store metadata. :return: list of Certificate objects :rtype: list """ logger.debug("Crts", "Scanning for certificates") assigns = {} if config.get("genesis", "ssl"): gen_cert = config.get("genesis", "cert_file") ssl = os.path.splitext(os.path.basename(gen_cert))[0] if ssl and ssl in assigns: assigns[ssl].append({"type": "genesis", "id": "genesis", "name": "arkOS Genesis/API"}) elif ssl: assigns[ssl] = [{"type": "genesis", "id": "genesis", "name": "arkOS Genesis/API"}] for x in applications.get(installed=True): if hasattr(x, "ssl"): for ssl, data in x.ssl.get_ssl_assigned(): if ssl in assigns: assigns[ssl] += data else: assigns[ssl] = [] assigns[ssl].append(data) if not os.path.exists(config.get("certificates", "cert_dir")): os.makedirs(config.get("certificates", "cert_dir")) if not os.path.exists(config.get("certificates", "key_dir")): os.makedirs(config.get("certificates", "key_dir")) storage.certificates.clear() cert_glob = os.path.join(config.get("certificates", "cert_dir"), "*.crt") for cert_path in glob.glob(cert_glob): id = os.path.splitext(os.path.basename(cert_path))[0] key_path = os.path.join( config.get("certificates", "key_dir"), "{0}.key".format(id)) storage.certificates[id] = \ _scan_a_cert(id, cert_path, key_path, assigns) acmedir = config.get("certificates", "acme_dir") if not os.path.exists(acmedir): os.makedirs(acmedir) le_cert_glob = os.path.join(acmedir, "*/cert.pem") for cert_path in glob.glob(le_cert_glob): basedir = os.path.dirname(cert_path) id = os.path.basename(basedir) key_path = os.path.join(basedir, "privkey.pem") storage.certificates[id] = \ _scan_a_cert(id, cert_path, key_path, assigns, True) return storage.certificates
def ssl_able(): assigns = [] assigns.append({"type": "genesis", "id": "genesis", "name": "arkOS Genesis/API"}) for x in websites.get(): assigns.append({"type": "website", "id": x.id, "name": x.id if x.app else x.name}) for x in applications.get(installed=True): if x.type == "app" and x.uses_ssl: for y in x.get_ssl_able(): assigns.append(y) return jsonify(assignments=assigns)
def _post(self, job, data): nthread = NotificationThread(id=job.id) sapp = applications.get(data["app"]) site = sapp._website site = site(sapp, data["id"], data["domain"], data["port"]) try: specialmsg = site.install(data["extra_data"], True, nthread) if specialmsg: Notification("info", "Websites", specialmsg).send() push_record("website", site.serialized) except Exception as e: remove_record("website", data["id"]) raise
def scan_managers(): """ Retrieve a list of all database managers registered with arkOS. :return: DatabaseManager(s) :rtype: DatabaseManager or list thereof """ storage.database_engines.clear() for x in applications.get(type="database"): if x.installed and hasattr(x, "_database_mgr"): storage.database_engines[x.id] = \ x._database_mgr(id=x.id, name=x.name, meta=x) return storage.database_engines
def get_able(): able = [] for x in applications.get(installed=True): if x.type != "website" and hasattr(x, "_backup"): able.append({"type": "app", "icon": x.icon, "id": x.id}) for x in websites.get(): if not isinstance(x, websites.ReverseProxy): able.append({"type": "site", "icon": x.meta.icon, "id": x.id}) for x in get(): if not x["pid"] in [y["id"] for y in able]: able.append({"type": x["type"], "icon": x["icon"], "id": x["pid"]}) if not "arkOS" in [x["id"] for x in able]: able.append({"type": "app", "icon": "fa fa-cog", "id": "arkOS"}) return able
def _post(self, data): message = Message() app = applications.get(data["site_type"]) site = app._website site = site(data["id"], data["addr"], data["port"]) try: specialmsg = site.install(app, data["extra_data"], True, message) message.complete("success", "%s site installed successfully" % site.meta.name) if specialmsg: Message("info", specialmsg) push_record("website", site.as_dict()) except Exception, e: message.complete("error", "%s could not be installed: %s" % (data["id"], str(e))) remove_record("website", data["id"]) raise
def create(id, data=True): controller = None if id == "arkOS": controller = arkOSBackupCfg(id="arkOS", icon="fa fa-cog", version=arkos_version) return controller.backup() app = applications.get(id) if app and app.type != "website" and hasattr(app, "_backup"): controller = app._backup(app.id, app.icon, version=app.version) else: sites = websites.get() for x in sites: if x.id == id: controller = x.backup break if not controller: raise Exception("No backup controller found") return controller.backup(data=data)
def get(self, id): if request.args.get("rescan", None): applications.scan() installed = request.args.get("installed", None) if installed and installed.lower() == "true": installed = True elif installed and installed.lower() == "false": installed = False apps = applications.get( id, type=request.args.get("type", None), loadable=request.args.get("loadable", None), installed=installed, cry=False) if id and not apps: abort(404) if isinstance(apps, applications.App): return jsonify(app=apps.serialized) else: return jsonify(apps=[x.serialized for x in apps])
def create(id, site_type, address, port, extra_data): """Create a website""" try: edata = {} if extra_data: for x in extra_data.split(","): edata[x.split("=")[0]] = x.split("=")[1] sapp = applications.get(site_type.lower()) if hasattr(sapp, "website_options") and not extra_data: for x in sapp.website_options: if x == "messages": continue for y in sapp.website_options[x]: edata[y["id"]] = click.prompt(y["label"]) site = sapp._website site = site(sapp, id, address, port) site.install(edata, True) except Exception as e: raise CLIException(str(e))
def put(self, id): operation = request.get_json()["app"]["operation"] app = applications.get(id) if not app: abort(404) if operation == "install": if app.installed and not getattr(app, "upgradable", None): return jsonify(app=app.serialized) id = as_job(self._install, app) elif operation == "uninstall": if not app.installed: resp = jsonify(message="Application isn't yet installed") resp.status_code = 422 return resp id = as_job(self._uninstall, app) else: return jsonify(errors={"msg": "Unknown operation"}), 422 data = app.serialized data["is_ready"] = False return job_response(id, {"app": data})
def put(self, id): operation = json.loads(request.data)["app"]["operation"] app = applications.get(id) if not app: abort(404) if operation == "install": id = as_job(self._install, app) elif operation == "uninstall": if not app.installed: resp = jsonify(message="Application isn't yet installed") resp.status_code = 422 return resp id = as_job(self._uninstall, app) else: resp = jsonify(message="Unknown operation specified") resp.status_code = 422 return resp data = app.as_dict() data["is_ready"] = False return job_response(id, {"app": data})
def get_able(): """ Obtain a list of arkOS application instances that support backups. This list includes all currently installed websites, apps and also arkOS. :returns: Website/app information :rtype: dict """ able = [] for x in applications.get(installed=True): if x.type != "website" and hasattr(x, "_backup"): able.append({"type": "app", "icon": x.icon, "id": x.id}) for x in websites.get(): if not isinstance(x, websites.ReverseProxy): able.append({"type": "site", "icon": x.app.icon, "id": x.id}) for x in get(): if not x["pid"] in [y["id"] for y in able]: able.append({"type": x["type"], "icon": x["icon"], "id": x["pid"]}) if "arkOS" not in [x["id"] for x in able]: able.append({"type": "app", "icon": "setting", "id": "arkOS"}) return able
def assign(self, assign): signals.emit("certificates", "pre_assign", (self, assign)) nginx_reload = False if assign["type"] == "genesis": config.set("genesis", "cert_file", self.cert_path) config.set("genesis", "cert_key", self.key_path) config.set("genesis", "ssl", True) config.save() self.assigns.append(assign) elif assign["type"] == "website": w = websites.get(assign["id"]) w.cert = self w.ssl_enable() self.assigns.append(assign) nginx_reload = True else: d = applications.get(assign["aid"]).ssl_enable(self, assign["sid"]) self.assigns.append(d) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_assign", (self, assign)) return self
def make_json_error(err): if hasattr(err, "description"): message = err.description else: message = str(err) if traceback.format_exc(): stacktrace = traceback.format_exc() report = "arkOS %s Crash Report\n" % version() report += "--------------------\n\n" report += "Running in %s\n" % config.get("enviro", "run") report += "System: %s\n" % shell("uname -a")["stdout"] report += "Platform: %s %s\n" % (config.get("enviro", "arch"), config.get("enviro", "board")) report += "Python version %s\n" % '.'.join([str(x) for x in platform.python_version_tuple()]) report += "Config path: %s\n\n" % config.filename report += "Loaded applicatons: \n%s\n\n" % "\n".join([x.id for x in applications.get()]) report += "Request: %s %s\n\n" % (request.method, request.path) report += stacktrace response = jsonify(message=message, stacktrace=stacktrace, report=report, version=version(), arch=config.get("enviro", "arch")) else: response = jsonify(message=message) response.status_code = err.code if isinstance(err, HTTPException) else 500 return add_cors(response)
def genesis_init(state): path = "" apps = applications.get() if config.get("enviro", "run") == "vagrant": path = '/home/vagrant/genesis' elif config.get("enviro", "run") == "dev": sdir = os.path.dirname(os.path.realpath(__file__)) path = os.path.abspath(os.path.join(sdir, '../../genesis')) elif os.path.exists('/var/lib/arkos/genesis'): path = '/var/lib/arkos/genesis' if not os.path.exists(path): return backend.add_url_rule('/', defaults={'path': None}, view_func=genesis, methods=['GET',]) backend.add_url_rule('/<path:path>', view_func=genesis, methods=['GET',]) for x in os.listdir(os.path.join(path, 'lib')): if os.path.islink(os.path.join(path, 'lib', x)): os.unlink(os.path.join(path, 'lib', x)) libpaths = [] for x in apps: genpath = "/var/lib/arkos/applications/%s/genesis" % x.id if os.path.exists(genpath): libpaths.append("lib/%s"%x.id) os.symlink(genpath, os.path.join(path, 'lib', x.id)) if libpaths: with open(os.path.join(path, 'package.json'), 'r') as f: data = json.loads(f.read()) data["ember-addon"] = {"paths": libpaths} with open(os.path.join(path, 'package.json'), 'w') as f: f.write(json.dumps(data, sort_keys=True, indent=2, separators=(',', ': '))) mydir = os.getcwd() os.chdir(path) s = shell("ember build") os.chdir(mydir) if s["code"] != 0: raise Exception("Genesis rebuild process failed")
def install(job, to_install): errors = False nthread = NotificationThread(id=job.id) nthread.title = "Setting up your server..." for x in to_install: a = applications.get(x) msg = "Installing {0}...".format(x) nthread.update(Notification("info", "FirstRun", msg)) try: a.install() push_record("app", a.serialized) except: errors = True if to_install: if errors: msg = ("One or more applications failed to install. " "Check the App Store pane for more information.") nthread.complete(Notification("warning", "FirstRun", msg)) else: msg = ("You may need to restart your device before " "changes will take effect.") nthread.complete(Notification("success", "FirstRun", msg))
def get_app_logo(id): app = applications.get(id) if not app: abort(404) return send_from_directory(os.path.join('/var/lib/arkos/applications', id, 'assets'), "logo.png")
def setup(addr, port): # Make sure Radicale is installed and ready if not python.is_installed('Radicale'): python.install('radicale') # due to packaging bugs, make extra sure perms are readable pver = "{0}.{1}".format(sys.version_info.major, sys.version_info.minor) raddir = '/usr/lib/python{0}/site-packages/radicale'.format(pver) st = os.stat(raddir) for r, d, f in os.walk(raddir): for x in d: os.chmod(os.path.join(r, x), st.st_mode | stat.S_IROTH | stat.S_IRGRP) for x in f: os.chmod(os.path.join(r, x), st.st_mode | stat.S_IROTH | stat.S_IRGRP) if not os.path.exists('/etc/radicale/config'): if not os.path.isdir('/etc/radicale'): os.mkdir('/etc/radicale') with open('/etc/radicale/config', 'w') as f: f.write(default_config) if not os.path.isdir('/usr/lib/radicale'): os.mkdir('/usr/lib/radicale') # Add the site process u = users.SystemUser("radicale") u.add() g = groups.SystemGroup("radicale", users=["radicale"]) g.add() wsgi_file = 'import radicale\n' wsgi_file += 'radicale.log.start()\n' wsgi_file += 'application = radicale.Application()\n' with open('/etc/radicale/radicale.wsgi', 'w') as f: f.write(wsgi_file) os.chmod('/etc/radicale/radicale.wsgi', 0o766) cfg = { 'directory': '/etc/radicale', 'user': '******', 'command': 'uwsgi -s /tmp/radicale.sock -C ' '--plugin python --wsgi-file radicale.wsgi', 'stdout_logfile': '/var/log/radicale.log', 'stderr_logfile': '/var/log/radicale.log' } s = services.Service("radicale", "supervisor", cfg=cfg) s.add() block = [ nginx.Location( '/', nginx.Key('include', 'uwsgi_params'), nginx.Key('uwsgi_pass', 'unix:///tmp/radicale.sock'), ) ] s = websites.get("radicale") if s: s.remove() a = applications.get('radicale') s = websites.ReverseProxy(app=a, id="radicale", domain=addr, port=int(port), base_path="/usr/lib/radicale", block=block) s.install()
def install(id): """Install an application.""" try: applications.get(id).install(force=True) except Exception as e: raise CLIException(str(e))
def uninstall(id): """Uninstall an application.""" try: applications.get(id).uninstall() except Exception as e: raise CLIException(str(e))
def scan(): """Search website directories for sites, load them and store metadata.""" from arkos import certificates logger.debug("Webs", "Scanning for websites") for x in os.listdir("/etc/nginx/sites-available"): path = os.path.join("/srv/http/webapps", x) if not os.path.exists(path): continue # Read metadata meta = configparser.SafeConfigParser() if not meta.read(os.path.join(path, ".arkos")): continue # Create the proper type of website object app = None app_type = meta.get("website", "app") app = applications.get(app_type) if app and app.type == "website": # If it's a regular website, initialize its class, metadata, etc if not app or not app.loadable or not app.installed: logger.debug( "Webs", "Website found but could not be loaded: {0}".format( meta.get("website", "id"))) continue site = app._website(id=meta.get("website", "id")) site.app = app site.data_path = (meta.get("website", "data_path") or "") \ if meta.has_option("website", "data_path") else "" site.db = databases.get(site.id) \ if meta.has_option("website", "dbengine") else None elif app: # If it's a reverse proxy, follow a simplified procedure site = ReverseProxy(id=meta.get("website", "id")) site.app = app else: # Unknown website type. logger.debug( "Webs", "Unknown website found and ignoring, id {0}".format( meta.get("website", "id"))) continue certname = meta.get("website", "ssl", fallback="None") site.cert = certificates.get(certname) if certname != "None" else None if site.cert: site.cert.assigns.append({ "type": "website", "id": site.id, "name": site.id if site.app else site.name }) site.version = meta.get("website", "version", fallback=None) site.enabled = os.path.exists( os.path.join("/etc/nginx/sites-enabled", x)) site.installed = True # Load the proper nginx serverblock and get more data try: block = nginx.loadf(os.path.join("/etc/nginx/sites-available", x)) for y in block.servers: if "ssl" in y.filter("Key", "listen")[0].value: site.ssl = True server = y break else: server = block.server port_regex = re.compile("(\\d+)\s*(.*)") listen = server.filter("Key", "listen")[0].value.lstrip("[::]:") site.port = int(re.match(port_regex, listen).group(1)) site.domain = server.filter("Key", "server_name")[0].value site.path = server.filter("Key", "root")[0].value site.php = "php" in server.filter("Key", "index")[0].value except IndexError: pass storage.websites[site.id] = site signals.emit("websites", "site_loaded", site) return storage.websites
def app(): """Application commands.""" conns.connect() applications.get(cry=False) certificates.get()
def scan(): from arkos import certificates sites = [] for x in os.listdir("/etc/nginx/sites-available"): path = os.path.join("/srv/http/webapps", x) if not os.path.exists(path): continue # Read metadata meta = ConfigParser.SafeConfigParser() if not meta.read(os.path.join(path, ".arkos")): continue # Create the proper type of website object site_type = meta.get("website", "type") if site_type != "ReverseProxy": # If it's a regular website, initialize its class, metadata, etc app = applications.get(site_type) if not app.loadable or not app.installed: continue site = app._website(id=meta.get("website", "id")) site.meta = app site.data_path = meta.get("website", "data_path", "") \ if meta.has_option("website", "data_path") else "" site.db = databases.get(site.id) \ if meta.has_option("website", "dbengine") else None else: # If it's a reverse proxy, follow a simplified procedure site = ReverseProxy(id=meta.get("website", "id")) site.name = meta.get("website", "name") site.type = meta.get("website", "extra") site.meta = None certname = meta.get("website", "ssl", "None") site.cert = certificates.get(certname) if certname != "None" else None if site.cert: site.cert.assigns.append({ "type": "website", "id": site.id, "name": site.id if site.meta else site.name }) site.version = meta.get("website", "version", None) site.enabled = os.path.exists(os.path.join("/etc/nginx/sites-enabled", x)) site.installed = True # Load the proper nginx serverblock and get more data try: ssl = None block = nginx.loadf(os.path.join("/etc/nginx/sites-available", x)) for y in block.servers: if "ssl" in y.filter("Key", "listen")[0].value: site.ssl = True server = y break else: server = block.servers[0] port_regex = re.compile("(\\d+)\s*(.*)") site.port = int(re.match(port_regex, server.filter("Key", "listen")[0].value).group(1)) site.addr = server.filter("Key", "server_name")[0].value site.path = server.filter("Key", "root")[0].value site.php = "php" in server.filter("Key", "index")[0].value except IndexError: pass sites.append(site) signals.emit("websites", "site_loaded", site) storage.sites.set("sites", sites) return sites
def get_app_asset(id, asset): app = applications.get(id) if not app: abort(404) return send_from_directory( os.path.join('/var/lib/arkos/applications', id, 'assets'), asset)