GithubHelp home page GithubHelp logo

edgebox-iot / edgeboxctl Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 192 KB

Edgebox host system and dependencies configuration and control module

License: Other

Dockerfile 0.23% Go 96.92% Makefile 2.13% Shell 0.72%
async go iot system systemctl

edgeboxctl's People

Contributors

dependabot[bot] avatar inverse avatar paulotruta avatar

Stargazers

 avatar

Watchers

 avatar

edgeboxctl's Issues

Running the Go binary as a systemd service

The Go language with its simplicity, concurrency support, rich package ecosystem, and ability to compile down to a single binary is an attractive solution for writing services.

However, the Go language does not natively provide a reliable way to daemonize itself. In this issue, we will try to describe how to take our baseline sysctl executable, and run it using a systemd service file that starts at boot time and keeps checking a source for commands to run.

Service Considerations

Let’s consider the issues we must address when going from running a foreground task versus a daemon.

First, the application needs to run in the background. Because of complex interactions with the Go thread pool and forks/dropping permissions, running a simple nohup or double fork of the program is not an option – but it should not be anyway given the rich set of alternatives available today.

There are many process control systems such as Supervisor and monit, but with Debian (as in EdgeboxOS), we can use the systemd which is the default init system.

Background processes are detached from the terminal, but can still receive signals, so we would like a way to catch those so we can gracefully exit if required.

A second phase (to be done in https://github.com/edgebox-iot/ua-netinst-config), is to add the files and configurations that will allow this binary to be properly running as a service.

  • Address main loop for running as service
  • Capture signals for graceful exit or direct command execution

[TESTS] Implement Mocking where needed

Using mocking to be able to test some of the functions in modules that depend on dynamic functionality (measuring available disks and disk sizes, getting a list of running apps, etc).

This is an iteration on our efforts to provide complete app testing.

There are two types of mocking we will be interested in doing:

  • function return mocking, which mocks the return value of a function, be it internally or in external dependencies / apis. This can be achieve through clever implementation of Interfaces in Golang. More information about Interfaces here, and a tutorial on mocking using Interfaces here.
  • DB call mocking, that we can leverage to simulate the existence of various states within the application. [MORE INFORMATION AND REFERENCES NEEDED HERE]

Some task guidelines for a PR:

  • Implement interfaces for mocking data that is called within storage.getDevicesSpaceUsage and storage.getDevices.
  • Reliably test all branches of those functions
  • Gather information about what in the codebase can benefit from this approach
  • Research DB call mocking to test edgeapps.go

[FEATURE] Implementing task: Restart edgeboxctl

Supporting a task to mark a restart of edgeboxctl.

Expected behaviour:

  • A new task ´taskRestartEdgeboxctl´ is supported in the codebase.
  • Behaves like any other task such as taskStartEdgeapp, so it can be called from the dashboard interface or endpoints of edgebox-iot/api
  • Since terminating the program will not allow it to save state on the database, On edgeboxctl's 1st valid work tick, which is supposedly after a restart, the system should fetch the latest restart task with status executing (1) issued in the last minute, and mark it as finished (2).
  • If no restart task is found on the DB within that time span, it means that the program might have crashed and restarted by itself, or has been manually restarted. In this case, a Task entry should be created on the database with restart_edgeboxctl, but the status should be set to error (3).

EDIT: We can potentially also implement taskRestartEdgebox, which can issue a full system restart. The 1st work tick can then also search for a Task entry restart_edgebox (maybe use a more extended grace period for the find query), and finish updating its status.

Investigation on Network-external access to the system

ADR

This is base on the template in Documenting architecture decisions - Michael Nygard.

Network-external access to the system

Status

Proposed - This needs to be currently considered for easiness of implementation of app wireframes and API structure, but should only be tackled in sysctl implementation phase. This issue opens the discussion. An eventual decision should be documented in the assets repository inside of the docs/arquitecture_decision_records folder.

Context

Edgebox needs to provide functionality for remote access. This would allow the mobile app to connect to the box when outside of the network where it is attached to.
Other EdgeApps, especially the ones that provide web/api endpoints and services can benefit from this. Conversely, there should be a way to activate and deactivate external access to independent features and services.

Some minimum requirements for easy usability:

  1. I should be able to access my services from any computer in the world.
  2. I should be able to punch in an easy-to-remember web address like access.edgebox.io/myserver. This means all standard HTTP/HTTPS ports should be used!
  3. All transmission of my content should be encrypted.
  4. Moving houses or ISP's should not break the remote access capabilities.

Problems with home internet connections

When talking about possibly complicated network connections that need to act in a reliable way, we should strive for as few dependencies on external factors as possible. This is our objective here in order for people to be able to consider Edgebox a reliable possible replacement for SaaS services.

Home networks don't help in our quest. Some problems these type of connections have are:

May not have a static IP

Very rarely does a home connection come with a static IP. Getting a static IP typically results in extra charges, and would require updating the DNS record if anything changes. The solution is to use a dynamic DNS service that solves both these issues and is a consideration, but we still end up with some problems to solve.

May not have control of the router

Port forwarding needs to be set up on your router so incoming connections are forwarded to the home server. However, you may not have full control over the router to set up these rules. Many routers will also take the default HTTP/HTTPS ports for their own services, leaving you with non-standard port numbers for everything else.

May not be able to get incoming connections

Finally, once we’ve sorted out everything above, you may not be able to get incoming traffic to reach your house! As a result of the IPv4 address shortage and ISP firewalls, incoming connections don’t always work. Never fear, we can still tunnel traffic through the internet with the help of another computer with a more accessible connection.
So for this, we need to consider an option to allow a direct tunnel between a network-external machine and the box.

Decision

What is the change that we're proposing and/or doing?

Implement a system for remote access that gives as little friction as possible for the user. Considering two options, one for direct access through DDNS techniques, and/or a tinc based option.

Using Tinc to access Edgebox through a tunneled connection

Tunnelling out

tunneling_out

The concept of using a tunnel is pretty simple. We may not be able to get incoming connections to the Edgebox, but the box itself can setup an outgoing tunnel connection with some other machine on the internet. This other machine can be accessed from anywhere and forward connections through the tunnel to get to the home server.

The other machine

To meet these requirements, another machine needs to be involved. There are services dedicated to providing remote access to networks. These work well but require some sort of client software configuration to join this virtual network, which fundamentally might not work in every computer, not meeting one of the requirements above.

Other than that, there are virtual private network (VPN) services that provide port forwarding. However, it’s unlikely you’d be able to use the HTTP and HTTPS ports.

As part of our cloud helper services for Edgebox, this should possibly be built by ourselves, providing frictionless configuration and usability. But still adhering to our openness filosofy, we should provide clear documentation and path for users to be able to implement this themselves without resorting to a cloud service provided by the company operating the development of Edgebox.

The cloud service provided by Edgebox for frictionless setup should basically run multiple versions of the setup described below (one for each Edgebox using the service). This might call for Docker-based management of multiple NGINX + tinc instances running in a scalable solution. It should be possible, but for feasibility effects, we will describe the process with 1 instance.

Reverse SSH Tunnel

A common way to get remote access through a firewall is with a Reverse SSH Tunnel. This is easy to set up and works well, but I discovered that HTTP based services through the tunnel run extremely slow. The most likely reason for this is that both SSH and HTTP use the TCP protocol to transmit data over a network. TCP ensures a reliable connection with built-in error checking and transmission control but this comes at a cost of speed. Running HTTP through the SSH tunnel is performing these error checks twice, resulting in much slower speeds.

The answer is to switch to something UDP based. UDP is much faster because it’s just packets sent straight over the network without error checking or flow control. A UDP based tunneling solution means that only the HTTP layer is performing these extra tasks.

tinc VPN

The tinc VPN software might the answer that meets these requirements. It can be used to create virtual networks between computers. It utilizes UDP so runs quickly, all traffic is encrypted and has a status re-check routine so can work moderately well even on unreliable connections.

tinc is not available originally for arm architecture (which we need for our project on Edgeboxe's side), but there is a docker image (rpi-tinc) that supports Raspberry Pi

Pretty URL’s & Proxying connections

With tinc working, all the services on Edgebox can be accessed through a local IP on the cloud server, like 10.0.0.2:32400 for Plex. Time to turn that into something nice like acess.edgebox.io/myserver/plex!

The subdomains point to the cloud server’s IP address. The cloud server has the NGINX server running with the official NGINX Docker image. NGINX is set up as a proxy server to the home server’s IP address using the NGINX documentation, meaning external traffic is forwarded through the tinc link to Edgebox.

HTTPS should be used to ensure all data transport is encrypted. This requires valid SSL certificates which can be obtained for free with Let’s Encrypt through their automated verification process. To set up Let’s Encrypt to automatically renew certificates, a solution like docker-letsencrypt-manager and shared the volumes with the NGINX containers will work as it was previously tested. A very useful tool when working with HTTPS is SSL Labs’ SSL Test.

Example usage trial with Plex

Finally, setting up something like Plex through the tinc tunnel and as a preliminary test, this Gist was used to help with the NGINX configuration, and set up a custom URL in Plex settings, like https://access.edgebox.io/myserver/plex:443 (the port number must be explicitly defined for it to work). This works well, but sometimes some difficulties arose when Chromecasting from Android while on an external network. Some more tests should then be done but overall this setup seems to work.

[TBD]Using some DDNS service to directly access Edgebox through WAN IP

Following something on the lines of https://github.com/dprandzioch/docker-ddns might be able to provide the same kind of access to the box (but also possibly to other devices in the network), avoiding a whole tunneling setup, but unfortunately still with the need to manage IP records. ** This may also require configuration on the user's router, which is not desirable. **

[TBD] Consequences

What becomes easier or more difficult to do because of this change?
Multiple considerations to be taken, especially in the case of tinc.

Research Links

[FEATURE] Storage Module Basis

The storage module is all about visualizing and managing your box storage, both internal to the Edgebox, as well as external storage media such as Pen-Drives, External HDD's, and possibly even network locations.

The storage page should show a summary of the storage available in the box, its overall usage state, and options (tasks) that can be triggered, such as adding a new storage media, swapping edgeapp data between drives, etc.

Additional context

The following actions are to be implemented:

  • Geting and showing storage information (internal and external drives with an id and metadata such as total space used, total space available, statistics about disk occupation, etc...
  • Getting and showing storage buckets information (id, name, creation date, update date, storage drive location) and list them. Also runs in a tick schedule.
  • (...) More information will be complete as necessary (...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.