---
# System prepended metadata

title: Arkens

---

# 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>,
}
```