Compare commits

...

10 commits
master ... wip

Author SHA1 Message Date
ab625847c5 a 2019-09-26 20:07:56 +05:00
7b614da847 a 2019-09-17 13:07:17 +05:00
fb940b60d7 a 2019-09-17 13:01:46 +05:00
edb63e2211 a 2019-09-17 12:41:40 +05:00
6bb6f31f7f a 2019-09-17 10:35:19 +05:00
f704772c6c a 2019-09-16 19:37:03 +05:00
f0af8aec72 a 2019-09-14 20:53:12 +05:00
5092c6e1c6 a 2019-09-14 19:45:50 +05:00
5248204575 a 2019-09-14 00:00:54 +05:00
b28fe5d78b a 2019-09-13 16:26:26 +05:00
5 changed files with 167 additions and 495 deletions

14
Pipfile
View file

@ -3,19 +3,13 @@ name = "pypi"
url = "https://pypi.org/simple" url = "https://pypi.org/simple"
verify_ssl = true verify_ssl = true
[dev-packages]
bandit = "*"
pylama = "*"
prospector = "*"
[packages] [packages]
python-decouple = "*" python-decouple = "*"
cython = "*"
pylint = "*"
grpcio = "*"
python-etcd3 = {editable = true,git = "https://github.com/kragniz/python-etcd3"}
sshtunnel = "*" sshtunnel = "*"
bitmath = "*" bitmath = "*"
python-etcd3 = {editable = true,git = "git+https://github.com/kragniz/python-etcd3.git"}
etcd3-wrapper = {editable = true,git = "git+https://code.ungleich.ch/ungleich-public/etcd3_wrapper.git",ref = "wip"}
ucloud-common = {editable = true,git = "git+https://code.ungleich.ch/ucloud/ucloud_common.git",ref = "wip"}
[requires] [requires]
python_version = "3.7" python_version = "3.5"

408
Pipfile.lock generated Executable file → Normal file
View file

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "05c0e0fbcad89f0740bfca9356e4493d95eb898c35017258f750c8c4674034fa" "sha256": "75946fbe11dd27d206178e7c6f2972ea55772061eccfdcea250d301b7ddde61c"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.7" "python_version": "3.5"
}, },
"sources": [ "sources": [
{ {
@ -23,13 +23,6 @@
], ],
"version": "==0.24.0" "version": "==0.24.0"
}, },
"astroid": {
"hashes": [
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
],
"version": "==2.2.5"
},
"bcrypt": { "bcrypt": {
"hashes": [ "hashes": [
"sha256:0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89", "sha256:0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89",
@ -112,39 +105,10 @@
], ],
"version": "==2.7" "version": "==2.7"
}, },
"cython": { "etcd3-wrapper": {
"hashes": [ "editable": true,
"sha256:07efba7b32c082c519b75e3b03821c2f32848e2b3e9986c784bbd8ffaf0666d7", "git": "https://code.ungleich.ch/ungleich-public/etcd3_wrapper.git",
"sha256:08db41daf18fabf7b7a85e39aa26954f6246994540043194af026c0df65a4942", "ref": "76fb0bdf797199e9ea161dad1d004eea9b4520f8"
"sha256:19bbe3caf885a1d2e2c30eacc10d1e45dbbefb156493fe1d5d1adc1668cc1269",
"sha256:1c574f2f2ba760b82b2bcf6262e77e75589247dc5ef796a3ff1b2213e50ee452",
"sha256:1dfe672c686e34598bdbaa93c3b30acb3720ae9258232a4f68ba04ee9969063d",
"sha256:283faea84e6c4e54c3f5c8ff89aa2b6c1c3a813aad4f6d48ed3b9cc9043ef9f9",
"sha256:2a145888d0942e7c36e86a7b7c7e2923cb9f7055805a3b72dcb137e3efdb0979",
"sha256:3f75065936e16569d6e13dfd76de988f5eabeae460aa54770c9b961ab6f747fc",
"sha256:4d78124f5f281f1d5d5b7919cbbc65a7073ff93562def81ee78a8307e6e72494",
"sha256:5ba4d088b8e5d59b8a5911ca9c72952acf3c83296b57daf75af92fb2af1e8423",
"sha256:6b19daeda1d5d1dfc973b291246f6a63a663b20c33980724d6d073c562719536",
"sha256:790c7dc80fd1c3e38acefe06027e2f5a8466c128c7e47c6e140fd5316132574d",
"sha256:7f8c4e648881454ba3ba0bcf3b21a9e1878a67d20ea2b8d9ec1c4c628592ab6b",
"sha256:8bcd3f597290f9902548d6355898d7e376e7f3762f89db9cd50b2b58429df9e8",
"sha256:8ffb18f71972a5c718a8600d9f52e3507f0d6fb72a978e03270d34a7035c98fb",
"sha256:92f025df1cb391e09f65775598c7dfb7efad72d74713775db54e267f62ca94a1",
"sha256:93cf1c72472a2fd0ef4c52f6074dab08fc28d475b9c824ba73a52701f7a48ae1",
"sha256:9a7fa692cdc967fdbf6a053c1975137d01f6935dede2ef222c71840b290caf79",
"sha256:a68eb0c1375f2401de881692b30370a51e550052b8e346b2f71bbdbdc74a214f",
"sha256:ac3b7a12ddd52ea910ee3a041e6bc65df7a52f0ba7bd10fb7123502af482c152",
"sha256:b402b700edaf571a0bae18ec35d5b71c266873a6616412b672435c10b6d8f041",
"sha256:c29d069a4a30f472482343c866f7486731ad638ef9af92bfe5fca9c7323d638e",
"sha256:d822311498f185db449b687336b4e5db7638c8d8b03bdf10ae91d74e23c7cc0c",
"sha256:dccc8df9e1ac158b06777bbaaeb4516f245f9b147701ae25e6023960e4a0c2a3",
"sha256:e31f4b946c2765b2f35440fdb4b00c496dfc5babc53c7ae61966b41171d1d59f",
"sha256:eb43f9e582cc221ee2832e25ea6fe5c06f2acc9da6353c562e922f107db12af8",
"sha256:f07822248110fd6213db8bc2745fdbbccef6f2b3d18ac91a7fba29c6bc575da5",
"sha256:ff69854f123b959d4ae14bd5330714bb9ee4360052992dc0fbd0a3dee4261f95"
],
"index": "pypi",
"version": "==0.29.13"
}, },
"grpcio": { "grpcio": {
"hashes": [ "hashes": [
@ -183,43 +147,6 @@
], ],
"version": "==1.23.0" "version": "==1.23.0"
}, },
"isort": {
"hashes": [
"sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
"sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
],
"version": "==4.3.21"
},
"lazy-object-proxy": {
"hashes": [
"sha256:159a745e61422217881c4de71f9eafd9d703b93af95618635849fe469a283661",
"sha256:23f63c0821cc96a23332e45dfaa83266feff8adc72b9bcaef86c202af765244f",
"sha256:3b11be575475db2e8a6e11215f5aa95b9ec14de658628776e10d96fa0b4dac13",
"sha256:3f447aff8bc61ca8b42b73304f6a44fa0d915487de144652816f950a3f1ab821",
"sha256:4ba73f6089cd9b9478bc0a4fa807b47dbdb8fad1d8f31a0f0a5dbf26a4527a71",
"sha256:4f53eadd9932055eac465bd3ca1bd610e4d7141e1278012bd1f28646aebc1d0e",
"sha256:64483bd7154580158ea90de5b8e5e6fc29a16a9b4db24f10193f0c1ae3f9d1ea",
"sha256:6f72d42b0d04bfee2397aa1862262654b56922c20a9bb66bb76b6f0e5e4f9229",
"sha256:7c7f1ec07b227bdc561299fa2328e85000f90179a2f44ea30579d38e037cb3d4",
"sha256:7c8b1ba1e15c10b13cad4171cfa77f5bb5ec2580abc5a353907780805ebe158e",
"sha256:8559b94b823f85342e10d3d9ca4ba5478168e1ac5658a8a2f18c991ba9c52c20",
"sha256:a262c7dfb046f00e12a2bdd1bafaed2408114a89ac414b0af8755c696eb3fc16",
"sha256:acce4e3267610c4fdb6632b3886fe3f2f7dd641158a843cf6b6a68e4ce81477b",
"sha256:be089bb6b83fac7f29d357b2dc4cf2b8eb8d98fe9d9ff89f9ea6012970a853c7",
"sha256:bfab710d859c779f273cc48fb86af38d6e9210f38287df0069a63e40b45a2f5c",
"sha256:c10d29019927301d524a22ced72706380de7cfc50f767217485a912b4c8bd82a",
"sha256:dd6e2b598849b3d7aee2295ac765a578879830fb8966f70be8cd472e6069932e",
"sha256:e408f1eacc0a68fed0c08da45f31d0ebb38079f043328dce69ff133b95c29dc1"
],
"version": "==1.4.1"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"paramiko": { "paramiko": {
"hashes": [ "hashes": [
"sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf", "sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf",
@ -229,24 +156,24 @@
}, },
"protobuf": { "protobuf": {
"hashes": [ "hashes": [
"sha256:00a1b0b352dc7c809749526d1688a64b62ea400c5b05416f93cfb1b11a036295", "sha256:26c0d756c7ad6823fccbc3b5f84c619b9cc7ac281496fe0a9d78e32023c45034",
"sha256:01acbca2d2c8c3f7f235f1842440adbe01bbc379fa1cbdd80753801432b3fae9", "sha256:3200046e4d4f6c42ed66257dbe15e2e5dc76072c280e9b3d69dc8f3a4fa3fbbc",
"sha256:0a795bca65987b62d6b8a2d934aa317fd1a4d06a6dd4df36312f5b0ade44a8d9", "sha256:368f1bae6dd22d04fd2254d30cd301863408a96ff604422e3ddd8ab601f095a4",
"sha256:0ec035114213b6d6e7713987a759d762dd94e9f82284515b3b7331f34bfaec7f", "sha256:3902fa1920b4ef9f710797496b309efc5ccd0faeba44dc82ed6a711a244764a0",
"sha256:31b18e1434b4907cb0113e7a372cd4d92c047ce7ba0fa7ea66a404d6388ed2c1", "sha256:3a7a8925ba6481b9241cdb5d69cd0b0700f23efed6bb691dc9543faa4aa25d6f",
"sha256:32a3abf79b0bef073c70656e86d5bd68a28a1fbb138429912c4fc07b9d426b07", "sha256:4bc33d49f43c6e9916fb56b7377cb4478cbf25824b4d2bedfb8a4e3df31c12ca",
"sha256:55f85b7808766e5e3f526818f5e2aeb5ba2edcc45bcccede46a3ccc19b569cb0", "sha256:568b434a36e31ed30d60d600b2227666ce150b8b5275948f50411481a4575d6d",
"sha256:64ab9bc971989cbdd648c102a96253fdf0202b0c38f15bd34759a8707bdd5f64", "sha256:5c393cd665d03ce6b29561edd6b0cc4bcb3fb8e2a7843e8f223d693f07f61b40",
"sha256:64cf847e843a465b6c1ba90fb6c7f7844d54dbe9eb731e86a60981d03f5b2e6e", "sha256:80072e9ba36c73cf89c01f669c7b123733fc2de1780b428082a850f53cc7865f",
"sha256:917c8662b585470e8fd42f052661fc66d59fccaae450a60044307dcbf82a3335", "sha256:843f498e98ad1469ad54ecb4a7ccf48605a1c5d2bd26ae799c7a2cddab4a37ec",
"sha256:afed9003d7f2be2c3df20f64220c30faec441073731511728a2cb4cab4cd46a6", "sha256:aa45443035651cbfae74c8deb53358ba660d8e7a5fbab3fc4beb33fb3e3ca4be",
"sha256:bf8e05d638b585d1752c5a84247134a0350d3a8b73d3632489a014a9f6f1e758", "sha256:aaab817d9d038dd5f56a6fb2b2e8ae68caf1fd28cc6a963c755fa73268495c13",
"sha256:d831b047bd69becaf64019a47179eb22118a50dd008340655266a906c69c6417", "sha256:e6f68b9979dc8f75299293d682f67fecb72d78f98652da2eeb85c85edef1ca94",
"sha256:de2760583ed28749ff885789c1cbc6c9c06d6de92fc825740ab99deb2f25ea4d", "sha256:e7366cabddff3441d583fdc0176ab42eba4ee7090ef857d50c4dd59ad124003a",
"sha256:eabc4cf1bc19689af8022ba52fd668564a8d96e0d08f3b4732d26a64255216a4", "sha256:f0144ad97cd28bfdda0567b9278d25061ada5ad2b545b538cd3577697b32bda3",
"sha256:fcff6086c86fb1628d94ea455c7b9de898afc50378042927a59df8065a79a549" "sha256:f655338491481f482042f19016647e50365ab41b75b486e0df56e0dcc425abf4"
], ],
"version": "==3.9.1" "version": "==3.9.2"
}, },
"pycparser": { "pycparser": {
"hashes": [ "hashes": [
@ -254,14 +181,6 @@
], ],
"version": "==2.19" "version": "==2.19"
}, },
"pylint": {
"hashes": [
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
"sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1"
],
"index": "pypi",
"version": "==2.3.1"
},
"pynacl": { "pynacl": {
"hashes": [ "hashes": [
"sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255", "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255",
@ -295,7 +214,7 @@
}, },
"python-etcd3": { "python-etcd3": {
"editable": true, "editable": true,
"git": "https://github.com/kragniz/python-etcd3", "git": "https://github.com/kragniz/python-etcd3.git",
"ref": "cdc4c48bde88a795230a02aa574df84ed9ccfa52" "ref": "cdc4c48bde88a795230a02aa574df84ed9ccfa52"
}, },
"six": { "six": {
@ -319,280 +238,11 @@
], ],
"version": "==5.1.1" "version": "==5.1.1"
}, },
"typed-ast": { "ucloud-common": {
"hashes": [ "editable": true,
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "git": "https://code.ungleich.ch/ucloud/ucloud_common.git",
"sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "ref": "0976a3e2ef648564483e69e89a530f55be630e08"
"sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0",
"sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c",
"sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631",
"sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4",
"sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34",
"sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b",
"sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a",
"sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233",
"sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1",
"sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36",
"sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d",
"sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a",
"sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"
],
"markers": "implementation_name == 'cpython'",
"version": "==1.4.0"
},
"wrapt": {
"hashes": [
"sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
],
"version": "==1.11.2"
} }
}, },
"develop": { "develop": {}
"astroid": {
"hashes": [
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
],
"version": "==2.2.5"
},
"bandit": {
"hashes": [
"sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952",
"sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"
],
"index": "pypi",
"version": "==1.6.2"
},
"ddt": {
"hashes": [
"sha256:474546b4020ce8a2f9550ba8899c28aa2c284c7bbf175bddede98be949d1ca7c",
"sha256:d13e6af8f36238e89d00f4ebccf2bda4f6d1878be560a6600689e42077e164e3"
],
"version": "==1.2.1"
},
"dodgy": {
"hashes": [
"sha256:65e13cf878d7aff129f1461c13cb5fd1bb6dfe66bb5327e09379c3877763280c"
],
"version": "==0.1.9"
},
"gitdb2": {
"hashes": [
"sha256:83361131a1836661a155172932a13c08bda2db3674e4caa32368aa6eb02f38c2",
"sha256:e3a0141c5f2a3f635c7209d56c496ebe1ad35da82fe4d3ec4aaa36278d70648a"
],
"version": "==2.0.5"
},
"gitpython": {
"hashes": [
"sha256:259a8b6d6a4a118738c4a65fa990f8c8c91525bb43970aed2868952ebb86ceb8",
"sha256:73aa7b59e58dd3435121421c33c284e5ef51bc7b2f4373e1a1e4cc06e9c928ec"
],
"version": "==3.0.1"
},
"isort": {
"hashes": [
"sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
"sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
],
"version": "==4.3.21"
},
"lazy-object-proxy": {
"hashes": [
"sha256:159a745e61422217881c4de71f9eafd9d703b93af95618635849fe469a283661",
"sha256:23f63c0821cc96a23332e45dfaa83266feff8adc72b9bcaef86c202af765244f",
"sha256:3b11be575475db2e8a6e11215f5aa95b9ec14de658628776e10d96fa0b4dac13",
"sha256:3f447aff8bc61ca8b42b73304f6a44fa0d915487de144652816f950a3f1ab821",
"sha256:4ba73f6089cd9b9478bc0a4fa807b47dbdb8fad1d8f31a0f0a5dbf26a4527a71",
"sha256:4f53eadd9932055eac465bd3ca1bd610e4d7141e1278012bd1f28646aebc1d0e",
"sha256:64483bd7154580158ea90de5b8e5e6fc29a16a9b4db24f10193f0c1ae3f9d1ea",
"sha256:6f72d42b0d04bfee2397aa1862262654b56922c20a9bb66bb76b6f0e5e4f9229",
"sha256:7c7f1ec07b227bdc561299fa2328e85000f90179a2f44ea30579d38e037cb3d4",
"sha256:7c8b1ba1e15c10b13cad4171cfa77f5bb5ec2580abc5a353907780805ebe158e",
"sha256:8559b94b823f85342e10d3d9ca4ba5478168e1ac5658a8a2f18c991ba9c52c20",
"sha256:a262c7dfb046f00e12a2bdd1bafaed2408114a89ac414b0af8755c696eb3fc16",
"sha256:acce4e3267610c4fdb6632b3886fe3f2f7dd641158a843cf6b6a68e4ce81477b",
"sha256:be089bb6b83fac7f29d357b2dc4cf2b8eb8d98fe9d9ff89f9ea6012970a853c7",
"sha256:bfab710d859c779f273cc48fb86af38d6e9210f38287df0069a63e40b45a2f5c",
"sha256:c10d29019927301d524a22ced72706380de7cfc50f767217485a912b4c8bd82a",
"sha256:dd6e2b598849b3d7aee2295ac765a578879830fb8966f70be8cd472e6069932e",
"sha256:e408f1eacc0a68fed0c08da45f31d0ebb38079f043328dce69ff133b95c29dc1"
],
"version": "==1.4.1"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"pbr": {
"hashes": [
"sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc",
"sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf"
],
"version": "==5.4.2"
},
"pep8-naming": {
"hashes": [
"sha256:1b419fa45b68b61cd8c5daf4e0c96d28915ad14d3d5f35fcc1e7e95324a33a2e",
"sha256:4eedfd4c4b05e48796f74f5d8628c068ff788b9c2b08471ad408007fc6450e5a"
],
"version": "==0.4.1"
},
"prospector": {
"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"
},
"pylama": {
"hashes": [
"sha256:9bae53ef9c1a431371d6a8dca406816a60d547147b60a4934721898f553b7d8f",
"sha256:fd61c11872d6256b019ef1235be37b77c922ef37ac9797df6bd489996dddeb15"
],
"index": "pypi",
"version": "==7.7.1"
},
"pylint": {
"hashes": [
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
"sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1"
],
"index": "pypi",
"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:8d9e31d5ea8b7b0003e1f0f136b44a5235896a32e47c5bc2ef1143e9f6ba0b74"
],
"version": "==0.5"
},
"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"
},
"requirements-detector": {
"hashes": [
"sha256:9fbc4b24e8b7c3663aff32e3eba34596848c6b91bd425079b386973bd8d08931"
],
"version": "==0.6"
},
"setoptconf": {
"hashes": [
"sha256:5b0b5d8e0077713f5d5152d4f63be6f048d9a1bb66be15d089a11c898c3cf49c"
],
"version": "==0.2.0"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"smmap2": {
"hashes": [
"sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde",
"sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"
],
"version": "==2.0.5"
},
"snowballstemmer": {
"hashes": [
"sha256:9f3b9ffe0809d174f7047e121431acf99c89a7040f0ca84f94ba53a498e6d0c9"
],
"version": "==1.9.0"
},
"stevedore": {
"hashes": [
"sha256:7be098ff53d87f23d798a7ce7ae5c31f094f3deb92ba18059b1aeb1ca9fec0a0",
"sha256:7d1ce610a87d26f53c087da61f06f9b7f7e552efad2a7f6d2322632b5f932ea2"
],
"version": "==1.30.1"
},
"typed-ast": {
"hashes": [
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
"sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e",
"sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0",
"sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c",
"sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631",
"sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4",
"sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34",
"sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b",
"sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a",
"sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233",
"sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1",
"sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36",
"sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d",
"sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a",
"sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"
],
"markers": "implementation_name == 'cpython'",
"version": "==1.4.0"
},
"wrapt": {
"hashes": [
"sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
],
"version": "==1.11.2"
}
}
} }

View file

@ -18,8 +18,13 @@ logging.basicConfig(
etcd_client = Etcd3Wrapper(host=config("ETCD_URL")) etcd_client = Etcd3Wrapper(host=config("ETCD_URL"))
host_pool = HostPool(etcd_client, "/v1/host") HOST_PREFIX = config("HOST_PREFIX")
vm_pool = VmPool(etcd_client, "/v1/vm") VM_PREFIX = config("VM_PREFIX")
request_pool = RequestPool(etcd_client, "/v1/request") REQUEST_PREFIX = config("REQUEST_PREFIX")
host_pool = HostPool(etcd_client, HOST_PREFIX)
vm_pool = VmPool(etcd_client, VM_PREFIX)
request_pool = RequestPool(etcd_client, REQUEST_PREFIX)
running_vms = [] running_vms = []

27
main.py
View file

@ -7,7 +7,8 @@ from ucloud_common.host import HostEntry
from ucloud_common.request import RequestEntry, RequestType from ucloud_common.request import RequestEntry, RequestType
from config import (vm_pool, host_pool, request_pool, from config import (vm_pool, host_pool, request_pool,
etcd_client, logging, running_vms) etcd_client, logging, running_vms,
REQUEST_PREFIX)
def update_heartbeat(host: HostEntry): def update_heartbeat(host: HostEntry):
@ -16,7 +17,7 @@ def update_heartbeat(host: HostEntry):
host_pool.put(host) host_pool.put(host)
time.sleep(10) time.sleep(10)
logging.info(f"Updated last heartbeat time {host.last_heartbeat}") logging.info("Updated last heartbeat time %s", host.last_heartbeat)
def maintenance(host): def maintenance(host):
@ -49,10 +50,9 @@ def maintenance(host):
# This is to capture poweroff/shutdown of a VM # This is to capture poweroff/shutdown of a VM
# initiated by user inside VM. OR crash of VM by some # initiated by user inside VM. OR crash of VM by some
# user running process # user running process
if (_vm and not _vm.handle.is_running())\ if (_vm and not _vm.handle.is_running()) or not _vm:
or not _vm: vm_entry.add_log("""{} is not running but is said to be running.
vm_entry.add_log(f"{vm_entry.key} is not running but is said to be running." So, shutting it down and declare it killed""".format(vm_entry.key))
"So, shutting it down and declare it killed")
vm_entry.declare_killed() vm_entry.declare_killed()
vm_pool.put(vm_entry) vm_pool.put(vm_entry)
if _vm: if _vm:
@ -69,7 +69,7 @@ def main():
print("No Such Host") print("No Such Host")
exit(1) exit(1)
logging.info(f"{'*' * 5} Session Started {'*' * 5}") logging.info("%s Session Started %s", '*' * 5, '*' * 5)
# It is seen that under heavy load, timeout event doesn't come # It is seen that under heavy load, timeout event doesn't come
# in a predictive manner (which is intentional because we give # in a predictive manner (which is intentional because we give
@ -88,8 +88,8 @@ def main():
exit(-1) exit(-1)
for events_iterator in [ for events_iterator in [
etcd_client.get_prefix("/v1/request/", value_in_json=True), etcd_client.get_prefix(REQUEST_PREFIX, value_in_json=True),
etcd_client.watch_prefix("/v1/request/", timeout=10, value_in_json=True), etcd_client.watch_prefix(REQUEST_PREFIX, timeout=10, value_in_json=True),
]: ]:
for request_event in events_iterator: for request_event in events_iterator:
request_event = RequestEntry(request_event) request_event = RequestEntry(request_event)
@ -100,13 +100,12 @@ def main():
continue continue
# If the event is directed toward me OR I am destination of a InitVMMigration # If the event is directed toward me OR I am destination of a InitVMMigration
if hasattr(request_event, "hostname") and request_event.hostname == host.key or\ if (request_event.hostname == host.key or request_event.destination == host.key):
hasattr(request_event, "destination") and request_event.destination == host.key: logging.debug("EVENT: %s", request_event)
request_pool.client.client.delete(request_event.key) request_pool.client.client.delete(request_event.key)
vm_entry = vm_pool.get(request_event.uuid) vm_entry = vm_pool.get(request_event.uuid)
logging.debug(f"EVENT: {request_event}")
if request_event.type == RequestType.StartVM: if request_event.type == RequestType.StartVM:
virtualmachine.start(vm_entry) virtualmachine.start(vm_entry)
@ -122,7 +121,7 @@ def main():
elif request_event.type == RequestType.TransferVM: elif request_event.type == RequestType.TransferVM:
virtualmachine.transfer(request_event) virtualmachine.transfer(request_event)
logging.info(f"Running VMs {running_vms}") logging.info("Running VMs %s", running_vms)
main() main()

View file

@ -4,56 +4,63 @@
# For QEMU Monitor Protocol Commands Information, See # For QEMU Monitor Protocol Commands Information, See
# https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor # https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor
import subprocess
import traceback
import errno import errno
import qmp
import tempfile
import bitmath
import time
import os import os
import subprocess
import tempfile
import time
from config import (vm_pool, request_pool, etcd_client,
logging, running_vms, WITHOUT_CEPH)
from ucloud_common.vm import VMStatus, VMEntry
from typing import Union
from functools import wraps from functools import wraps
from dataclasses import dataclass
from ucloud_common.request import RequestEntry, RequestType
import sshtunnel
from decouple import config
from os.path import join from os.path import join
from typing import Union
import bitmath
import sshtunnel
from decouple import config
import qmp
from config import (WITHOUT_CEPH, etcd_client, logging, request_pool,
running_vms, vm_pool)
from ucloud_common.helpers import get_ipv4_address from ucloud_common.helpers import get_ipv4_address
from ucloud_common.request import RequestEntry, RequestType
from ucloud_common.vm import VMEntry, VMStatus
@dataclass
class VM: class VM:
key: str def __init__(self, key, handle, vnc_socket_file):
handle: qmp.QEMUMachine self.key = key # type: str
vnc_socket_file: tempfile.NamedTemporaryFile self.handle = handle # type: qmp.QEMUMachine
self.vnc_socket_file = vnc_socket_file # type: tempfile.NamedTemporaryFile
def __repr__(self): def __repr__(self):
return f"VM({self.key})" return "VM({})".format(self.key)
def get_start_command_args(vm_entry, vnc_sock_filename: str, migration=False, migration_port=4444): def get_start_command_args(
vm_entry, vnc_sock_filename: str, migration=False, migration_port=4444
):
threads_per_core = 1 threads_per_core = 1
vm_memory = int(bitmath.Byte(int(vm_entry.specs["ram"])).to_MB()) vm_memory = int(bitmath.Byte(int(vm_entry.specs["ram"])).to_MB())
vm_cpus = int(vm_entry.specs["cpu"]) vm_cpus = int(vm_entry.specs["cpu"])
vm_uuid = vm_entry.uuid vm_uuid = vm_entry.uuid
if WITHOUT_CEPH: if WITHOUT_CEPH:
command = f"-drive file={os.path.join('/var/vm', vm_uuid)},format=raw,if=virtio,cache=none" command = "-drive file={},format=raw,if=virtio,cache=none".format(
os.path.join("/var/vm", vm_uuid)
)
else: else:
command = f"-drive file=rbd:uservms/{vm_uuid},format=raw,if=virtio,cache=none" command = "-drive file=rbd:uservms/{},format=raw,if=virtio,cache=none".format(
vm_uuid
)
command += " -device virtio-rng-pci -vnc unix:{}".format(vnc_sock_filename)
command += " -m {} -smp cores={},threads={}".format(
vm_memory, vm_cpus, threads_per_core
)
command += " -name {}".format(vm_uuid)
command += (f" -device virtio-rng-pci -vnc unix:{vnc_sock_filename}"
f" -m {vm_memory} -smp cores={vm_cpus},threads={threads_per_core}"
f" -name {vm_uuid}")
if migration: if migration:
command += f" -incoming tcp:0:{migration_port}" command += " -incoming tcp:0:{}".format(migration_port)
return command.split(" ") return command.split(" ")
@ -66,12 +73,13 @@ def create_vm_object(vm_entry, migration=False, migration_port=4444):
# REQUIREMENT: Use Unix Socket instead of TCP Port for VNC # REQUIREMENT: Use Unix Socket instead of TCP Port for VNC
vnc_sock_file = tempfile.NamedTemporaryFile() vnc_sock_file = tempfile.NamedTemporaryFile()
qemu_args = get_start_command_args(vm_entry=vm_entry, qemu_args = get_start_command_args(
vnc_sock_filename=vnc_sock_file.name, vm_entry=vm_entry,
migration=migration, vnc_sock_filename=vnc_sock_file.name,
migration_port=migration_port) migration=migration,
qemu_machine = qmp.QEMUMachine("/usr/bin/qemu-system-x86_64", migration_port=migration_port,
args=qemu_args) )
qemu_machine = qmp.QEMUMachine("/usr/bin/qemu-system-x86_64", args=qemu_args)
return VM(vm_entry.key, qemu_machine, vnc_sock_file) return VM(vm_entry.key, qemu_machine, vnc_sock_file)
@ -86,17 +94,13 @@ def need_running_vm(func):
if vm: if vm:
try: try:
status = vm.handle.command("query-status") status = vm.handle.command("query-status")
logging.debug(f"VM Status Check - {status}") logging.debug("VM Status Check - %s", status)
except Exception as exception: except Exception as exception:
logging.info( logging.info("%s failed - VM %s %s", func.__name__, e, exception)
f"{func.__name__} failed - VM {e} {exception} - Unknown Error"
)
else: else:
return func(e) return func(e)
else: else:
logging.info( logging.info("%s failed because VM %s is not running", func.__name__, e.key)
f"{func.__name__} failed because VM {e.key} is not running"
)
return return
return wrapper return wrapper
@ -106,23 +110,39 @@ def create(vm_entry: VMEntry):
vm_hdd = int(bitmath.Byte(int(vm_entry.specs["hdd"])).to_MB()) vm_hdd = int(bitmath.Byte(int(vm_entry.specs["hdd"])).to_MB())
if WITHOUT_CEPH: if WITHOUT_CEPH:
_command_to_create = ["cp", _command_to_create = [
os.path.join("/var/image", vm_entry.image_uuid), "cp",
os.path.join("/var/vm", vm_entry.uuid)] os.path.join("/var/image", vm_entry.image_uuid),
os.path.join("/var/vm", vm_entry.uuid),
]
_command_to_extend = ["qemu-img", "resize", os.path.join("/var/vm", vm_entry.uuid), vm_entry.specs["hdd"]] _command_to_extend = [
"qemu-img",
"resize",
os.path.join("/var/vm", vm_entry.uuid),
"{}M".format(vm_hdd),
]
else: else:
_command_to_create = ["rbd", "clone", _command_to_create = [
f"images/{vm_entry.image_uuid}@protected", "rbd",
f"uservms/{vm_entry.uuid}"] "clone",
"images/{}@protected".format(vm_entry.image_uuid),
"uservms/{}".format(vm_entry.uuid),
]
_command_to_extend = ["rbd", "resize", f"uservms/{vm_entry.uuid}", "--size", vm_hdd] _command_to_extend = [
"rbd",
"resize",
"uservms/{}".format(vm_entry.uuid),
"--size",
vm_hdd,
]
try: try:
subprocess.check_output(_command_to_create) subprocess.check_output(_command_to_create)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
if e.returncode == errno.EEXIST: if e.returncode == errno.EEXIST:
logging.debug(f"Image for vm {vm_entry.uuid} exists") logging.debug("Image for vm %s exists", vm_entry.uuid)
# File Already exists. No Problem Continue # File Already exists. No Problem Continue
return return
@ -145,25 +165,11 @@ def start(vm_entry: VMEntry):
# VM already running. No need to proceed further. # VM already running. No need to proceed further.
if _vm: if _vm:
logging.info(f"VM {vm_entry.uuid} already running") logging.info("VM %s already running", vm_entry.uuid)
return return
else: else:
create(vm_entry) create(vm_entry)
launch_vm(vm_entry)
logging.info(f"Starting {vm_entry.key}")
vm = create_vm_object(vm_entry)
try:
vm.handle.launch()
except (qmp.QEMUMachineError, TypeError, Exception):
vm_entry.declare_killed()
vm_entry.add_log(f"Machine Error occurred - {traceback.format_exc()}")
vm_pool.put(vm_entry)
else:
running_vms.append(vm)
vm_entry.status = VMStatus.running
vm_entry.add_log("Started successfully")
vm_pool.put(vm_entry)
@need_running_vm @need_running_vm
@ -178,9 +184,9 @@ def stop(vm_entry):
def delete(vm_entry): def delete(vm_entry):
logging.info(f"Deleting VM {vm_entry}") logging.info("Deleting VM | %s", vm_entry)
stop(vm_entry) stop(vm_entry)
path_without_protocol = vm_entry.path[vm_entry.path.find(":") + 1:] path_without_protocol = vm_entry.path[vm_entry.path.find(":") + 1 :]
if WITHOUT_CEPH: if WITHOUT_CEPH:
vm_deletion_command = ["rm", os.path.join("/var/vm", vm_entry.uuid)] vm_deletion_command = ["rm", os.path.join("/var/vm", vm_entry.uuid)]
@ -211,14 +217,16 @@ def transfer(request_event):
ssh_username=config("ssh_username"), ssh_username=config("ssh_username"),
ssh_pkey=config("ssh_pkey"), ssh_pkey=config("ssh_pkey"),
ssh_private_key_password=config("ssh_private_key_password"), ssh_private_key_password=config("ssh_private_key_password"),
remote_bind_address=('127.0.0.1', _port), remote_bind_address=("127.0.0.1", _port),
) )
try: try:
tunnel.start() tunnel.start()
except sshtunnel.BaseSSHTunnelForwarderError: except sshtunnel.BaseSSHTunnelForwarderError:
logging.exception(f"Couldn't establish connection to ({_host}, 22)") logging.exception("Couldn't establish connection to (%s, 22)", _host)
else: else:
vm.handle.command("migrate", uri=f"tcp:{_host}:{tunnel.local_bind_port}") vm.handle.command(
"migrate", uri="tcp:{}:{}".format(_host, tunnel.local_bind_port)
)
status = vm.handle.command("query-migrate")["status"] status = vm.handle.command("query-migrate")["status"]
while status not in ["failed", "completed"]: while status not in ["failed", "completed"]:
@ -250,32 +258,48 @@ def init_migration(vm_entry, destination_host_key):
if _vm: if _vm:
# VM already running. No need to proceed further. # VM already running. No need to proceed further.
logging.info(f"{_vm.key} Already running") logging.info("%s Already running", _vm.key)
return return
logging.info(f"Starting {vm_entry.key}") launch_vm(vm_entry, migration=True, migration_port=4444,
destination_host_key=destination_host_key)
vm = create_vm_object(vm_entry, migration=True, migration_port=4444)
def launch_vm(vm_entry, migration=False, migration_port=None, destination_host_key=None):
logging.info("Starting %s", vm_entry.key)
vm = create_vm_object(vm_entry, migration=migration, migration_port=migration_port)
try: try:
vm.handle.launch() vm.handle.launch()
except Exception as e: except Exception as e:
# We don't care whether MachineError or any other error occurred
logging.exception(e) logging.exception(e)
vm.handle.shutdown()
else:
vm_entry.in_migration = True
vm_pool.put(vm_entry)
if migration:
# We don't care whether MachineError or any other error occurred
vm.handle.shutdown()
else:
# Error during typical launch of a vm
vm_entry.add_log("Error Occurred while starting VM")
vm_entry.declare_killed()
vm_pool.put(vm_entry)
else:
vm_entry.vnc_socket = vm.vnc_socket_file.name
running_vms.append(vm) running_vms.append(vm)
r = RequestEntry.from_scratch(type=RequestType.TransferVM, if migration:
hostname=vm_entry.hostname, vm_entry.in_migration = True
parameters={ r = RequestEntry.from_scratch(
"host": get_ipv4_address(), type=RequestType.TransferVM,
"port": 4444, hostname=vm_entry.hostname,
}, parameters={"host": get_ipv4_address(), "port": 4444},
uuid=vm_entry.uuid, uuid=vm_entry.uuid,
destination_host_key=destination_host_key destination_host_key=destination_host_key,
) )
request_pool.put(r) request_pool.put(r)
else:
# Typical launching of a vm
vm_entry.status = VMStatus.running
vm_entry.add_log("Started successfully")
vm_pool.put(vm_entry)