Compare commits

..

1 Commits

Author SHA1 Message Date
Jaromil cbb303663f updated webpage documentation 2018-05-03 17:37:42 +02:00
25 changed files with 81 additions and 2116 deletions

6
.gitmodules vendored
View File

@ -1,12 +1,12 @@
[submodule "vm-sdk"]
path = vm-sdk
url = https://github.com/parazyd/vm-sdk.git
url = https://git.devuan.org/sdk/vm-sdk.git
[submodule "arm-sdk"]
path = arm-sdk
url = https://github.com/parazyd/arm-sdk.git
url = https://git.devuan.org/sdk/arm-sdk.git
[submodule "live-sdk"]
path = live-sdk
url = https://github.com/parazyd/live-sdk.git
url = https://git.devuan.org/sdk/live-sdk.git
[submodule "docs/webnomad"]
path = docs/webnomad
url = https://github.com/dyne/webnomad

View File

@ -1,29 +0,0 @@
notifications:
email: false
git:
submodules:
false
env:
- RELEASE_BRANCH="master"
sudo: required
language: ruby
services:
- docker
before_install:
- docker build -t dyne/decodeos:travis docker-sdk
script:
- container=$(docker create dyne/decodeos:travis)
- docker start $container
- docker exec $container dam-client -gen
- sleep 10
- docker exec $container ps axf
- docker stop $container
- docker rm $container

View File

@ -1,10 +0,0 @@
from dyne/devuan:ascii
maintainer parazyd "https://github.com/parazyd"
run echo "deb-src http://deb.devuan.org/merged ascii main" > /etc/apt/sources.list
run echo "deb http://deb.devuan.org/merged ascii main" >> /etc/apt/sources.list
run apt-get -qq update
run apt-get -yy install zsh cgpt parted xz-utils qemu qemu-utils python-markdown ruby-ronn --no-install-recommends
copy . .
run git submodule update --init --recursive --checkout

104
README.md
View File

@ -1,43 +1,33 @@
# Operating System for Private and Anonymous Computation Clusters
# Operating System for DEcentralised Data Ecosystems
[![software by Dyne.org](https://www.dyne.org/wp-content/uploads/2015/12/software_by_dyne.png)](http://www.dyne.org)
<div class="center">
The DECODE operating system is a brand new GNU+Linux distribution
designed to run on servers, embedded computers and virtual machines to
automatically connect micro-services to a private and anonymous
peer-to-peer network cluster.
The DECODE operating system is designed to run on servers, embedded
computers and virtual machines to automatically connect applications
to a private and anonymous peer-to-peer network cluster.
</div>
<img src="https://www.dyne.org/wp-content/uploads/2019/12/decode-os_only-logo.png" class="pic" alt="DECODE OS logo">
![DECODE OS logo](https://decodeos.dyne.org/img/decodeos_logo-800px.jpg)
| Features | Components |
|--------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Wide compatibility with industry standards | GNU + Linux minimal base |
| Anonimity and privacy by design | [Tor](https://torproject.org) hidden service family |
| Very secure, restricted environment | [grsec](https://github.com/minipli/linux-unofficial_grsec/wiki) community fork |
| Customisable to run different applications | [Devuan](https://devuan.org) GNU+Linux SDK |
| Pluggable consensus algorithm | [Redis](https://redis.io) based consensus broker |
| Read-only and authenticated system | [SquashFS](http://tldp.org/HOWTO/SquashFS-HOWTO/whatis.html) + [overlayfs](https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt) + [Btrfs](https://btrfs.wiki.kernel.org/index.php/Main_Page) |
| Integrated updating mechanism | [Roundshot](https://github.com/DECODEproject/roundshot) initramfs |
| Built-in Graphical dashboard | [Netdata](https://github.com/netdata/netdata) resource monitor |
| Low power consumption, outdoor usage | Ports to embedded ARM boards |
| Extensible platform support | Includes latest JDK, Golang, Python etc. |
| Minimal resource consumption | Online with less than 64MB of RAM |
| Features | Components |
|--------------------------------------------|--------------------------------------------------------------------------------|
| Wide compatibility with industry standards | GNU + Linux minimal base |
| Anonimity and privacy by design | [Tor](https://torproject.org) hidden service family |
| Very secure, restricted environment | [grsec](https://github.com/minipli/linux-unofficial_grsec/wiki) community fork |
| Customisable to run different applications | [Devuan](https://devuan.org) GNU+Linux SDK |
| Pluggable consensus algorithm | [Redis](https://redis.io) based consensus broker |
| Read-only and authenticated system | SquashFS + overlayfs + Btrfs |
| Integrated updating mechanism | [Roundshot](https://github.com/DECODEproject/roundshot) initramfs |
| Low power consumption, outdoor usage | Ports to embedded ARM boards |
## For stable releases see <a href="https://files.dyne.org/decode">files.dyne.org/decode</a>
For stable releases see https://files.dyne.org/decode
## For more information see <a href="https://decodeproject.eu">the DECODE project</a>
For more information about the DECODE project see https://decodeproject.eu
In particular, the following publications:
- <a href="https://decodeproject.eu/publications/privacy-design-strategies-decode-architecture">Privacy Design Strategies for the DECODE Architecture</a>
- <a href="https://decodeproject.eu/publications/decode-os-first-release">Decode OS first release</a>
- <a href="https://decodeproject.eu/publications/decode-os-software-development-kit">DECODE OS Software Development Kit</a> (soon to be superseeded by the upcoming Devuan's Developer Manual)
## Usage instructions
## Usage
DECODE OS comes in a variety of flavors:
@ -52,45 +42,28 @@ The default username is `decode` with password `decode`
The default `root` password is `toor`.
## Get in touch!
## Support
Developers of the Dyne.org foundation are available to support
customisations and adaptations of this operating system for particular
purposes in line with the foundation's goals.
You are welcome to contact us:
- **#devuan-dev** on **freenode** IRC (public, logged IPs)
- **#dyne** on <a href="https://irc.dyne.org">irc.dyne.org</a> (public and private, no IPs logged)
- E-mail **info@dyne.org**
This project is a work in progress proceeding along a clear roadmap
agreed for the DECODE project. The DECODE OS **stable release is planned
for 1st quarter 2019**.
agreed for the DECODE project. The DECODE OS stable release is planned
for 1st quarter 2019.
<img alt="Horizon 2020" src="https://zenroom.dyne.org/img/ec_logo.png" class="pic">
![Horizon 2020](https://zenroom.dyne.org/img/ec_logo.png)
This project is receiving funding from the **European Unions Horizon
This project is receiving funding from the European Unions Horizon
2020 research and innovation programme under grant agreement
nr. 732546**.
nr. 732546 (DECODE).
## Build from source
## Build
The following instructions illustrate how one can build DECODE OS from
scratch, eventually adding software to it. This section is a work in
progress.
scratch, eventually adding software to it.
Building can be done from any GNU+Linux distribution, it entails
bootstrapping a new Devuan base and then customising it via its SDK
using a "blend", root access is needed in order to operate in `chroot`
and in KVM accellerated `qemu`.
More information on this process is provided by the "Devuan's
Developers Manual", here is an outline on the steps to be taken.
### System requirements
### Requirements
A GNU/Linux system is required in order to build DECODE OS.
@ -111,25 +84,7 @@ To update the repository:
git pull origin master && git submodule update --init --recursive --checkout
```
### Building for ARM targets
A more detailed reference for the arm-sdk can be found here: https://git.devuan.org/sdk/arm-sdk
```
cd arm-sdk # (or vm-sdk or live-sdk depending from your target)
zsh -f
./init.sh # and when this is done, execute the command in the bottom of the output
source sdk
load devuan raspi3 decode # (replace "raspi3" with your board name, from the list below)
bootstrap_complete_base
```
Here is the list of the supported boxes: https://git.devuan.org/sdk/arm-sdk/blob/master/sdk
### Building for VM targets
### Building
To enter the build console just run `./console.sh`.
@ -195,7 +150,8 @@ each sdk if the base system doesn't differ.
DECODE OS is Copyright (c) 2017-2018 by the Dyne.org Foundation
DECODE OS and its core components are designed, written and maintained
by Denis Roio and Ivan J.
by Denis Roio and Ivan J. Other applications included may belong to
DECODE project partners and released under compatible licensing.
Devuan is a registered trademark of the Dyne.org foundation.

@ -1 +1 @@
Subproject commit 5ea550fe6ce8adcba8eac84c212cb8c49d8626f6
Subproject commit 926680290f3cdaf8bc1ce895d064b68910d848b3

31
config
View File

@ -26,8 +26,13 @@ zenroom_url="${dyneci_url}/zenroom-static-${arch}/lastSuccessfulBuild/artifact/s
golang_url="${dyneci_url}/go-binaries/lastBuild/architecture=${arch}/artifact/go.${arch}.tar.gz"
zulujava_version="1.8.0_152-8.25.0.76-eval"
zulujava_url="http://cdn.azul.com/zulu-embedded/bin/ezdk-${zulujava_version}-linux_aarch32hf.tar.gz"
chainspace_url="https://github.com/chainspace/chainspace"
chainspacedist_url="${dyneci_url}/chainspace-jar/lastSuccessfulBuild/artifact/chainspacedist.tgz"
chainspacejar_version="1.0-SNAPSHOT"
chainspacejar_url="${dyneci_url}/chainspace-jar/lastSuccessfulBuild/artifact/chainspacecore/target/chainspace-${chainspacejar_version}-jar-with-dependencies.jar"
size="4098"
@ -35,6 +40,8 @@ filesystem="btrfs"
TAR_STAGE4=true
[[ -n "$vmsdk_version" ]] && extra_packages+=(default-jre-headless)
extra_packages+=(
openrc
eudev
@ -55,8 +62,6 @@ extra_packages+=(
paxctl
net-tools
default-jre-headless
apt-transport-tor
apt-transport-https
deb.torproject.org-keyring
@ -71,7 +76,6 @@ extra_packages+=(
mlocate
gettext
miscfiles
tree
# troubleshooting
lsof
@ -80,24 +84,6 @@ extra_packages+=(
iotop
strace
python-pip
python3-pip
libpython-dev
libffi-dev
python-tox
python-cffi
python-pytest
python-pytest-cov
python-msgpack
python-numpy
python3-numpy
python-requests
python3-requests
sqlite
sqlite3
libssl1.0-dev
# build tools
build-essential
cmake
@ -113,6 +99,7 @@ extra_packages+=(
libbison-dev
libtool-bin
libtool
libssl-dev
libgcrypt20
libgcrypt20-dev
equivs

View File

@ -53,6 +53,7 @@ blend_postinst() {
notice "executing $blend_name postinst"
nopackage=(musl tomb golang tordam stem netdata zenroom chainspace)
[[ -n "$armsdk_version" ]] && nopackage+=(zulujava)
for app in $nopackage; do
blend_install_${app} || zerr
done || zerr
@ -222,10 +223,38 @@ blend_install_zenroom() {
sudo chmod +x "$strapdir/usr/local/bin/zenroom"
}
## }}}
## {{{ blend_install_zulujava()
blend_install_zulujava() {
fn blend_install_zulujava
req=(strapdir zulujava_url)
ckreq || return 1
notice "installing zulu embedded java"
cat <<EOF | sudo tee ${strapdir}/install-zulujava >/dev/null
#!/bin/sh
cd /usr/local
wget ${zulujava_url} || exit 1
tar xf $(basename ${zulujava_url}) || exit 1
mv $(basename -s .tar.gz ${zulujava_url}) ezdk || exit 1
cd ezdk
paxctl -c bin/*
paxctl -m bin/*
paxctl -c jre/bin/*
paxctl -m jre/bin/*
find . -name 'jexec' | xargs paxctl -c
find . -name 'jexec' | xargs paxctl -m
find . -name '*.so' | xargs paxctl -c
find . -name '*.so' | xargs paxctl -m
EOF
chroot-script -d install-zulujava || zerr
}
## }}}
## {{{ blend_install_chainspace()
blend_install_chainspace() {
fn blend_install_chainspace
req=(strapdir chainspace_url chainspacedist_url)
req=(strapdir chainspace_url chainspacejar_url)
ckreq || return 1
local p="$strapdir/home/decode/chainspace"
@ -233,25 +262,12 @@ blend_install_chainspace() {
notice "installing chainspace"
sudo git clone "$chainspace_url" "$p" || zerr
pushd "${p}"
sudo wget ${chainspacedist_url} || zerr
sudo tar xvf $(basename $chainspacedist_url) || zerr
sudo mkdir -p chainspacecore/target
pushd chainspacecore/target
sudo wget ${chainspacejar_url} || zerr
popd
popd
sudo chown -R 1000:1000 "$strapdir/home/decode"
cat <<EOF | sudo tee "${strapdir}/install-chainspace"
#!/bin/sh
paxctl -c /usr/bin/python*
paxctl -m /usr/bin/python*
pip install petlib
pip install bplib
cd /home/decode/chainspace
pip install -e ./chainspacecontract
pip install -e ./chainspaceapi
rm -f /install-chainspace
EOF
chroot-script -d install-chainspace
}
## }}}
@ -317,14 +333,14 @@ deb http://pkgmaster.devuan.org/merged ascii main
deb http://pkgmaster.devuan.org/merged ascii-updates main
deb http://pkgmaster.devuan.org/merged ascii-security main
deb http://deb.torproject.org/torproject.org stretch main
deb http://deb.torproject.org/torproject.org tor-experimental-0.4.0.x-stretch main
deb http://deb.torproject.org/torproject.org tor-experimental-0.3.3.x-stretch main
## source repositories
#deb-src http://pkgmaster.devuan.org/merged ascii main
#deb-src http://pkgmaster.devuan.org/merged ascii-updates main
#deb-src http://pkgmaster.devuan.org/merged ascii-security main
#deb-src http://deb.torproject.org/torproject.org stretch main
#deb-src http://deb.torproject.org/torproject.org tor-experimental-0.4.0.x-stretch main
#deb-src http://deb.torproject.org/torproject.org tor-experimental-0.3.3.x-stretch main
EOF
}
## }}}

View File

@ -1,55 +0,0 @@
Stable DECODE OS release
========================
This document accompanies the stable release of the DECODE OS, one of
the core development outputs of the DECODE project, aimed at providing
a reliable operating system to run application space development in an
environment ensuring privacy by design outside of the application
domain. This deliverable references, without duplication of
information, the research and development done and detailed in
previous deliverables D4.1 and D4.4.
The DECODE OS is a GNU+Linux distribution based on Devuan.org to
provide a minimalist base for distributed computing micro-services
capable of targeting any mainstream hardware platform, from
virtual-machines to ARM boards to bare-metal server racks.
The main website for this distribution is https://decodeos.dyne.org
As part of the DECODE OS distribution, backend software applications
have been developed to implement
1. a front-end web application to facilitate the adoption of the
DECODE continuous integration infrastructure (toaster)
https://toaster.dyne.org
2. a continuous integration system to release and customize new
versions of DECODE OS (SDK) https://git.devuan.org/sdk
3. a private peer-to-peer network over the Tor protocol (tor-dam)
https://github.com/decodeproject/tor-dam
These core features of these three components will be described in the
following sections of this document, along with operational
instructions.
Due to the experimental stage of development of other components in
DECODE and according to the LEAN principles declared in the project,
this stable release doesn't only constitute a final point of arrival
for this development task. What DECODE OS can do today is facilitating
the deployment of lab-tested software applications (for example made
in a Docker format, widely adopted by other partners in DECODE) and
render these prototypes into a production ready format that can be
deployed on the open-hardware DECODE BOX as well on virtual-machines.
We consider this achievement highly beneficial for a project whose
development is still in-flux, as well for the free and open source
community out there, since the access to the powerful features of the
SDK is now made very easy via an integrated continuous pipeline.
In light of these advantages, there is a clear intention within our
organisation (mainly by DYNE) to keep maintaining DECODE OS also
beyond the span of the project and this very task now concluded, since
it greatly helps the manning of prototypes into stable production
environments.

View File

@ -1,293 +0,0 @@
The DECODE SDK
==============
The DECODE SDK is a unique build framework written to ease maintenance
and production of various types of the Devuan distribution images,
such as: live ISOs, virtual machine images, and images targeted at
embedded ARM boards. This section explains how to use the SDK, gives
and inside look at its various parts and documents the workflow to be
used when modifying its code.
The SDK is designed in such a way that there are levels of priority
within the scripts. First there is `libdevuansdk`, which holds the
vanilla configuration, then come the various wrappers targeted around
specific targets (`live`, `virtual`, `embedded`), and afterwards we
optionally add more on top of it if we need to customize or override
specific functions. This is for example the case with DECODE OS,
where we have to add additional software and extra components on top
of the base Devuan system.
libdevuansdk
------------
_libdevuansdk_ is the core of any part of the Devuan SDK. It holds the
common knowledge between all of the upper wrappers such as _live-sdk_,
_vm-sdk_, and _arm-sdk_. Simply put, it is a shell script library to
unify the use and creation of various functions spread throughout the
complete Devuan SDK.
The wrappers are designed to be used interactively from a terminal, as
well as automated from shell scripts. _libdevuansdk_ uses an
additional _zsh_ library called [zuper](https://github.com/dyne/zuper)
to ease the variable declaration and scoping, as well as error
checking and debugging. However, _zuper_ is not included in
_libdevuansdk_ itself - one is required to include it in its
respective wrapper. _live-sdk_, _vm-sdk_, and _arm-sdk_ can be taken
as example. libdevuansdk itself has some software dependencies that
should be installed prior to use:
```
zsh
debootstrap
sudo
kpartx
cgpt
xz-utils
```
### Workflow
Working with _libdevuansdk_ splits into categories of what you want to
do. _zlibs_ are files separated into the following categories:
* ***bootstrap*** Contains the functions for the bootstrap process.
Creating a minimal debootstrap base system, and making it into a
compressed file (tar.gz) for later use so one does not have to wait
for the lengthy bootstrap process on each consequent build.
* ***helpers*** Contains the helper functions for _libdevuansdk_ that
make the workflow a bit easier to use and handle.
* ***imaging*** Contains the functions necessary for creating raw
dd-able images.
* ***rsync*** Contains rsync and file copying functions.
* ***sysconf*** Contains the default system configuration.
### Usage
As libdevuansdk is not very useful when invoked on its own, its usage
will be explained at later parts, for each specific wrapper. The
technical documentation of _libdevuansdk_ will follow in its
appropriate section.
The wrappers
------------
As mentioned, _libdevuansdk_ is the core library we wrap around. The
currently existing wrappers are called _live-sdk_, _vm-sdk_, and
_arm-sdk_. These facilitate the builds of liveCDs, virtual machines, and
images for embedded ARM devices, respectively. Each of them have their
own section in this paper.
Since all of these wrappers, along with _libdevuansdk_, hold a
_vanilla_ Devuan configuration, it is best to keep their code
untouched. To allow for custom configurations, we introduced a concept
called *blends*. Blends are a simple way to customize the base image
of the OS-to-be before building it, allowing to easily add packages,
kernels, and virtually anything one might want to do in the
image. This exactly is the case with DECODE OS.
arm-sdk
-------
The _arm-sdk_ is our way of facilitating builds for embedded ARM boards
such as Allwinner-based CPUs, Raspberry Pis, Chromebooks, etc. It holds
a knowledgebase for a number of embedded devices, and how to build
according kernels and bootloaders.
### Directory structure
_arm-sdk_'s directory structure is separated into places where we hold
our boards and their kernel configurations, device-specific
directories with firmware and/or configuration, and a _lib_ directory
(where we keep _libdevuansdk_ and the like).
### Obtaining arm-sdk
The SDK, like any other part of Devuan's software toolchain, should be
obtained via _git_. The repositories are hosted on Devuan's Gitlab. To
grab it, we simply issue a _git clone_ command on a terminal, and
since it contains linked git submodules - we append _--recursive_ to
it:
```
$ git clone https://git.devuan.org/sdk/arm-sdk --recursive
```
Consult the _README.md_ file found in this repository to see what are
the required dependencies to use _arm-sdk_.
### Using arm-sdk
Once the build system is obtained, it can now be used interactively. The
process is very simple, and to build an image one can actually use a
single shell command. However, we shall first show how it works.
In _arm-sdk_, every board has its own script located in the _boards_
directory. In most cases, these scripts contain functions to build the
Linux kernel, and a bootloader needed for the board to boot. This is
the only difference between all the boards, which requires every board
to have their own script. We are able to reuse the _rootfs_ that was
bootstrapped before. For our example, let's take the _Nokia N900_
build script. To build a _vanilla_ image for it, we simply issue:
```
$ zsh -f -c 'source sdk && load devuan n900 && build_image_dist'
```
This will fire up the build process, and after a certain amount of time
we will have our compressed image ready and checksummed inside the
_dist_ directory.
The oneliner above is self-explanatory: We first start a new untainted
shell, source the sdk file to get an interactive SDK shell, then we
initialize the operating system along with the board we are building,
and finally we issue a helper command that calls all the necessary
functions to build our image. The _load_ command takes an optional
third argument which is the name of our _blend_ (the way to customize
our _vanilla_ image) which will be explained later. So in this case,
our oneliner would look like:
```
$ zsh -f -c 'source sdk && load devuan n900 decode && build_image_dist'
```
This would create an image with the _"decode"_ blend, which is available
by cloning the DECODE OS git repository. The *build_image_dist* command
is a helper function located in _libdevuansdk_ that wraps around the 8
functions needed to build our image. They are all explained in the
technical part of this paper.
live-sdk
--------
The _live-sdk_ is used to build bootable images, better known as Live
CDs. Its structure is very similar to _vm-sdk_ and is a lot smaller than
_arm-sdk_.
### Directory structure
Unlike _arm-sdk_, in _live-sdk_ we have no need for specific boards or
setups, so in this case we only host the interactive shell init, and
libraries.
### Obtaining live-sdk
The SDK, like any other, should be obtained via _git_. The repositories
are hosted on Devuan's Gitlab. To grab it, we simply issue a _git clone_
command, an since it contains git submodules - we append _--recursive_
to it:
```
$ git clone https://git.devuan.org/sdk/live-sdk --recursive
```
Consult the _README.md_ file found in this repository to see what are
the required dependencies to use _live-sdk_.
### Using live-sdk
Much like _arm-sdk_, the _live-sdk_ is used the same way. With two
specific differences. Since we don't have any need for specific
boards, when loading we don't specify a board, but rather the CPU
architecture we are building for. Currently supported are *i386* and
*amd64* which represent 32bit and 64bit respectively. To build a
_vanilla_ live ISO, we issue:
```
$ zsh -f -c 'source sdk && load devuan amd64 && build_iso_dist'
```
This will start the build process, and after a certain amount of time we
will have our ISO ready and inside the _dist_ directory.
Just like in _arm-sdk_, we can use a _blend_ and customize our OS:
```
$ zsh -f -c 'source sdk && load devuan amd64 decode && build_iso_dist'
```
So this would create a live ISO of DECODE OS. Again as noted, this can
be obtained by recursively cloning the corresponding (DECODE-OS) git
repository.
The *build_iso_dist* command is a helper function located in
_libdevuansdk_ that wraps around the 9 functions needed to build our
image. They are all explained in the technical part of this manual.
vm-sdk
------
The _vm-sdk_ is used to build VirtualBox/Vagrant boxes, and virtual
images for emulation, in QCOW2 format, which is the byproduct of
building a Vagrant box. Its structure is very similar to _live-sdk_
and is the smallest of the three wrappers currently found in the
Devuan SDK.
### Directory structure
Like with _live-sdk_, in _vm-sdk_ we have no need for specific boards
or setups, so in this case we only host the interactive shell init,
and libraries.
### Obtaining vm-sdk
The SDK, like any other, should be obtained via _git_. The
repositories are hosted on Devuan's Gitlab. To grab it, we simply
issue a _git clone_ command, an since it contains git submodules - we
append _--recursive_ to it:
```
$ git clone https://git.devuan.org/sdk/vm-sdk --recursive
```
Consult the _README.md_ file found in this repository to see what are
the required dependencies to use _vm-sdk_.
### Using vm-sdk
Once obtained, we can use it interactively. The process is very simple,
and to build an image we use the oneliner we've already seen above.
Also like with _live-sdk_, we don't build for specific boards, however
we also do not create any non-amd64 images, so we don't have to pass
an architecture to the load command either. To build a _vanilla_
Vagrant Box, VirtualBox image, QCOW2 image, and a cloud-based QCOW2
image, we issue:
```
$ zsh -f -c 'source sdk && load devuan && build_vagrant_dist'
```
This line would create all the four types of the VM image.
As shown with the previous two wrappers, the _blend_ concept works as
advertised here as well:
```
$ zsh -f -c 'source sdk && load deuvan decode && build_vagrant_dist'
```
The *build_vagrant_dist* command is a helper function located in
_libdevuansdk_ that wraps around the 11 functions needed to build our
image. They are all explained in the technical part of this manual.

View File

@ -1,322 +0,0 @@
Blends
======
Introduction
------------
In the Devuan SDK, a _blend_ is the preferred way we use to make
customizations to the _vanilla_ image. Using blends we can very easily
create different flavors of our image, by easily including/excluding
certain software packages, files, or anything we wish to do. Blends
can become a very quick way of creating entire new derivatives of the
original _vanilla_ distribution we are building.
This time, we will take the DECODE OS as a _blend_ example. In DECODE
OS we provide a blend called _decode_ which is the blend we use to
create a production release of DECODE OS. The blend's files are
contained within their own directory in the _decode-os_ git
repository.
Configuration
-------------
Any SDK requires a single file to act as a _blend_. This file is also a
_zsh_ script, and, at the very least, it must contain two functions
called:
```
blend_preinst()
blend_postinst()
```
These functions are your pathway to expanding your blend into whatever
you would like it to do. The _preinst_ function is usually called
right after bootstrapping the _vanilla_ root filesystem, and the
_postinst_ function is called near the very end, just before packing
or compressing the image. These two strategic places should be enough
to do changes within the image. If this is not enough, blends also
allow you to simply **override any variable or function** contained
within _libdevuansdk_ or the sdk you are using.
Our _decode_ blend is such an example. It is a somewhat expanded blend,
not contained within a single file, but rather a directory. This allows
easier maintenance and makes the scripts clearer and cleaner.
### Adding and removing packages
When we want to add or remove specific packages to our build, we have
to override or append to _libdevuansdk_'s arrays. The array for
packages we want installed is called *extra_packages*, and the array
for packages we want purged is called *purge_packages*. In the Decode
blend, these can be found in the _config_ file located inside the
_decode-os_ blend directory. Keep in mind that these arrays could
already contain specific packages, so you are advised to rather append
to them, than overriding them.
If the packages you want to install are not available in the
repositories, you still have a way of automatically installing
them. All you have to do is copy your corresponding .deb files to the
following directory of the blend:
```
$R/extra/custom-packages/
```
And when that is done, just call the function *install-custdebs*
Creating a blend
----------------
Rather than explaining the following in theory, you are best off
viewing the blend files that are provided with _decode-os_. It is a
fairly simple blend and should give you enough insight on how to
create your own blend. Here are some important guidelines for creating
a blend:
* The blend should always contain at least two functions
This means you must provide *blend_preinst* and *blend_postinst* in your
blend. They don't even have to do anything, but they should be there.
These two functions open the path for you to call any other functions
you created for your blend.
* When overriding functions, make sure they provide a result that
doesn't break the API
Breaking the API may result in unwanted behavior. You should always
study well the functions you are planning to override and figure out if
it is safe to override them in the way you want. The same goes for any
variables as well.
* Any arguments used after the blend name when loading from the SDK are
free for you to use in the blend.
This means you can use anything after the fourth argument (**$4** in
_zsh_) inside your blend if you require passing arguments to it.
These are some of the more important guidelines. There is plenty more
tricks and quirks, but it's easy to find out how to tweak the
configuration files and the blend in general once you read through a
blend or two on your own.
### Enable the blend
To use your blend in the first place, you need to make the SDK know
about it. Thus you should append the path to your new blend inside
the **blend_map** of the _sdk_ file:
```
blend_map=(
"devuan-live" "$R/blends/devuan-live/devuan-live.blend"
"decode" "$R/../decode.blend"
"heads" "$R/../heads.blend"
"ournewblend" "$R/blends/newblend/new-blend.blend"
)
```
As you can see, the map is a key-value storage. So you can have an alias
(name) for your blend, and just use that to point to the path of the
blend. The blend file will be sourced by the SDK once it is told to do
so.
### A configuration file
For having a finer-grained control of what goes into our build, we can
create a config file for our blend. From here we can easily control
any configurable aspect of it, such as packages that go in or out, the
blend name, and much more. **Make sure you source this file from your
blend.**
Adding and removing packages was abstractly mentioned earlier: it goes
into two separate arrays holding package names. To add packages, we
append to the `extra_packages` array, which would look like this:
```
extra_packages+=(
my_new_package
foo
bar
baz
)
```
This would install the four packages `my_new_package`, `foo`, `bar`,
and `baz` along with the ones predefined in either _libdevuansdk_ or
the SDK you are using. You may also want to see which those are in
case you wish to exclude them, but they are sane and useful utilities
which should be included in your build if possible. Overriding all
those packages, you would need to reset the whole array, so you would
simply issue this:
```
extra_packages=(
my_new_package
foo
bar
baz
)
```
As you can see, we no longer have the `+=`, but rather only `=`, which
means we are not appending to the array, but rather redefining it.
All of the above applies as well for removing packages, but in this case
the array is called `purge_packages`.
#### Custom packages
If you want to install deb packages that aren't in any repositories, put
them in the blend directory and simply add them to another array in the
configuration file. The contents of the arrays are the paths to the
debs, relative to this configuration file:
```
custom_deb_packages=(
yad_0.27.0-1_amd64.deb
palemoon_27.2.0~repack-1_amd64.deb
)
```
To trigger the installation of these packages, you will need to copy
them to `$R/extra/custom_packages`, and then call the
`install_custdebs` function somewhere from your blend.
### Custom files
Any files you want to add to the system to override what's there by
default you can add using a *rootfs overlay*. Create a directory
inside your blend directory called *rootfs-overlay* and simply put
files inside it. The directory structure is absolute to the image we
are building. For example what's in "rootfs-overlay/etc/" would end
up in the "/etc" of our final image. See _hier(7)_ in the Linux
manpages for more explanation on this directory hierarchy.
If you end up with any files here, to actually copy them, you will need
to either run `cp -f` it, or `rsync` the directory if you prefer.
### The .blend file
We listed a path to the .blend file in our first step. We need to create
this file now.
Start your blend file with the following, so the sdk is aware of the
environment:
```
BLENDPATH="${BLENDPATH:-$(dirname $0)}"
source $BLENDPATH/config
```
The minimum blend should contain two functions: `blend_preinst` and
`blend_postinst`. These functions are called at specific points in the
build, where they give the most power: just after bootstrapping the
_vanilla_ system, and just before packaging the final build,
respectively.
#### blend_preinst
A preinst function can look like this:
```
blend_preinst() {
fn blend_preinst
req=(BLENDPATH R)
ckreq || return 1
notice "executing blend preinst"
add-user "user" "pass"
cp -fv "$BLENDPATH"/*.deb "$R/extra/custom-packages" || zerr
install-custdebs || zerr
}
```
As you can see, the pre-install function will add a new user with the
credentials `user:pass`, it will copy our custom debs where they can
be used, and finally it will trigger their installation.
The `fn, req, ckreq` part on the top of the function is a safety check
for the function that is enabled by _zuper_. It allows us to check if
variables are defined when the function is called and fail if it is
wrong. You should utilize this as much as possible. The `zerr` calls
are used to exit if the function fails.
#### blend_postinst
A post-install function can look like the following:
```
blend_postinst() {
fn blend_postinst
req=(BLENDPATH strapdir)
ckreq || return 1
notice "executing blend postinst"
sudo cp -vf "$BLENDPATH"/rootfs-overlay/* $strapdir || zerr
blend_finalize || zerr
}
```
This function would copy the `rootfs-overlay` to the `strapdir` (which
holds our image's filesystem) and it would call the `blend_finalize`
function. By default this function doesn't exist, we quote it as an
example for you to see how it is possible to call your own functions
as well. You can define them within the blend file.
Using a blend
-------------
As previously explained, you can use your blends through the SDK's
interactive shell. In _decode-os_ the blend is placed in the root of
the git repository, and the sdk wrappers are located within. Therefore
an SDK would have to source it with such a path:
```
$R/../decode.blend
```
If you take a look at _vm-sdk_'s `sdk` file, you will see the
`blend_map` array. Using a new blend requires you to add it to this
map in the same manner. The map is key-value formatted, and on the
left you have an alias of your blend, and on the right you have a
script you have to write. It can either be the blend itself or any
helper file you might need to initialize your blend.
After you've added it to the blend map, you simply initialize the SDK,
and use the same *load* command we learned earlier, while appending
the blend alias and any optional argument.
```
$ zsh -f
$ source sdk
$ load devuan decode <these> <arguments> <we> <can> <use> <in> <the> <blend>
```
With this, we've initialized our *decode* blend. It's always good to add a
*notice()* call to your blend to signal it's been loaded successfully.
Once this is done, we simply build the image the same way we have
learned before:
```
$ build_vagrant_dist
```
Consult the _vm-sdk_ chapter for this.

View File

@ -1,131 +0,0 @@
The Devuan SDK more in-depth
============================
The following parts will explain the Devuan SDK more technically. It
will show its configuration, important functions, and show how it all
glues together.
Configuration
-------------
Much of the _libdevuansdk_ configuration is done in
`libdevuansdk/config`. Here you can edit the defaults if you wish to
do something your needs are expressing. However, overriding these
through upper levels is recommended.
### `config` file
`vars` and `arrs` are global arrays for holding other global variables
and arrays, respectively. This is required for `zuper` and helps a lot
with debugging. If you declare new variables or arrays, add them to the
aforementioned variables.
* `os` holds the name of the distribution being worked on.
* `release` holds the release codename of the distribution. Used for apt
repositories mostly.
* `version` is the version of the distribution being worked on.
* `mirror` is a mirror holding the required packages for `debootstrap`.
* `section` are the sections of the repository. For adding in
`/etc/apt/sources.list`. Separate them with whitespaces.
* `image_name` is the output name of the raw image. If you declare a
blend or a device name (arm-sdk), they will be appended to this name.
* `rootcredentials` and `usercredentials` are currently placeholders.
* `core_packages` is an array holding the core packages that will be
installed in the bootstrap process.
* `base_packages` is an array holding the base packages that will be
installed at a later point in the bootstrap process.
* `purge_packages` is an array of packages that will get purged at the
end of the bootstrap process.
Helper functions
----------------
You can find useful helper functions in `libdevuansdk/zlibs/helpers`.
They are intended to help when it comes to writing wrappers, as well
as making the developers' jobs easier for developing
_libdevuansdk_. Some of these functions are required for
_libdevuansdk_ to work properly as well.
### `build_image_dist()`
This function is a kind of a wrapper function. It's used in _arm-sdk_
to build a complete dd-able image from start to end. To run, it
requires `$arch`, `$size`, `$parted_type`, `$workdir`, `$strapdir`,
and `$image_name` to be declared. See the section dedicated to
"Creating wrappers" for insight on these variables.
The workflow of this function is bootstrapping a complete _rootfs_,
creating a raw image, installing/compiling a kernel, rsyncing
everything to the raw image, and finally compressing the raw image.
This same workflow is applied in the next two functions in this file,
which are `build_iso_dist` and `build_vagrant_dist`. To get a better
understanding of _libdevuansdk_, it's recommended to go through one of
these functions and following it deeper to find and figure out the
other functions and how they work together.
### `devprocsys()`
This function is a simple helper function that takes two arguments. It
mounts or unmounts `/dev`, `/proc`, and `/sys` filesystems to or from
wherever you tell it to. For example:
```
$ devprocsys mount $strapdir
$ devprocsys umount $strapdir
```
It is very necessary to use this if one wants to do anything requiring
access to hardware or the system's resources, i.e. cryptography.
### `dpkgdivert()`
This function, like `devprocsys` takes two arguments and will create
or remove a dpkg diversion in the place you tell it to and remove
`invoke-rc.d` so that _apt_ does not autostart daemons when they are
installed.
### `chroot-script()`
This very useful functions allows you to _chroot_ into `$strapdir` and
execute the script/binary that's passed as a parameter to this
function. It also takes an optional argument `-d` that will call
`dpkgdivert` on and off before and after execution.
The `chroot-script` is also an example on its own that shows how to use
the `chroot-script` function.
Mandatory variables
-------------------
* `$R` is the root directory of a wrapper. It's defined already in all
the existing ones. In almost evert situation it can be `$PWD`.
* `$workdir` is the working directory of the current build. A sane
default is `$R/tmp/workdir`
* `$strapdir` is the bootstrap directory of the build. It holds the
rootfs when you debootstrap it, and customize it further on. Default
is `$workdir/rootfs`.
* `$arch` is the CPU architecture of the build. I.e. `amd64`, `armhf`,
etc.

View File

@ -1,45 +0,0 @@
toaster.do
==========
The **toaster.do** setup is a modular web app relying on different
parts of DECODE's CI (continuous integration) and operating system
development software (SDK) used to facilitate builds of customized
Devuan images using Dockerfiles and a web interface. It allows us to
have a seamless way of using the Dockerfiles that are used in testing
to make production images using the same Dockerfile. This brings a
deterministic approach to debugging and allows centralization of
resources, while avoiding extra work needed to write a Devuan blend.
The web application is public on https://toaster.dyne.org
All following documentation contained in this document details the
internals of this application, of the components and infrastructure
that it is using. Unless specifically interested in these
implementation details, the web application facilitates the adoption
of all features described through a simple visual workflow.
The setup is comprised of a web interface written in Clojure, a backend
glue written in Python, the Devuan SDK, and the Jenkins CI system.
The main repository of this software component is
https://github.com/decodeproject/toaster.do
Clojure frontend
----------------
The Clojure frontend is an embedded web server with its own database,
which allows for managing of users. A user registered within this part
is then allowed to upload Dockerfiles and manage their image builds.
The frontend talks to the Python backend through SSH, and runs a
specific command to enable or disable a build job.
Jenkins backend
---------------
The backend glue is a Python tool which talks to Jenkins itself and
does all the managing and configuration of build jobs. It serves as the
backend to the Devuan SDK's web interface and is executed by the web CGI
when a build function is requested.

View File

@ -1,130 +0,0 @@
Tor DAM
=======
Tor Distributed Announce Mechanism (DAM) is a protocol and tooling for
mapping machines in the Tor network running this software.
The Tor DAM network is imagined to be pseudo-distributed inside the Tor
network itself. Nodes running Tor DAM can use an existing entrypoint and
start announcing themselves to the entry point(s), or they can be their
own and let others announce to themselves. Tor DAM will store all of
these announcements in a storage backend and utilize it to expand the
knowledge of the nodes using this software. Over time the network will
keep expanding and the user will be able to see all other nodes in the
network either by querying the storage backend, or visualizing it with
some kind of software.
Abstract
--------
* Every node has a HTTP API allowing to list other nodes and announce
new ones.
* They keep propagating to all valid nodes they know.
* Announcing implies the need of knowledge of at least one or two nodes.
* It is possible to make this random enough once there are at least 6
nodes in the network.
* A node announces itself to others by sending a JSON-formatted HTTP
POST request to one or more active node.
* Once the POST request is received, the node will validate the
request and return a secret encrypted with the requester's public
key.
* The requester will try to decrypt this secret, and return the
secret in plain text back to the node it's announcing to, along
with a cryptographic signature, so the node can confirm the
requester is in actual possession of the private key.
* Tor DAM **does not validate** if a node is malicious or not. This is a
layer that has to be established on top. Tor DAM is just the entry
point into the network.
Protocol
--------
A node announcing itself has to do a JSON-formatted HTTP POST request to
one or more active nodes with the format explained below. N.B. The
strings shown in this document might not be valid, but they represent a
correct example.
* `type` reflects the type of the node
* `address` holds the address of the Tor hidden service
* `message` is the message that has to be signed using the private key
of this same hidden service.
* `signature` is the base64 encoded signature of the above message.
* `secret` is a string that is used for exchanging messages between the
client and server.
```
{
"type": "node",
"address": "22mobp7vrb7a4gt2.onion",
"message": "I am a DAM node!",
"signature": "BuB/Dv8E44CLzUX88K2Ab0lUNS9A0GSkHPtrFNNWZMihPMWN0ORhwMZBRnMJ8woPO3wSONBvEvaCXA2hvsVrUJTa+hnevQNyQXCRhdTVVuVXEpjyFzkMamxb6InrGqbsGGkEUqGMSr9aaQ85N02MMrM6T6JuyqSSssFg2xuO+P4=",
"secret": ""
}
```
Sending this as a POST request to a node will make it ask for the
public key of the given address from a "hidden service directory"
(HSDir) in the Tor network. It will retrieve the public key and try to
validate the signature that was made. Validating this, we assume that
the requester is in possession of the private key.
Following up, the node shall generate a cryptographically secure random
string and encrypt it using the before acquired public key. It will then
be encoded using base64 and sent back to the client:
```
{
"secret": "eP07xSZWlDdK4+AL0WUkIA3OnVTc3sEgu4MUqGr43TUXaJLfAILvWxKihPxytumBmdJ4LC45LsrdDuhmUSmZZMJxxiLmB4Gf3zoWa1DmStdc147VsGpexY05jaJUZlbmG0kkTFdPmdcKNbis5xfRn8Duo1e5bOPj41lIopwiil0="
}
```
The client will try to decode and decrypt this secret, and send it back
to the node to complete its part of the handshake. The POST request this
time will contain the following data:
* `type` reflects the type of the node
* `address` holds the address of the Tor hidden service
* `message` is the decrypted and base64 encoded secret that the server
had just sent us.
* `signature` is the base64 encoded signature of the above secret.
* `secret` is a copy of `message` here.
```
{
"type": "node",
"address": "22mobp7vrb7a4gt2.onion",
"message": "ZShhYHYsRGNLOTZ6YUwwP3ZXPnxhQiR9UFVWfmk5TG56TEtLb04vMms+OTIrLlQ7aS4rflR3V041RG5Je0tnYw==",
"signature": "L1N+VEi3T3aZaYksAy1+0UMoYn7B3Gapfk0dJzOUxUtUYVhj84TgfYeDnADNYrt5UK9hN/lCTIhsM6zPO7mSjQI43l3dKvMIikqQDwNey/XaokyPI4/oKrMoGQnu8E8UmHmI1pFvwdO5EQQaKbi90qWNj93KB/NlTwqD9Ir4blY=",
"secret": "ZShhYHYsRGNLOTZ6YUwwP3ZXPnxhQiR9UFVWfmk5TG56TEtLb04vMms+OTIrLlQ7aS4rflR3V041RG5Je0tnYw=="
}
```
The node will verify the received plain secret against what it has
encrypted to validate. If the comparison yields no errors, we assume
that the requester is actually in possession of the private key. If the
node is not valid in our database, we will complete the handshake by
welcoming the client into the network:
```
{
"secret": "Welcome to the DAM network!"
}
```
Further on, the node will append useful metadata to the struct. We will
add the encoded public key, timestamps of when the client was first seen
and last seen, and a field to indicate if the node is valid. The latter
is not to be handled by Tor DAM, but rather the upper layer, which
actually has consensus handling.
If the node is valid in another node's database, the remote node will
then propagate back all the valid nodes it knows (including itself) back
to the client in a gzipped and base64 encoded JSON struct. The client
will then handle this and update its own database accordingly.

View File

@ -1,125 +0,0 @@
#
# Build this image with the command
# docker build -f docker/build -t dyne/clojure:latest
#
# Then run with the command
# docker run -p 3000:3000 -it dyne/clojure:latest
#
FROM dyne/devuan:beowulf
ENV debian buster
LABEL maintainer="Denis Roio <jaromil@dyne.org>" \
homepage="https://github.com/decodeproject/decode-os"
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
# CLI arguments
ARG foreground=true
ENV DYNESDK=https://sdk.dyne.org:4443/job \
NETDATA_VERSION=1.10.0 \
STEM_VERSION=1.6.0 \
STEM_GIT=https://git.torproject.org/stem.git
ENV BUILD_DEPS="build-essential zlib1g-dev gcc make autoconf automake pkg-config uuid-dev golang"
WORKDIR /root
# # debugging travis (finds gpg in local builds)
RUN apt-get update \
&& apt-get --yes --force-yes install gnupg1 ca-certificates --no-install-recommends \
&& echo "ENVIRONMENT VARIABLES:" \
&& export
# Tor repository
ADD https://raw.githubusercontent.com/DECODEproject/decode-os/master/docker-sdk/tor.pub.asc tor.pub.asc
RUN apt-key add tor.pub.asc
RUN echo "deb https://deb.torproject.org/torproject.org $debian main" \
>> /etc/apt/sources.list
# Nodejs repository
ADD https://deb.nodesource.com/gpgkey/nodesource.gpg.key nodesource.gpg.key
RUN apt-key add nodesource.gpg.key
RUN echo "deb https://deb.nodesource.com/node_8.x $debian main" \
>> /etc/apt/sources.list
# && apt-get -yy update && apt-get -yy upgrade \
RUN mkdir -p /usr/share/man/man1/ \
&& apt-get update \
&& apt-get --yes --force-yes install tor deb.torproject.org-keyring \
supervisor daemontools \
tmux curl redis-tools redis-server net-tools \
python3 python3-stem nodejs
RUN apt-get --yes --force-yes install $BUILD_DEPS
# Latest Zenroom built static for x86-amd64 taken from our own builds at Dyne.org
ADD $DYNESDK/zenroom-static-amd64/lastSuccessfulBuild/artifact/src/zenroom-static /usr/bin/zenroom
RUN chmod +x /usr/bin/zenroom
# Compile some software from the source
WORKDIR /usr/src
# Stem built from source
# RUN git clone $STEM_GIT && cd stem && git checkout -b $STEM_VERSION $STEM_VERSION && python3 setup.py install
# Configure Tor Controlport auth
ENV TORDAM_GIT=github.com/decodeproject/tor-dam
RUN torpass=`echo "print(RNG.new():octet(16):base58())" | zenroom` \
&& go get -v -u $TORDAM_GIT/... && cd ~/go/src/github.com/decodeproject/tor-dam \
&& sed -i python/damhs.py -e "s/topkek/$torpass/" \
&& sed -i python/damauth.py -e "s/topkek/$torpass/" \
&& make install && make -C contrib install-init \
&& torpasshash=`HOME=/var/lib/tor setuidgid debian-tor tor --hash-password "$torpass"` \
&& sed -e 's/User tor/User debian-tor/' < contrib/torrc > /etc/tor/torrc \
&& sed -e 's/HashedControlPassword .*//' -i /etc/tor/torrc \
&& echo "HashedControlPassword $torpasshash" >> /etc/tor/torrc
RUN chmod -R go-rwx /etc/tor && chown -R debian-tor /etc/tor \
&& rm -rf /var/lib/tor/data && chown -R debian-tor /var/lib/tor \
&& mkdir -p /var/run/tor && chown -R debian-tor /var/run/tor
RUN cp /root/go/bin/dam* /usr/bin
# fix npm - not the latest version installed by apt-get
RUN npm install -g npm
RUN npm install -g redis-commander
ENV REDIS_HOSTS=localhost
# Netdata
ADD https://github.com/firehol/netdata/releases/download/v$NETDATA_VERSION/netdata-${NETDATA_VERSION}.tar.gz netdata.tgz
RUN tar xf netdata.tgz && cd netdata-$NETDATA_VERSION \
&& ./netdata-installer.sh --dont-wait --dont-start-it \
&& cd - && rm -rf netdata.tgz netdata-$NETDATA_VERSION
# Openresty
ADD https://openresty.org/package/pubkey.gpg openresty.gpg
RUN apt-key add openresty.gpg
RUN echo "deb http://openresty.org/package/debian stretch openresty" \
>> /etc/apt/sources.list
RUN apt-get update \
&& apt-get --yes --force-yes install --no-install-recommends openresty
# cleanup
RUN apt-get --yes --force-yes purge $BUILD_DEPS \
&& apt-get --yes --force-yes --purge autoremove && apt-get clean \
&& npm cache clean --force && npm uninstall -g npm
ADD https://raw.githubusercontent.com/DECODEproject/decode-os/master/docker-sdk/supervisord.conf \
/etc/supervisor/supervisord.conf
RUN sed -i "s/nodaemon=true/nodaemon=$foreground/" /etc/supervisor/supervisord.conf
RUN groupadd -g 6000 app && useradd -r -u 6000 -g app -d /home/app app
WORKDIR /home/app
RUN chown -R app:app /home/app
# Tor's socks5
EXPOSE 9150
# supervisor
EXPOSE 9001 9001
# redis-commander
EXPOSE 8081 8081
# netdata
EXPOSE 19999 19999
CMD bash -c '/etc/init.d/supervisor start'

View File

@ -1,37 +0,0 @@
# DECODE OS - Docker facility
[![Powered by DECODE OS](https://decodeos.dyne.org/img/decodeos_logo-800px.jpg)](https://decodeos.dyne.org)
The DECODE operating system is a brand new GNU+Linux distribution designed to run on servers, embedded computers and virtual machines to automatically connect micro-services to a private and anonymous peer-to-peer network cluster.
This is a Docker build of it to facilitate development and testing.
## DO NOT USE IN PRODUCTION
This Docker image is provided only for testing and showcase. We do release DECODE OS images for use in production on https://files.dyne.org/decode
In order to test DECODE OS in Docker is possible to get the latest image with:
```
docker pull dyne/decodeos:latest
```
And then run it with:
```
docker run -it -p 9150 -p 9001:9001 -p 8081:8081 -p 19999:19999 dyne/decodeos:latest
```
Then connect to the web interfaces to monitor the functioning of DECODE OS:
- http://localhost:9001 to supervise the daemons running and their logs
- http://localhost:8081 to access the list of nodes and their values
- http://localhost:19999 to monitor the resource usage
At last, you can use localhost port 9150 using Socks5 connections to be routed through Tor. Your application may then interact with the listed nodes.
## Build
To re-build this docker image:
```
docker build dyne/decodeos:local .
```

View File

@ -1,27 +0,0 @@
#!/bin/sh
#
# This script will run the keygen script for a requested amount of times.
# It takes an optional integer parameter - amount - for the amount of dockers.
# Otherwise it will default to 5.
usage() {
echo "$(basename $0) [number]"
exit 1
}
[ -z "$1" ] && AMOUNT=5
case "$1" in
*[!0-9]*)
usage
;;
*)
AMOUNT="$1"
;;
esac
rm -f onions.txt
for i in $(seq 1 $AMOUNT); do
./keygen
done

View File

@ -1,9 +0,0 @@
#!/bin/sh
#
# This script will start containers that were generated with create.sh
for i in $(cat onions.txt); do
onion="$(echo $i | cut -d':' -f2)"
container="$(docker run -d dyne/decodeos:$onion)"
echo "Started container $container for $onion"
done

View File

@ -1,12 +0,0 @@
#!/bin/sh
#
# This script will stop and delete the created containers and images.
containers="$(docker container ls | awk '/dyne\/decodeos:.*\.onion/ {print $1}')"
echo "$containers" | xargs docker stop
echo "$containers" | xargs docker rm
images="$(docker images | awk '/dyne\/decodeos:.*\.onion/ {print $3}')"
echo "$images" | xargs docker rmi

View File

@ -1,4 +0,0 @@
9001:9001
8081:8081
19999:19999
9150:9150

View File

@ -1,13 +0,0 @@
#!/bin/sh
container=$(docker create dyne/decodeos:latest)
container=$(docker start $container)
onion=$(docker exec $container dam-client -gen 2>&1| awk '/Our hostname/ {print $6}')
echo "New DECODE-OS node address: $onion"
image=$(docker commit $container dyne/decodeos:$onion)
echo "Docker image: dyne/decodeos:$onion"
echo "DIR:$onion" >> onions.txt
echo "$image"
container=$(docker stop $container)

View File

@ -1,12 +0,0 @@
#!/bin/sh
ports=""
exposed=$(cat exposed-ports);
for i in $exposed; do
ports="$ports -p $i"
done
echo "Starting DECODE OS Docker"
for p in $exposed; do
echo "port exposed: http://localhost:`echo $p | cut -d: -f2`"
done
docker run -it $ports dyne/decodeos:latest

View File

@ -1,54 +0,0 @@
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
nodaemon=true
; supervisor web GUI
[inet_http_server]
port=*:9001
; username=decode
; password=decode
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=http://127.0.0.1:9001
; username=decode
; password=decode
prompt=DECODE
[program:tor]
command=tor
[program:dam-dir]
command=dam-dir -t -ttl 10
redirect_stderr=true
stdout_logfile=/var/log/dam-dir.log
stderr_logfile=/var/log/dam-dir.err
[program:dam-client]
command=dam-client -ai 5 -dh https://dam.decodeproject.eu/testnet.txt
redirect_stderr=true
stdout_logfile=/var/log/dam-client.log
stderr_logfile=/var/log/dam-client.err
[program:redis-commander]
command=redis-commander
user=app
[program:netdata]
command=netdata -D
user=netdata
[group:network]
programs=tor,dam-dir,dam-client,redis-commander,netdata
priority=10
umask=022
autostart=true
startsecs=10

View File

@ -1,686 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
gWYe12v64S7MdlH4EeQdFlt+BPHE87omc4mGpSAv/eveL4zrT2kk6Yj8itgZ/4Dh
es1xKrVGD03VX2AA8oQ9NLjQMQLJoJo7vipKGJeo+KBt2u9S2VnHUPocd5/k4KTc
edYV5anb/INR5pBjOSiVt9WYMXz5qoDuiX1IlrnEWhhzYwNgHYp1PqRava5SGh1m
sRvscPrRTbXUw8Zps2o9qQrGFM/6kwDd9YkCGwQQAQIABgUCUVSNVAAKCRB+fTNc
Wi1ewX4xD/d0R2OHFLo42KJPsIc9Wz3AMO7mfpbCmSXcxoM+Cyd9/GT2qgAt9hgI
tv3iqg9dj+AbjPNUKfpGG4Q4D/x/tb018C3F4U1PLC/PQ2lYX0csvuv3Gp5MuNpC
uHS5bW4kLyOpRZh1JrqniL8K1Mp8cdBhMf6H+ZckQuXShGHwOhGyBMu3X7biXikS
vdgQmbDQMtaDbxuYZ+JGXF0uacPVnlAUwW1F55IIhmUHIV7t+poYo/8M0HJ/lB9y
5auamrJT4acsPWS+fYHAjfGfpSE7T7QWuiIKJ2EmpVa5hpGhzII9ahF0wtHTKkF7
d7RYV1p1UUA5nu8QFTope8fyERJDZg88ICt+TpXJ7+PJ9THcXgNI+papKy2wKHPf
ly6B+071BA4n0UX0tV7zqWk9axoN+nyUL97/k572kLTbxahrBEYXphdNeqqXHa/u
dWpTYaKwSGYmIohTSIqBZh7Xa/rhLsx2UfgR5B0WW34E8cTzuiZz////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////iQIcBBABAgAG
BQJLaRPhAAoJEMXpfCtjn2pmYaYP/j/TT5PPK6kZxLg1Qx6HZZAOYRtHdGIub5Ff
a8NO8o2LreO+GlHdxYyRajRKIlvunRWzcumKqmD4a1y7Z3yZeSwFCVMzANmki7W7
l/nKtfAwr+WZlOA1upGTloub1+0JEAk0yz9N1ZXA9xruh8qH7HgTIBOM6BF3ZmUm
Zj5zsoGpBS8wvcPg9V3ytoHGkyowCSXVvNGmOenlHsxQyi4TsPmMyCtf2Xnjk0uC
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
rDbp3JxYjJouxklxQ2J4jOXD1cehjZ+xFRfdnyUDV2o9FzvWCc3N04var7Wx8+0m
tok0N0xTkJunN8rkxvVUuh32zJlFlvZX4u61ZY4wI3hPz072AFBdqv+B645Hrk04
Hbu93iZ5ZgcICNZppyd6xZeBvqaEZXS+Zv92HCbxIBS9P7zB3sXmQT57jusVSUdQ
tfJwiQIcBBABAgAGBQJQezFyAAoJEFOcQ2uC5Av326UQALBzrx914us/lT+hEnfz
5aRDE7TwOhrt2ymPVzLvreRcaXOnbvG9eVz3FYwSQtl4UbprP6wjdi9bourU9ljN
BEuyOAwoM0MwMwHnFHeDrmVFbgop3SkKzn8JHGzaEM+Tq6WKHYTXY3/KrCBdOy1s
QPNeZoF7/rq4Z20CcrQaKdd0T7nAEy7TLQIXEnKCQKa2j+E55i584dIshxVWvNuw
sfeZ649f2FTGM3hEg527BZ4eLQhZQLHkjIY+0w0EB9f4AhViZfutakQf5uqV9oRl
gmHmQsN5vMKryC1G15HO9HPSMJf9mvtJm7U+ySNE354wt2Q2CwX1NdDLa8UUzlpG
gR6cd4PmAyVrykEWdtk/4ADic+tu4pTJVx92ssgiBAQoi/GMp61KPcxXU9O4flg0
HDYjerGuCau/5iUKWaLL9VBe3f//////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////iQIcBBABAgAGBQJRcGlBAAoJELlvIwCtEcvuoWwP
/ReLzhFKWlc/F35MvNyO1usz+qvs+SrlAtwaNcv3Dd9ih0mw+bH+U+PVVgXlk1g0
NY9hNNRLxt2mUc+mg9ttN+ha0RkqUYsYjg1Wj9bDuR0a+3DhtuS9hhEjWrBBT3Ub
TcWT5lxKkUgy4Sj+Dh0N78spHo2orUN3qRw3VkHY4hWcxAvlXreuEv6J7Ik4uZ+8
MMgJFld4oVhMmnWOrMwt10D58URvZsGypI+dK0p2JSue5yfBWkSMpFsJ8z2cCOBM
APQq9S63mhXZiORrxJS4pzJ87wcYG/H3R1pqF6I/49tWBlyZwiwOYs0fFEJc9idF
/hSzen/qDDQpvy4gNF48if7SGEtOBu1vEGqWKvNsataNcjYgj4BZhDlMHgAxWn0G
7VNRVsx1D6nzOzEAlFa/PQgQfCXScJXRV72uKoMk2uuOk8yb2+toOW5LoS/0Ubsn
Ui77VvknpZPbQPQ5svsGBCU1BQpDeFsQk4IMW5Flv1VVSEtxnfLi89An4HPMN92+
qNUDRM3E/eLkFnrPdiB3yMkjAgDbao5Gh+CTszQ118xkhmRC+pNCI75AS/X4V1Wr
cAJUniTbFgBRZr4t2tWfLMgx44XMtVrKraROj7QH4rEODSInBBEWT2hiJeWm4QS1
g5Rfoym4ur02xxqhwXAsCXFGFKZirXDoTMHDds6dI0QXiQIcBBABAgAGBQJR+DzB
AAoJECIs6MQ2RAKIjU4QAIi24KlFH1hL0d45GsQswFJ3YiokF62jpXRU2x7/+D+c
JUqA4omjaGkSn0Go+J2MG8/bQST/Eioev8/PtHpPVRWyOq1ACUueDFpvzXAmxEBA
25OkdDRWiy2y2CUSwu2n/OJBg6+C3TIRyoqzs2YiXIDr9TDi7NcXUP2Gd+xDWyEh
5zd3xilAZl/SNkW73gen2GnG0WRMjzvJ9SSqYVFGw2L0oaSyX+HI3ulAybWuYaHt
wREcgcKJpRK7VMeICERRzmGQxaUzbBtsWf1lhVUaCjINbKEOOfuqEqcRGsXl3AJw
/qYUaj3CE7hTiUpQ0kcDw7G0NvuYOFqBjTAZVOpr45vbOqCqKp4upNh2KLsGcGqz
By+RubsEsbOmIuDImyjFLpGHOZv54mJNLQ+SDbbLcj96EPZ5+gg7ip7+e6gGqGhJ
EOQLWeXejTk2rAX5zgkHutmjqY7qZIe63iXnlq88B66tZct2dYwv3M9t2X2Mkx3U
R1UxQZ8wJjmSYSS49HDfIZh5NIz58QH8AePltBk32yMxSFq0lndGKEyhE2omMyNY
zSt0EcXcsaaiqrphQ9iPJ8fCY29MOkKRQz9S3P/NOZFQrqL3zavfJX2+npx0umP9
7xPIowMPn0QZEWkTf2rvcG3s8s5jfUNOsi+ZcPazhjwqV6tX2OvbfK49CG3vTdcA
iQIcBBABAgAGBQJTChVdAAoJEA7aqUXopP+Xnn8QAITUo4Kkapocg1wurgpYjetG
yz9pI6PwtV27Q9xWWjLWRnZhlsHhSo1JhvNY9QBIKb2QQU+WGoBRtWPIxm0Atbhm
GBlKscRRMYfKB0U2pFE6HGDh7tWPzSzPWHKb3oobyB2bmgtBNsWGBxgcoQESC18u
ZnYJ2ffk6N5BhU7JnN5PD6TeKFokengr+BVkxwB0sVP5Zahc7lXNnj7mDTeths0Z
yxDTzog9AnImKlJR7Qu/uhhhz2mYnobS9tgzvyqRtibmxd7RLwlGOwf6/jUA3wmY
gvN1B17reB1GwylK9eRIem1OPG0t2UV/i6ik9BFMrwruoeTDd1POnA7+SDLXC2tU
bGwBK4PEKbD/IMe43dKQypaAYXQgWqwl3Lf3t9eCAfW0X/PRUdcSxA8WWpY6pFqT
6Eg1GicSnwarhvSWcs9I3FNo7foBcu3S6+wO6jK6/izOOymznuzGputQnVCZuVIL
3FF+QC95popTUjnTBRF6O1p2o5OfEOAJ2f76c3a/tZuPB5Z0WfivuQXzDDsEC7O7
SRkYMvCI8Vs/H6fijsOnKYtSvHRbm52R0zFWHPFCK36/tFaoUVrcPNbGyFYT2klL
177G+e6mJubz8nzPMLlWzP5utUYY8gM4UIaGr/mPudKmT2jFp/25oFKpxaiBrROs
XVv9+NQ01QYtxT5BueyoiQIcBBABAgAGBQJTgEpqAAoJEPEtmFdD7iYgp/AP/jMb
Tr4b6Vqyrbaq/SBAfN2SpcmqOWmQn5tiBRvG/FgV68v55dugKMiaB1Opw3zGgF3l
8xzdjFduMFH1iZBgv7kaooguZ7ttV84g6xGVE/9XjOughX4KchIRrpS8Qqba7Sr4
6vYrNmGhP6YMh9CmOG5ydg0H6MwXmiC9osKY/G71OyP8/K07ziE+iImS+oOsCrnn
wkxBEDLkwo3engbJMoCNLK+qpSuatwydtI6Gy7LaZOIBjEuf8I3mD4wkKU1SE6f6
w83pEMzDq6xC2Y6hLCz1kooamJA08WJ01u1npIrje873yY6Qw0WfE5Jsp0WR4gdh
bScL4S4m2Q9ZLW/2jWFbwz6tNHAfo3//nWZn2II6GDJfgfX7dU9W6pid+p52bAAu
ghh6hDjbH/eVF9BaWommIVtjjHAkpHWJ8V6vOKpojG+lyrrzi3YeTw44s14BsfxR
x/8TcSKzM+1jXNpeT27pIHohjvlRVdJtrw5MYUOqTGpVtH6GhoJSm62sM196CbB7
RkpEH0TojOenzQhsV+e+W4FVrb2QEQQqWB3TkmGLpiRt98FPltZO7fHJmMSaqe+W
OxTxrciP0FoyZJxYQM+NujQUTlMxmAdSw5AHAwhVIHmtreTEZKHplx984hSZiiKz
dsTUr7/AcndDcdY9KN2/p3Zf11y6nPlYsv4ToDXTiQIcBBABAgAGBQJTwUz5AAoJ
EHhUBU7O/hnkcfcP/3+Vv2CLClRCfpgPTLjoG31P425RxTLmx0HgH+ULaQI8D1Ym
rx6j+UUW5mkFNtx1HkF8ebezH+wi4PrROJ5UNdJ0pW4cgMZCHlPU2uh1d/THKQnV
OaBlqsDIyOAZem1sUtJfkYsOZTnUbbyS4CSYkf9HTfPfQ3TWePS0gEhj2zV4r4AP
MPKrfAfc761CWu33IY0SqYLwDWPQezd50pGJDJYnBWJixArgJQK7PCkD6hRslnXP
W/Vj8VqBptiNO5yZGAKn8UPUg5LeMeXTU21Qh9KQbQHAGOWxbpUFVnon3pVPms7J
brBA5I4U9Q3emBoiFgV+ARLQFcBehTBDOB3NHN+1nKaA0ZG7Q7HkpTH1ophpbC9q
67NvQvDgihlMXHwZRF+EwKBafo1IsgXwx8k/0Ju+6N+i8PlbnB98yTpxgo2rnj+9
V5HkfqGGV33s9Aio959mNM6gOrTwVZvL/DzfyyOXvdUl9nIWM6suazxO6wWRItj9
vUqDgq/byJ6X5R9rXyCioKhwe6ztU283hgpNAY7KkvTDyPpK+W8ru2sfY0IENUtT
6w3pHGVVkoqGox5dkcO9fv+Ok0eGOLJnperFcvGdd4V/mGLKH+TSKsn3fJPs+9MH
8XMKcp6NDbki3aff5vPDfj2+nhwLXG6WT9l9IPmAxeaw5QxmkNDWv/2zU4RFiQIc
BBABAgAGBQJT6qc3AAoJEDov2JR5p8TBfZEP/Rgw5Imwcis+iIVVIW7r3DyW+A9+
9JAI8muShU+Z1zliImIwanwNWn5RbcmY4sohQ9SDmnb8L7wMuCNYtXR/neys4J2q
n2pcHH/TIo629E0aVMRjLBU8Dok543ONx2BSAGuRPyXDciPzn54kNVXpAW5NI+Z5
SniEQRJ40o9YpPQHcjGXnNtUc7pB9r02JsIqk6WX1iSzAl3Ke14UySlWb4urmamv
omlufVYOtGdxeniN1lgbrJY/BCb2b/ZRr0gupv3EEEp/uU2TLBVuS7yGbNlf+9gZ
k8ZVl117HVALCnpQ11QxodQaGH8HuR/QEex4Y802DyzEsT1Fnzm8eZcqZB9QO8pj
crOTU3yCiB/7vwpeHymLkogrMirQaxQK6OUnEhYNOuj9Det7cJPwzeinerHaCNlu
mxKbB6gm0w1R8tjqHHkzcjp9rEoH1UDf91ugHCxevhR11Cz4ZSwFbkx6+sUr1HgK
4fCktKlkFcP8adDSncz8N2btbLmWYfBSKZK1z6GStIquwTLyLFrmxXSGrsiLaETX
F0S0VI4IuCggggDOn43oxqoISSaMJTPr//vhbL387wwXbK271wC7WVAQmslrZhIm
TzLbxjTvL2L1/NCSRBJXKalRV9HCzZgGaq+7LFwz0PQeciSK+ijqRrmQKIyxhDVj
cXm4OU6LrIFzoAzniQIcBBABAgAGBQJUOeCYAAoJENFZiZ/T2fiy0AcP/i7qIAAF
w6wqYgojDsqA7/YifGh9RGvrxmC4dWdrgLxW7dorUh0uw/JLn0JRrzKoS6EF3hHr
PQasmCPyz9ckZeRZjIhR5mKYtqrWsF3vpaL2VALXsb54KqAR8l4/iT083JTm1mvE
bMJ4JFVGNrGNVIWYdDgfQOKzD6lZtwRZTEjY5u+sJHS4VRvjAju82vlmEx8hmrcD
V2f+9St40pThNR9o1Rcna562NFldsccL7fFL9uM7kmFMGid5JwaRU4b/iXiSZ6Yc
tNQyfitkOWoHG0aKXvJM39WsJulHKCekSi4z4nNd5hZgMRFG2L4fzgcm6wNEh081
yhsVN4xHxURT1DrMg3Xtd3Zj4wBL5XFHySludRCd/PYPRpvfcCweJJ/OTroepfr3
DGw/Qo2VnZKe+Hu+4KpZnB5NrYIz5mMcysJMDCXiA9YdwRlF7EsP/ma8FdYpxyrR
61+GRY+ANUP1KMqautJj9qW7HtIbqaZUFAuhmD6uetcCraWD7EF7meaFJuozenO9
fBzBgcpJiJWKjNElJxpaPXiWPC+dQVvK0jpy12U1UNp38PBs18M9w2eOsC70tVhk
o53rCr1clL5Tdb133jNWo+jyWmKcYFKARziGQ3Q3GTE8ycRwebZeSgIHYLzm9zHG
ZQc9crpC0Mfoa09vcbBNyt5NRT6s/nOE4tjTiQIcBBABAgAGBQJUOiR+AAoJEJo0
q5orsokP9bYQALApojYAycnlIEF8GVnt0fbzSYLwGBxWuMMmzdiH3HHvTxsUBQ2K
vcBRrvSC1C8gOhpYdouI+RSXPXb6pkBHWJPFmGaPp0RKqgLMDi+wK7zZiPESMK8v
aYJS9RmLS2KzJMn30QYQ0VZfrJiw+K5ejSgdoFz3pOpcJCNlBmNjMocA6M+u6O1P
Db/OOqSPRqSlzZzu1S5HyDaOK32XXZj20G7ltwn5abtdk9KO8KWR2b3ZT6GMzxx3
L83lBL6hcg7a6NrYQKsXdUP/HEvt6pnVBBKTk6LzjRNAPp79a2w4muT0rMAfHdGz
Rhe77828KTlTllQXFBEKH6m23daQAHEw1ydB/9H+rG+S0ulP1V2Igza9agB9XASI
gRKLjwkDdMzOehf0oKt0U6P6kpytS3M025t9yVA2qUuG6A5DWwwfuRrY+dxUdbF5
ZoQYEJuXDLk7vVuh2ggJcnfGZ3fIHjtCwvdlMRQzDX2adpzoNy7uxZHz0QBbaSOe
FhGs2xE1/lLfpRaWw+ISXdp7b9HjB6dI6bSfYUP940Mi72d62HUHwbWNkaWe4afe
CAWbTuHWCe4jnPvTBF0t6mU4k+lwWo0uYYjJM2W4V0OGSflIdB8sgOxgmFzlB72T
IwwVBeLrCUEvymHqbTUedY4jUSWrL15sfDjxAhGJxZiHe4ydqxz6p29jiQIcBBAB
AgAGBQJUZxhJAAoJEM2XTJo5TWM/ICcQAI5555kQLg4N5+fmq1rN6AwjrI4lW13I
jX3H462PMvVWCHgJV86o+5/ab747czA0xbszW8vr/K0iayA6hfwRVtuEXfQl0Uh/
Taj4+fhI8cfW2+5EX4+lpGrOclVCsHHVfVZ/k8LL7mbjboJhG9xjSFf6JBtqr+/A
FsEIA+MYGFBaiLgL68j3CJuDPvjkwpC/Ofov5FRdPEOWQ9odC0z2yvDjAqxOkmDj
jZ04FJ5PBnNbo67AOUk25shqHuBzVH94MAP7Hrg7UaFeRQiMgNElf8qsTzukyzCF
PxJ4yyFpb56dDil8wxsvGcJlOEfT8sAi3YT2J2QoT7KAcES+aYgP1Q2Uj3gv0Mka
LNcDtPsQGksbxXoipq/Wygj2UwOQh9ZVtycjuv0D2LyfPMVTPVG66DYUpaverd5Q
B2nT2LZLxXhOH0tIqmFUaoIFrvrLn25A0Z5QFy/HbPfWAw7PJvgjl6AoxT3nKvoz
t0tUdZ2DfE3h4zjBXDiv3Y014FmhgqwEOgnCn89SR/7SHMJsMKp8oyn1mfzsncs+
gqcpOhvj2XfPEpnObDLqg98J6eyFGDfhEv1bNEOB4IcFF8YrUNEu6/rS+l7rNH7v
lw7hVWE0D1EnpZ8KYk8qPlOuHDHLMgemECUbR7Ogt63H3jqFfDAhlKBUY3hG5S7l
pWiLzcQccYZciQIcBBABAgAGBQJUa/DbAAoJEFyzYeVS+w0Q16QP/10IdfE8aurL
IfVMURxzr0CWHBwuAGV6mCKAriYRaEEjMWFThYsRtCS/CGtdc9BxXU5GwuHFcHFu
BCP425I9kxmxh/Rc+w8A/ZZAVU5A4gaSB0hkM5oZdB2QwYmXrECESdt0iHxcz9/z
yB1R4q2KryzbbkJNJJzbOrGpxG6vh6Dk4B9rFJeRYc7lVfH3TqiOHCljlHBdEw9i
QDGl6IFuQxUqOJNJK75p+4/f0eK64W1jXI2bGekTAQ3V1mA9xv6P+SR+NjPg4WQl
x6sTyksaxbkzOcchyx8zzm1DNH9wm4NsoZKME4n0sCIB7CdY7oBSFxJfyRp1JSPr
UwdNIX8kSsdgJpM7ORgZkojfWWCqt6unlgRsZmurFYigzZFWBAGReHIeHJ54eULp
g2QPKnwwWuwYHdEPp/bbuaLcPQcklPOGnnQynBpUvu3Ud/Fr7+4TMHmOI/e5EUUy
KbmK0pJLP36Lp3i28bHUTALF2mrDlx3+oMRjF5iSySC41KikBSBipRx0WO3jFzdS
6NLVdjNlxG9lpiHCkc7bHz9edMvuAnahK/EbS6hFUEkWQOJtJKc8B8hXJmChM2Yx
tEDVv0GngAAwcHZAvphFeuy9vYf2S5IbIqKMNrKgq4VQ+jTqHHXI57LkGHDCY2ig
DHQGo/StbI4s8Ow5btQMdXPnAO4rZ61FiQIcBBABAgAGBQJUcelGAAoJEJjdu04i
yiyDqF0QAJUdUtSUzHV3Vo36pbamTnCtyOqEp2X5L5wCjh+UAw9KGeZu7Jiiz7ue
QqxKQtz0miLnb2i3NeK9EWdoaKrM1+PIym7H40ATaurleKD9sq49b859tz5iy6DL
h1YPeeeuQV/NbjJyh06SzNkMjke6S34CcpDa1OoczVsI1RufWVMuq1C94+PZD0yC
CVLjMUD53c0AldgsFXdd2oEU/JPd7P9wCYSKV/+9F+wRa7/U77HRKNHd2FCshmJ1
mbhk3BFHTALFn9ld1/mqtjUTArt14wxs5GxsPkr1YsWQ1A8uVUtnW3rsn0UnP9bF
cAfn3/d382HhuyW+HOV4g5JhKVlG/hBbvdL+HV17Y+YksGeQW1sKIqmjvr7ArFhC
IUYo4+emyDEjQmTfuv8RRO1u4yR0iAZqlkk8/8z53ewE3HEfepwxuo6el/uuRuXf
QOmWfdNENjd9xn5gzIDbwqwvtZExjN2PolbiaSLP/3pI8prtrOYuW+Mk5o6iucce
azwdPyevOhoMuW5gZFffKo9w6TU5SRGcYIhrTJY8C7h2Yumsmir/XXpLaadcBp2R
4uDEoHb6eGlXqvSYMED/mu1fw2VOuKosddCpf/JkwXHwwB39z+dXo3HYSofyec1m
b3kcAsOUbTkAh86IWN1ymqcNTyytK8AEwOLHQ1f4o0ml7n9Xzf1HiQIcBBABAgAG
BQJUsRPJAAoJEBe/lIwEdhN9Z5MP/3Oo8Oc767lRFi1Oj5FVoHvRxfZvX3oKrG3j
phPlCBgKWK8xR7c5YECNIwnlQ8uCqUgxpFf8/iPV3xVuO1HFwDnafokTqyNtKz2X
gpmyfteV/02e32hsDNGfaDCkqbUC2hkuDfWWZa/g0tWfSCryZaI6OkoD8UHSiYeD
wVzLQXgGsR08iFP9xiHyQHNtCpy0HHeOutrjiWibADwEMZ6n9/1DSqTQkxnxBwIH
pGqK1M06QQT6ty2Bbm16gru0N6ulMr3Dc516PdOzQzqo0T7c2BzS4wOydYE7UGEe
RzuzA7Q57dVK+P0DLtqhiblJuyxBgMLxKICgEeR6ScjWQpHW19bCwfmbHIqHeeNC
ZCirF17KEtPqFCv5k5uzsqPvRv9yVwjo1/LF+k1iFgRez41AvGlNB+VrzziRK0Yv
dfS5wtQ1I/a9m2g+oyWPj6c3p57CrqxaSiGa+FOHOxUx+rQk2AdB8l4xtG3HNuiw
jEy75CbKsHwIBRd/9kRrGcilb16/osU/c/jr4QopKU9HKhb0DIclpY8B/ZMdYV3u
G+oy0aLlld10GJ4SHW0x1uB/rZU5zireTudOb+12qMfF6AyVV/tsAq4pELEVFD4I
NWxgh4EuzDAkJCvt6r7XfmojXTFR3vv9fHCc8vAVwRdbxK1NKn4BmMUVlSwZwLyy
1roeLveCiQIcBBABAgAGBQJW5/QxAAoJEPvqMRCoU3iU3SkP+wRdT8z3EczONAcv
Jsu7ZHgh1ggzsmozTciSuaAZRfvFmUyB9h63cKNTS86CIrqHmMZrtHRu9llkNNiE
4Nj8JAAsMPSR4YaKHfHxc3bOH0iWtcPxtIiQEwYs/7oP0/YzFAxcUmZBDeLvy7aK
pFqdPUcEhMTWmscVajjJXv+6G8IZwYGFAFvSkYSimZP102gmgKQhcfPDqmlqy78F
t+T5MfIha1Q950iZyAM3j46lVWMkBaKPQKq1G3kKaL7Sy3o75y4N7lgzY5WfYnBY
VAU8eUjv408FoFKAYFTsA3RG7P2VROoNefPaLRSgEgZPR6efVux9Z3R4zOUQuljv
q8r00zMS0t5RVcDp1gCNZQ9xv2QeN/ZDld0U0IbDQRrlT15+l3SthkXapMMvbSVK
EILMgaL+ysl7raMW/Zqv1KN2ByVJsPjWnwWCPnn0fMFWr15ExzfZBUNh2rZlQ56j
BsJanHF69Th0vI7JNm7/Gd5FRWL8RcXzAL/UbVDuyGaO2JPztQ2dL1lnHVL5mgOM
js90YpADenNR5XkQxuazTRiQIOXfoZhgPwe99S9vEdYM6UPYZjt8uo1bmFEkV0CG
jWngJc2ySSurftXPFJ7gzFhDbx70Ga/1lw/4H2RPs9ZiZKKTtiGcDLhDxSuX5z3M
gzzD3CNp7uKJQlTIg4aFeX9JWQvUiQIcBBABCAAGBQJX+0LWAAoJEAJ4If97HP7G
ahAQAMxf3Nyab2t+xJlFR+/ZCvqMq5rM8iq67ZK5fLG000RjLiBN5bd6BglAq03l
2DuE3b9hdnosKfU3FCeysivn0af0kxjMaH+W+9JSQJ9E5EjO+RgIJDkn3n6X/lQj
Vl3N7R6FeaWY6Ug9paSCtAlVlwCfg/rn2jFIiHQb++44nQFpaX4WuNzZWoy1SOGg
32e624fjsgqB0aH2cmY3oGdMFt8FGuzOfa89JGW8P7mUeZsiQQRxR4y+L7omQ60r
lveKZeEo/ZVfSZUVtzM9wplXpUMbF6/XtUC9dmsVrSZePrsAHnjjbbk0GBKit2Us
wC8fKdHVz9YiWKuM4QLEWiucYLkcWcHUFyp1Tk9ZeS3R3yPASC4eWV72IVGS0mjj
olcFwatMfYghQ42+sR+G6duEcJSN7sqrdzYxRny7aYz7GFXv1GCEiz/CzhepHDRO
pu9KZv6xetyP4xmaunanzzrd7kM23530jFRK53GJ/4p6XlwYA3jNsxaGoAADOTIw
qolgxtvdrNwEeX0pNpFI85BXSJrvBxKseL4o2NlxxvkyrLPIuuU6EfnOgMtu5v1j
gLkA3ON3eERxl7DM1I2bqFT2+Fpvsme6KFm1o4DepsO4wL9ZKmqUMZs6AxfmUopi
a93EtsZs801vNNUBmSsh3pvIyXGc/v3v2LJY236rsf0DmticiQIcBBABCAAGBQJb
HUVXAAoJEMIYUlgZ94RRdLEP/jpetLMM956YJJkBbzALzmXFux3Kl3z9+YA/kXgZ
C6NDNRItBnsxUlOFkBaTSvvq+18RGIDr5St3+cLjZnnOGoR0YY+KcAEzlOM0GMr1
18O6Bd+p61CqpA3oV0BErV3jmUe283OBw6q1+2HlDMAv1W1xpRhGb0UpBS2OvXQn
zAHS5hqkSwnB9os5Uitaud/k1kxvS/IklAidb3nsx6CQDvlx3BvxZ8WUWDz4uqrA
oOyr5xw2G9zVZgbaV8t7i5mHegoie1mQWjo1kVesZ16buKoeire08eIcbFYNBcQR
eTw6TzunHOJoSg4fSXPhj3g8PjJIuw3uSPbR1cV8DyRwtLXEogulnC2L+JHh2g7P
DenKmNtP2pZByQA7pM7CPDZAsS0IIeaCs2n2kF0I4m61Lntx17XXT7k5P5Jl9+L7
GwGWz7vxxtvsckpJV6LT8YphBWgPA/TYI1vBsHDVJdfaBWKVE+UspRJIAhDPIsJH
Nw4+Y+rbDzsaxXGc7QTspkWSRLfKAkBLcS/xJ7HPDWCu7NMV6p8pwhbzFQ54GyUP
bIkGhsMru6G6cRMOiB1pB5XNyMVWmSqHKSxaTfEEdoyS4giu1h2/WLZxLsJOKu1n
s1BsVmxNEOwX6OuBCq8JMuaIq7EOk/+Xs9TJbXDTQ0GvfnNMvTZorYYrySR3xCJ9
ju7riQIcBBABCgAGBQJTgEwEAAoJEBYg3FrGoH2curQQAKKAZDUbPFSAyRMFlr3T
FAYjzPgHz4+tdSgwFGaXjHb1b0Z9MJKBkqjoiTOo6ysTOzFeOVuql5tFv5lUR1oc
HJHtIX7kARvLrlaAMAVPsG+f9Ft7jNg2B0E3uokZHUOCXdvX8O5KNMFjiT8arYbi
w1hugAJrQ1KMKIv3EsT5Zf6AnwXIUN8eI4hUjZrJqmx1jjhKLam3SLuF8YMpAIAF
wFb/OutQoRUU7CQzVb6/1B5FCIYdSWEHv5tT6dguFyUC2pjxIf7Oxz4qntPk4HDJ
tr4sOBj46cNUsW7Xrr23wpvabCQWYcGQc4gK12bB9uyleIo52UoDqjqLddbhDDv2
6GuyJVu1mlJR6oW6EYtRLZLb8cp+9p+9vWtLbp4AeyX3NGtY5iyZkGZCj7aks1Dv
xpNdcdU2u3Qp4IBZyneVvVYaj+UMy/jrVX6uKYvKUEW6xHsR6g9DIGUFK8dexYdk
RHQ52ueT7W9cA6V8jzME8CE8YCtTJxw/IQM1mHbcHkrx1iNXz33Of2qBouqMf2vD
XyAvd/ilzca+dwOyoSGum2tnpD2MnCROrfo4eCeAOb4bZ46hEayzr6RNtmtUgnrT
mV0iIxDkxSzGXfjWWt11H2W9H5bgaPG8dEqKcxFLYPOnCLJfvmYn4hhy72MKqdI/
4/DlHHa13gBuL+2cm1pTLgltiQIcBBABCgAGBQJTgLe0AAoJELdhiDtEKL3AEToP
/3kV24dJyYCcqzWg2NWLHUACkeXCGOLmKSoVVV3oFzu1OnZ9KSdhpwU0M+b199GA
UM4Q4o6cIeTnqLd/plfWdNDmEtqw8T7hyGJWAHkf0n4c1nNgE3QFW4ri8zPeWPaJ
3+nDms7GpIbYcLjLLNCzSActo68pvaKrn6EQ5UOub97g500VjWlcS7qfXWlgMcKv
LVLUNHBgVSxTyghQDkQwhRl1IZB+LSM1p1qHgWYZdeMu7DXzK2m5htscHjcv+BlV
xRXCPFf6zh7ZIKnaZoWKiWAjp2zXy9VntYJ7DpbOmYukH7PWys9b26agMUa+iHyl
BPlyijC2dvEEu5+myqPBZk60T+OntrTp4PPXpX50TgylbabM0glxoHJBvPtgyOW5
QM4UMdn1WAX3ohW+9y55WyMWWPXWnrQl9sZ79QyKLmoPJE8u7pcOXBpBJ5NvLghR
/wRb04DPXjLrRvqE5V+mPpIYFFrGXD9wXhjWsgMIVC6oxGH55LIS2ZgLto1MJ7Hf
MEPWG6zkx/NIGss1Xxbd7ZOMvUFieY2l7zWWVDs1aAA3ydc6/tA2ekjvbRWjOkIb
A2ctmdGqo6CfqiqZsDhoqDs+xY6tJ0IkOek5TRAMGbN3GpO92n3IO5BLpZ8mzoi4
9uoDNiVlZlDLViWclETtmr9CfvavYXui4CtPbIsik4utiQIcBBABCgAGBQJTgSAw
AAoJEF1w0uvK0snmuUcP/1kWyfoAqIt1DFY+Od+vL5HY1IMKG62t9c3TTff7le+Q
tOG7fvu0IHFZHpsiiYumOvhSDBBo0Bfy3aDHF13ul+hcTfDzuGdvbDNoma+GO6cc
W0ZrFjD3eSVrUnO9nT12sTqrWl5+/GywcuH8htfA6pL60GgktympcMbi/lvTtFNW
1Dcfo423f9bYdEkN71+P1UfT594bbGUQclIugeCLHsGK/GIN9tAoBOpa6b98U28c
Hxs6eoWaTRu1fhAW9MCP4Juj7d4OvfPA7o9XIRrQzcKFicpmRi0VRe7zB4btbIMi
e8jhMrUm1mez13PSVB8LB3/bivxtDgqYBy+B9V2dNQjYE7+aT0g8JVmoXr8WdyfP
18wD9orWUowpBBj4R+RgpR/S8QfMlZJMfHIkAhSAYIwaAcJ4dboaNGAEtKsS7aeH
/6LUUGIUuUeTJmFSn0o7v0hD0PUGd6Z33/v5JR4f5esaZwZd38SSjj7lObtzdgkQ
L5sCd73gTLhZm511DjNasnlJpROqKeB9LQCUON463vX6QWLXHtD72gaG4G8SRIUU
Hjt7vd9UoVUwqoV2N5ZRhoDmg+LaUpnHz1zdbmVZrE6WHBDqxB1J3C09HQbV822E
JAW/CRDrN9Y0fhucWN3TFQ6ZG+UXUSWcJg7zxyUYB0tOMNULNvC+XrkiahmtxspW
iQIcBBABCgAGBQJTpLA5AAoJEHQ3f59qR5Gf128P/iBTk6pvJaqe+17zV3z1G3WV
yUtQOdMkVptBuMtHIykZZuBUQmTYXptQH+t+4da6pMFrxcsqu7JZAvelkz49y0zK
t0cYpKivG/87qCAER/x3E24FoMkVWlrsN5J3STT30SXSZyL+lVEKU5zuqgtK2wjs
tn2xT4TuhQOZ3CDSWxjWBjbqcl4PJOnhzSlRJL28kq0Zx8SukxVwTpJarIKSL2dP
ivy7TZrlSdPO7sdIKnaOPHnekVaF35/SfTCm/sfnaZcCobQZd4sJij+xgc/HDJJc
fsROhRUK9BvlBzcJDCohlz3FnOyKXjafmk7nVfcwqRMlhX2rsO0abQQKxxnVzoUG
SBf6SpRq3q1g2SRy7ABe2YnnCl+cq9acwmH7S0tzGGNLwdjEAHUA/1HdVq984kqx
2eUiSCJ1vxIuHR36cNQYdyplnxr0+bn9Yb/wghF6E++z8xkX6WxKT/oWV/GTqL+j
cH2efOOksR8MfjmTkncRsESbi1X/xAt6Fn9hv+qJUas7MSkKCkiOhAz7ZRxZMu2Q
d9Vh//i6hP7qs8aMNo+/pXlYwJYJYGuPo0oU/NhWm7yTM+MDrdBZDZ0EvP+t11R/
yMrHk+aFXqEqTaB+Uw/LaaHMWv+YDB8mfRUE0jbFipuWoSt55ElemSa18nnRcgBT
bFL+U8Nm2IGbDGeqToGniQIcBBABCgAGBQJVfZS1AAoJEFuCGoE7lKfEYBsP+gOU
OmmHg0c09v/iPkel7JJGcNnipk4z8xl5nTxXay4nTY6TKtelOhQUBqDHBqdOe8PN
WVutXqSDQKyzRPvXJRYgF2i3IUHq/GtCK2yPaGV7XnYfEvddXmjAlYS9LkHcYH7z
p7vLMW/8HgZ0JjeHAfmNF5+Q62rkDUMVBnSRVlA+1mc3/o1O5p/Kn1Tt47kCkLJU
MNyBxXl9BnbqJtFWKzoqgMovr2QEIZeUQzlJKygexnU4tCP5q5VefVqaVnEHkluX
Jq9knYK/G3c2Pet/GEDe5FkukzouQvcqGaujjvc/pmT7VISkeO4YXvmfctOpggJ9
J/ohxg4RgvqaRYdGoFgnNQMEnFLIxd5+8Sb48mskS59rVwwOllWsbR+6T/ZDW8FY
mpNzzuK7Af/JoOcWy7/j0fwOhJa4qX5aKgph5S/rE9pvhmhbkgZta5m8GQ9bHInQ
nbefud5axRtSyx4cG1ZB/mRLFD7+kkVfW/KrtdP/7PuuYtIP/nEhs9HnwOmcoRI1
WpDGERC6eUc+Dgc5sFD16tvp+2PW8/EBAWQK55b9jZ4Uws0D/3Tn8BE0CP1lJCZz
IzKqbO4+VhWNq0eJgwZWTUNoXQuFP1gOhJT+yqtxBRBP9YAOg+bO5kdjqS9Iinbb
YoaMkY8rUmqrF5r5XNob9mJzgF522npjWOx4P+7KiQIcBBABCgAGBQJZtcGvAAoJ
EGKrbC2pNmtMIVgP/0eNCkI5HX643HQs3G9xGg8OmyO0Kk5wv0T1BIAwPjA2tzz3
iNEmVMDac8/3qeKCfOyEhdJpqvZxRZ8BKoOkmnIvbwdxPBow8ixdWGLN3ZIeRJL/
c9/oxElQ35qyVmCVEkvSKFvpQAG5mvxq4usMRBeol/f7VSsKR7kqU40GamW1q8Ex
oLkAmnQAHfHx8dZmMBBG4tgVvSGwP0gpKBydEI6xtJXGexL6JumvHmmAAnImGQOL
+cfv8oaVp9vXRFwrUZsx5ObGXtV4xeGTr3nd+ZvCoocK6AHXcZiLF3XsnkoAUh7I
kTsFPMjQ9w3lb/E8MPjfLrIbw0WJYyNk4VoMePFYfWjGMU6zVRKwdurV1ndiSC4r
Zlapqfro78+u8pDoijNpzFsvmy4Y89w80N5l5qyMZ6PMOoZo+iH5hvxITXCtCJHs
0QaNzvu8PZSG5Gb4hVn+NcjHUfqulNxTIsyfISyvbdgQxEmFxSXeHPoMOhvaZn0n
iWL9JRAAXyM1urOhPG3mo5sqGPpQu1/DbbkA2oo02Uw/Ngh7MP7ujRhwsnC0BQOE
gshkeEzACJ3FwB/HbZ1bd0eMjhhcMPwT4lbFQFadcFEhBSd96g93xpeLIIVw9+O4
47MtA8GHHmng+TE7QWFXL/CUu+n8l7IQtlBSt1KMktSgWEqs6LSvsySDMIETiQIc
BBABCgAGBQJZ6mC5AAoJEKhbOua8Odf3rvIP/iiehjNNyKMkzELw7xLRXbQ7AXes
G+BKkVXBFZ4ertW6B1ovIkfDmM63Xv3xTQDCWjf/AewDSEF06k3TpV8P1a/Weu5E
SnigHah801dk3GoSNs0CWRSLmZEMwRnyCK968PlZUdIdEr80SCy0pijFtuI2h81G
bLZl5ic09jSXu2up+IxMb5w/cF7EeHNbyFtdn6WNnYCCWPM442eTpm1241+DCw17
MvuOyyUSH23bBc9VePe3VsBXS0aNAJhZVrAuY3UWFEdnVcwmN0QIO4qTqxApT1ja
MjvaP5O7TQ0O1X6nReJ4217Dlb/Vj3FzVZl2f/BLjlQae0kBD/2p8waX8R7KSIvz
aWJxtUWroOOgzlZgkzj1coD0PK0yysgM0KzoHEJFZcFz2Khde5SbbTz3iWE0KQgL
iBuT0MVxRWrJcWq1b4cFeCr6C10ppmiTWqMlkWFczhXWZu+83b1uMeV1iXZGC0ld
JTdscO8O4o9IXdhjr8BiLm7qsGuGJCtWZID8+5GlY+A09rDmwh2Kr5R/aBzQ+JPm
zbNYvVmqAvMbYnl1IDowxWv0w6kduvMfTbUB6UkM/zfsbl4PccxlPXO1yPsiFe+f
/HIJMcM0aFGqjxY3SmVtKcDXqy7w7Q3uTiy0u9MCqXCdpJRlDoMauM65Vcc/i3fR
/MZdqPWcHcL8zKjSiQIcBBIBAgAGBQJUyWhmAAoJEIHFzE+IMpocFMoP/RJWptx2
l2qaaJW1r5p1F1wSYHFgkUPWgS2mNwcgkFgGm0+QhPXiNAw7evt6aTMLMatewzq3
i34W9rIaNj1UNs7VFYEVzYzWrAGlBiMgkmvHpmMmNIoH5sOc6D8pzxagOalvHjHX
XabRCh6r8C6FX2jpQmwYVT/lF10ARGoQMW59MGFhUcEPfGVTFWgSEj5hgKvLhvDY
j3LqLreSsiKuVU7yU+K5kMY7q7wT+8jGt5zdoV/99OjbJOo/a7gmIDHGeuJnSuNR
RV3DltaRyk0N2FQcoB96q53++BdNXwDNTVA3eKVcrjpTXJcxMlpcmDvaF/KlIpct
EDIA50aTNlkLvRLMnPTlFMeoNyURSc38HO5c35chioH8zd+2Cs/QHGyI+JBlTZOO
odUB4alKB6SKHwMrWpy4+JfSxF+DUEW0VQwj/wXEpi+B3HKGYI0QNuzpEGZ1qvaq
0Vi7SqlcyKbZuvUGBz/RdKeAFiSjmOOQUbm2cebmFQzYNr8KWPt42knV+PQMet92
aaNVWhgPp7Z/OcvpUABQZBPchJvBRr+Qso+uqQvLRvlXGD+rRni1/NZxgnVh1cHN
7CiFIJOlE+bBozJ+xtDx5ZOAlH5qWJ/bm19zQDnufWxocqNv3ek8DuM2iyOmvpbi
1REi4ASbhDjMQDFmRNYx+3bIi80KJEnC2kZViQIcBBMBAgAGBQJWOIXXAAoJEE8/
UHhsQB3OlqIP/3lofZqqiV+uoiTdV91Tjmij9Rioz0kohpQsm/tau6JKXItjG7Da
G3XPL6NPckNGI+twD393Hdb/VkqatbpxLeJUQLoCjV3M02p6zDJHQ5wPiXgC/8HZ
VdcP2jlvnrkg4N5dpLJJK4wpZ/KXMsw/SrBj047ZnySIl5qw9ytXrQm58R7FBB/A
NjENvo9C3LEsaDAKv0TL4vyMpz52TjUfgoz68g31Sl6KKOw1HG+dUB69M7MARSVE
gaWUOm33eM12QQtCTndJQDg+LeYjfvfHbcnMZnniCZR7rHGxAhBzgKQqJU/JizfZ
4FDcBkABhsUQgkSeg3llFVzSU1iofT37A5cbQr0xUShPQwKgkESryuyL059neVsA
hDY/hFeyWCKtVQ12i3H7cvzRlfYxD8c/mN5TDiC70Cft1pcLU++u/6Ga1kuzA7rk
foUocrCSjqb9FwLBokWcwbi7SyA8YD5m7W8sPINx7reokK7mvDsbOxpBp/y/yT5Z
pTjK3/MNgESrq2N+Qg9EFC4Srlg8wzovn0zamzb2xDJpLfrV/t2DsFrVf2SWFd/Y
MjkljOLQhbsEpQIdrfS8/hNGgfoUIiko8lqNi50sGQ7kO9kirmjCZaAuOaOi8U0K
1C9RvVGTN3oGrxzRRXeqt2Z3bBqs5Lz5lrCNkerWZYXcItIyZ415i/FsiQIzBBAB
CgAdFiEExB/CGya6nZqq0a63ajVKIh777qgFAlrMzKYACgkQajVKIh777qjRPA/+
NV/GvceePkKjxHKsUsFP5r9acmMBWtgyDddv3me3rN2wTR1inUji/ezPxrXOBlKx
UC+6CK1Au3wuQsENRy2vqYrtWS/yc31chzuA4YolpFjy8BlRluobZJOoT9TYeVnE
cZYhBMKV0HpoEXSgb+uca+dnIaFSgMXi/qXYfM0g1IOLcR+wAW+ptBzY0KSpxkqn
qcmrwJPiMbtwExDcY0cAjHdl35MMSFe12KZdST4ZGScaXpzvB95JPeiC6kqPXaa6
1bgUJteG2n85CZ0O9eSZXt2QSyaQapl8PLkI2cm7C7m12q7OqE2vrOIADnS2KTZh
I7Jh6pJZbvuYvxoc0u1aofmV0IeYcWmE5fT0Hjf8Aw+K3l7DEBAQs/EXyxZ6JUom
TJEQRM8lS7iYwPtuF0Q6c6H5HsmpJ8+zInyeqf4iwdmtu1YWohT8sIjYNHzWSraQ
SXevJ0B+SvERjsZU3RonFbodQBtEJNS/LZ9JM6ROR/XCXFwrXF/X72SN6twZjsMh
uKEv+KwJNyhsOU5uM4TVf+1aFmUeMSBIFfFOjtCeyJ6bmeqpBhme6gFoxgS326pS
JvLf8H76l4CeZACzxStXnoDb/RFucIH/8GLtH/dCzlbv9Atd813+o4Sr9WLD2O/O
agNXDgMiQu3j++RXB1VfMXVnrGy4BwFdvkueR5d85Q+JBBwEEAEIAAYFAlgGbPAA
CgkQemOAneUSdiLOth/+LNI/VXkol7A+9Z3qdIdyqMA3zYqAq1RoV1Szxk5uqvVw
uW7NziOBXr7hgx3JI3m+UlaLovFLCwWfZj4E0eRGmGs4ji82V6+1nczLBXjoETFf
WsNKPOi9VHvi4M5/CBenei8JrVwhlVO6IlQobO4ik09EnB9EzujqqoVpMMARQtgn
3Mo3YxhsgTUCC/A7iO8bQC02wFTyrIbjmhpmICJDdr+kd+18qDgJPZh31m9rYVwF
gaEQU8bQtKgf/5uKX1CohbqF6HJNIsNkbIFWl0A0EK8B/mPPaBYLV5bbSCwhINWo
3NC2pZMhltTQP6ubI1a97nRj9u+stg/WD/VlICgxIUhx3iawGvjIV49fPM1b9xwx
caxosg21OrVpjCcYFoMQUgsDzwsMZz1L+F/Ut2R/KD3ShXE+yFu+h9ZVIFx+tzd9
Tt6f8ApHbw9McAL2jldouJgPqfZoK+yl3PzdDgJSvF4QsINBGZmicNwzEvBgaxj5
PubBby6FBhMrsd5oHn5S7yAaA8wGlZklehyLhN4C7/sZmisIGatfVJJYPP0h0Nfb
tfZ90o28aapZqwCA5R2vXg/oBre5pF9+D95KpdRXHZlITfeIgN4bT5uhfucw2CRy
jWDUfLRkh+n4gpRiub5Wq8lqcrFP98v4tmyNlgufPe9QZNA1wSI2+/WlN4VNZXjf
54O0AWdStM6EbZrakSBB/riY6mv4Mzch1aEVF0wNJSmSw1pWr1TEDGvUd1qDp4KB
qaX53S0eONpykGHnpY5qfm51QowLlqmNQP4EhtmDq2tiFTvIR85MJyUaE+BDIDOr
mpi7w9xODXL74Tx4FGcL3SqPwB7jdUEb5ZqACZVwTsb0pERTuXyN1S1vWxjz8wk5
k3YUE/eLaXxIvgSbUkxB3/kd9CYhn259HivpfuT2r6SieQe9wUOQdQ9LybKjKLfb
5H77I58eq9yR3KbqhQcdfxV99P/1x89nWkv9Z/hES23rlsGK1oMDRiJyD/Tk8otA
8Wffa2nkNwzLVPRm+TJd9JplA2u/RPO/79Cfqa2RU3Qwf0GSU4qARLR8REJ2KS6N
sg80j3s2Nj0OHp6k+QBPMo2Fi8Dde29SJNB99x7Gf+/QdtO/QtU8jV5a+jVO9ZnY
5usRpYg9h6UOUlHwxtWL7Aw48oMy2nVMvDGFGcx72EWoTXp9NX+i0Pz235Gxf3C4
b498vQMR/COA2c0JcwiYK1FFKSDFOV4aFp9UXWeP1pyZh27iDDCO+ZX0Arrbt7y9
rhwXEEd2O2FtIyGINa7QdHDJLcv75KX/obtffzijp8DGS78uIVt+EnlyEdcrDn0d
+XSTM8HMJW/yjNaeV9n4/jIHrMMpWefft1tue5TFDrkBDQRKoO2QAQgA2uKxSRSK
pd2JO1ODUDuxppYacY1JkemxDUEHG31cqCVTuFz4alNyl4I+8pmtX2i+YH7W9ew7
uGgjRzPEjTOm8/Zz2ue+eQeroveuo0hyFa9Y3CxhNMCE3EH4AufdofuCmnUf/W7T
zyIvzecrwFPlyZhqWnmxEqu8FaR+jXK9Jsx2Zby/EihNoCwQOWtdv3I4Oi5KBbgl
xfxE7PmYgo9DYqTmHxmsnPiUE4FYZG263Ll1ZqkbwW77nwDEl1uh+tjbOu+Y1cKw
ecWbyVIuY1eKOnzVC88ldVSKxzKOGu37My4z65GTByMQfMBnoZ+FZFGYiCiThj+c
8i93DIRzYeOsjQARAQABiF4EEBYIAAYFAlpeZjsACgkQG7icBgI2dEl5UQD+Lepk
okCazIBkNFnZraHcCESgXDW5f8f+dpOxZVo5Z0sA/1FkP70D6Mw5HbRuebIZJ6Ma
56I7+Hjg2pVSs+vJ050HiQJbBBgBAgAmAhsCFiEEo8Tw+XnKoizbqPUS7oy8noht
3YkFAltn6kUFCRUaaLUBKcBdIAQZAQIABgUCSqDtkAAKCRB0qUG6IZ7IELQRB/kB
/8bT/bHPRDAfnw3oLH9mgxy09vGKb4X4y1la2Jl0YnsbXAUYgsC0+pIbpYQNr5OE
54dtnW4a/O4VLbgiWRkeWOBNmUvfSnwMV3LvelqOiotF+uuRv0MlMaBWE/ZrGGc5
b9Dpm7iGhA9KfZUZU5Wa7AxvevWv3d9BvDRtDL+gh/0n6ratunj9yE6h13tcxb3l
UzCJYgR2lhoPSah4rv5ptjMFMbkAMy5mgrZmuS15Bk1B7FK7iHR6ZZ6suwx29wwv
JiI51Y/Xbz6zV7+eJscYU8B5E+RD4xU8xmWuqBWr2Lfhc8D0eu3FUF38+44ehpLX
Ksa4AOylJlMLmifg8xpCCRDujLyeiG3diclXB/9/opjmKSgD2OzYwy7MG466iinA
/Ei+baz3fvNdUk9N1Pfz0Y6EbGGahkPXjIOCjekcdJQ4qU5XQu2H6nQT+GInX3bC
f+jAxDlbs1B3sFsB62gVaDCOvGBu3Q90TANP8QKp+ULAxMmR5XSxGY6v6lwiQJKq
htrYfYZ2BZZrL6OOr1u/PoyND+jFv6gMYieXgLzX9L09aT+DGoDj0/DWes2EyTXk
DxN5IkjfcBTBGHKCeUsMnzh0Kka2cvelwwQhdxewX64HDdIfiEOM/QUmvMgcXFnw
yYroYDvyrNiRrKzwQITpElG3acbG9vzMwEoG4jdNMLBrBHo1R8b1+/4jhN6z
=Rej8
-----END PGP PUBLIC KEY BLOCK-----

@ -1 +1 @@
Subproject commit aff7daadab16657b69ade1a01315389f25bb032d
Subproject commit dd708cfcfeda609c0b33fc61882a9b7deff3f6dd

2
vm-sdk

@ -1 +1 @@
Subproject commit 742bd8318604acf2ebf45594eda053c3ea78e9f6
Subproject commit 2826c9255813b56a0f7cb0b43d4dca5fd6914ef3