# Arkens
Written in Rust.
## Libraries
```
tokio - Provides unified async API and system-wide communication
tokio-rustls - Provides TLS for networking
rustls-pemfile - Provides PEM file parsing
cabrpc - Provides RPC
serde, serde_json - Provides Json parsing
nftnl - Provides nftables configuration for network filtering
xxhash-rust - Provides hashing for RPC signatures and template IDs
clap? - Provides command line parsing (Possibly use custom implementation later)
nix? - Provides user namespaces for userspace filtered networking (Very optional)
nix? - Provides PCI driver swapping for passthrough
Possibly useful:
bitflags
rand
dirs
bytes
```
## Examples:
[alacritty](https://github.com/alacritty/alacritty/blob/master/alacritty/Cargo.toml)
[bat](https://github.com/sharkdp/bat/blob/master/Cargo.toml)
[exa](https://github.com/ogham/exa/blob/master/Cargo.toml)
[fd](https://github.com/sharkdp/fd/blob/master/Cargo.toml)
[zoxide](https://github.com/ajeetdsouza/zoxide/blob/main/Cargo.toml)
[mullvad](https://github.com/mullvad/mullvadvpn-app/blob/main/Cargo.toml)
# Command Line | Rust
## Usage
```
version
help
reload
daemon <node|server|mirror> ???
```
```
slot list
slot info <slot>
```
```
repository list
repository info <repository>
repository add <host:repository> [repository]
repository del <repository> [--clean]
repository edit <repository> <host:repository>
repository pull <repository>
repository push <repository>
repository sync <repository>
repository reset <repository>
```
```
branch list [repository]
branch info <[repository]:branch>
branch head <[repository]:branch>
branch add <repository:branch> [--template <template>] [--description <description>]
branch del <[repository]:branch>
branch edit <[repository]:branch> template [template]
branch edit <[repository]:branch> description [description]
```
```
template list [repository] [--tree]
template info <[repository]:template>
template copy <repository:template> <target repository> [--recursive]
template del <[repository]:template> [--recursive] [--force]
```
```
draft list
draft info <draft>
draft add <draft> [--size <size>] [--template <[repository]:template>] [--branch <[repository]:branch>]
draft del <draft>
draft mv <draft> <new draft>
draft edit <draft> [TODO]
draft reset <draft>
draft commit <draft> <repository> [--pack] [message]
```
```
instance? list
instance? info <instance>
instance? add [TODO]
instance? del <instance>
instance? start <instance> [TODO]
instance? prune [-r|--reserve <space>]
```
```
machine list
machine info <machine>
machine shutdown <machine> [-t|--timeout <timeout>]
machine kill <machine>
machine power-signal? <machine>
machine pause <machine>
machine continue <machine>
```
## Examples
### Creating a new branch
```bash!=
# Add the remote repository from 127.0.0.1 (empty)
repository add 127.0.0.1:remote
# Create and edit an empty draft
draft add archlinux-draft --size 64G
draft edit archlinux-draft --iso archlinux.iso --vnc 5900
# Commit the draft to the repository, creating a template
draft commit archlinux-draft remote "Initial configuration"
# Create a branch for the new template
branch add remote:archlinux --template XXXXXXXX --description "Arch Linux"
# Push the modifications to the repository
repository push remote
```
### Editing an existing branch
```bash!=
# Add the remote repository from 127.0.0.1
repository add 127.0.0.1:remote
repository pull remote
# Create a draft to edit the current branch head
draft add archlinux-draft --branch remote:archlinux
draft edit archlinux-draft --vnc 5900
# Commit the draft to the repository
draft commit archlinux-draft remote "Some edits"
# Edit the branch head to point to the new template
branch edit remote:archlinux template XXXXXXXX
# Push the modifications to the repository
repository push remote
```
### Rollback an branch by removing the head template
```bash!=
# Add the remote repository from 127.0.0.1
repository add 127.0.0.1:remote
repository pull remote
# Remove the template pointed by the branch head
branch head remote:archlinux
template del remote:XXXXXXXX --force
# Push the modifications to the repository
repository push remote
```
# Core | Rust
## Filesystem
### Repositories
```toml
📁 $REPOSITORY_POOL [/var/lib/arkens/repositories/]
├── 📁 <repository name> <- Repository's custom name
│ ├── 📄 info <- Json file containing information about the repository
│ ├── 📄 branches <- Json file containing the different branches' heads
│ ├── 📄 edits <- Json file containing the local edits made to the repository (add/remove)
│ ├── 📁 <template id> <- ID generated by the hash of the disk
│ │ ├── 📄 template <- QCOW2 disk, possibly backed on a template
│ │ └── 📄 info <- Json file containing information about the template
...
```
### Drafts
```toml
📁 $DRAFT_POOL [/var/lib/arkens/drafts/]
├── 📁 <draft name> <- Draft's custom name
│ ├── 📄 draft <- QCOW2 disk, possibly backed on a template
│ └── 📄 info <- Json file containing information about the draft
...
```
### Instances
```toml
📁 $INSTANCE_POOL [/var/lib/arkens/instances/]
├── 📁 <instance id> <- ID given by the server to identify the user
│ ├── 📄 instance <- Encrypted QCOW2 disk, backed on a template
│ └── 📄 info <- Json file containing information about the instance
...
```
# Server | Rust
# Mirror | Rust
# Interface | Other ?
# Login | Rust ?
# CabRPC
Continuous Asynchronous Bidirectional Remote Procedure Call
**Basic** RPC protocol over a single channel, allowing for bidirectional requests with asynchronous responses.
## Components
### Transport
Transports take care of sending and receiving raw data from other types of communication layers, like TCP or unix sockets.
### Translator
Translators take care of converting the raw data coming from the transports into calls (messages). Translators also provide the argument serialization and deserialization.
### Channel
Channels take care of receiving and sending calls and responses through the transport. Channels have a set of registered handlers that handle RPC calls.
### Caller
Callers are helpers used to send calls using function signatures from the traits marked with [rpc].
### Executor
Executors are helpers used to register callable functions to a channel.
## Format
### Message
```
Total Inclusive Length -> u32
Identifier -> u16
Message Type -> u8
Message Data -> Data
```
#### Message Types
```
Procedure Call - 0x01:
Procedure : Hash
[Data]
Procedure Return - 0x81:
[Data]
Error - 0xFF:
[Error]
```
#### Errors
```
0x00 -> Unknown error
[String]
0x01 -> Internal system error
[String]
TODO
```
### Simple translator
```
Little-endian
Input -> Output | Hash
() | Nothing | 0x00
u8 | char -> u8 | 0x10
i8 -> i8 | 0x11
u16 -> u16 | 0x12
i16 -> u16 | 0x13
u32 -> u32 | 0x14
i32 -> i32 | 0x15
u64 -> u64 | 0x16
i64 -> i64 | 0x17
u128 -> u128 | 0x18
i128 -> i128 | 0x19
bool -> u8 | 0x1A
f16 (IEEE 754) -> f16 | 0x20
f32 (IEEE 754) -> f32 | 0x21
f64 (IEEE 754) -> f64 | 0x22
tuple -> data | [0x40, [T1], [T2], [T3]...] -> [(((0x40, [T1]), [T2]), [T3])...]
struct -> data | [0x41, [id], [T1], [T2], [T3]...]
T[N] -> data | [0x42, [T], N]
Vec<T> -> uv + data | [0x43, [T]]
dynamic -> uv + data | [0x44, [D1], [T1], [D2], [T2]] (Ordered by determinant hashes)
enum{2,1,3...} | [0x45, [id], [D1], [T1], [D2], [T2]] (Ordered by determinant hashes)
fn Name(T1, T2...)-> R | [0x80, [id], [R], [T1], [T2]...]
String -> Vec<u8> | [0x42, 0x10]
Option<T> -> dynamic | [0x44, [0u8], [T], [1u8], 0x00]
Result<T,E> -> dynamic | [0x44, [0u8], [T], [1u8], [E]]
```
#### Parsing example
```
target: (Vec<u32>, Option<Vec<char>>, Result<Vec<char>, u32>, Vec<Vec<Vec<char>>>)
parseInt -> length
for length
parseInt -> arg[0]
parseBool -> present
if present
parseInt -> length
parseData(length) -> arg[1]
parseInt -> id
if id == 0
parseInt -> length
parseData(length) -> arg[2]
else if id == 1
parseInt -> arg[2]
parseInt -> length
for length
parseInt -> length
for length
parseInt -> length
parseData(length) -> arg[3]
```
### Rust macro
```
#[derive(cbrpc::Transcodable)]
struct Test {
#[cbrpc::order(0)]
v1: u32,
#[cbrpc::order(1)]
v2: Vec<String>,
}
```