From 1e7300b56e5d8d22527d860f3f4a5a5635426a43 Mon Sep 17 00:00:00 2001
From: meow <ahmedbilal96@gmail.com>
Date: Tue, 3 Dec 2019 15:40:41 +0500
Subject: [PATCH] Efforts to make ucloud a python package

---
 .gitignore                                    |   6 +-
 Pipfile                                       |  26 -
 Pipfile.lock                                  | 936 ------------------
 README.md                                     |   9 +
 ucloud.py => bin/ucloud                       |  16 +-
 scheduler/tests/__init__.py                   |   0
 setup.py                                      |  35 +
 __init__.py => ucloud/__init__.py             |   0
 {api => ucloud/api}/README.md                 |   0
 {api => ucloud/api}/__init__.py               |   0
 {api => ucloud/api}/common_fields.py          |   2 +-
 {api => ucloud/api}/create_image_store.py     |   2 +-
 {api => ucloud/api}/helper.py                 |  12 +-
 {api => ucloud/api}/main.py                   |  14 +-
 {api => ucloud/api}/schemas.py                |   6 +-
 {filescanner => ucloud/common}/__init__.py    |   0
 {common => ucloud/common}/classes.py          |   0
 {common => ucloud/common}/counters.py         |   0
 {common => ucloud/common}/helpers.py          |   0
 {common => ucloud/common}/host.py             |   0
 {common => ucloud/common}/request.py          |   0
 {common => ucloud/common}/storage_handlers.py |   2 +-
 {common => ucloud/common}/vm.py               |   0
 config.py => ucloud/config.py                 |   8 +-
 {docs => ucloud/docs}/Makefile                |   0
 {common => ucloud/docs}/__init__.py           |   0
 {docs => ucloud/docs/source}/__init__.py      |   0
 {docs => ucloud/docs}/source/conf.py          |   0
 .../docs}/source/diagram-code/ucloud          |   0
 .../docs}/source/images/ucloud.svg            |   0
 {docs => ucloud/docs}/source/index.rst        |   0
 .../source/introduction/installation.rst      | 136 ++-
 .../source/introduction/introduction.rst      |   5 +-
 {docs => ucloud/docs}/source/misc/todo.rst    |   0
 .../docs}/source/theory/summary.rst           |   4 +-
 .../installation-troubleshooting.rst          |   0
 .../how-to-create-an-os-image-for-ucloud.rst  |   0
 .../docs}/source/usage/usage-for-admins.rst   |   4 +-
 .../docs}/source/usage/usage-for-users.rst    |   8 +-
 {host => ucloud/filescanner}/__init__.py      |   0
 {filescanner => ucloud/filescanner}/main.py   |   4 +-
 {hack => ucloud/hack}/README.org              |   0
 {hack => ucloud/hack}/conf.d/ucloud-host      |   0
 {hack => ucloud/hack}/nftables.conf           |   0
 {hack => ucloud/hack}/rc-scripts/ucloud-api   |   0
 {hack => ucloud/hack}/rc-scripts/ucloud-host  |   0
 ucloud/hack/rc-scripts/ucloud-metadata        |   8 +
 .../hack}/rc-scripts/ucloud-scheduler         |   0
 {imagescanner => ucloud/host}/__init__.py     |   0
 {host => ucloud/host}/helper.py               |   0
 {host => ucloud/host}/main.py                 |   4 +-
 {host => ucloud/host}/qmp/__init__.py         |   0
 {host => ucloud/host}/qmp/qmp.py              |   0
 {host => ucloud/host}/virtualmachine.py       |   8 +-
 ucloud/imagescanner/__init__.py               |   3 +
 {imagescanner => ucloud/imagescanner}/main.py |   4 +-
 {docs/source => ucloud/metadata}/__init__.py  |   0
 {metadata => ucloud/metadata}/main.py         |   2 +-
 {network => ucloud/network}/README            |   0
 {metadata => ucloud/network}/__init__.py      |   0
 {network => ucloud/network}/create-bridge.sh  |   0
 {network => ucloud/network}/create-tap.sh     |   0
 {network => ucloud/network}/create-vxlan.sh   |   0
 .../network}/radvd-template.conf              |   0
 sanity_checks.py => ucloud/sanity_checks.py   |   2 +-
 {scheduler => ucloud/scheduler}/__init__.py   |   0
 {scheduler => ucloud/scheduler}/helper.py     |   8 +-
 {scheduler => ucloud/scheduler}/main.py       |   8 +-
 .../scheduler/tests}/__init__.py              |   0
 .../scheduler}/tests/test_basics.py           |   2 +-
 .../tests/test_dead_host_mechanism.py         |   0
 71 files changed, 241 insertions(+), 1043 deletions(-)
 delete mode 100644 Pipfile
 delete mode 100644 Pipfile.lock
 create mode 100644 README.md
 rename ucloud.py => bin/ucloud (79%)
 delete mode 100644 scheduler/tests/__init__.py
 create mode 100644 setup.py
 rename __init__.py => ucloud/__init__.py (100%)
 rename {api => ucloud/api}/README.md (100%)
 rename {api => ucloud/api}/__init__.py (100%)
 rename {api => ucloud/api}/common_fields.py (96%)
 rename {api => ucloud/api}/create_image_store.py (87%)
 rename {api => ucloud/api}/helper.py (94%)
 rename {api => ucloud/api}/main.py (97%)
 rename {api => ucloud/api}/schemas.py (99%)
 rename {filescanner => ucloud/common}/__init__.py (100%)
 rename {common => ucloud/common}/classes.py (100%)
 rename {common => ucloud/common}/counters.py (100%)
 rename {common => ucloud/common}/helpers.py (100%)
 rename {common => ucloud/common}/host.py (100%)
 rename {common => ucloud/common}/request.py (100%)
 rename {common => ucloud/common}/storage_handlers.py (99%)
 rename {common => ucloud/common}/vm.py (100%)
 rename config.py => ucloud/config.py (83%)
 rename {docs => ucloud/docs}/Makefile (100%)
 rename {common => ucloud/docs}/__init__.py (100%)
 rename {docs => ucloud/docs/source}/__init__.py (100%)
 rename {docs => ucloud/docs}/source/conf.py (100%)
 rename {docs => ucloud/docs}/source/diagram-code/ucloud (100%)
 rename {docs => ucloud/docs}/source/images/ucloud.svg (100%)
 rename {docs => ucloud/docs}/source/index.rst (100%)
 rename {docs => ucloud/docs}/source/introduction/installation.rst (55%)
 rename {docs => ucloud/docs}/source/introduction/introduction.rst (91%)
 rename {docs => ucloud/docs}/source/misc/todo.rst (100%)
 rename {docs => ucloud/docs}/source/theory/summary.rst (98%)
 rename {docs => ucloud/docs}/source/troubleshooting/installation-troubleshooting.rst (100%)
 rename {docs => ucloud/docs}/source/usage/how-to-create-an-os-image-for-ucloud.rst (100%)
 rename {docs => ucloud/docs}/source/usage/usage-for-admins.rst (96%)
 rename {docs => ucloud/docs}/source/usage/usage-for-users.rst (92%)
 rename {host => ucloud/filescanner}/__init__.py (100%)
 rename {filescanner => ucloud/filescanner}/main.py (97%)
 rename {hack => ucloud/hack}/README.org (100%)
 rename {hack => ucloud/hack}/conf.d/ucloud-host (100%)
 rename {hack => ucloud/hack}/nftables.conf (100%)
 rename {hack => ucloud/hack}/rc-scripts/ucloud-api (100%)
 rename {hack => ucloud/hack}/rc-scripts/ucloud-host (100%)
 create mode 100644 ucloud/hack/rc-scripts/ucloud-metadata
 rename {hack => ucloud/hack}/rc-scripts/ucloud-scheduler (100%)
 rename {imagescanner => ucloud/host}/__init__.py (100%)
 rename {host => ucloud/host}/helper.py (100%)
 rename {host => ucloud/host}/main.py (98%)
 rename {host => ucloud/host}/qmp/__init__.py (100%)
 rename {host => ucloud/host}/qmp/qmp.py (100%)
 rename {host => ucloud/host}/virtualmachine.py (97%)
 create mode 100644 ucloud/imagescanner/__init__.py
 rename {imagescanner => ucloud/imagescanner}/main.py (96%)
 rename {docs/source => ucloud/metadata}/__init__.py (100%)
 rename {metadata => ucloud/metadata}/main.py (98%)
 rename {network => ucloud/network}/README (100%)
 rename {metadata => ucloud/network}/__init__.py (100%)
 rename {network => ucloud/network}/create-bridge.sh (100%)
 rename {network => ucloud/network}/create-tap.sh (100%)
 rename {network => ucloud/network}/create-vxlan.sh (100%)
 rename {network => ucloud/network}/radvd-template.conf (100%)
 rename sanity_checks.py => ucloud/sanity_checks.py (96%)
 rename {scheduler => ucloud/scheduler}/__init__.py (100%)
 rename {scheduler => ucloud/scheduler}/helper.py (94%)
 rename {scheduler => ucloud/scheduler}/main.py (95%)
 rename {network => ucloud/scheduler/tests}/__init__.py (100%)
 rename {scheduler => ucloud/scheduler}/tests/test_basics.py (99%)
 rename {scheduler => ucloud/scheduler}/tests/test_dead_host_mechanism.py (100%)

diff --git a/.gitignore b/.gitignore
index 55adfaf..8cd5f99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,7 @@
 
 __pycache__
 
-docs/build
-logs.txt
\ No newline at end of file
+ucloud/docs/build
+logs.txt
+
+ucloud.egg-info
\ No newline at end of file
diff --git a/Pipfile b/Pipfile
deleted file mode 100644
index 63c2610..0000000
--- a/Pipfile
+++ /dev/null
@@ -1,26 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-prospector = {extras = ["with_everything"],version = "*"}
-pylama = "*"
-
-[packages]
-python-decouple = "*"
-requests = "*"
-flask = "*"
-flask-restful = "*"
-bitmath = "*"
-etcd3-wrapper = {editable = true,git = "git+https://code.ungleich.ch/ungleich-public/etcd3_wrapper.git",ref = "wip"}
-python-etcd3 = {editable = true,git = "git+https://github.com/kragniz/python-etcd3.git"}
-pyotp = "*"
-sshtunnel = "*"
-helper = "*"
-sphinx = "*"
-pynetbox = "*"
-sphinx-rtd-theme = "*"
-
-[requires]
-python_version = "3.5"
diff --git a/Pipfile.lock b/Pipfile.lock
deleted file mode 100644
index 5853a4b..0000000
--- a/Pipfile.lock
+++ /dev/null
@@ -1,936 +0,0 @@
-{
-    "_meta": {
-        "hash": {
-            "sha256": "7f5bc76f02cef7e98fa631f1954b2b7afa46a7796650386b91c9a6c591945f75"
-        },
-        "pipfile-spec": 6,
-        "requires": {
-            "python_version": "3.5"
-        },
-        "sources": [
-            {
-                "name": "pypi",
-                "url": "https://pypi.org/simple",
-                "verify_ssl": true
-            }
-        ]
-    },
-    "default": {
-        "alabaster": {
-            "hashes": [
-                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
-                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
-            ],
-            "version": "==0.7.12"
-        },
-        "aniso8601": {
-            "hashes": [
-                "sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072",
-                "sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a"
-            ],
-            "version": "==8.0.0"
-        },
-        "babel": {
-            "hashes": [
-                "sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab",
-                "sha256:e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"
-            ],
-            "version": "==2.7.0"
-        },
-        "bcrypt": {
-            "hashes": [
-                "sha256:0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89",
-                "sha256:0b0069c752ec14172c5f78208f1863d7ad6755a6fae6fe76ec2c80d13be41e42",
-                "sha256:19a4b72a6ae5bb467fea018b825f0a7d917789bcfe893e53f15c92805d187294",
-                "sha256:5432dd7b34107ae8ed6c10a71b4397f1c853bd39a4d6ffa7e35f40584cffd161",
-                "sha256:6305557019906466fc42dbc53b46da004e72fd7a551c044a827e572c82191752",
-                "sha256:69361315039878c0680be456640f8705d76cb4a3a3fe1e057e0f261b74be4b31",
-                "sha256:6fe49a60b25b584e2f4ef175b29d3a83ba63b3a4df1b4c0605b826668d1b6be5",
-                "sha256:74a015102e877d0ccd02cdeaa18b32aa7273746914a6c5d0456dd442cb65b99c",
-                "sha256:763669a367869786bb4c8fcf731f4175775a5b43f070f50f46f0b59da45375d0",
-                "sha256:8b10acde4e1919d6015e1df86d4c217d3b5b01bb7744c36113ea43d529e1c3de",
-                "sha256:9fe92406c857409b70a38729dbdf6578caf9228de0aef5bc44f859ffe971a39e",
-                "sha256:a190f2a5dbbdbff4b74e3103cef44344bc30e61255beb27310e2aec407766052",
-                "sha256:a595c12c618119255c90deb4b046e1ca3bcfad64667c43d1166f2b04bc72db09",
-                "sha256:c9457fa5c121e94a58d6505cadca8bed1c64444b83b3204928a866ca2e599105",
-                "sha256:cb93f6b2ab0f6853550b74e051d297c27a638719753eb9ff66d1e4072be67133",
-                "sha256:ce4e4f0deb51d38b1611a27f330426154f2980e66582dc5f438aad38b5f24fc1",
-                "sha256:d7bdc26475679dd073ba0ed2766445bb5b20ca4793ca0db32b399dccc6bc84b7",
-                "sha256:ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc"
-            ],
-            "version": "==3.1.7"
-        },
-        "bitmath": {
-            "hashes": [
-                "sha256:293325f01e65defe966853111df11d39215eb705a967cb115851da8c4cfa3eb8"
-            ],
-            "index": "pypi",
-            "version": "==1.3.3.1"
-        },
-        "certifi": {
-            "hashes": [
-                "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
-                "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
-            ],
-            "version": "==2019.9.11"
-        },
-        "cffi": {
-            "hashes": [
-                "sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42",
-                "sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04",
-                "sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5",
-                "sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54",
-                "sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba",
-                "sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57",
-                "sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396",
-                "sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12",
-                "sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97",
-                "sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43",
-                "sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db",
-                "sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3",
-                "sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b",
-                "sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579",
-                "sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346",
-                "sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159",
-                "sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652",
-                "sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e",
-                "sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a",
-                "sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506",
-                "sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f",
-                "sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d",
-                "sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c",
-                "sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20",
-                "sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858",
-                "sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc",
-                "sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a",
-                "sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3",
-                "sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e",
-                "sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410",
-                "sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25",
-                "sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b",
-                "sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d"
-            ],
-            "version": "==1.13.2"
-        },
-        "chardet": {
-            "hashes": [
-                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
-                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
-            ],
-            "version": "==3.0.4"
-        },
-        "click": {
-            "hashes": [
-                "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
-                "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
-            ],
-            "version": "==7.0"
-        },
-        "cryptography": {
-            "hashes": [
-                "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c",
-                "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595",
-                "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad",
-                "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651",
-                "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2",
-                "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff",
-                "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d",
-                "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42",
-                "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d",
-                "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e",
-                "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912",
-                "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793",
-                "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13",
-                "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7",
-                "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0",
-                "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879",
-                "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f",
-                "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9",
-                "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2",
-                "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf",
-                "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"
-            ],
-            "version": "==2.8"
-        },
-        "docutils": {
-            "hashes": [
-                "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0",
-                "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827",
-                "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99"
-            ],
-            "version": "==0.15.2"
-        },
-        "etcd3-wrapper": {
-            "editable": true,
-            "git": "https://code.ungleich.ch/ungleich-public/etcd3_wrapper.git",
-            "ref": "76fb0bdf797199e9ea161dad1d004eea9b4520f8"
-        },
-        "flask": {
-            "hashes": [
-                "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52",
-                "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6"
-            ],
-            "index": "pypi",
-            "version": "==1.1.1"
-        },
-        "flask-restful": {
-            "hashes": [
-                "sha256:ecd620c5cc29f663627f99e04f17d1f16d095c83dc1d618426e2ad68b03092f8",
-                "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9"
-            ],
-            "index": "pypi",
-            "version": "==0.3.7"
-        },
-        "grpcio": {
-            "hashes": [
-                "sha256:0419ae5a45f49c7c40d9ae77ae4de9442431b7822851dfbbe56ee0eacb5e5654",
-                "sha256:1e8631eeee0fb0b4230aeb135e4890035f6ef9159c2a3555fa184468e325691a",
-                "sha256:24db2fa5438f3815a4edb7a189035051760ca6aa2b0b70a6a948b28bfc63c76b",
-                "sha256:2adb1cdb7d33e91069517b41249622710a94a1faece1fed31cd36904e4201cde",
-                "sha256:2cd51f35692b551aeb1fdeb7a256c7c558f6d78fcddff00640942d42f7aeba5f",
-                "sha256:3247834d24964589f8c2b121b40cd61319b3c2e8d744a6a82008643ef8a378b1",
-                "sha256:3433cb848b4209717722b62392e575a77a52a34d67c6730138102abc0a441685",
-                "sha256:39671b7ff77a962bd745746d9d2292c8ed227c5748f16598d16d8631d17dd7e5",
-                "sha256:40a0b8b2e6f6dd630f8b267eede2f40a848963d0f3c40b1b1f453a4a870f679e",
-                "sha256:40f9a74c7aa210b3e76eb1c9d56aa8d08722b73426a77626967019df9bbac287",
-                "sha256:423f76aa504c84cb94594fb88b8a24027c887f1c488cf58f2173f22f4fbd046c",
-                "sha256:43bd04cec72281a96eb361e1b0232f0f542b46da50bcfe72ef7e5a1b41d00cb3",
-                "sha256:43e38762635c09e24885d15e3a8e374b72d105d4178ee2cc9491855a8da9c380",
-                "sha256:4413b11c2385180d7de03add6c8845dd66692b148d36e27ec8c9ef537b2553a1",
-                "sha256:4450352a87094fd58daf468b04c65a9fa19ad11a0ac8ac7b7ff17d46f873cbc1",
-                "sha256:49ffda04a6e44de028b3b786278ac9a70043e7905c3eea29eed88b6524d53a29",
-                "sha256:4a38c4dde4c9120deef43aaabaa44f19186c98659ce554c29788c4071ab2f0a4",
-                "sha256:50b1febdfd21e2144b56a9aa226829e93a79c354ef22a4e5b013d9965e1ec0ed",
-                "sha256:559b1a3a8be7395ded2943ea6c2135d096f8cc7039d6d12127110b6496f251fe",
-                "sha256:5de86c182667ec68cf84019aa0d8ceccf01d352cdca19bf9e373725204bdbf50",
-                "sha256:5fc069bb481fe3fad0ba24d3baaf69e22dfa6cc1b63290e6dfeaf4ac1e996fb7",
-                "sha256:6a19d654da49516296515d6f65de4bbcbd734bc57913b21a610cfc45e6df3ff1",
-                "sha256:7535b3e52f498270e7877dde1c8944d6b7720e93e2e66b89c82a11447b5818f5",
-                "sha256:7c4e495bcabc308198b8962e60ca12f53b27eb8f03a21ac1d2d711d6dd9ecfca",
-                "sha256:8a8fc4a0220367cb8370cedac02272d574079ccc32bffbb34d53aaf9e38b5060",
-                "sha256:8b008515e067232838daca020d1af628bf6520c8cc338bf383284efe6d8bd083",
-                "sha256:8d1684258e1385e459418f3429e107eec5fb3d75e1f5a8c52e5946b3f329d6ea",
-                "sha256:8eb5d54b87fb561dc2e00a5c5226c33ffe8dbc13f2e4033a412bafb7b37b194d",
-                "sha256:94cdef0c61bd014bb7af495e21a1c3a369dd0399c3cd1965b1502043f5c88d94",
-                "sha256:9d9f3be69c7a5e84c3549a8c4403fa9ac7672da456863d21e390b2bbf45ccad1",
-                "sha256:9fb6fb5975a448169756da2d124a1beb38c0924ff6c0306d883b6848a9980f38",
-                "sha256:a5eaae8700b87144d7dfb475aa4675e500ff707292caba3deff41609ddc5b845",
-                "sha256:aaeac2d552772b76d24eaff67a5d2325bc5205c74c0d4f9fbe71685d4a971db2",
-                "sha256:bb611e447559b3b5665e12a7da5160c0de6876097f62bf1d23ba66911564868e",
-                "sha256:bc0d41f4eb07da8b8d3ea85e50b62f6491ab313834db86ae2345be07536a4e5a",
-                "sha256:bf51051c129b847d1bb63a9b0826346b5f52fb821b15fe5e0d5ef86f268510f5",
-                "sha256:c948c034d8997526011960db54f512756fb0b4be1b81140a15b4ef094c6594a4",
-                "sha256:d435a01334157c3b126b4ee5141401d44bdc8440993b18b05e2f267a6647f92d",
-                "sha256:d46c1f95672b73288e08cdca181e14e84c6229b5879561b7b8cfd48374e09287",
-                "sha256:d5d58309b42064228b16b0311ff715d6c6e20230e81b35e8d0c8cfa1bbdecad8",
-                "sha256:dc6e2e91365a1dd6314d615d80291159c7981928b88a4c65654e3fefac83a836",
-                "sha256:e0dfb5f7a39029a6cbec23affa923b22a2c02207960fd66f109e01d6f632c1eb",
-                "sha256:eb4bf58d381b1373bd21d50837a53953d625d1693f1b58fed12743c75d3dd321",
-                "sha256:ebb211a85248dbc396b29320273c1ffde484b898852432613e8df0164c091006",
-                "sha256:ec759ece4786ae993a5b7dc3b3dead6e9375d89a6c65dfd6860076d2eb2abe7b",
-                "sha256:f55108397a8fa164268238c3e69cc134e945d1f693572a2f05a028b8d0d2b837",
-                "sha256:f6c706866d424ff285b85a02de7bbe5ed0ace227766b2c42cbe12f3d9ea5a8aa",
-                "sha256:f8370ad332b36fbad117440faf0dd4b910e80b9c49db5648afd337abdde9a1b6"
-            ],
-            "version": "==1.25.0"
-        },
-        "helper": {
-            "hashes": [
-                "sha256:33d4a58046018fea9f46da5835a768feb9beab3528d4025d063bf354c4a19750",
-                "sha256:a63d4a9255ad5071043e7e4ab8000a512627f1db958b1941b63c7d75e56ea65c"
-            ],
-            "index": "pypi",
-            "version": "==2.4.2"
-        },
-        "idna": {
-            "hashes": [
-                "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
-                "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
-            ],
-            "version": "==2.8"
-        },
-        "imagesize": {
-            "hashes": [
-                "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
-                "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
-            ],
-            "version": "==1.1.0"
-        },
-        "itsdangerous": {
-            "hashes": [
-                "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
-                "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
-            ],
-            "version": "==1.1.0"
-        },
-        "jinja2": {
-            "hashes": [
-                "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
-                "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
-            ],
-            "version": "==2.10.3"
-        },
-        "markupsafe": {
-            "hashes": [
-                "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
-                "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
-                "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
-                "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
-                "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
-                "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
-                "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
-                "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
-                "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
-                "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
-                "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
-                "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
-                "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
-                "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
-                "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
-                "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
-                "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
-                "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
-                "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
-                "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
-                "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
-                "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
-                "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
-                "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
-                "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
-                "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
-                "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
-                "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
-            ],
-            "version": "==1.1.1"
-        },
-        "packaging": {
-            "hashes": [
-                "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47",
-                "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"
-            ],
-            "version": "==19.2"
-        },
-        "paramiko": {
-            "hashes": [
-                "sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf",
-                "sha256:f4b2edfa0d226b70bd4ca31ea7e389325990283da23465d572ed1f70a7583041"
-            ],
-            "version": "==2.6.0"
-        },
-        "protobuf": {
-            "hashes": [
-                "sha256:125713564d8cfed7610e52444c9769b8dcb0b55e25cc7841f2290ee7bc86636f",
-                "sha256:1accdb7a47e51503be64d9a57543964ba674edac103215576399d2d0e34eac77",
-                "sha256:27003d12d4f68e3cbea9eb67427cab3bfddd47ff90670cb367fcd7a3a89b9657",
-                "sha256:3264f3c431a631b0b31e9db2ae8c927b79fc1a7b1b06b31e8e5bcf2af91fe896",
-                "sha256:3c5ab0f5c71ca5af27143e60613729e3488bb45f6d3f143dc918a20af8bab0bf",
-                "sha256:45dcf8758873e3f69feab075e5f3177270739f146255225474ee0b90429adef6",
-                "sha256:56a77d61a91186cc5676d8e11b36a5feb513873e4ae88d2ee5cf530d52bbcd3b",
-                "sha256:5984e4947bbcef5bd849d6244aec507d31786f2dd3344139adc1489fb403b300",
-                "sha256:6b0441da73796dd00821763bb4119674eaf252776beb50ae3883bed179a60b2a",
-                "sha256:6f6677c5ade94d4fe75a912926d6796d5c71a2a90c2aeefe0d6f211d75c74789",
-                "sha256:84a825a9418d7196e2acc48f8746cf1ee75877ed2f30433ab92a133f3eaf8fbe",
-                "sha256:b842c34fe043ccf78b4a6cf1019d7b80113707d68c88842d061fa2b8fb6ddedc",
-                "sha256:ca33d2f09dae149a1dcf942d2d825ebb06343b77b437198c9e2ef115cf5d5bc1",
-                "sha256:db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe",
-                "sha256:f50f3b1c5c1c1334ca7ce9cad5992f098f460ffd6388a3cabad10b66c2006b09",
-                "sha256:f99f127909731cafb841c52f9216e447d3e4afb99b17bebfad327a75aee206de"
-            ],
-            "version": "==3.10.0"
-        },
-        "pycparser": {
-            "hashes": [
-                "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
-            ],
-            "version": "==2.19"
-        },
-        "pygments": {
-            "hashes": [
-                "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
-                "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
-            ],
-            "version": "==2.4.2"
-        },
-        "pynacl": {
-            "hashes": [
-                "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255",
-                "sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c",
-                "sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e",
-                "sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae",
-                "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621",
-                "sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56",
-                "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39",
-                "sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310",
-                "sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1",
-                "sha256:53126cd91356342dcae7e209f840212a58dcf1177ad52c1d938d428eebc9fee5",
-                "sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a",
-                "sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786",
-                "sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b",
-                "sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b",
-                "sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f",
-                "sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20",
-                "sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415",
-                "sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715",
-                "sha256:bf459128feb543cfca16a95f8da31e2e65e4c5257d2f3dfa8c0c1031139c9c92",
-                "sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1",
-                "sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0"
-            ],
-            "version": "==1.3.0"
-        },
-        "pynetbox": {
-            "hashes": [
-                "sha256:7c2282891ab1d3a5f5b28cb3b83c30d33c7ac3da1ee928c7332a4d2fac32f283"
-            ],
-            "index": "pypi",
-            "version": "==4.2.0"
-        },
-        "pyotp": {
-            "hashes": [
-                "sha256:c88f37fd47541a580b744b42136f387cdad481b560ef410c0d85c957eb2a2bc0",
-                "sha256:fc537e8acd985c5cbf51e11b7d53c42276fee017a73aec7c07380695671ca1a1"
-            ],
-            "index": "pypi",
-            "version": "==2.3.0"
-        },
-        "pyparsing": {
-            "hashes": [
-                "sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f",
-                "sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a"
-            ],
-            "version": "==2.4.5"
-        },
-        "python-decouple": {
-            "hashes": [
-                "sha256:55c546b85b0c47a15a47a4312d451a437f7344a9be3e001660bccd93b637de95"
-            ],
-            "index": "pypi",
-            "version": "==3.3"
-        },
-        "python-etcd3": {
-            "editable": true,
-            "git": "https://github.com/kragniz/python-etcd3.git",
-            "ref": "247e3952d0b47324091a36ace3ad9717469fb6b9"
-        },
-        "pytz": {
-            "hashes": [
-                "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
-                "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
-            ],
-            "version": "==2019.3"
-        },
-        "pyyaml": {
-            "hashes": [
-                "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
-                "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
-                "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
-                "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
-                "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
-                "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
-                "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
-                "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
-                "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
-                "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
-                "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
-                "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
-                "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
-            ],
-            "version": "==5.1.2"
-        },
-        "requests": {
-            "hashes": [
-                "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
-                "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
-            ],
-            "index": "pypi",
-            "version": "==2.22.0"
-        },
-        "six": {
-            "hashes": [
-                "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
-                "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
-            ],
-            "version": "==1.13.0"
-        },
-        "snowballstemmer": {
-            "hashes": [
-                "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0",
-                "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"
-            ],
-            "version": "==2.0.0"
-        },
-        "sphinx": {
-            "hashes": [
-                "sha256:31088dfb95359384b1005619827eaee3056243798c62724fd3fa4b84ee4d71bd",
-                "sha256:52286a0b9d7caa31efee301ec4300dbdab23c3b05da1c9024b4e84896fb73d79"
-            ],
-            "index": "pypi",
-            "version": "==2.2.1"
-        },
-        "sphinx-rtd-theme": {
-            "hashes": [
-                "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4",
-                "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"
-            ],
-            "index": "pypi",
-            "version": "==0.4.3"
-        },
-        "sphinxcontrib-applehelp": {
-            "hashes": [
-                "sha256:edaa0ab2b2bc74403149cb0209d6775c96de797dfd5b5e2a71981309efab3897",
-                "sha256:fb8dee85af95e5c30c91f10e7eb3c8967308518e0f7488a2828ef7bc191d0d5d"
-            ],
-            "version": "==1.0.1"
-        },
-        "sphinxcontrib-devhelp": {
-            "hashes": [
-                "sha256:6c64b077937330a9128a4da74586e8c2130262f014689b4b89e2d08ee7294a34",
-                "sha256:9512ecb00a2b0821a146736b39f7aeb90759834b07e81e8cc23a9c70bacb9981"
-            ],
-            "version": "==1.0.1"
-        },
-        "sphinxcontrib-htmlhelp": {
-            "hashes": [
-                "sha256:4670f99f8951bd78cd4ad2ab962f798f5618b17675c35c5ac3b2132a14ea8422",
-                "sha256:d4fd39a65a625c9df86d7fa8a2d9f3cd8299a3a4b15db63b50aac9e161d8eff7"
-            ],
-            "version": "==1.0.2"
-        },
-        "sphinxcontrib-jsmath": {
-            "hashes": [
-                "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178",
-                "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"
-            ],
-            "version": "==1.0.1"
-        },
-        "sphinxcontrib-qthelp": {
-            "hashes": [
-                "sha256:513049b93031beb1f57d4daea74068a4feb77aa5630f856fcff2e50de14e9a20",
-                "sha256:79465ce11ae5694ff165becda529a600c754f4bc459778778c7017374d4d406f"
-            ],
-            "version": "==1.0.2"
-        },
-        "sphinxcontrib-serializinghtml": {
-            "hashes": [
-                "sha256:c0efb33f8052c04fd7a26c0a07f1678e8512e0faec19f4aa8f2473a8b81d5227",
-                "sha256:db6615af393650bf1151a6cd39120c29abaf93cc60db8c48eb2dddbfdc3a9768"
-            ],
-            "version": "==1.1.3"
-        },
-        "sshtunnel": {
-            "hashes": [
-                "sha256:c813fdcda8e81c3936ffeac47cb69cfb2d1f5e77ad0de656c6dab56aeebd9249"
-            ],
-            "index": "pypi",
-            "version": "==0.1.5"
-        },
-        "tenacity": {
-            "hashes": [
-                "sha256:72f397c2bb1887e048726603f3f629ea16f88cb3e61e4ed3c57e98582b8e3571",
-                "sha256:947e728aedf06e8db665bb7898112e90d17e48cc3f3289784a2b9ccf6e56fabc"
-            ],
-            "version": "==6.0.0"
-        },
-        "urllib3": {
-            "hashes": [
-                "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293",
-                "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"
-            ],
-            "version": "==1.25.7"
-        },
-        "werkzeug": {
-            "hashes": [
-                "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7",
-                "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"
-            ],
-            "version": "==0.16.0"
-        }
-    },
-    "develop": {
-        "astroid": {
-            "hashes": [
-                "sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
-                "sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
-            ],
-            "version": "==2.2.5"
-        },
-        "certifi": {
-            "hashes": [
-                "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
-                "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
-            ],
-            "version": "==2019.9.11"
-        },
-        "chardet": {
-            "hashes": [
-                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
-                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
-            ],
-            "version": "==3.0.4"
-        },
-        "coverage": {
-            "hashes": [
-                "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6",
-                "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650",
-                "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5",
-                "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d",
-                "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351",
-                "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755",
-                "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef",
-                "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca",
-                "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca",
-                "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9",
-                "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc",
-                "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5",
-                "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f",
-                "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe",
-                "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888",
-                "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5",
-                "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce",
-                "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5",
-                "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e",
-                "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e",
-                "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9",
-                "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437",
-                "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1",
-                "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c",
-                "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24",
-                "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47",
-                "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2",
-                "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28",
-                "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c",
-                "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7",
-                "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0",
-                "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"
-            ],
-            "version": "==4.5.4"
-        },
-        "coveralls": {
-            "hashes": [
-                "sha256:9bc5a1f92682eef59f688a8f280207190d9a6afb84cef8f567fa47631a784060",
-                "sha256:fb51cddef4bc458de347274116df15d641a735d3f0a580a9472174e2e62f408c"
-            ],
-            "version": "==1.8.2"
-        },
-        "docopt": {
-            "hashes": [
-                "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
-            ],
-            "version": "==0.6.2"
-        },
-        "docutils": {
-            "hashes": [
-                "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0",
-                "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827",
-                "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99"
-            ],
-            "version": "==0.15.2"
-        },
-        "dodgy": {
-            "hashes": [
-                "sha256:65e13cf878d7aff129f1461c13cb5fd1bb6dfe66bb5327e09379c3877763280c"
-            ],
-            "version": "==0.1.9"
-        },
-        "frosted": {
-            "hashes": [
-                "sha256:c6a30ad502ea373f6fe4cafbcd896ece66948406b04365d14a3eb764cc529b07",
-                "sha256:d1e5d2b43a064b33c289b9a986a7425fd9a36bed8f519ca430ac7a0915e32b51"
-            ],
-            "version": "==1.4.1"
-        },
-        "idna": {
-            "hashes": [
-                "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
-                "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
-            ],
-            "version": "==2.8"
-        },
-        "isort": {
-            "hashes": [
-                "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
-                "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
-            ],
-            "version": "==4.3.21"
-        },
-        "lazy-object-proxy": {
-            "hashes": [
-                "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
-                "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
-                "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
-                "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
-                "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
-                "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
-                "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
-                "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
-                "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
-                "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
-                "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
-                "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
-                "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
-                "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
-                "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
-                "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
-                "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
-                "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
-                "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
-                "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
-                "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
-            ],
-            "version": "==1.4.3"
-        },
-        "mccabe": {
-            "hashes": [
-                "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
-                "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
-            ],
-            "version": "==0.6.1"
-        },
-        "mock": {
-            "hashes": [
-                "sha256:83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3",
-                "sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"
-            ],
-            "version": "==3.0.5"
-        },
-        "mypy": {
-            "hashes": [
-                "sha256:1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f",
-                "sha256:31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00",
-                "sha256:3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae",
-                "sha256:48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d",
-                "sha256:540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9",
-                "sha256:672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391",
-                "sha256:6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f",
-                "sha256:9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9",
-                "sha256:ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990",
-                "sha256:b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7",
-                "sha256:d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb",
-                "sha256:d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453",
-                "sha256:dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b",
-                "sha256:f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb"
-            ],
-            "version": "==0.740"
-        },
-        "mypy-extensions": {
-            "hashes": [
-                "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
-                "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
-            ],
-            "version": "==0.4.3"
-        },
-        "nose": {
-            "hashes": [
-                "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac",
-                "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a",
-                "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"
-            ],
-            "version": "==1.3.7"
-        },
-        "pep8-naming": {
-            "hashes": [
-                "sha256:1b419fa45b68b61cd8c5daf4e0c96d28915ad14d3d5f35fcc1e7e95324a33a2e",
-                "sha256:4eedfd4c4b05e48796f74f5d8628c068ff788b9c2b08471ad408007fc6450e5a"
-            ],
-            "version": "==0.4.1"
-        },
-        "pies": {
-            "hashes": [
-                "sha256:79a652dddc64c6fa42c7dfe9686ae7b1d856391094b873e2f52fcd0bd662c102",
-                "sha256:e8a76923ce0e0f605240901983fe492814a65d3d803efe3013a0e1815b75e4e9"
-            ],
-            "version": "==2.6.7"
-        },
-        "prospector": {
-            "extras": [
-                "with_everything"
-            ],
-            "hashes": [
-                "sha256:aba551e53dc1a5a432afa67385eaa81d7b4cf4c162dc1a4d0ee00b3a0712ad90"
-            ],
-            "index": "pypi",
-            "version": "==1.1.7"
-        },
-        "pycodestyle": {
-            "hashes": [
-                "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
-                "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
-            ],
-            "version": "==2.4.0"
-        },
-        "pydocstyle": {
-            "hashes": [
-                "sha256:04c84e034ebb56eb6396c820442b8c4499ac5eb94a3bda88951ac3dc519b6058",
-                "sha256:66aff87ffe34b1e49bff2dd03a88ce6843be2f3346b0c9814410d34987fbab59"
-            ],
-            "version": "==4.0.1"
-        },
-        "pyflakes": {
-            "hashes": [
-                "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f",
-                "sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805"
-            ],
-            "version": "==1.6.0"
-        },
-        "pygments": {
-            "hashes": [
-                "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
-                "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
-            ],
-            "version": "==2.4.2"
-        },
-        "pylama": {
-            "hashes": [
-                "sha256:9bae53ef9c1a431371d6a8dca406816a60d547147b60a4934721898f553b7d8f",
-                "sha256:fd61c11872d6256b019ef1235be37b77c922ef37ac9797df6bd489996dddeb15"
-            ],
-            "index": "pypi",
-            "version": "==7.7.1"
-        },
-        "pylint": {
-            "hashes": [
-                "sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
-                "sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1"
-            ],
-            "version": "==2.3.1"
-        },
-        "pylint-celery": {
-            "hashes": [
-                "sha256:41e32094e7408d15c044178ea828dd524beedbdbe6f83f712c5e35bde1de4beb"
-            ],
-            "version": "==0.3"
-        },
-        "pylint-django": {
-            "hashes": [
-                "sha256:75c69d1ec2275918c37f175976da20e2f1e1e62e067098a685cd263ffa833dfd",
-                "sha256:c7cb6384ea7b33ea77052a5ae07358c10d377807390ef27b2e6ff997303fadb7"
-            ],
-            "version": "==2.0.10"
-        },
-        "pylint-flask": {
-            "hashes": [
-                "sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"
-            ],
-            "version": "==0.6"
-        },
-        "pylint-plugin-utils": {
-            "hashes": [
-                "sha256:2f30510e1c46edf268d3a195b2849bd98a1b9433229bb2ba63b8d776e1fc4d0a",
-                "sha256:57625dcca20140f43731311cd8fd879318bf45a8b0fd17020717a8781714a25a"
-            ],
-            "version": "==0.6"
-        },
-        "pyroma": {
-            "hashes": [
-                "sha256:351758a81e2a12c970deb73687e239636aad52795cd81429695073d59fff0699",
-                "sha256:c49c00377219626bf83df42adf018cc231e6162b68cc7aaf2ff1c63803924102"
-            ],
-            "version": "==2.6"
-        },
-        "pyyaml": {
-            "hashes": [
-                "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
-                "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
-                "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
-                "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
-                "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
-                "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
-                "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
-                "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
-                "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
-                "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
-                "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
-                "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
-                "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
-            ],
-            "version": "==5.1.2"
-        },
-        "requests": {
-            "hashes": [
-                "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
-                "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
-            ],
-            "index": "pypi",
-            "version": "==2.22.0"
-        },
-        "requirements-detector": {
-            "hashes": [
-                "sha256:9fbc4b24e8b7c3663aff32e3eba34596848c6b91bd425079b386973bd8d08931"
-            ],
-            "version": "==0.6"
-        },
-        "setoptconf": {
-            "hashes": [
-                "sha256:5b0b5d8e0077713f5d5152d4f63be6f048d9a1bb66be15d089a11c898c3cf49c"
-            ],
-            "version": "==0.2.0"
-        },
-        "six": {
-            "hashes": [
-                "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
-                "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
-            ],
-            "version": "==1.13.0"
-        },
-        "snowballstemmer": {
-            "hashes": [
-                "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0",
-                "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"
-            ],
-            "version": "==2.0.0"
-        },
-        "typed-ast": {
-            "hashes": [
-                "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161",
-                "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
-                "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e",
-                "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0",
-                "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c",
-                "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47",
-                "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631",
-                "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4",
-                "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34",
-                "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b",
-                "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2",
-                "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e",
-                "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a",
-                "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233",
-                "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1",
-                "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36",
-                "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d",
-                "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a",
-                "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66",
-                "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"
-            ],
-            "markers": "implementation_name == 'cpython'",
-            "version": "==1.4.0"
-        },
-        "typing-extensions": {
-            "hashes": [
-                "sha256:091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2",
-                "sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d",
-                "sha256:cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"
-            ],
-            "version": "==3.7.4.1"
-        },
-        "urllib3": {
-            "hashes": [
-                "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293",
-                "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"
-            ],
-            "version": "==1.25.7"
-        },
-        "vulture": {
-            "hashes": [
-                "sha256:17be5f6a7c88ea43f2619f80338af7407275ee46a24000abe2570e59ca44b3d0",
-                "sha256:23d837cf619c3bb75f87bc498c79cd4f27f0c54031ca88a9e05606c9dd627fef"
-            ],
-            "version": "==0.24"
-        },
-        "wrapt": {
-            "hashes": [
-                "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
-            ],
-            "version": "==1.11.2"
-        }
-    }
-}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b36fe90
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# ucloud
+
+**Open** + **Simple** + **Easy to hack** + **IPv6 First**.
+
+ucloud is an easy to use cloud management system.
+
+It is an alternative to OpenStack, OpenNebula or Cloudstack.
+
+ucloud is the first cloud management system that puts IPv6 first. ucloud also has an integral ordering process that we missed in existing solutions.
\ No newline at end of file
diff --git a/ucloud.py b/bin/ucloud
similarity index 79%
rename from ucloud.py
rename to bin/ucloud
index 28979b3..0d4309a 100644
--- a/ucloud.py
+++ b/bin/ucloud
@@ -1,9 +1,11 @@
+#!/usr/bin/env python3
+
 import argparse
 import multiprocessing as mp
 import logging
 
 from os.path import join as join_path
-from sanity_checks import check
+from ucloud.sanity_checks import check
 
 if __name__ == "__main__":
     arg_parser = argparse.ArgumentParser(prog='ucloud',
@@ -26,29 +28,29 @@ if __name__ == "__main__":
         check()
 
         if args.component == 'api':
-            from api.main import main
+            from ucloud.api.main import main
 
             main()
         elif args.component == 'host':
-            from host.main import main
+            from ucloud.host.main import main
 
             hostname = args.component_args
             mp.set_start_method('spawn')
             main(*hostname)
         elif args.component == 'scheduler':
-            from scheduler.main import main
+            from ucloud.scheduler.main import main
 
             main()
         elif args.component == 'filescanner':
-            from filescanner.main import main
+            from ucloud.filescanner.main import main
 
             main()
         elif args.component == 'imagescanner':
-            from imagescanner.main import main
+            from ucloud.imagescanner.main import main
 
             main()
         elif args.component == 'metadata':
-            from metadata.main import main
+            from ucloud.metadata.main import main
 
             main()
 
diff --git a/scheduler/tests/__init__.py b/scheduler/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..88b85e5
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,35 @@
+from setuptools import setup, find_packages
+
+with open("README.md", "r") as fh:
+    long_description = fh.read()
+
+setup(name='ucloud',
+      version='0.1',
+      description='All ucloud server components.',
+      url='https://code.ungleich.ch/ucloud/ucloud',
+      long_description=long_description,
+      long_description_content_type='text/markdown',
+      classifiers=[
+          'Development Status :: 3 - Alpha',
+          'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
+          'Programming Language :: Python :: 3'
+      ],
+      author='ungleich',
+      author_email='technik@ungleich.ch',
+      packages=find_packages(),
+      install_requires=[
+          'requests',
+          'python-decouple',
+          'flask',
+          'flask-restful',
+          'bitmath',
+          'pyotp',
+          'sshtunnel',
+          'sphinx',
+          'pynetbox',
+          'sphinx-rtd-theme',
+          'etcd3_wrapper @ https://code.ungleich.ch/ungleich-public/etcd3_wrapper/repository/master/archive.tar.gz#egg=etcd3_wrapper',
+          'etcd3 @ https://github.com/kragniz/python-etcd3/tarball/master#egg=etcd3',
+      ],
+      scripts=['bin/ucloud'],
+      zip_safe=False)
\ No newline at end of file
diff --git a/__init__.py b/ucloud/__init__.py
similarity index 100%
rename from __init__.py
rename to ucloud/__init__.py
diff --git a/api/README.md b/ucloud/api/README.md
similarity index 100%
rename from api/README.md
rename to ucloud/api/README.md
diff --git a/api/__init__.py b/ucloud/api/__init__.py
similarity index 100%
rename from api/__init__.py
rename to ucloud/api/__init__.py
diff --git a/api/common_fields.py b/ucloud/api/common_fields.py
similarity index 96%
rename from api/common_fields.py
rename to ucloud/api/common_fields.py
index 6a68763..e9903ac 100755
--- a/api/common_fields.py
+++ b/ucloud/api/common_fields.py
@@ -1,6 +1,6 @@
 import os
 
-from config import etcd_client, env_vars
+from ucloud.config import etcd_client, env_vars
 
 
 class Optional:
diff --git a/api/create_image_store.py b/ucloud/api/create_image_store.py
similarity index 87%
rename from api/create_image_store.py
rename to ucloud/api/create_image_store.py
index cddbacb..99e33c2 100755
--- a/api/create_image_store.py
+++ b/ucloud/api/create_image_store.py
@@ -2,7 +2,7 @@ import json
 import os
 from uuid import uuid4
 
-from config import etcd_client, env_vars
+from ucloud.config import etcd_client, env_vars
 
 data = {
     "is_public": True,
diff --git a/api/helper.py b/ucloud/api/helper.py
similarity index 94%
rename from api/helper.py
rename to ucloud/api/helper.py
index ed3ea28..3271461 100755
--- a/api/helper.py
+++ b/ucloud/api/helper.py
@@ -6,7 +6,7 @@ import subprocess as sp
 import requests
 from pyotp import TOTP
 
-from config import vm_pool, env_vars
+from ucloud.config import vm_pool, env_vars
 
 
 def check_otp(name, realm, token):
@@ -83,8 +83,8 @@ def resolve_image_name(name, etcd_client):
 
     # Try to find image with name == image_name and store_name == store_name
     try:
-        image = next(filter(lambda im: im.value['name'] == image_name \
-                                       and im.value['store_name'] == store_name, images))
+        image = next(filter(lambda im: im.value['name'] == image_name
+                            and im.value['store_name'] == store_name, images))
     except StopIteration:
         raise KeyError("No image with name {} found.".format(name))
     else:
@@ -155,10 +155,10 @@ def mac2ipv6(mac, prefix):
     parts[0] = "%x" % (int(parts[0], 16) ^ 2)
 
     # format output
-    ipv6Parts = [str(0)] * 4
+    ipv6_parts = [str(0)] * 4
     for i in range(0, len(parts), 2):
-        ipv6Parts.append("".join(parts[i:i + 2]))
+        ipv6_parts.append("".join(parts[i:i + 2]))
 
-    lower_part = ipaddress.IPv6Address(":".join(ipv6Parts))
+    lower_part = ipaddress.IPv6Address(":".join(ipv6_parts))
     prefix = ipaddress.IPv6Address(prefix)
     return str(prefix + int(lower_part))
diff --git a/api/main.py b/ucloud/api/main.py
similarity index 97%
rename from api/main.py
rename to ucloud/api/main.py
index 224ab2e..d325ecb 100644
--- a/api/main.py
+++ b/ucloud/api/main.py
@@ -7,13 +7,13 @@ from os.path import join as join_path
 from flask import Flask, request
 from flask_restful import Resource, Api
 
-from common import counters
-from common.vm import VMStatus
-from common.request import RequestEntry, RequestType
-from config import (etcd_client, request_pool, vm_pool, host_pool, env_vars, image_storage_handler)
+from ucloud.common import counters
+from ucloud.common.vm import VMStatus
+from ucloud.common.request import RequestEntry, RequestType
+from ucloud.config import (etcd_client, request_pool, vm_pool, host_pool, env_vars, image_storage_handler)
 from . import schemas
 from .helper import generate_mac, mac2ipv6
-from api import logger
+from ucloud.api import logger
 
 app = Flask(__name__)
 api = Api(app)
@@ -35,9 +35,9 @@ class CreateVM(Resource):
                 "os-ssd": validator.specs["os-ssd"],
                 "hdd": validator.specs["hdd"],
             }
-            macs = [generate_mac() for i in range(len(data["network"]))]
+            macs = [generate_mac() for _ in range(len(data["network"]))]
             tap_ids = [counters.increment_etcd_counter(etcd_client, "/v1/counter/tap")
-                       for i in range(len(data["network"]))]
+                       for _ in range(len(data["network"]))]
             vm_entry = {
                 "name": data["vm_name"],
                 "owner": data["name"],
diff --git a/api/schemas.py b/ucloud/api/schemas.py
similarity index 99%
rename from api/schemas.py
rename to ucloud/api/schemas.py
index e50d9f0..c4f60ca 100755
--- a/api/schemas.py
+++ b/ucloud/api/schemas.py
@@ -19,9 +19,9 @@ import os
 
 import bitmath
 
-from common.host import HostStatus
-from common.vm import VMStatus
-from config import etcd_client, env_vars, vm_pool, host_pool
+from ucloud.common.host import HostStatus
+from ucloud.common.vm import VMStatus
+from ucloud.config import etcd_client, env_vars, vm_pool, host_pool
 from . import helper
 from .common_fields import Field, VmUUIDField
 from .helper import check_otp, resolve_vm_name
diff --git a/filescanner/__init__.py b/ucloud/common/__init__.py
similarity index 100%
rename from filescanner/__init__.py
rename to ucloud/common/__init__.py
diff --git a/common/classes.py b/ucloud/common/classes.py
similarity index 100%
rename from common/classes.py
rename to ucloud/common/classes.py
diff --git a/common/counters.py b/ucloud/common/counters.py
similarity index 100%
rename from common/counters.py
rename to ucloud/common/counters.py
diff --git a/common/helpers.py b/ucloud/common/helpers.py
similarity index 100%
rename from common/helpers.py
rename to ucloud/common/helpers.py
diff --git a/common/host.py b/ucloud/common/host.py
similarity index 100%
rename from common/host.py
rename to ucloud/common/host.py
diff --git a/common/request.py b/ucloud/common/request.py
similarity index 100%
rename from common/request.py
rename to ucloud/common/request.py
diff --git a/common/storage_handlers.py b/ucloud/common/storage_handlers.py
similarity index 99%
rename from common/storage_handlers.py
rename to ucloud/common/storage_handlers.py
index c74bca8..8b1097a 100644
--- a/common/storage_handlers.py
+++ b/ucloud/common/storage_handlers.py
@@ -4,7 +4,7 @@ import os
 import stat
 
 from abc import ABC
-from host import logger
+from . import logger
 from os.path import join as join_path
 
 
diff --git a/common/vm.py b/ucloud/common/vm.py
similarity index 100%
rename from common/vm.py
rename to ucloud/common/vm.py
diff --git a/config.py b/ucloud/config.py
similarity index 83%
rename from config.py
rename to ucloud/config.py
index c58cf33..d5e5b77 100644
--- a/config.py
+++ b/ucloud/config.py
@@ -1,9 +1,9 @@
 from etcd3_wrapper import Etcd3Wrapper
 
-from common.host import HostPool
-from common.request import RequestPool
-from common.vm import VmPool
-from common.storage_handlers import FileSystemBasedImageStorageHandler, CEPHBasedImageStorageHandler
+from ucloud.common.host import HostPool
+from ucloud.common.request import RequestPool
+from ucloud.common.vm import VmPool
+from ucloud.common.storage_handlers import FileSystemBasedImageStorageHandler, CEPHBasedImageStorageHandler
 from decouple import Config, RepositoryEnv
 
 
diff --git a/docs/Makefile b/ucloud/docs/Makefile
similarity index 100%
rename from docs/Makefile
rename to ucloud/docs/Makefile
diff --git a/common/__init__.py b/ucloud/docs/__init__.py
similarity index 100%
rename from common/__init__.py
rename to ucloud/docs/__init__.py
diff --git a/docs/__init__.py b/ucloud/docs/source/__init__.py
similarity index 100%
rename from docs/__init__.py
rename to ucloud/docs/source/__init__.py
diff --git a/docs/source/conf.py b/ucloud/docs/source/conf.py
similarity index 100%
rename from docs/source/conf.py
rename to ucloud/docs/source/conf.py
diff --git a/docs/source/diagram-code/ucloud b/ucloud/docs/source/diagram-code/ucloud
similarity index 100%
rename from docs/source/diagram-code/ucloud
rename to ucloud/docs/source/diagram-code/ucloud
diff --git a/docs/source/images/ucloud.svg b/ucloud/docs/source/images/ucloud.svg
similarity index 100%
rename from docs/source/images/ucloud.svg
rename to ucloud/docs/source/images/ucloud.svg
diff --git a/docs/source/index.rst b/ucloud/docs/source/index.rst
similarity index 100%
rename from docs/source/index.rst
rename to ucloud/docs/source/index.rst
diff --git a/docs/source/introduction/installation.rst b/ucloud/docs/source/introduction/installation.rst
similarity index 55%
rename from docs/source/introduction/installation.rst
rename to ucloud/docs/source/introduction/installation.rst
index 450a9e7..87e71ff 100644
--- a/docs/source/introduction/installation.rst
+++ b/ucloud/docs/source/introduction/installation.rst
@@ -1,9 +1,16 @@
 Installation
 ============
+This guides includes two type of installation
+
+* File System as Image Storage + Level 2 Network without IPAM and Routing
+* CEPH as Image Storage + Level 2 Network with automatic IPAM and Routing
+  (using Router Advertisement + Netbox)
+
+The guide will explicitly mention a section/subsection if it is exclusive to any
+one of the above mentioned scenario.
+
 
 .. note::
-    The below installation instructions are for single node and without ceph ucloud installation.
-    
     The instructions assumes the following things
     
     * User is **root**.
@@ -13,14 +20,18 @@ Alpine
 ------
 
 .. note::
-    Python Wheel (Binary) Packages does not support Alpine Linux as it is using musl libc instead of glibc.
-    Therefore, expect longer installation times than other linux distributions.
+    Python Wheel (Binary) Packages does not support Alpine Linux as it is
+    using musl libc instead of glibc. Therefore, expect longer installation
+    times than other linux distributions.
 
 Enable Edge Repos, Update and Upgrade
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. warning::
-    The below commands would overwrite your repositories sources and upgrade all packages and their dependencies to match those available in edge repos. **So, be warned**
+    The below commands would overwrite your repositories sources and
+    upgrade all packages and their dependencies to match those available
+    in edge repos. **So, be warned**
+
 .. code-block:: sh
     :linenos:
 
@@ -40,17 +51,31 @@ Install Dependencies
 ~~~~~~~~~~~~~~~~~~~~
 .. note::
     The installation and configuration of a production grade etcd cluster
-    is out of scope of this manual. So, we will install etcd with default configuration.
+    is out of scope of this manual. So, we will install etcd with default
+    configuration.
 
 .. code-block:: sh
     :linenos:
 
     apk add git python3 alpine-sdk python3-dev etcd etcd-ctl openntpd \
-            libffi-dev openssl-dev make py3-protobuf py3-tempita chrony \
-            qemu qemu-system-x86_64 qemu-img
-    
+            libffi-dev openssl-dev make py3-protobuf py3-tempita chrony
+
     pip3 install pipenv
 
+
+**Install QEMU (For Filesystem based Installation)**
+
+.. code-block:: sh
+
+    apk add qemu qemu-system-x86_64 qemu-img
+
+**Install QEMU/CEPH/radvd (For CEPH based Installation)**
+
+.. code-block:: sh
+
+    $(git clone https://code.ungleich.ch/ahmedbilal/qemu-with-rbd-alpine.git && cd qemu-with-rbd-alpine && apk add apks/*.apk --allow-untrusted)
+    apk add ceph radvd
+
 Syncronize Date/Time
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -64,10 +89,15 @@ Syncronize Date/Time
 Start etcd and enable it
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. note::
+    The following :command:`curl` statement shouldn't be run once
+    etcd is fixed in alpine repos.
+
 .. code-block:: sh
     :linenos:
 
-    start-stop-daemon -b etcd
+    curl https://raw.githubusercontent.com/etcd-io/etcd/release-3.4/etcd.conf.yml.sample -o /etc/etcd/conf.yml
+    service etcd start
     rc-update add etcd
 
 
@@ -85,7 +115,8 @@ Install uotp
     pipenv install
     pipenv run python app.py
 
-Run :code:`ETCDCTL_API=3 etcdctl get /uotp/admin --print-value-only` to get admin seed. A sample output
+Run :code:`$(cd scripts && pipenv run python get-admin.py)` to get
+admin seed. A sample output
 
 .. code-block:: json
 
@@ -94,17 +125,21 @@ Run :code:`ETCDCTL_API=3 etcdctl get /uotp/admin --print-value-only` to get admi
         "realm": ["ungleich-admin"]
     }
 
-Now, run :code:`pipenv run python scripts/create-auth.py FYTVQ72A2CJJ4TB4` (Replace **FYTVQ72A2CJJ4TB4** with your admin seed obtained in previous step).
+Now, run :code:`pipenv run python scripts/create-auth.py FYTVQ72A2CJJ4TB4`
+(Replace **FYTVQ72A2CJJ4TB4** with your admin seed obtained in previous step).
 A sample output is as below. It shows seed of auth.
 
 .. code-block:: json
 
     {
-        "message": "Account Created\nname: auth, realm: ['ungleich-auth'], seed: XZLTUMX26TRAZOXC"
+        "message": "Account Created",
+        "name": "auth",
+        "realm": ["ungleich-auth"],
+        "seed": "XZLTUMX26TRAZOXC"
     }
 
 .. note::
-    Please note both **admin** and **auth** seeds as we would need them in setting up ucloud
+    Please note both **admin** and **auth** seeds as we would need them in setting up ucloud.
 
 
 Install and configure ucloud
@@ -119,14 +154,16 @@ Install and configure ucloud
     pipenv --three --site-packages
     pipenv install
 
+**Filesystem based Installation**
 
 You just need to update **AUTH_SEED** in the below code to match your auth's seed.
 
-
 .. code-block:: sh
     :linenos:
 
-    cat > .env << EOF
+    mkdir /etc/ucloud
+
+    cat > /etc/ucloud/ucloud.conf << EOF
     AUTH_NAME=auth
     AUTH_SEED=XZLTUMX26TRAZOXC
     AUTH_REALM=ungleich-auth
@@ -160,6 +197,60 @@ You just need to update **AUTH_SEED** in the below code to match your auth's see
     EOF
 
 
+
+**CEPH based Installation**
+You need to update the following
+
+* **AUTH_SEED**
+* **NETBOX_URL**
+* **NETBOX_TOKEN**
+* **PREFIX**
+* **PREFIX_LENGTH**
+
+
+.. code-block:: sh
+    :linenos:
+
+    mkdir /etc/ucloud
+
+    cat > /etc/ucloud/ucloud.conf << EOF
+    AUTH_NAME=auth
+    AUTH_SEED=XZLTUMX26TRAZOXC
+    AUTH_REALM=ungleich-auth
+
+    REALM_ALLOWED = ["ungleich-admin", "ungleich-user"]
+
+    OTP_SERVER="http://127.0.0.1:8000/"
+
+    ETCD_URL=localhost
+
+    STORAGE_BACKEND=ceph
+
+    BASE_DIR=/var/www
+    IMAGE_DIR=/var/image
+    VM_DIR=/var/vm
+
+    VM_PREFIX=/v1/vm/
+    HOST_PREFIX=/v1/host/
+    REQUEST_PREFIX=/v1/request/
+    FILE_PREFIX=/v1/file/
+    IMAGE_PREFIX=/v1/image/
+    IMAGE_STORE_PREFIX=/v1/image_store/
+    USER_PREFIX=/v1/user/
+    NETWORK_PREFIX=/v1/network/
+
+    ssh_username=meow
+    ssh_pkey="~/.ssh/id_rsa"
+
+    VXLAN_PHY_DEV="eth0"
+
+    NETBOX_URL="<url-for-your-netbox-installation>"
+    NETBOX_TOKEN="netbox-token"
+    PREFIX="your-prefix"
+    PREFIX_LENGTH="64"
+    EOF
+
+
 Install and configure ucloud-cli
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -171,11 +262,16 @@ Install and configure ucloud-cli
     pipenv --three --site-packages
     pipenv install
 
-    cat > .env << EOF
+    cat > ~/.ucloud.conf << EOF
     UCLOUD_API_SERVER=http://localhost:5000
     EOF
 
     mkdir /var/www/
+
+**Only for Filesystem Based Installation**
+
+.. code-block:: sh
+
     mkdir /var/image/
     mkdir /var/vm/
 
@@ -183,8 +279,8 @@ Install and configure ucloud-cli
 Environment Variables and aliases
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To ease usage of ucloud and its various componenets put the following in your shell
-profile e.g *~/.profile*
+To ease usage of ucloud and its various components put the following in
+your shell profile e.g *~/.profile*
 
 .. code-block:: sh
 
@@ -193,7 +289,7 @@ profile e.g *~/.profile*
     export OTP_SEED=FYTVQ72A2CJJ4TB4
 
     alias ucloud='cd /root/ucloud/ && pipenv run python ucloud.py'
-    alias ucloud-cli='cd /root/ucloud-cli/ && pipenv run python ucloud.py'
+    alias ucloud-cli='cd /root/ucloud-cli/ && pipenv run python ucloud-cli.py'
     alias uotp='cd /root/uotp/ && pipenv run python app.py'
 
 and run :code:`source ~/.profile`
diff --git a/docs/source/introduction/introduction.rst b/ucloud/docs/source/introduction/introduction.rst
similarity index 91%
rename from docs/source/introduction/introduction.rst
rename to ucloud/docs/source/introduction/introduction.rst
index f45b3c1..8f47acc 100644
--- a/docs/source/introduction/introduction.rst
+++ b/ucloud/docs/source/introduction/introduction.rst
@@ -17,8 +17,11 @@ Tech Stack
 * JSON for specifications.
 * QEMU (+ kvm acceleration) as hypervisor.
 * etcd for key/value storage (specifically all metadata e.g Virtual Machine Specifications, Networks Specifications, Images Specifications etc.).
-* Ceph for image storage.
+* CEPH for image storage.
 * uotp for user authentication.
+* netbox for IPAM.
+* radvd for Router Advertisement.
+
 
 Components
 ----------
diff --git a/docs/source/misc/todo.rst b/ucloud/docs/source/misc/todo.rst
similarity index 100%
rename from docs/source/misc/todo.rst
rename to ucloud/docs/source/misc/todo.rst
diff --git a/docs/source/theory/summary.rst b/ucloud/docs/source/theory/summary.rst
similarity index 98%
rename from docs/source/theory/summary.rst
rename to ucloud/docs/source/theory/summary.rst
index 62f6200..864a797 100644
--- a/docs/source/theory/summary.rst
+++ b/ucloud/docs/source/theory/summary.rst
@@ -62,8 +62,8 @@ later for creating OS Images.
 format which would then be imported into image store.
 
 * In case of **File System**, the converted image would be copied to
-  :file:`/var/image/` or the path referred by :envvar:`IMAGE_PATH` environement variable
-  mentioned in :file:`/etc/ucloud/ucloud.conf`.
+  :file:`/var/image/` or the path referred by :envvar:`IMAGE_PATH`
+  environement variable mentioned in :file:`/etc/ucloud/ucloud.conf`.
 
 * In case of **CEPH**, the converted image would be imported into
   specific pool (it depends on the image store in which the image
diff --git a/docs/source/troubleshooting/installation-troubleshooting.rst b/ucloud/docs/source/troubleshooting/installation-troubleshooting.rst
similarity index 100%
rename from docs/source/troubleshooting/installation-troubleshooting.rst
rename to ucloud/docs/source/troubleshooting/installation-troubleshooting.rst
diff --git a/docs/source/usage/how-to-create-an-os-image-for-ucloud.rst b/ucloud/docs/source/usage/how-to-create-an-os-image-for-ucloud.rst
similarity index 100%
rename from docs/source/usage/how-to-create-an-os-image-for-ucloud.rst
rename to ucloud/docs/source/usage/how-to-create-an-os-image-for-ucloud.rst
diff --git a/docs/source/usage/usage-for-admins.rst b/ucloud/docs/source/usage/usage-for-admins.rst
similarity index 96%
rename from docs/source/usage/usage-for-admins.rst
rename to ucloud/docs/source/usage/usage-for-admins.rst
index 3c20fb4..44298cc 100644
--- a/docs/source/usage/usage-for-admins.rst
+++ b/ucloud/docs/source/usage/usage-for-admins.rst
@@ -76,12 +76,12 @@ contexualize VMs.
 
 Upload Sample OS Image
 ~~~~~~~~~~~~~~~~~~~~~~
-Execute the following to upload the sample OS image file.
+Execute the following to get the sample OS image file.
 
 .. code-block:: sh
 
     mkdir /var/www/admin
-    (cd /var/www/admin && wget http://[2a0a:e5c0:2:12:0:f0ff:fea9:c3d9]/alpine-untouched.qcow2)
+    (cd /var/www/admin && wget https://cloud.ungleich.ch/s/qTb5dFYW5ii8KsD/download)
 
 Run File Scanner and Image Scanner
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/source/usage/usage-for-users.rst b/ucloud/docs/source/usage/usage-for-users.rst
similarity index 92%
rename from docs/source/usage/usage-for-users.rst
rename to ucloud/docs/source/usage/usage-for-users.rst
index 315fa80..1c59408 100644
--- a/docs/source/usage/usage-for-users.rst
+++ b/ucloud/docs/source/usage/usage-for-users.rst
@@ -4,7 +4,8 @@ Usage Guide For End Users
 Create VM
 ---------
 
-The following command would create a Virtual Machine (name: meow) with following specs
+The following command would create a Virtual Machine (name: meow)
+with following specs
 
 * CPU: 1
 * RAM: 1GB
@@ -55,8 +56,9 @@ Check VM Status
 Connect to VM using VNC
 -----------------------
 
-We would need **socat** utility and a remote desktop client e.g Remmina, KRDC etc.
-We can get the vnc socket path by getting its status, see :ref:`how-to-check-vm-status`.
+We would need **socat** utility and a remote desktop client
+e.g Remmina, KRDC etc. We can get the vnc socket path by getting
+its status, see :ref:`how-to-check-vm-status`.
 
 
 .. code-block:: sh
diff --git a/host/__init__.py b/ucloud/filescanner/__init__.py
similarity index 100%
rename from host/__init__.py
rename to ucloud/filescanner/__init__.py
diff --git a/filescanner/main.py b/ucloud/filescanner/main.py
similarity index 97%
rename from filescanner/main.py
rename to ucloud/filescanner/main.py
index 385d31d..b9fefcc 100755
--- a/filescanner/main.py
+++ b/ucloud/filescanner/main.py
@@ -5,8 +5,8 @@ import subprocess as sp
 import time
 from uuid import uuid4
 
-from filescanner import logger
-from config import env_vars, etcd_client
+from ucloud.filescanner import logger
+from ucloud.config import env_vars, etcd_client
 
 
 def getxattr(file, attr):
diff --git a/hack/README.org b/ucloud/hack/README.org
similarity index 100%
rename from hack/README.org
rename to ucloud/hack/README.org
diff --git a/hack/conf.d/ucloud-host b/ucloud/hack/conf.d/ucloud-host
similarity index 100%
rename from hack/conf.d/ucloud-host
rename to ucloud/hack/conf.d/ucloud-host
diff --git a/hack/nftables.conf b/ucloud/hack/nftables.conf
similarity index 100%
rename from hack/nftables.conf
rename to ucloud/hack/nftables.conf
diff --git a/hack/rc-scripts/ucloud-api b/ucloud/hack/rc-scripts/ucloud-api
similarity index 100%
rename from hack/rc-scripts/ucloud-api
rename to ucloud/hack/rc-scripts/ucloud-api
diff --git a/hack/rc-scripts/ucloud-host b/ucloud/hack/rc-scripts/ucloud-host
similarity index 100%
rename from hack/rc-scripts/ucloud-host
rename to ucloud/hack/rc-scripts/ucloud-host
diff --git a/ucloud/hack/rc-scripts/ucloud-metadata b/ucloud/hack/rc-scripts/ucloud-metadata
new file mode 100644
index 0000000..d41807f
--- /dev/null
+++ b/ucloud/hack/rc-scripts/ucloud-metadata
@@ -0,0 +1,8 @@
+#!/sbin/openrc-run
+
+name="$RC_SVCNAME"
+pidfile="/var/run/${name}.pid"
+command="$(which pipenv)"
+command_args="run python ucloud.py metadata"
+command_background="true"
+directory="/root/ucloud"
\ No newline at end of file
diff --git a/hack/rc-scripts/ucloud-scheduler b/ucloud/hack/rc-scripts/ucloud-scheduler
similarity index 100%
rename from hack/rc-scripts/ucloud-scheduler
rename to ucloud/hack/rc-scripts/ucloud-scheduler
diff --git a/imagescanner/__init__.py b/ucloud/host/__init__.py
similarity index 100%
rename from imagescanner/__init__.py
rename to ucloud/host/__init__.py
diff --git a/host/helper.py b/ucloud/host/helper.py
similarity index 100%
rename from host/helper.py
rename to ucloud/host/helper.py
diff --git a/host/main.py b/ucloud/host/main.py
similarity index 98%
rename from host/main.py
rename to ucloud/host/main.py
index 9b12c30..1a3e449 100755
--- a/host/main.py
+++ b/ucloud/host/main.py
@@ -4,8 +4,8 @@ import time
 
 from etcd3_wrapper import Etcd3Wrapper
 
-from common.request import RequestEntry, RequestType
-from config import (vm_pool, request_pool,
+from ucloud.common.request import RequestEntry, RequestType
+from ucloud.config import (vm_pool, request_pool,
                     etcd_client, running_vms,
                     etcd_wrapper_args, etcd_wrapper_kwargs,
                     HostPool, env_vars)
diff --git a/host/qmp/__init__.py b/ucloud/host/qmp/__init__.py
similarity index 100%
rename from host/qmp/__init__.py
rename to ucloud/host/qmp/__init__.py
diff --git a/host/qmp/qmp.py b/ucloud/host/qmp/qmp.py
similarity index 100%
rename from host/qmp/qmp.py
rename to ucloud/host/qmp/qmp.py
diff --git a/host/virtualmachine.py b/ucloud/host/virtualmachine.py
similarity index 97%
rename from host/virtualmachine.py
rename to ucloud/host/virtualmachine.py
index 52bf7dc..ce23daa 100755
--- a/host/virtualmachine.py
+++ b/ucloud/host/virtualmachine.py
@@ -18,10 +18,10 @@ from os.path import join as join_path
 import bitmath
 import sshtunnel
 
-from common.helpers import get_ipv6_address
-from common.request import RequestEntry, RequestType
-from common.vm import VMEntry, VMStatus
-from config import etcd_client, request_pool, running_vms, vm_pool, env_vars, image_storage_handler
+from ucloud.common.helpers import get_ipv6_address
+from ucloud.common.request import RequestEntry, RequestType
+from ucloud.common.vm import VMEntry, VMStatus
+from ucloud.config import etcd_client, request_pool, running_vms, vm_pool, env_vars, image_storage_handler
 from . import qmp
 from host import logger
 
diff --git a/ucloud/imagescanner/__init__.py b/ucloud/imagescanner/__init__.py
new file mode 100644
index 0000000..eea436a
--- /dev/null
+++ b/ucloud/imagescanner/__init__.py
@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)
diff --git a/imagescanner/main.py b/ucloud/imagescanner/main.py
similarity index 96%
rename from imagescanner/main.py
rename to ucloud/imagescanner/main.py
index 4b41642..20ce9d5 100755
--- a/imagescanner/main.py
+++ b/ucloud/imagescanner/main.py
@@ -3,8 +3,8 @@ import os
 import subprocess
 
 from os.path import join as join_path
-from config import etcd_client, env_vars, image_storage_handler
-from imagescanner import logger
+from ucloud.config import etcd_client, env_vars, image_storage_handler
+from ucloud.imagescanner import logger
 
 
 def qemu_img_type(path):
diff --git a/docs/source/__init__.py b/ucloud/metadata/__init__.py
similarity index 100%
rename from docs/source/__init__.py
rename to ucloud/metadata/__init__.py
diff --git a/metadata/main.py b/ucloud/metadata/main.py
similarity index 98%
rename from metadata/main.py
rename to ucloud/metadata/main.py
index 7176d41..e7cb33b 100644
--- a/metadata/main.py
+++ b/ucloud/metadata/main.py
@@ -3,7 +3,7 @@ import os
 from flask import Flask, request
 from flask_restful import Resource, Api
 
-from config import etcd_client, env_vars, vm_pool
+from ucloud.config import etcd_client, env_vars, vm_pool
 
 app = Flask(__name__)
 api = Api(app)
diff --git a/network/README b/ucloud/network/README
similarity index 100%
rename from network/README
rename to ucloud/network/README
diff --git a/metadata/__init__.py b/ucloud/network/__init__.py
similarity index 100%
rename from metadata/__init__.py
rename to ucloud/network/__init__.py
diff --git a/network/create-bridge.sh b/ucloud/network/create-bridge.sh
similarity index 100%
rename from network/create-bridge.sh
rename to ucloud/network/create-bridge.sh
diff --git a/network/create-tap.sh b/ucloud/network/create-tap.sh
similarity index 100%
rename from network/create-tap.sh
rename to ucloud/network/create-tap.sh
diff --git a/network/create-vxlan.sh b/ucloud/network/create-vxlan.sh
similarity index 100%
rename from network/create-vxlan.sh
rename to ucloud/network/create-vxlan.sh
diff --git a/network/radvd-template.conf b/ucloud/network/radvd-template.conf
similarity index 100%
rename from network/radvd-template.conf
rename to ucloud/network/radvd-template.conf
diff --git a/sanity_checks.py b/ucloud/sanity_checks.py
similarity index 96%
rename from sanity_checks.py
rename to ucloud/sanity_checks.py
index 2c645a5..143f767 100644
--- a/sanity_checks.py
+++ b/ucloud/sanity_checks.py
@@ -2,7 +2,7 @@ import sys
 import subprocess as sp
 
 from os.path import isdir
-from config import env_vars
+from ucloud.config import env_vars
 
 
 def check():
diff --git a/scheduler/__init__.py b/ucloud/scheduler/__init__.py
similarity index 100%
rename from scheduler/__init__.py
rename to ucloud/scheduler/__init__.py
diff --git a/scheduler/helper.py b/ucloud/scheduler/helper.py
similarity index 94%
rename from scheduler/helper.py
rename to ucloud/scheduler/helper.py
index 79bfd70..ba577d6 100755
--- a/scheduler/helper.py
+++ b/ucloud/scheduler/helper.py
@@ -3,10 +3,10 @@ from functools import reduce
 
 import bitmath
 
-from common.host import HostStatus
-from common.request import RequestEntry, RequestType
-from common.vm import VMStatus
-from config import vm_pool, host_pool, request_pool, env_vars
+from ucloud.common.host import HostStatus
+from ucloud.common.request import RequestEntry, RequestType
+from ucloud.common.vm import VMStatus
+from ucloud.config import vm_pool, host_pool, request_pool, env_vars
 
 
 def accumulated_specs(vms_specs):
diff --git a/scheduler/main.py b/ucloud/scheduler/main.py
similarity index 95%
rename from scheduler/main.py
rename to ucloud/scheduler/main.py
index 4511dcc..54d81d6 100755
--- a/scheduler/main.py
+++ b/ucloud/scheduler/main.py
@@ -4,12 +4,12 @@
 #  2. Introduce a status endpoint of the scheduler -
 #     maybe expose a prometheus compatible output
 
-from common.request import RequestEntry, RequestType
-from config import etcd_client
-from config import host_pool, request_pool, vm_pool, env_vars
+from ucloud.common.request import RequestEntry, RequestType
+from ucloud.config import etcd_client
+from ucloud.config import host_pool, request_pool, vm_pool, env_vars
 from .helper import (get_suitable_host, dead_host_mitigation, dead_host_detection,
                      assign_host, NoSuitableHostFound)
-from scheduler import logger
+from ucloud.scheduler import logger
 
 
 def main():
diff --git a/network/__init__.py b/ucloud/scheduler/tests/__init__.py
similarity index 100%
rename from network/__init__.py
rename to ucloud/scheduler/tests/__init__.py
diff --git a/scheduler/tests/test_basics.py b/ucloud/scheduler/tests/test_basics.py
similarity index 99%
rename from scheduler/tests/test_basics.py
rename to ucloud/scheduler/tests/test_basics.py
index ef82fc0..92b3a83 100755
--- a/scheduler/tests/test_basics.py
+++ b/ucloud/scheduler/tests/test_basics.py
@@ -15,7 +15,7 @@ from main import (
     main,
 )
 
-from config import etcd_client
+from ucloud.config import etcd_client
 
 
 class TestFunctions(unittest.TestCase):
diff --git a/scheduler/tests/test_dead_host_mechanism.py b/ucloud/scheduler/tests/test_dead_host_mechanism.py
similarity index 100%
rename from scheduler/tests/test_dead_host_mechanism.py
rename to ucloud/scheduler/tests/test_dead_host_mechanism.py