implemented host status, ceph integeration, monkey patched vnc port number
This commit is contained in:
		
					parent
					
						
							
								ebbd04ad03
							
						
					
				
			
			
				commit
				
					
						b021d63a3e
					
				
			
		
					 4 changed files with 288 additions and 38 deletions
				
			
		
							
								
								
									
										2
									
								
								Pipfile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Pipfile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,10 +4,12 @@ url = "https://pypi.org/simple"
 | 
			
		|||
verify_ssl = true
 | 
			
		||||
 | 
			
		||||
[dev-packages]
 | 
			
		||||
bandit = "*"
 | 
			
		||||
 | 
			
		||||
[packages]
 | 
			
		||||
python-decouple = "*"
 | 
			
		||||
etcd3 = "*"
 | 
			
		||||
cython = "*"
 | 
			
		||||
 | 
			
		||||
[requires]
 | 
			
		||||
python_version = "3.7"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										210
									
								
								Pipfile.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								Pipfile.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,210 @@
 | 
			
		|||
{
 | 
			
		||||
    "_meta": {
 | 
			
		||||
        "hash": {
 | 
			
		||||
            "sha256": "60ec9dd9adb030a2f5c569016cd23b6d3c2bf29c3ee746531017928b0b496fe7"
 | 
			
		||||
        },
 | 
			
		||||
        "pipfile-spec": 6,
 | 
			
		||||
        "requires": {
 | 
			
		||||
            "python_version": "3.7"
 | 
			
		||||
        },
 | 
			
		||||
        "sources": [
 | 
			
		||||
            {
 | 
			
		||||
                "name": "pypi",
 | 
			
		||||
                "url": "https://pypi.org/simple",
 | 
			
		||||
                "verify_ssl": true
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "default": {
 | 
			
		||||
        "cython": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:04ebf16df9406d3279a2489c3327803c782d9e17637d525bfb44ecf5ec65850f",
 | 
			
		||||
                "sha256:1486ec88d1c73dea3846a5640054018b002608e04a791ccbd2082a47bce4440a",
 | 
			
		||||
                "sha256:20da832a5e9a8e93d1e1eb64650258956723940968eb585506531719b55b804f",
 | 
			
		||||
                "sha256:2464688b523d7a133b52cf1343c1c595b92fc6554af1015f74b9e49951e992d4",
 | 
			
		||||
                "sha256:27827b68a8359e9ab6bf683c68d8ee79863a0c94a577acf56aa02cc302e16f51",
 | 
			
		||||
                "sha256:27deeeeca0fd8933af07923e809c8fed0763d150a4fdd4082932a33b8c874ed6",
 | 
			
		||||
                "sha256:31f4da785d5e09deb852ea59795a629c5befb6040929e7880c6f63e6668246ce",
 | 
			
		||||
                "sha256:4828cf8fa638c35139e643f30201b240c0d156b1b9967a7321ae42d721d7224c",
 | 
			
		||||
                "sha256:48b365e32cc5639ae2c239d7bd4f8a1d920a13a7ae92113c4c938903c9400147",
 | 
			
		||||
                "sha256:4eb71856c1d1b33083df9318fd30143470ad6f0d1b9ad2ee61a120710842d28b",
 | 
			
		||||
                "sha256:5b06ef8422d27d8128f8f80bdefa111eadcab246fba1d668720af4f0b97b7a0e",
 | 
			
		||||
                "sha256:71c553640e1ddaaf143e38dbc6cd1863fa3c0738fb1830a9aaffba9a51838f30",
 | 
			
		||||
                "sha256:73e2742ee1f923c5f213183bf493901f9630e395634fce5b739a53b7dc5d64be",
 | 
			
		||||
                "sha256:82a632bc02063eff0b8e7ff3089aa3d912d1c7499709f51c8f04f57c8832cfe6",
 | 
			
		||||
                "sha256:977ca1ac059e4d4a4bf5fe2224986baf42b69290453eda44822606f4deae6515",
 | 
			
		||||
                "sha256:a7e6217d0dd864a7cc4f457172766864496efd64d24d4980df1521f75f992761",
 | 
			
		||||
                "sha256:ad0ed7dd5dff76eb3aae8c18d95b1c9f885a91a92132728051a704fb8060d08c",
 | 
			
		||||
                "sha256:b1b8eda9e931f0ca1aadb95a890811bdf530407e48c962643b85675329d99abf",
 | 
			
		||||
                "sha256:cec99c79205131da3ee75becea1f3f55c57bf6a1c500431de9ae7a32ac8a5cc4",
 | 
			
		||||
                "sha256:d4bbdaa6f61ce2ef26535a7d473d6ffa6e413013c5c580af999546bf1627ae11",
 | 
			
		||||
                "sha256:d8bdb4208975b12048bdace46e9dd8e3dda3872432f95b53789700a1330e6060",
 | 
			
		||||
                "sha256:dce0362ff9b61f8411d1efc9e16fc528dadbd3707a557561992457f5cb446297",
 | 
			
		||||
                "sha256:defbbbf5653629ce5cc54091ce49c6830da8d3104de53ed2169c9efcb0720f27",
 | 
			
		||||
                "sha256:e0c53a7e2b6d82ec3c26c009c937fc88eb8c7edf000c54334261beaf56bb08f2",
 | 
			
		||||
                "sha256:e1065bacfe5303f107896e63263537dee90920d26050f2e23c4af12c37da2db6",
 | 
			
		||||
                "sha256:e142837c4212c0b2c71e6773cb6740828922806b4c00ee4215be3ceb558671e6",
 | 
			
		||||
                "sha256:f4cbbab28c93ffee6ec929cf0826f0b11d2488e53a708d51142a5e62f8cd9806",
 | 
			
		||||
                "sha256:fa8f63b6551621eea9efea4db37ae401104352f0ebaee32f7d20be88cbe589c3"
 | 
			
		||||
            ],
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==0.29.12"
 | 
			
		||||
        },
 | 
			
		||||
        "etcd3": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:25a524b9f032c6631ff0097532907dea81243eaa63c3744510fd1598cc4e0e87"
 | 
			
		||||
            ],
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==0.10.0"
 | 
			
		||||
        },
 | 
			
		||||
        "grpcio": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:03b78b4e7dcdfe3e257bb528cc93923f9cbbab6d5babf15a60d21e9a4a70b1a2",
 | 
			
		||||
                "sha256:1ce0ccfbdfe84387dbcbf44adb4ae16ec7ae70e166ffab478993eb1ea1cba3ce",
 | 
			
		||||
                "sha256:22e167a9406d73dd19ffe8ed6a485f17e6eac82505be8c108897f15e68badcbb",
 | 
			
		||||
                "sha256:31d0aeca8d8ee2301c62c5c340e0889d653b1280d68f9fa203982cb6337b050e",
 | 
			
		||||
                "sha256:44c7f99ca17ebbcc96fc54ed00b454d8313f1eac28c563098d8b901025aff941",
 | 
			
		||||
                "sha256:5471444f53f9db6a1f1f11f5dbc173228881df8446380b6b98f90afb8fd8348e",
 | 
			
		||||
                "sha256:561bca3b1bde6d6564306eb05848fd155136e9c3a25d2961129b1e2edba22fce",
 | 
			
		||||
                "sha256:5bf58e1d2c2f55365c06e8cb5abe067b88ca2e5550fb62009c41df4b54505acf",
 | 
			
		||||
                "sha256:6b7163d1e85d76b0815df63fcc310daec02b44532bb433f743142d4febcb181f",
 | 
			
		||||
                "sha256:766d79cddad95f5f6020037fe60ea8b98578afdf0c59d5a60c106c1bdd886303",
 | 
			
		||||
                "sha256:770b7372d5ca68308ff66d7baee53369fa5ce985f84bcb6aa1948c1f2f7b02f2",
 | 
			
		||||
                "sha256:7ab178da777fc0f55b6aef5a755f99726e8e4b75e3903954df07b27059b54fcf",
 | 
			
		||||
                "sha256:8078305e77c2f6649d36b24d8778096413e474d9d7892c6f92cfb589c9d71b2e",
 | 
			
		||||
                "sha256:85600b63a386d860eeaa955e9335e18dd0d7e5477e9214825abf2c2884488369",
 | 
			
		||||
                "sha256:857d9b939ae128be1c0c792eb885c7ff6a386b9dea899ac4b06f4d90a31f9d87",
 | 
			
		||||
                "sha256:87a41630c90c179fa5c593400f30a467c498972c702f348d41e19dafeb1d319e",
 | 
			
		||||
                "sha256:8805d486c6128cc0fcc8ecf16c4095d99a8693a541ef851429ab334e028a4a97",
 | 
			
		||||
                "sha256:8d71b7a89c306a41ccc7741fc9409b14f5b86727455c2a1c0c7cfcb0f784e1f2",
 | 
			
		||||
                "sha256:9e1b80bd65f8f160880cb4dad7f55697f6d37b2d7f251fc0c2128e811928f369",
 | 
			
		||||
                "sha256:9e290c84a145ae2411ee0ec9913c41cd7500e2e7485fe93632434d84ef4fda67",
 | 
			
		||||
                "sha256:9ec9f88b5bc94bd99372f27cdd53af1c92ba06717380b127733b953cfb181174",
 | 
			
		||||
                "sha256:a0a02a8b4ba6deadf706d5f849539b3685b72b186a3c9ef5d43e8972ed60fb6f",
 | 
			
		||||
                "sha256:a4059c59519f5940e01a071f74ae2a60ea8f6185b03d22a09d40c7959a36b16b",
 | 
			
		||||
                "sha256:a6e028c2a6da2ebfa2365a5b32531d311fbfec0e3600fc27e901b64f0ff7e54e",
 | 
			
		||||
                "sha256:adcdebf9f8463df4120c427cf6c9aed39258bccd03ed37b6939e7a145d64d6e0",
 | 
			
		||||
                "sha256:bdec982610259d07156a58f80b8c3e69be7751a9208bc577b059c5193d087fad",
 | 
			
		||||
                "sha256:cefc4d4251ffb73feb303d4b7e9d6c367cb60f2db16d259ea28b114045f965aa",
 | 
			
		||||
                "sha256:d4145c8aa6afbac10ad27e408f7ce15992fe89ba5d0b4abca31c0c2729864c03",
 | 
			
		||||
                "sha256:da76dc5ad719ee99de5ea28a5629ff92172cbb4a70d8a6ae3a5b7a53c7382ce1",
 | 
			
		||||
                "sha256:dde2452c08ef8b6426ccab6b5b6de9f06d836d9937d6870e68153cbf8cb49348",
 | 
			
		||||
                "sha256:e3d88091d2539a4868750914a6fe7b9ec50e42b913851fc1b77423b5bd918530",
 | 
			
		||||
                "sha256:f9c67cfe6278499d7f83559dc6322a8bbb108e307817a3d7acbfea807b3603cc"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==1.22.0"
 | 
			
		||||
        },
 | 
			
		||||
        "protobuf": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:05c36022fef3c7d3562ac22402965c0c2b9fe8421f459bb377323598996e407f",
 | 
			
		||||
                "sha256:139b7eadcca0a861d60b523cb37d9475505e0dfb07972436b15407c2b968d87e",
 | 
			
		||||
                "sha256:15f683006cb77fb849b1f561e509b03dd2b7dcc749086b8dd1831090d0ba4740",
 | 
			
		||||
                "sha256:2ad566b7b7cdd8717c7af1825e19f09e8fef2787b77fcb979588944657679604",
 | 
			
		||||
                "sha256:35cfcf97642ef62108e10a9431c77733ec7eaab8e32fe4653de20403429907cb",
 | 
			
		||||
                "sha256:387822859ecdd012fdc25ec879f7f487da6e1d5b1ae6115e227e6be208836f71",
 | 
			
		||||
                "sha256:4df14cbe1e7134afcfdbb9f058949e31c466de27d9b2f7fb4da9e0b67231b538",
 | 
			
		||||
                "sha256:586c4ca37a7146d4822c700059f150ac3445ce0aef6f3ea258640838bb892dc2",
 | 
			
		||||
                "sha256:58b11e530e954d29ab3180c48dc558a409f705bf16739fd4e0d3e07924ad7add",
 | 
			
		||||
                "sha256:63c8c98ccb8c95f41c18fb829aeeab21c6249adee4ed75354125bdc44488f30e",
 | 
			
		||||
                "sha256:72edcbacd0c73eef507d2ff1af99a6c27df18e66a3ff4351e401182e4de62b03",
 | 
			
		||||
                "sha256:83dc8a561b3b954fd7002c690bb83278b8d1742a1e28abba9aaef28b0c8b437d",
 | 
			
		||||
                "sha256:913171ecc84c2726b86574e40549a0ea619d569657c5a5ff782a3be7d81401a5",
 | 
			
		||||
                "sha256:aabb7c741d3416671c3e6fe7c52970a226e6a8274417a97d7d795f953fadef36",
 | 
			
		||||
                "sha256:b3452bbda12b1cbe2187d416779de07b2ab4c497d83a050e43c344778763721d",
 | 
			
		||||
                "sha256:c5d5b8d4a9212338297fa1fa44589f69b470c0ba1d38168b432d577176b386a8",
 | 
			
		||||
                "sha256:d86ee389c2c4fc3cebabb8ce83a8e97b6b3b5dc727b7419c1ccdc7b6e545a233",
 | 
			
		||||
                "sha256:f2db8c754de788ab8be5e108e1e967c774c0942342b4f8aaaf14063889a6cfdc"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==3.9.0"
 | 
			
		||||
        },
 | 
			
		||||
        "python-decouple": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:1317df14b43efee4337a4aa02914bf004f010cd56d6c4bd894e6474ec8c4fe2d"
 | 
			
		||||
            ],
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==3.1"
 | 
			
		||||
        },
 | 
			
		||||
        "six": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
 | 
			
		||||
                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==1.12.0"
 | 
			
		||||
        },
 | 
			
		||||
        "tenacity": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:a0c3c5f7ae0c33f5556c775ca059c12d6fd8ab7121613a713e8b7d649908571b",
 | 
			
		||||
                "sha256:b87c1934daa0b2ccc7db153c37b8bf91d12f165936ade8628e7b962b92dc7705"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==5.0.4"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "develop": {
 | 
			
		||||
        "bandit": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952",
 | 
			
		||||
                "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"
 | 
			
		||||
            ],
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==1.6.2"
 | 
			
		||||
        },
 | 
			
		||||
        "gitdb2": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:83361131a1836661a155172932a13c08bda2db3674e4caa32368aa6eb02f38c2",
 | 
			
		||||
                "sha256:e3a0141c5f2a3f635c7209d56c496ebe1ad35da82fe4d3ec4aaa36278d70648a"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==2.0.5"
 | 
			
		||||
        },
 | 
			
		||||
        "gitpython": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:563221e5a44369c6b79172f455584c9ebbb122a13368cc82cb4b5addff788f82",
 | 
			
		||||
                "sha256:8237dc5bfd6f1366abeee5624111b9d6879393d84745a507de0fda86043b65a8"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==2.1.11"
 | 
			
		||||
        },
 | 
			
		||||
        "pbr": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:0ca44dc9fd3b04a22297c2a91082d8df2894862e8f4c86a49dac69eae9e85ca0",
 | 
			
		||||
                "sha256:4aed6c1b1fa5020def0f22aed663d87b81bb3235f112490b07d2643d7a98c5b5"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==5.4.1"
 | 
			
		||||
        },
 | 
			
		||||
        "pyyaml": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:57acc1d8533cbe51f6662a55434f0dbecfa2b9eaf115bede8f6fd00115a0c0d3",
 | 
			
		||||
                "sha256:588c94b3d16b76cfed8e0be54932e5729cc185caffaa5a451e7ad2f7ed8b4043",
 | 
			
		||||
                "sha256:68c8dd247f29f9a0d09375c9c6b8fdc64b60810ebf07ba4cdd64ceee3a58c7b7",
 | 
			
		||||
                "sha256:70d9818f1c9cd5c48bb87804f2efc8692f1023dac7f1a1a5c61d454043c1d265",
 | 
			
		||||
                "sha256:86a93cccd50f8c125286e637328ff4eef108400dd7089b46a7be3445eecfa391",
 | 
			
		||||
                "sha256:a0f329125a926876f647c9fa0ef32801587a12328b4a3c741270464e3e4fa778",
 | 
			
		||||
                "sha256:a3c252ab0fa1bb0d5a3f6449a4826732f3eb6c0270925548cac342bc9b22c225",
 | 
			
		||||
                "sha256:b4bb4d3f5e232425e25dda21c070ce05168a786ac9eda43768ab7f3ac2770955",
 | 
			
		||||
                "sha256:cd0618c5ba5bda5f4039b9398bb7fb6a317bb8298218c3de25c47c4740e4b95e",
 | 
			
		||||
                "sha256:ceacb9e5f8474dcf45b940578591c7f3d960e82f926c707788a570b51ba59190",
 | 
			
		||||
                "sha256:fe6a88094b64132c4bb3b631412e90032e8cfe9745a58370462240b8cb7553cd"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==5.1.1"
 | 
			
		||||
        },
 | 
			
		||||
        "six": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
 | 
			
		||||
                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==1.12.0"
 | 
			
		||||
        },
 | 
			
		||||
        "smmap2": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde",
 | 
			
		||||
                "sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==2.0.5"
 | 
			
		||||
        },
 | 
			
		||||
        "stevedore": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:7be098ff53d87f23d798a7ce7ae5c31f094f3deb92ba18059b1aeb1ca9fec0a0",
 | 
			
		||||
                "sha256:7d1ce610a87d26f53c087da61f06f9b7f7e552efad2a7f6d2322632b5f932ea2"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==1.30.1"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								main.py
									
										
									
									
									
								
							
							
						
						
									
										111
									
								
								main.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,4 +1,7 @@
 | 
			
		|||
# TODO
 | 
			
		||||
# TODO: Use Unix File Socket for VNC instead of TCP
 | 
			
		||||
 | 
			
		||||
# QEMU Manual
 | 
			
		||||
# https://qemu.weilnetz.de/doc/qemu-doc.html
 | 
			
		||||
 | 
			
		||||
# For QEMU Monitor Protocol Commands Information, See
 | 
			
		||||
# https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor
 | 
			
		||||
| 
						 | 
				
			
			@ -8,15 +11,19 @@ import argparse
 | 
			
		|||
import qmp
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
import subprocess
 | 
			
		||||
import atexit
 | 
			
		||||
import signal
 | 
			
		||||
 | 
			
		||||
from etcd3_wrapper import Etcd3Wrapper
 | 
			
		||||
from dataclasses import dataclass
 | 
			
		||||
from typing import Union
 | 
			
		||||
from functools import wraps
 | 
			
		||||
from decouple import config
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
 | 
			
		||||
running_vms = []
 | 
			
		||||
vnc_port_pool = list(range(5900, 6000))
 | 
			
		||||
client = Etcd3Wrapper()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +42,14 @@ logging.basicConfig(
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def goodbye(host):
 | 
			
		||||
    host.value["status"] = "DEAD"
 | 
			
		||||
    host.value["last_heartbeat"] = datetime.utcnow().isoformat()
 | 
			
		||||
    client.put(host.key, json.dumps(host.value))
 | 
			
		||||
    logging.info(f"Host {host.key} dead! at {host.value['last_heartbeat']}")
 | 
			
		||||
    os.kill(os.getpid(), signal.SIGKILL)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def need_running_vm(func):
 | 
			
		||||
    @wraps(func)
 | 
			
		||||
    def wrapper(e):
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +68,7 @@ def need_running_vm(func):
 | 
			
		|||
    return wrapper
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_vm(owner_dir, vm_uuid, e):
 | 
			
		||||
def create_vm(vm_uuid, e):
 | 
			
		||||
    image = client.get(
 | 
			
		||||
        f"/v1/image/{e.value['image_uuid']}", value_in_json=True
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -62,25 +77,34 @@ def create_vm(owner_dir, vm_uuid, e):
 | 
			
		|||
        image_uuid = e.value["image_uuid"]
 | 
			
		||||
 | 
			
		||||
        logging.info("Creating New VM...")
 | 
			
		||||
        _command_to_create = f"rbd clone images/{image_uuid}@protected uservms/{vm_uuid}"
 | 
			
		||||
        subprocess.call(_command_to_create.split(" "))
 | 
			
		||||
 | 
			
		||||
        os.makedirs(f"{owner_dir}/.vm", exist_ok=True)
 | 
			
		||||
        # DELETEME: Delete when CEPH integeration is complete
 | 
			
		||||
 | 
			
		||||
        if not os.path.isfile(f"{owner_dir}/.vm/{vm_uuid}.raw"):
 | 
			
		||||
            shutil.copy(
 | 
			
		||||
                f"/var/vm/{image_uuid}.raw", f"{owner_dir}/.vm/{vm_uuid}.raw"
 | 
			
		||||
            )
 | 
			
		||||
        # os.makedirs(f"{owner_dir}/.vm", exist_ok=True)
 | 
			
		||||
 | 
			
		||||
        # if not os.path.isfile(f"{owner_dir}/.vm/{vm_uuid}.raw"):
 | 
			
		||||
        #     shutil.copy(
 | 
			
		||||
        #         f"/var/vm/{image_uuid}.raw", f"{owner_dir}/.vm/{vm_uuid}.raw"
 | 
			
		||||
        #     )
 | 
			
		||||
 | 
			
		||||
        e.value["status"] = "REQUESTED_START"
 | 
			
		||||
    client.put(e.key, json.dumps(e.value))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def start_vm(vm_path, e):
 | 
			
		||||
    if not os.path.isfile(vm_path):
 | 
			
		||||
        logging.info(f"Image file of vm {e.key} does not exists")
 | 
			
		||||
        logging.info(f"Setting vm {e.key} status to DELETED")
 | 
			
		||||
        e.value["status"] = "DELETED"
 | 
			
		||||
        client.put(e.key, json.dumps(e.value))
 | 
			
		||||
        return
 | 
			
		||||
    # FIXME: Assume for the moment that the image exists
 | 
			
		||||
    #        Use librados to list files that exists in
 | 
			
		||||
    #        uservms pool then checkwhether the e.key.split("/").pop()
 | 
			
		||||
    #        exists in rbd_ls(uservms_pool)
 | 
			
		||||
 | 
			
		||||
    # if not os.path.isfile(vm_path):
 | 
			
		||||
    #     logging.info(f"Image file of vm {e.key} does not exists")
 | 
			
		||||
    #     logging.info(f"Setting vm {e.key} status to DELETED")
 | 
			
		||||
    #     e.value["status"] = "DELETED"
 | 
			
		||||
    #     client.put(e.key, json.dumps(e.value))
 | 
			
		||||
    #     return
 | 
			
		||||
 | 
			
		||||
    _vm = get_vm(running_vms, e.key)
 | 
			
		||||
    if _vm:
 | 
			
		||||
| 
						 | 
				
			
			@ -89,21 +113,16 @@ def start_vm(vm_path, e):
 | 
			
		|||
        client.put(e.key, json.dumps(e.value))
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # FIXME: There should be better vnc port allocation scheme
 | 
			
		||||
    vm = qmp.QEMUMachine(
 | 
			
		||||
        "/usr/bin/qemu-system-x86_64",
 | 
			
		||||
        test_dir="vm_socklog",
 | 
			
		||||
        args=[
 | 
			
		||||
            vm_path,
 | 
			
		||||
            "-boot",
 | 
			
		||||
            "c",
 | 
			
		||||
            "-net",
 | 
			
		||||
            "nic",
 | 
			
		||||
            "-net",
 | 
			
		||||
            "user",
 | 
			
		||||
            "-m",
 | 
			
		||||
            "1024",
 | 
			
		||||
            "-vnc",
 | 
			
		||||
            f":{len(running_vms)}",
 | 
			
		||||
            "-boot", "c",  # First Boot Hard drive
 | 
			
		||||
            "-m", "1024",  # RAM limit
 | 
			
		||||
            # Ever growing port number
 | 
			
		||||
            "-vnc", f":{vnc_port_pool.pop(0)}",  # Allow VNC
 | 
			
		||||
        ],
 | 
			
		||||
    )
 | 
			
		||||
    try:
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +137,8 @@ def start_vm(vm_path, e):
 | 
			
		|||
            client.put(e.key, e.value, value_in_json=True)
 | 
			
		||||
            return
 | 
			
		||||
    except (qmp.QEMUMachineError, TypeError):
 | 
			
		||||
        logging.info(f"Machine Error Occurred on {e.key}")
 | 
			
		||||
        logging.info()
 | 
			
		||||
        logging.exception(f"Machine Error Occurred on {e.key}")
 | 
			
		||||
        e.value["status"] = "KILLED"
 | 
			
		||||
        client.put(e.key, e.value, value_in_json=True)
 | 
			
		||||
    else:
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +201,17 @@ def get_vm(vm_list: list, vm_key) -> Union[VM, None]:
 | 
			
		|||
    return next((vm for vm in vm_list if vm.key == vm_key), None)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main(hostname):
 | 
			
		||||
def main():
 | 
			
		||||
    argparser = argparse.ArgumentParser()
 | 
			
		||||
    argparser.add_argument("hostname", help="Name of this host. e.g /v1/host/1")
 | 
			
		||||
    args = argparser.parse_args()
 | 
			
		||||
 | 
			
		||||
    host = client.get(args.hostname, value_in_json=True)
 | 
			
		||||
    host.value["status"] = "ALIVE"
 | 
			
		||||
    host.value["last_heartbeat"] = datetime.utcnow().isoformat()
 | 
			
		||||
 | 
			
		||||
    atexit.register(goodbye, host=host)
 | 
			
		||||
 | 
			
		||||
    events = client.watch_prefix("/v1/vm/", timeout=10)
 | 
			
		||||
 | 
			
		||||
    # events = client.get_prefix("/v1/vm/")
 | 
			
		||||
| 
						 | 
				
			
			@ -196,8 +226,9 @@ def main(hostname):
 | 
			
		|||
 | 
			
		||||
        if e_status == "TIMEOUT":
 | 
			
		||||
            logging.info("Timeout")
 | 
			
		||||
            _vms = filter(lambda v: v.value["hostname"] == hostname, client.get_prefix("/v1/vm", value_in_json=True))
 | 
			
		||||
            _vms = filter(lambda v: v.value["hostname"] == args.hostname, client.get_prefix("/v1/vm", value_in_json=True))
 | 
			
		||||
            alleged_running_vms = filter(lambda v: v.value["status"] == "RUNNING", _vms)
 | 
			
		||||
            should_be_running = filter(lambda v: v.value["status"] == "REQUESTED_START", _vms)
 | 
			
		||||
            for vm in alleged_running_vms:
 | 
			
		||||
                _vm = get_vm(running_vms, vm.key)
 | 
			
		||||
                if (_vm and not _vm.vm.is_running()) or _vm is None:
 | 
			
		||||
| 
						 | 
				
			
			@ -206,20 +237,28 @@ def main(hostname):
 | 
			
		|||
                    logging.info(f"Updating {vm.key} status to KILLED")
 | 
			
		||||
                    vm.value["status"] = "KILLED"
 | 
			
		||||
                    client.put(vm.key, json.dumps(vm.value))
 | 
			
		||||
 | 
			
		||||
            for vm in should_be_running:
 | 
			
		||||
                vm_path = f"rbd:uservms/{vm.key.split('/')[-1]}"
 | 
			
		||||
                start_vm(vm_path, e)
 | 
			
		||||
 | 
			
		||||
            host.value["status"] = "ALIVE"
 | 
			
		||||
            host.value["last_heartbeat"] = datetime.utcnow().isoformat()
 | 
			
		||||
            client.put(host.key, json.dumps(host.value))
 | 
			
		||||
            logging.info(f"Updated last heartbeat time {host.value['last_heartbeat']}")
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        e_hostname = e.value["hostname"]
 | 
			
		||||
        vm_uuid = e.key.split("/")[-1]
 | 
			
		||||
        owner_dir = f"{config('BASE_DIR')}/{e.value['owner']}"
 | 
			
		||||
 | 
			
		||||
        # If it is not for me then skip it
 | 
			
		||||
        if e_hostname != hostname:
 | 
			
		||||
        if e_hostname != args.hostname:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        logging.debug(f"EVENT: {e}")
 | 
			
		||||
 | 
			
		||||
        if e_status == "SCHEDULED_DEPLOY":
 | 
			
		||||
            create_vm(owner_dir, vm_uuid, e)
 | 
			
		||||
            create_vm(vm_uuid, e)
 | 
			
		||||
 | 
			
		||||
        elif e_status == "REQUESTED_SUSPEND":
 | 
			
		||||
            suspend_vm(e)
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +267,11 @@ def main(hostname):
 | 
			
		|||
            resume_vm(e)
 | 
			
		||||
 | 
			
		||||
        elif e_status == "REQUESTED_START":
 | 
			
		||||
            vm_path = f"{owner_dir}/.vm/{vm_uuid}.raw"
 | 
			
		||||
            
 | 
			
		||||
            # DELETEME: Delete when CEPH integeration is complete
 | 
			
		||||
            # vm_path = f"{owner_dir}/.vm/{vm_uuid}.raw"
 | 
			
		||||
 | 
			
		||||
            vm_path = f"rbd:uservms/{vm_uuid}"
 | 
			
		||||
            start_vm(vm_path, e)
 | 
			
		||||
 | 
			
		||||
        elif e_status == "REQUESTED_SHUTDOWN":
 | 
			
		||||
| 
						 | 
				
			
			@ -240,8 +283,4 @@ def main(hostname):
 | 
			
		|||
        logging.info(f"Running VMs {running_vms}")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
argparser = argparse.ArgumentParser()
 | 
			
		||||
argparser.add_argument("hostname", help="Name of this host. e.g /v1/host/1")
 | 
			
		||||
args = argparser.parse_args()
 | 
			
		||||
 | 
			
		||||
main(args.hostname)
 | 
			
		||||
main()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -234,8 +234,7 @@ class QEMUMachine(object):
 | 
			
		|||
        else:
 | 
			
		||||
            moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
 | 
			
		||||
        args = ['-chardev', moncdev,
 | 
			
		||||
                '-mon', 'chardev=mon,mode=control',
 | 
			
		||||
                '-display', 'none', '-vga', 'none']
 | 
			
		||||
                '-mon', 'chardev=mon,mode=control']
 | 
			
		||||
        if self._machine is not None:
 | 
			
		||||
            args.extend(['-machine', self._machine])
 | 
			
		||||
        if self._console_set:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue