Compare commits

..

No commits in common. "48611df2cb775ad3255e6c23be640796619e3fe7" and "64fdba0a485eda5e941d8e93e32f5f84f96c3294" have entirely different histories.

23 changed files with 217 additions and 254 deletions

116
README.md
View File

@ -6,41 +6,103 @@ rely on it for anything._**
# Isle
Welcome to Isle's technical documentation. You can find a less technical
entrypoint to Isle on [the Micropelago website][isle].
The Isle project provides the foundation for an **autonomous community
cloud infrastructure**.
Isle runs on a host as a server daemon, and connects to other isle instances to
form a peer-to-peer network. Isle networks are completely self-hosted; no
third-parties are required for a network to function.
This project targets communities of individuals, where certain members of the
community would like to host services and applications from servers running in
their homes or offices. These servers can range from simple Raspberry Pis to
full-sized home PCs.
Members of a network are able to build upon the capabilities provided by Isle to
host services for themselves and others. These capabilities include:
The core components of Isle, currently, are:
* A VPN which enables direct peer-to-peer communication between network members.
Even if most hosts in the network are on a private LAN (e.g. their home WiFi
network) or have a dynamic IP, they can still communicate directly with each
other.
* A VPN which enables direct peer-to-peer communication. Even if most hosts in
the network are on a private LAN (e.g. their home WiFi network) or have a
dynamic IP, they can still communicate directly with each other.
* An S3-compatible network filesystem. Each member can provide as much storage
as they care to, if any. Stored data is sharded and replicated across all
hosts that choose to provide storage.
* An S3-compatible network filesystem. Each users can provide as much storage as
they care to, if any. Stored data is sharded and replicated across all hosts
that choose to provide storage.
* A DNS server which provides automatic host discovery within the network.
* A DNS server which provides automatic host and service (coming soon) discovery
within the network.
Every isle daemon is able to create or join multiple independent networks. In
this case the networks remain siloed from each other, such that members of one
network are unable to access resources or communicate with members of the other.
These components are wrapped into a single binary, with all setup being
automated. Isle takes "just works" very seriously.
[isle]: http://portal.mozz.us/gemini/micropelago.net/isle/
Participants are able to build upon these foundations to host services for
themselves and others. They can be assured that their communications are private
and their storage is reliable, all with zero administrative overhead and zero
third parties involved.
## Getting Started
## Documentation
The following pages will guide you through setup of Isle, joining an existing
network, and all other functionality available via the command-line.
Isle users fall into different roles, depending on their level of
involvement and expertise within their particular network. The documentation
is broken down by these categories, so that the reader can easily
decide which documents they need to care about.
* [Installation](./docs/install.md)
* [Command-line Usage](./docs/command-line.md)
* [Join a Network](./docs/user/join-a-network.md)
### User Docs
Those who want to dive in and contribute to the Isle codebase should check out
the [Developer Documentation](./docs/dev/index.md).
Users are participants who use network resources, but do not provide any network
resources themselves. Users may be accessing the network from a mobile device,
and so are not expected to be online at any particular moment.
Documentation for users:
* [Getting Started](docs/user/getting-started.md)
* [Using DNS](docs/user/using-dns.md) (advanced)
* Restic example (TODO)
### Operator Docs
Operators are users who own a dedicated host which they can expect to be
always-online (to the extent that's possible in a residential environment).
Operator hosts will need at least one of the following to be useful:
* A static public IP, or a dynamic public IP with [dDNS][ddns] set up.
* At least 1GB of unused storage which can be reserved for the network.
Operators are expected to be familiar with server administration, and to not be
afraid of a terminal.
Documentation for operators:
* [Contributing Storage](docs/operator/contributing-storage.md)
* [Contributing a Lighthouse](docs/operator/contributing-a-lighthouse.md)
* [Managing garage](docs/operator/managing-garage.md)
* [Firewalls](doc/operator/firewall.md)
[ddns]: https://www.cloudflare.com/learning/dns/glossary/dynamic-dns/
### Admin Docs
Admins are users who control membership within the network. They are likely
operators as well.
Documentation for admins:
* [Creating a New Network](docs/admin/creating-a-new-network.md)
* [Adding a Host to the Network](docs/admin/adding-a-host-to-the-network.md)
* Removing a Host From the Network (TODO)
### Dev Docs
Devs may or may not be users in any particular isle network. They instead are
those who work on the actual code for Isle.
Documentation for devs:
* [Design Principles](docs/dev/design-principles.md)
* [`isle daemon` process tree](docs/dev/daemon-process-tree.svg): Diagram
describing the [pmux](https://code.betamike.com/micropelago/pmux) process tree
created by `isle daemon` at runtime.
* [Rebuilding Documentation](docs/dev/rebuilding-documentation.md)
* [Releases](docs/dev/releases.md)
## Misc
Besides documentation, there are a few other pages which might be useful:
* [Glossary](docs/glossary.md)

View File

@ -7,7 +7,7 @@
revision ? "dev",
releaseName ? "dev",
bootstrap ? null, # TODO remove this
bootstrap ? null,
}: let
@ -69,7 +69,7 @@ in rec {
'';
};
vendorHash = "sha256-R+8uCjWnWCDG7WLuSnjKnVfZwYSbjKqMPqJfMnnj6G0=";
vendorHash = "sha256-N80aMMR67DjyEtz9/Yat1bft92nj7JuuF4i2xC9iJ6s=";
subPackages = [
"./cmd/entrypoint"

View File

@ -51,13 +51,13 @@ in
inherit pkgbuild;
src = appImage;
defaultDaemonYml = ../../../go/daemon/daecommon/daemon.yml;
appDir = ../../../AppDir;
systemdService = ../isle.service;
dontUnpack = true;
buildPhase = ''
mkdir -p root/etc/isle/
cp "$defaultDaemonYml" root/etc/isle/daemon.yml
cp "$appDir"/etc/daemon.yml root/etc/isle/daemon.yml
mkdir -p root/usr/lib/sysusers.d/
cat >root/usr/lib/sysusers.d/isle.conf <<EOF

View File

@ -1,6 +1,7 @@
# Creating a New Network
This guide is for those who wish to start a new isle network of their own.
This guide is for those who wish to start a new isle network of their
own.
By starting a new isle network, you are becoming the administrator of a
network. Be aware that being a network administrator is not necessarily easy,

View File

@ -1,54 +0,0 @@
# Command-line Usage
This documents provides examples of how to accomplish various tasks from Isle's
command-line interface.
Isle network members fall into different roles, depending on their level of
involvement and expertise within their particular network. The documentation is
broken down by these categories, so that the reader can easily decide which
documents they need to care about.
### User Docs
Users are members who use network resources, but do not provide any network
resources themselves. Users may be accessing the network from a mobile device,
and so are not expected to be online at any particular moment.
Documentation for users:
* [Joining a Network](./user/join-a-network.md)
* [Using DNS](./user/using-dns.md) (advanced)
* Restic example (TODO)
### Operator Docs
Operators are members who own a dedicated host which they can expect to be
always-online (to the extent that's possible in a residential environment).
Operator hosts will need at least one of the following to be useful:
* A static public IP, or a dynamic public IP with [dDNS][ddns] set up.
* At least 1GB of unused storage which can be reserved for the network.
Operators are expected to be familiar with server administration, and to not be
afraid of a terminal.
Documentation for operators:
* [Contributing Storage](./operator/contributing-storage.md)
* [Contributing a Lighthouse](./operator/contributing-a-lighthouse.md)
* [Managing garage](./operator/managing-garage.md)
* [Firewalls](./operator/firewall.md)
[ddns]: https://www.cloudflare.com/learning/dns/glossary/dynamic-dns/
### Admin Docs
Admins are members who control membership within the network. They are likely
operators as well.
Documentation for admins:
* [Creating a New Network](./admin/creating-a-new-network.md)
* [Adding a Host to the Network](./admin/adding-a-host-to-the-network.md)
* Removing a Host From the Network (TODO)

View File

@ -1,25 +0,0 @@
# Architecture
The isle daemon is the central point around which all operations occur. Users of
the isle command-line tool (or, soon, a GUI) communicate with the daemon over a
local RPC socket to issue commands, for example to tell it to join a new network
or to retrieve the names of hosts in an already-joined network.
For every network which is joined, the isle daemon will create and manage
sub-processes to provide certain parts of its functionality. These include:
* A [nebula][nebula] instance to provide VPN functionality.
* A [dnsmasq][dnsmasq] instance to act as DNS server.
* Zero or more [garage][garage] instances, depending on how storage is
configured on the host, to provide the S3 storage layer.
The isle daemon considers the configuration and management of these
sub-processes to be an implementation detail. In other words, its RPC interface,
and therefore all user interfaces, do not expose members to the fact that these
sub-processes exist, or even that these projects are being used under the hood.
![Architectural diagram](./architecture.svg)
[nebula]: https://github.com/slackhq/nebula
[garage]: https://garagehq.deuxfleurs.fr/
[dnsmasq]: https://dnsmasq.org/doc.html

View File

@ -1,49 +0,0 @@
@startuml
skinparam componentStyle rectangle
[isle command line] as isleCommand
() "daemon.RPC" as isleDaemonRPC
[daemon.Client] as daemonClient
frame "isle daemon process" {
portin "RPC Socket" as rpcSocket
[RPC Server] as rpcServer
() "daemon.RPC" as daemonRPC
[daemon.Daemon] as daemon
[network.Network (A)] as networkA
[network.Network (B)] as networkB
rpcServer --> rpcSocket : handle
rpcServer ..> daemonRPC : dispatch
daemon - daemonRPC
daemon --> networkA
daemon --> networkB
}
isleCommand ..> isleDaemonRPC : issue commands
daemonClient - isleDaemonRPC
daemonClient --> rpcSocket
package "network A child processes" {
[nebula] as networkANebula
[garage (alloc 1)] as networkAGarage1
[garage (alloc 2)] as networkAGarage2
[dnsmasq] as networkADNSMasq
}
networkA --> networkANebula
networkA --> networkAGarage1
networkA --> networkAGarage2
networkA --> networkADNSMasq
package "network B child processes" {
[nebula] as networkBNebula
[dnsmasq] as networkBDNSMasq
}
networkB --> networkBNebula
networkB --> networkBDNSMasq
@enduml

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,34 +0,0 @@
# Building Isle
Building from source requires [nix][nix].
(*NOTE* The first time you run some of these builds a lot of things will be
built from scratch. If you have not otherwise configured it, nix might be using
a tmpfs as its build directory, and the capacity of this tmpfs will probably be
exceeded by this build. You can change your build directory to somewhere on-disk
by setting the TMPDIR environment variable for `nix-daemon` (see [this github
issue][tmpdir-gh].))
[nix]: https://nixos.wiki/wiki/Nix_package_manager
[tmpdir-gh]: https://github.com/NixOS/nix/issues/2098#issuecomment-383243838
## Current System
You can build an AppImage for your current system by running the following from
the project's root:
```
nix-build -A appImageBin
```
The resulting binary can be found under `result/bin`.
## Cross-Compile
An AppImage can be cross-compiled by passing the `hostSystem` argument:
```
nix-build --argstr hostSystem "x86_64-linux" -A appImageBin
```
Supported system strings are enumerated in `nix/pkgs.nix`.

View File

@ -0,0 +1,37 @@
@startuml
hide empty description
state "./isle daemon -c ./daemon.yml" as init
state AppDir {
note "All relative paths are relative to the root of the AppDir" as N1
state "./bin/entrypoint daemon -c ./daemon.yml" as entrypoint {
entrypoint : * Create runtime dir
entrypoint : * Lock runtime dir
entrypoint : * Merge given and default daemon.yml files
entrypoint : * Copy bootstrap.json into state directory, if it's not there
entrypoint : * Merge daemon.yml config into bootstrap.json
entrypoint : * Create $RUNTIME_DIRECTORY/dnsmasq.conf
entrypoint : * Create $RUNTIME_DIRECTORY/nebula.yml
entrypoint : * Create $RUNTIME_DIRECTORY/garage-N.toml\n (one per storage allocation)
entrypoint : * Spawn child processes
entrypoint : * Wait for nebula & garage to initialize
entrypoint : * Updates garage cluster layout
entrypoint : * Stores host info in global bucket, based on latest bootstrap.json
}
init --> entrypoint : exec
state "./bin/dnsmasq -d -C $RUNTIME_DIRECTORY/dnsmasq.conf" as dnsmasq
entrypoint --> dnsmasq : child
state "./bin/nebula -config $RUNTIME_DIRECTORY/nebula.yml" as nebula
entrypoint --> nebula : child
state "./bin/garage -c $RUNTIME_DIRECTORY/garage-N.toml server" as garage
entrypoint --> garage : child (one per storage allocation)
}
@enduml

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -3,7 +3,7 @@
The following points form the basis for all design decisions made within the
Isle project.
* The UX is aggressively optimized to eliminate manual intervention by members.
* The UX is aggressively optimized to eliminate manual intervention by users.
All other concerns are secondary. The concept of "UX" extends beyond GUI
interfaces, and encompasses all interactions of any sort with an isle
process.

View File

@ -1,15 +0,0 @@
# Developer Documentation
This section of the documentation is targeted at those who are contributing to
the Isle codebase. It is recommended to start with the following pages, in order
to better understand how to navigate and work on the codebase.
* [Glossary](./glossary.md)
* [Design Principles](./design-principles.md)
* [Architecture](./architecture.md)
These pages can be helpful in specific situations.
* [Building Isle](./building.md)
* [Rebuilding Documentation](./rebuilding-documentation.md)
* [Releases](./releases.md)

View File

@ -2,8 +2,8 @@
A release consists of:
- A full set of `isle` binaries for all supported platforms, compiled from the
same source.
- A full set of binaries for all supported platforms, compiled from the same
source.
- A text file containing hashes of each binary.
- A file containing a signature of the hash file, created by whoever is building
the release.

View File

@ -8,8 +8,7 @@ documentation and source code.
be capitalized.
- "isle" - The name of the binary or program produced by the Isle project. isle
is the name of the file itself, as well as an instance of the process, and so
is always lower-case.
is the name of the file itself, and so is always lower-case.
- "host" - A computer or device on which isle is run.
@ -21,5 +20,5 @@ documentation and source code.
term "cluster" in the context of garage to stay consistent with garage's
documentation and command-line.
- "member" - A person who takes part in the usage, operation, or administration
of an isle network.
- "user" - A person who takes part in the usage, operation, or administration of
an isle network.

View File

@ -1,7 +1,7 @@
# Installation
# Getting Started
This document will guide you through the process of obtaining and installing
Isle on your machine.
This document will guide you through the process of obtaining an isle
binary and joining a network.
NOTE currently only linux machines with the following architectures are
supported:
@ -56,13 +56,33 @@ If your distro uses an init system other than systemd then you will need to
configure that yourself. You can use the systemd service file linked above as a
reference.
[latest]: https://code.betamike.com/micropelago/isle/releases/latest
[serviceFile]: https://code.betamike.com/micropelago/isle/src/branch/main/dist/linux/isle.service
### From Source
If you'd like to build your own `isle` binary from scratch, see the [Building
Isle](./dev/building.md) document.
(TODO probably move these instructions into the Dev docs section).
Building from source requires [nix][nix].
You can build your own AppImage by running the following from the project's
root:
```
nix-build -A appImageBin
```
(*NOTE* The first time you run this a lot of things will be built from scratch.
If you have not otherwise configured it, nix might be using a tmpfs as its build
directory, and the capacity of this tmpfs will probably be exceeded by this
build. You can change your build directory to somewhere on-disk by setting the
TMPDIR environment variable for `nix-daemon` (see
[this github issue][tmpdir-gh].))
The resulting binary can be found under `result/bin`. From here you can continue
with the instructions under the "AppImage" section above.
[nix]: https://nixos.wiki/wiki/Nix_package_manager
[tmpdir-gh]: https://github.com/NixOS/nix/issues/2098#issuecomment-383243838
## Add Users to the `isle` Group (Optional)
@ -84,3 +104,26 @@ sudo systemctl enable --now isle
(NOTE If your distro uses an init system other than systemd then you will need
to instead start isle according to that system's requirements.)
## Join a Network
This section will guide you through the process of joining an existing network
of isle hosts. If instead you wish to create a new network for others to join
then see the [Creating a New Network][creating-a-new-network] page.
To join an existing network you will need to first obtain a `bootstrap.json`
file. The `bootstrap.json` file contains all information required for your
particular host to join the network, and must be generated and provided to you
by an admin for the network.
Once obtained, you can join the network by doing:
```
isle network join --bootstrap-path /path/to/bootstrap.json
```
After a few moments you will have successfully joined the network!
[creating-a-new-network]: ../admin/creating-a-new-network.md
[latest]: https://code.betamike.com/micropelago/isle/releases/latest

View File

@ -1,20 +0,0 @@
# Join a Network
This document guide you through the process of joining an existing network
of isle hosts. If instead you wish to create a new network for others to join
then see the [Creating a New Network][creating-a-new-network] page.
To join an existing network you will need to first obtain a `bootstrap.json`
file. The `bootstrap.json` file contains all information required for your
particular host to join the network, and must be generated and provided to you
by an admin for the network.
Once obtained, you can join the network by doing:
```
isle network join --bootstrap-path /path/to/bootstrap.json
```
After a few moments you will have successfully joined the network!
[creating-a-new-network]: ../admin/creating-a-new-network.md

View File

@ -23,6 +23,12 @@ func StateDirPath(dataDirPath string) string {
return filepath.Join(dataDirPath, "bootstrap.json")
}
// AppDirPath returns the path within the AppDir where an embedded bootstrap
// file might be found.
func AppDirPath(appDirPath string) string {
return filepath.Join(appDirPath, "share/bootstrap.json")
}
// CreationParams are general parameters used when creating a new network. These
// are available to all hosts within the network via their bootstrap files.
type CreationParams struct {

View File

@ -41,7 +41,7 @@ var subCmdDaemon = subCmd{
}
if *dumpConfig {
return daecommon.CopyDefaultConfig(os.Stdout)
return daecommon.CopyDefaultConfig(os.Stdout, envAppDirPath)
}
logLevel := mlog.LevelFromString(*logLevelStr)

View File

@ -90,7 +90,7 @@ var subCmdGarageMC = subCmd{
*keyID, *keySecret, s3APIAddr,
)
binPath = binPath("mc")
binPath = filepath.Join(envAppDirPath, "bin/mc")
cliEnv = append(
os.Environ(),
mcHostVar,

View File

@ -1,17 +1,15 @@
package daecommon
import (
"bytes"
"fmt"
"io"
"isle/bootstrap"
"isle/toolkit"
"net"
"os"
"path/filepath"
"strconv"
_ "embed"
"gopkg.in/yaml.v3"
)
@ -21,8 +19,9 @@ const (
DeprecatedNetworkID = "_" // DEPRECATED
)
//go:embed daemon.yml
var defaultConfigB []byte
func defaultConfigPath(appDirPath string) string {
return filepath.Join(appDirPath, "etc", "daemon.yml")
}
type ConfigTun struct {
Device string `yaml:"device"`
@ -181,9 +180,22 @@ func (c Config) Validate() error {
// CopyDefaultConfig copies the daemon config file embedded in the AppDir into
// the given io.Writer.
func CopyDefaultConfig(into io.Writer) error {
_, err := io.Copy(into, bytes.NewReader(defaultConfigB))
return err
func CopyDefaultConfig(into io.Writer, appDirPath string) error {
defaultConfigPath := defaultConfigPath(appDirPath)
f, err := os.Open(defaultConfigPath)
if err != nil {
return fmt.Errorf("opening daemon config at %q: %w", defaultConfigPath, err)
}
defer f.Close()
if _, err := io.Copy(into, f); err != nil {
return fmt.Errorf("copying daemon config from %q: %w", defaultConfigPath, err)
}
return nil
}
// LoadConfig loads the daemon config from userConfigPath.

View File

@ -8,7 +8,7 @@
pname = "nebula";
# If this changes, remember to change:
# - the go/daemon/daecommon/daemon.yml vpn.firewall docs
# - the AppDir/etc/daemon.yml vpn.firewall docs
# - the version imported in go-workspace
version = "1.6.1";