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")
Beispiel #2
0
    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
Beispiel #3
0
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))
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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))
Beispiel #7
0
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:])
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
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))
Beispiel #11
0
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)
Beispiel #13
0
 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
Beispiel #14
0
 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())
Beispiel #15
0
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
Beispiel #16
0
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
Beispiel #17
0
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)
Beispiel #18
0
 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
Beispiel #19
0
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
Beispiel #20
0
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
Beispiel #21
0
 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
Beispiel #22
0
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)
Beispiel #23
0
 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])
Beispiel #24
0
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))
Beispiel #25
0
 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})
Beispiel #26
0
 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})
Beispiel #27
0
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
Beispiel #28
0
 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)
Beispiel #30
0
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")
Beispiel #31
0
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))
Beispiel #32
0
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")
Beispiel #33
0
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()
Beispiel #34
0
def install(id):
    """Install an application."""
    try:
        applications.get(id).install(force=True)
    except Exception as e:
        raise CLIException(str(e))
Beispiel #35
0
def uninstall(id):
    """Uninstall an application."""
    try:
        applications.get(id).uninstall()
    except Exception as e:
        raise CLIException(str(e))
Beispiel #36
0
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
Beispiel #37
0
def app():
    """Application commands."""
    conns.connect()
    applications.get(cry=False)
    certificates.get()
Beispiel #38
0
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
Beispiel #39
0
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)