Ejemplo n.º 1
0
def https_enable():

    board.set("tls", {
        "what": "enable",
        "state": "pending",
    })
    job_queue.put("EnableHTTPS")

    return success("HTTPS enabling pending")
Ejemplo n.º 2
0
def signal_handler(sig, frame):
    global job_queue, worker

    log.info("signal-handler, sending 'exit' as job for graceful termination")

    job_queue.put("exit")
    worker.join()
    
    log.info("joined background-worker - exiting now...")
    log.info("^" * 60)
    
    sys.exit(1)
Ejemplo n.º 3
0
    def set_led_state(self, state):
        """
        Top-level access to LED by state
        
        * 'ready'           => green
        * 'started'         => yellow
        * 'updating'        => yellow-blinking
        * 'stopped'         => red
        * 'factory-reset'   => red-blinking
        * 'button'          => blue
        * 'maintenance'     => purple
        * 'docker-wait'     => green-fast-blink
        """

        if state == "ready":
            self.set_led(0, 1, 0)
            shield.button.when_pressed = lambda: self.set_led_state("button")
            shield.button.when_released = lambda: self.set_led_state("ready")
            shield.button.when_held = lambda: (job_queue.put(
                "FactoryReset"), self.set_led_state("factory-reset"))

        elif state == "started":
            self.set_led(1, 1, 0)

        elif state == "updating":
            self.set_led_blink(1, 1, 0)

        elif state == "stopped":
            self.set_led(1, 0, 0)

        elif state == "factory-reset":
            self.set_led_blink(1, 0, 0)
            shield.button.when_pressed = None
            shield.button.when_released = None
            shield.button.when_held = None

        elif state == "button":
            self.set_led(0, 0, 1)

        elif state == "maintenance":
            self.set_led(0.5, 0, 1)
            shield.button.when_pressed = lambda: self.set_fast_blink(0.5, 0, 1)
            shield.button.when_released = lambda: (Nextcloud().soft_reset(),
                                                   job_queue.put("LED"))
            shield.button.when_held = lambda: (job_queue.put(
                "FactoryReset"), self.set_led_state("factory-reset"))

        elif state == "docker-wait":
            self.set_fast_blink(0, 1, 0)

        else:
            self.set_led(0, 1, 0)
Ejemplo n.º 4
0
def restore_start():
    src_path = request.form.get("src_path")

    if not backup_restore.check_backup(src_path):
        msg = "Invalid backup, cannot restore"
        log.error(msg)
        return error(msg)

    log.info(f"Initiating restore from: {src_path}")

    job_kwargs = {"tar_path": src_path, "mode": "restore"}
    job_queue.put(("BackupRestore", job_kwargs))

    return success("restore started")
Ejemplo n.º 5
0
def register_proxy():

    # assemble data
    for key in request.form:
        if key == "nk_token":
            token = request.form.get(key)
        elif key == "proxy_domain":
            proxy_domain = request.form.get(key)
            subdomain = proxy_domain.split(".")[0]

    scheme = "https" if cfg["config"]["https_port"] else "http"

    proxy_tunnel = ProxyTunnel()
    try:
        proxy_port = proxy_tunnel.setup(token, subdomain, scheme)
    except ProxySetupError as e:
        cfg["config"]["proxy_active"] = False
        cfg.save()
        log.error(str(e))
        return error(str(e))
    except Exception as e:
        cfg["config"]["proxy_active"] = False
        cfg.save()
        msg = "unexpected error during proxy setup"
        log.error(msg, exc_info=e)
        return error(msg)

    # configure nextcloud
    nc = Nextcloud()
    try:
        nc.set_config("overwriteprotocol", "https")
        nc.set_config("overwritecondaddr", "^172\\.18\\.238\\.1$")
        nc.set_config("trusted_proxies", ["172.18.238.1"])
    except NextcloudError as e:
        cfg["config"]["proxy_active"] = False
        cfg.save()
        msg = "could not configure nextcloud for proxy usage"
        log.error(msg, exc_info=e)
        return error(msg)

    cfg["config"]["proxy_domain"] = proxy_domain
    cfg["config"]["proxy_active"] = True
    cfg["config"]["proxy_port"] = proxy_port
    cfg.save()

    # ensure trusted domains are set
    job_queue.put("TrustedDomains")

    return success("Proxy successfully registered")
Ejemplo n.º 6
0
def backup_start():
    tar_path = request.form.get("tar_path")
    found = False
    for dev in partitions.backup_devices:
        if tar_path.startswith(dev["path"]):
            found = dev
            break

    if not found:
        msg = "Invalid backup location provided"
        log.error(msg)
        return error(msg)

    log.info(
        f"Initiating backup onto: {dev['friendly_name']} @ {dev['path']} with target: {tar_path}"
    )

    job_kwargs = {"tar_path": tar_path, "mode": "backup"}
    job_queue.put(("BackupRestore", job_kwargs))

    return success("backup started")
Ejemplo n.º 7
0
def handle_config():
    if request.method == "GET":
        data = dict(cfg["config"])
        try:
            data["conf"] = Path(DDCLIENT_CONFIG_PATH).read_text("utf-8")
        except FileNotFoundError:
            data["conf"] = ""
        return success(data=data)

    # save dyndns related values to configuration
    elif request.method == "POST":
        run_jobs = []
        for key in request.form:
            val = request.form.get(key)

            # special config-value 'conf' represents ddclient-config-contents
            if key == "conf":
                old_conf = Path(DDCLIENT_CONFIG_PATH).read_text("utf-8")
                if old_conf != val:
                    log.info("writing ddclient config and restarting service")
                    Path(DDCLIENT_CONFIG_PATH).write_text(val, "utf-8")

                elif len(val.strip()) == 0:
                    log.info("writing empty ddclient config")
                    Path(DDCLIENT_CONFIG_PATH).write_text(val, "utf-8")
                    services.stop("ddclient")
                    services.disable("ddclient")

                if len(val.strip()) > 0:
                    services.enable("ddclient")
                    services.restart("ddclient")

                run_jobs.append("DynDNSUpdate")

            elif key in AVAIL_CONFIGS and val is not None:
                # only allow valid DYNDNS_MODES
                if key == "dns_mode" and val not in DYNDNS_MODES:
                    log.warning(
                        f"key: 'dns_mode' has invalid value: {val} - skipping")
                    continue

                # start DynDNS update on "desec_done"
                elif key == "dns_mode" and val == "desec_done":
                    run_jobs.append("DynDNSUpdate")

                # start TrustedDomains update on new domain
                elif "domain" in key:
                    run_jobs.append("TrustedDomains")

                # deactivate proxy on request
                elif key == "proxy_active" and val.lower() == "false":
                    proxy_tunnel = ProxyTunnel()
                    proxy_tunnel.stop()

                # skip if 'val' is empty
                elif val is None:
                    log.debug(f"skipping key: '{key}' -> no value provided")
                    continue

                # convert to bool, ugly?
                if val.lower() in ["true", "false"]:
                    val = val.lower() == "true"

                # put key-value into cfg and save (yes, saving each value)
                cfg["config"][key] = val
                log.debug(f"saving key: '{key}' with value: '{val}'")
                cfg.save()

        # run jobs collected during configuration update
        if len(run_jobs) > 0:
            for job in run_jobs:
                job_queue.put(job)

        return success("DynDNS configuration saved")