diff --git a/Cargo.lock b/Cargo.lock index 38fb291..218c6de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,35 +62,28 @@ dependencies = [ ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "anyhow" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] -name = "bitflags" -version = "2.11.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "block-buffer" -version = "0.10.4" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bstr" -version = "1.12.1" +name = "bitflags" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" -dependencies = [ - "memchr", - "serde", -] +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bumpalo" @@ -98,6 +91,12 @@ version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + [[package]] name = "cfg-if" version = "1.0.4" @@ -116,56 +115,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "clap" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap-verbosity-flag" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d92b1fab272fe943881b77cc6e920d6543e5b1bfadbd5ed81c7c5a755742394" -dependencies = [ - "clap", - "log", -] - -[[package]] -name = "clap_builder" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "clap_lex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" - [[package]] name = "colog" version = "1.4.0" @@ -201,50 +150,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - [[package]] name = "darling" version = "0.20.11" @@ -280,16 +185,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "env_filter" version = "1.0.1" @@ -313,6 +208,22 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "fnv" version = "1.0.7" @@ -320,39 +231,139 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "generic-array" -version = "0.14.7" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ - "typenum", - "version_check", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "globset" -version = "0.4.18" +name = "futures-channel" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", + "futures-core", + "futures-sink", ] [[package]] -name = "globwalk" -version = "0.9.1" +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ - "bitflags 2.11.0", - "ignore", - "walkdir", + "futures-core", + "futures-task", + "futures-util", ] +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.5.0" @@ -365,6 +376,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -372,19 +389,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "ignore" -version = "0.4.25" +name = "indexmap" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -434,10 +447,10 @@ dependencies = [ ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "leb128fmt" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" @@ -445,6 +458,16 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libyml" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" +dependencies = [ + "anyhow", + "version_check", +] + [[package]] name = "lock_api" version = "0.4.14" @@ -461,10 +484,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] -name = "macaddr" -version = "1.0.1" +name = "mac-addr" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee0bbc17ce759db233beb01648088061bf678383130602a298e6998eedb2d8" +checksum = "d3d25b0e0b648a86960ac23b7ad4abb9717601dec6f66c165f5b037f3f03065f" dependencies = [ "serde", ] @@ -475,6 +498,17 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + [[package]] name = "num_cpus" version = "1.17.0" @@ -521,76 +555,111 @@ dependencies = [ ] [[package]] -name = "pest" -version = "2.8.6" +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ - "memchr", - "ucd-trie", + "portable-atomic", ] [[package]] -name = "pest_derive" -version = "2.8.6" +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "pest", - "pest_generator", + "zerocopy", ] [[package]] -name = "pest_generator" -version = "2.8.6" +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ - "pest", - "pest_meta", "proc-macro2", - "quote", "syn 2.0.117", ] [[package]] -name = "pest_meta" -version = "2.8.6" +name = "proc-macro2" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ - "pest", - "sha2", + "unicode-ident", ] [[package]] -name = "pkg-config" -version = "0.3.32" +name = "qapi" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "7b047adab56acc4948d4b9b58693c1f33fd13efef2d6bb5f0f66a47436ceada8" +dependencies = [ + "bytes", + "futures", + "log", + "memchr", + "qapi-qmp", + "qapi-spec", + "serde", + "serde_json", + "tokio", + "tokio-util", +] [[package]] -name = "portable-atomic" -version = "1.13.1" +name = "qapi-codegen" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "fb959fed63a69baa2e3ae57224d885e686bc3f56c9bb3b03406969980ea57a44" +dependencies = [ + "qapi-parser", +] [[package]] -name = "portable-atomic-util" -version = "0.2.6" +name = "qapi-parser" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "7b37f643cfdf67a409a9323334138a11636a5db5d56cedcc780d7a82a7fb7659" dependencies = [ - "portable-atomic", + "serde", + "serde_json", ] [[package]] -name = "proc-macro2" -version = "1.0.106" +name = "qapi-qmp" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "45303cac879d89361cad0287ae15f9ae1e7799b904b474152414aeece39b9875" dependencies = [ - "unicode-ident", + "qapi-codegen", + "qapi-spec", + "serde", +] + +[[package]] +name = "qapi-spec" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e6bdbbe5d13015b21a49a778a29ae3cee9c450c3154e1648aed670d57fe5ba" +dependencies = [ + "base64", + "serde", + "serde_json", ] [[package]] @@ -602,6 +671,47 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "raw-cpuid" version = "11.6.0" @@ -656,13 +766,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] -name = "same-file" -version = "1.0.6" +name = "ryu" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "scopeguard" @@ -670,6 +777,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "serde" version = "1.0.228" @@ -714,22 +827,61 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.10.9" +name = "serde_spanned" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "serde", +] + +[[package]] +name = "serde_yml" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +dependencies = [ + "indexmap", + "itoa", + "libyml", + "memchr", + "ryu", + "serde", + "version_check", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", ] +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "static_init" version = "1.0.4" @@ -786,22 +938,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tera" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8004bca281f2d32df3bacd59bc67b312cb4c70cea46cbd79dbe8ac5ed206722" -dependencies = [ - "globwalk", - "lazy_static", - "pest", - "pest_derive", - "regex", - "serde", - "serde_json", - "unicode-segmentation", -] - [[package]] name = "thiserror" version = "2.0.18" @@ -823,16 +959,117 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.19.0" +name = "tokio" +version = "1.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] -name = "ucd-trie" -version = "0.1.7" +name = "tracing-core" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] [[package]] name = "unicode-ident" @@ -846,6 +1083,12 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "utf8parse" version = "0.2.2" @@ -858,6 +1101,7 @@ version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ + "getrandom 0.4.2", "js-sys", "wasm-bindgen", ] @@ -869,34 +1113,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "virt" -version = "0.4.3" +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b191deb9f351999588bbd289fd40d5ca0076fd9784d1a1a0af531ec8684093c9" -dependencies = [ - "libc", - "uuid", - "virt-sys", -] +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "virt-sys" -version = "0.3.1" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8762dc8eb11b230e7ed6c94152910f8382a128eed861af21047a203e3e2ebb00" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "libc", - "pkg-config", + "wit-bindgen", ] [[package]] -name = "walkdir" -version = "2.5.0" +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "same-file", - "winapi-util", + "wit-bindgen", ] [[package]] @@ -944,6 +1181,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "winapi" version = "0.3.9" @@ -960,15 +1231,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -991,36 +1253,101 @@ dependencies = [ ] [[package]] -name = "xenith-cli" -version = "0.1.0" +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ - "anstyle", - "clap", - "clap-verbosity-flag", - "colog", - "log", + "memchr", ] [[package]] -name = "xenith-debugger" -version = "0.1.0" +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] [[package]] -name = "xenith-dm" -version = "0.1.0" +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap", "log", - "macaddr", "serde", - "tera", - "thiserror", - "virt", - "virt-sys", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", ] [[package]] -name = "xenith-gui" -version = "0.1.0" +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "xenith-redpill" @@ -1047,12 +1374,51 @@ dependencies = [ ] [[package]] -name = "xenith-scripting" +name = "xenith-stealth" version = "0.1.0" +dependencies = [ + "mac-addr", + "rand", + "serde", + "serde_yml", + "thiserror", +] [[package]] -name = "xenith-vmi" +name = "xenith-vm" version = "0.1.0" +dependencies = [ + "libc", + "mac-addr", + "qapi", + "serde", + "thiserror", + "tokio", + "toml", + "tracing", + "uuid", + "xenith-stealth", +] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] [[package]] name = "zmij" diff --git a/Cargo.toml b/Cargo.toml index 51bdca5..84f6b5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,9 @@ [workspace] resolver = "3" # see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions members = [ - "xenith-domain-management", - "xenith-vmi", - "xenith-cli", - "xenith-debugger", - "xenith-scripting", + "xenith-vm", + "xenith-stealth", "xenith-redpill", - "xenith-gui", ] exclude = [ "xenith-website" ] @@ -34,8 +30,19 @@ keywords = ["virtualization", "detection", "vmi", "debugger", "hypervisor"] [workspace.dependencies] # Those dependencies are shared across all packages, # so we define them here to avoid duplication. -log = "0.4.25" -thiserror = "2.0.18" +log = "0.4.25" +mac-addr = { version = "0.3", features = ["serde"] } +tracing = "0.1.44" +thiserror = "2.0.18" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.149" +serde_yml = "0.0.12" +tokio = { version = "1.51.0", features = ["full"] } +memflow = "0.2.4" +memflow-qemu = "0.2.1" +gdbstub = "0.7.10" +gdbstub_arch = "0.3.3" +pyo3 = "0.28.3" ################################################################################ # Lint settings diff --git a/xenith-cli/Cargo.toml b/xenith-cli/Cargo.toml deleted file mode 100644 index cf1fa59..0000000 --- a/xenith-cli/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "xenith-cli" -description = "A CLI tool for interacting with Xen and Xenith tools." - -# Inherit workspace settings -edition.workspace = true -rust-version.workspace = true -license.workspace = true -version.workspace = true -publish.workspace = true -authors.workspace = true -homepage.workspace = true -documentation.workspace = true -repository.workspace = true -keywords.workspace = true - -[[bin]] -name = "xenith" -path = "src/main.rs" - -[dependencies] -log = { workspace = true } - -anstyle = "1.0.10" -clap = { version = "4.5.30", features = ["derive"] } -clap-verbosity-flag = "3.0.2" -colog = "1.3.0" diff --git a/xenith-cli/src/commands.rs b/xenith-cli/src/commands.rs deleted file mode 100644 index a7e7798..0000000 --- a/xenith-cli/src/commands.rs +++ /dev/null @@ -1,112 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -//! Xenith main command handler -//! -//! This module contains the main command handler for the Xenith CLI. -//! All subcommands are listed in the [`Commands`] enum with their own -//! arguments. -//! -//! All commands are handled here and dispatched to the appropriate -//! command handler, each in their own module through the [`handle`] function. -//! This allows for easy extensibility and maintainability of the CLI. - -mod vm; - -use crate::commands::vm::VmArgs; - -use anstyle::{AnsiColor, Color, Style}; -use clap::{Parser, Subcommand}; -use clap_verbosity_flag::{InfoLevel, Verbosity}; - -/// Xenith CLI -/// -/// A CLI tool for interacting with Xen and Xenith tools, this tool is designed to be a -/// single entry point for those tools. -#[derive(Debug, Parser)] // requires `derive` feature -#[command(name = "xenith")] -#[command(version)] -#[command(about = "A CLI tool for interacting with Xen and Xenith tools", long_about = None)] -#[command(help_template = "\ -{before-help}Xenith v{version} -{about-with-newline} -{usage-heading} {usage} - -{all-args}{after-help} -")] -#[command(styles=xenith_styles())] -pub struct Cli { - #[command(subcommand)] - pub command: Commands, - - #[command(flatten)] - pub verbosity: Verbosity, -} - -/// Commands for the CLI -/// -/// The commands that can be run, this is the top level of the CLI. -#[derive(Debug, Subcommand)] -pub enum Commands { - #[command(about = "Interact with VMs")] - Vm(VmArgs), -} - -/// Handle the CLI command -/// -/// This function takes the CLI arguments and dispatches them to the -/// appropriate command handler. -/// -/// # Arguments -/// -/// * `args` - The `clap` CLI arguments -pub fn handle(args: Cli) { - match args.command { - Commands::Vm(args) => vm::handle(args), - } -} - -/// Get the styles for the CLI -/// -/// # Returns -/// -/// The styles for the CLI -fn xenith_styles() -> clap::builder::Styles { - let bold_underline_yellow = Style::new() - .bold() - .underline() - .fg_color(Some(Color::Ansi(AnsiColor::Yellow))); - let bold_red = Style::new() - .bold() - .fg_color(Some(Color::Ansi(AnsiColor::Red))); - let green = Style::new().fg_color(Some(Color::Ansi(AnsiColor::Green))); - let bold_underline_green = Style::new() - .bold() - .underline() - .fg_color(Some(Color::Ansi(AnsiColor::Green))); - let white = Style::new().fg_color(Some(Color::Ansi(AnsiColor::White))); - - clap::builder::Styles::styled() - .usage(bold_underline_yellow) - .header(bold_underline_yellow) - .literal(green) - .invalid(bold_red) - .error(bold_red) - .valid(bold_underline_green) - .placeholder(white) -} diff --git a/xenith-cli/src/commands/vm.rs b/xenith-cli/src/commands/vm.rs deleted file mode 100644 index 02c8d29..0000000 --- a/xenith-cli/src/commands/vm.rs +++ /dev/null @@ -1,58 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -use clap::{Args, Subcommand}; - -#[derive(Debug, Args)] -#[command(args_conflicts_with_subcommands = true)] -#[command(flatten_help = true)] -pub struct VmArgs { - #[command(subcommand)] - pub command: VmCommands, -} - -#[derive(Debug, Subcommand)] -pub enum VmCommands { - Create(VmCreateArgs), - Destroy, - Up, - Halt, -} - -#[derive(Debug, Args)] -pub struct VmCreateArgs { - #[arg(short, long)] - test: Option, -} - -pub fn handle(args: VmArgs) { - match args.command { - VmCommands::Create(create) => { - log::info!("Creating VM with message: {:?}", create.test); - } - VmCommands::Destroy => { - println!("Destroying VM"); - } - VmCommands::Up => { - println!("Starting VM"); - } - VmCommands::Halt => { - println!("Halting VM"); - } - } -} diff --git a/xenith-cli/src/main.rs b/xenith-cli/src/main.rs deleted file mode 100644 index 80f5fef..0000000 --- a/xenith-cli/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -use clap::Parser; - -mod commands; - -use commands::{Cli, handle}; - -fn main() { - let args = Cli::parse(); - - // Initialize the logger - let log_level = args.verbosity.log_level_filter(); - let mut clog = colog::default_builder(); - clog.filter(None, log_level); - clog.init(); - - // Handle CLI commands - handle(args); -} diff --git a/xenith-debugger/Cargo.toml b/xenith-debugger/Cargo.toml deleted file mode 100644 index 73699ce..0000000 --- a/xenith-debugger/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "xenith-debugger" -description = "Debugger bindings for interacting with Xenith domains : breakpoints, stepping, etc with semantic context." - -edition.workspace = true -rust-version.workspace = true -license.workspace = true -version.workspace = true -publish.workspace = true -authors.workspace = true -homepage.workspace = true -documentation.workspace = true -repository.workspace = true -keywords.workspace = true - -[dependencies] diff --git a/xenith-debugger/src/lib.rs b/xenith-debugger/src/lib.rs deleted file mode 100644 index e7a04e2..0000000 --- a/xenith-debugger/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ diff --git a/xenith-domain-management/Cargo.toml b/xenith-domain-management/Cargo.toml deleted file mode 100644 index 723dd94..0000000 --- a/xenith-domain-management/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "xenith-dm" -description = "Library for interacting with Xen. Allows to easily create and manage supported VMs through libvirt." - -# Inherit workspace settings -edition.workspace = true -rust-version.workspace = true -license.workspace = true -version.workspace = true -publish.workspace = true -authors.workspace = true -homepage.workspace = true -documentation.workspace = true -repository.workspace = true -keywords.workspace = true - -include = ["templates/"] - -[[bin]] -name = "xenith-dm" -path = "src/main.rs" - -[dependencies] -log = { workspace = true } -thiserror = { workspace = true } -virt = "0.4.2" -macaddr = { version = "1.0.1", features = ["serde_std"] } -tera = { version = "1.20.0", default-features = false } -serde = { version = "1.0.219", features = ["derive"] } -virt-sys = "0.3.0" diff --git a/xenith-domain-management/build.rs b/xenith-domain-management/build.rs deleted file mode 100644 index 8213122..0000000 --- a/xenith-domain-management/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("cargo::rustc-link-lib=virt"); -} diff --git a/xenith-domain-management/src/configuration.rs b/xenith-domain-management/src/configuration.rs deleted file mode 100644 index 68a6569..0000000 --- a/xenith-domain-management/src/configuration.rs +++ /dev/null @@ -1,433 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -//! Xenith domain configuration -//! This module contains the configuration for Xenith -//! domains like disks, templates, and the domain configuration -//! itself. -//! -//! The configuration is stored in the `/xenith` directory -//! and the images are stored in the `/xenith/images` directory. -//! The domain configuration files are stored in the `/xenith/domains` directory. -//! The ansible playbooks and roles are stored in the `/xenith/ansible` directory. - -mod disk; -mod domain; -mod image; -mod template; - -pub use disk::Disk; -pub use domain::Domain; -pub use image::Image; -pub use template::Template; - -use std::fs::create_dir_all; -use std::{fmt::Display, path::PathBuf}; - -use serde::{Deserialize, Serialize}; - -use crate::domain::DiskFormat; -use crate::error::ConfigurationError; - -#[derive(Debug, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] -pub struct Configuration { - images: Vec, - domains: Vec, -} - -impl Configuration { - /// Xenith domain configuration directory - /// This is the directory where all domain configurations are stored. - pub const DOMAIN_CONFIGURATION_PATH: &str = "/xenith"; - - /// Xenith images directory - /// This directory is used to store the images of the domains - /// created by Xenith. - pub const IMAGES_PATH: &str = "/xenith/images"; - - /// Xenith domains directory - /// This directory is used to store the domains created by Xenith. - /// It is used to store the domain configuration files and - /// the domain images. - pub const DOMAINS_PATH: &str = "/xenith/domains"; - - /// Xenith ansible directory - /// This directory is used to store the ansible playbooks - /// and roles used to configure the domains created by Xenith. - pub const ANSIBLE_PATH: &str = "/xenith/ansible"; - - pub fn new() -> Self { - Self { - images: Vec::new(), - domains: Vec::new(), - } - } - - pub fn get_images(&self) -> &Vec { - &self.images - } - - pub fn get_domains(&self) -> &Vec { - &self.domains - } - - /// Adds an image to the configuration. - /// - /// # Arguments - /// - /// * `image` - The image to add. - pub fn add_image(&mut self, image: Image) { - self.images.push(image); - } - - /// Adds a domain to the configuration. - /// - /// # Arguments - /// - /// * `domain` - The domain to add. - pub fn add_domain(&mut self, domain: Domain) { - self.domains.push(domain); - } - - /// Creates the necessary directories for Xenith - /// domains configuration and images. - /// - /// If the directory already exists, it does nothing. - /// - /// # Returns - /// - /// * `Ok(())` - If the directories were created successfully. - /// * `Err(std::io::Error)` - If the directories could not be created. - pub fn create_configuration(&self) -> Result<(), ConfigurationError> { - let paths = [ - Self::DOMAIN_CONFIGURATION_PATH, - Self::IMAGES_PATH, - Self::DOMAINS_PATH, - Self::ANSIBLE_PATH, - ]; - - for path in paths.iter() { - if !PathBuf::from(path).exists() { - create_dir_all(path).map_err(ConfigurationError::Creation)?; - } - } - - Ok(()) - } - - /// Creates the base domain configuration directory - /// for a given domain name. It creates the necessary directories - /// for the domain configuration, disks, and templates. - /// - /// If the directory already exists, it does nothing. - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// - /// # Returns - /// - /// * `Ok(PathBuf)` - The path to the domain configuration directory. - /// * `Err(std::io::Error)` - If the directory could not be created. - pub fn create_domain_configuration(domain_name: &str) -> Result { - let path = PathBuf::from(format!("{}/{}", Self::DOMAINS_PATH, domain_name)); - - if !path.exists() { - create_dir_all(&path).map_err(ConfigurationError::Creation)?; - - let disks_path = path.join("disks").join("snapshots"); - let templates_path = path.join("templates"); - - create_dir_all(&disks_path).map_err(ConfigurationError::Creation)?; - create_dir_all(&templates_path).map_err(ConfigurationError::Creation)?; - } - - Ok(path) - } - - /// Get an image by its name - /// - /// # Arguments - /// - /// * `name` - The name of the image. - /// - /// # Returns - /// - /// * `Option<&Image>` - The image if it exists, otherwise None. - pub fn get_image(&self, name: &str) -> Option<&Image> { - self.images.iter().find(|image| image.get_name() == name) - } - - /// Get the path to an image by its name - /// - /// # Arguments - /// - /// * `image_name` - The name of the image. - /// - /// # Returns - /// - /// * `Option` - The path to the image if it exists, otherwise None. - pub fn get_image_path(&self, image_name: &str) -> Option<&PathBuf> { - self.get_image(image_name).map(|image| image.get_path()) - } - - /// Get a domain by its name - /// - /// # Arguments - /// - /// * `name` - The name of the domain. - /// - /// # Returns - /// - /// * `Option<&Domain>` - The domain if it exists, otherwise None. - pub fn get_domain(&self, name: &str) -> Option<&Domain> { - self.domains.iter().find(|domain| domain.get_name() == name) - } - - /// Get the path to a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// - /// # Returns - /// - /// * `Option` - The path to the domain if it exists, otherwise None. - pub fn get_domain_path(&self, domain_name: &str) -> Option<&PathBuf> { - self.get_domain(domain_name).map(|domain| domain.get_path()) - } - - /// Get the disks for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// - /// # Returns - /// - /// * `Option<&Vec>` - The disks for the domain if it exists, otherwise None. - pub fn get_domain_disks(&self, domain_name: &str) -> Option<&Vec> { - self.get_domain(domain_name) - .map(|domain| domain.get_disks()) - } - - /// Get the libvirt configuration file for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// - /// # Returns - /// - /// * `Option<&PathBuf>` - The path to the libvirt configuration file if it exists, otherwise None. - pub fn get_domain_libvirt_configuration_file(&self, domain_name: &str) -> Option<&PathBuf> { - self.get_domain(domain_name) - .and_then(|domain| domain.get_configuration_file()) - } - - /// Get a disk for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// * `disk_name` - The name of the disk. - /// - /// # Returns - /// - /// * `Option<&Disk>` - The disk for the domain if it exists, otherwise None. - pub fn get_disk(&self, domain_name: &str, disk_name: &str) -> Option<&Disk> { - self.get_domain_disks(domain_name) - .and_then(|disks| disks.iter().find(|disk| disk.get_name() == disk_name)) - } - - /// Get the path to a disk for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// * `disk_name` - The name of the disk. - /// - /// # Returns - /// - /// * `Option` - The path to the disk if it exists, otherwise None. - pub fn get_disk_path(&self, domain_name: &str, disk_name: &str) -> Option<&PathBuf> { - self.get_disk(domain_name, disk_name) - .map(|disk| disk.get_path()) - } - - /// Get the size of a disk for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// * `disk_name` - The name of the disk. - /// - /// # Returns - /// - /// * `Option` - The size of the disk in bytes if it exists, otherwise None. - pub fn get_disk_size(&self, domain_name: &str, disk_name: &str) -> Option { - self.get_disk(domain_name, disk_name) - .map(|disk| disk.get_size_in_bytes()) - } - - /// Get the format of a disk for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// * `disk_name` - The name of the disk. - /// - /// # Returns - /// - /// * `Option` - The format of the disk if it exists, otherwise None. - pub fn get_disk_format(&self, domain_name: &str, disk_name: &str) -> Option<&DiskFormat> { - self.get_disk(domain_name, disk_name) - .map(|disk| disk.get_format()) - } - - /// Get the Packer templates for a domain by its name - /// - /// # Arguments - /// - /// * `domain_name` - The name of the domain. - /// - /// # Returns - /// - /// * `Option<&Template>` - The templates for the domain if it exists, otherwise None. - pub fn get_domain_templates(&self, domain_name: &str) -> Option<&Template> { - self.get_domain(domain_name) - .and_then(|domain| domain.get_templates()) - } -} - -impl Display for Configuration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Configuration({{ images: {:?}, domains: {:?} }})", - self.images, self.domains - ) - } -} -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_configuration_add_image() { - let mut config = Configuration::new(); - let image = Image::new( - "test_image".to_string(), - PathBuf::from("/xenith/images/test_image.img"), - "checksum123".to_string(), - ); - - config.add_image(image.clone()); - assert_eq!(config.get_images(), &vec![image]); - } - - #[test] - fn test_configuration_add_domain() { - let mut config = Configuration::new(); - let domain = Domain::new( - "test_domain".to_string(), - PathBuf::from("/xenith/domains/test_domain"), - None, - vec![], - vec![], - None, - ); - - config.add_domain(domain.clone()); - assert_eq!(config.get_domains(), &vec![domain]); - } - - #[test] - fn test_configuration_get_image() { - let mut config = Configuration::new(); - let image = Image::new( - "test_image".to_string(), - PathBuf::from("/xenith/images/test_image.img"), - "checksum123".to_string(), - ); - - config.add_image(image.clone()); - assert_eq!(config.get_image("test_image"), Some(&image)); - assert!(config.get_image("nonexistent_image").is_none()); - } - - #[test] - fn test_configuration_get_domain() { - let mut config = Configuration::new(); - let domain = Domain::new( - "test_domain".to_string(), - PathBuf::from("/xenith/domains/test_domain"), - None, - vec![], - vec![], - None, - ); - - config.add_domain(domain.clone()); - assert_eq!(config.get_domain("test_domain"), Some(&domain)); - assert!(config.get_domain("nonexistent_domain").is_none()); - } - - // This must be mocked or run in a test environment - - // #[test] - // fn test_configuration_create_configuration() { - // let config = Configuration::new(); - - // let result = config.create_configuration(); - // assert!(result.is_ok()); - // } - - // #[test] - // fn test_configuration_create_domain_configuration() { - // let result = Configuration::create_domain_configuration("test_domain"); - // assert!(result.is_ok()); - // assert_eq!( - // result.unwrap(), - // PathBuf::from("/xenith/domains/test_domain") - // ); - // } - - #[test] - fn test_configuration_get_disk() { - let disk = Disk::new( - "test_disk".to_string(), - PathBuf::from("/xenith/disks/test_disk.img"), - 1024 * 1024 * 1024, - DiskFormat::Raw, - ); - let domain = Domain::new( - "test_domain".to_string(), - PathBuf::from("/xenith/domains/test_domain"), - None, - vec![disk.clone()], - vec![], - None, - ); - let mut config = Configuration::new(); - config.add_domain(domain); - - assert_eq!(config.get_disk("test_domain", "test_disk"), Some(&disk)); - assert!(config.get_disk("test_domain", "nonexistent_disk").is_none()); - } -} diff --git a/xenith-domain-management/src/configuration/disk.rs b/xenith-domain-management/src/configuration/disk.rs deleted file mode 100644 index ced86c2..0000000 --- a/xenith-domain-management/src/configuration/disk.rs +++ /dev/null @@ -1,163 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -use std::fmt::Display; -use std::path::PathBuf; - -use serde::{Deserialize, Serialize}; - -use crate::domain::DiskFormat; - -#[derive(Debug, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] -pub struct Disk { - /// Name of the disk - name: String, - /// Path to the disk image - path: PathBuf, - /// Size of the disk in bytes. This is required for file-based disk images. - size: u64, - /// Format of the disk image - /// This is required for file-based disk images. - format: DiskFormat, -} - -impl Disk { - pub fn new(name: String, path: PathBuf, size: u64, format: DiskFormat) -> Self { - Self { - name, - path, - size, - format, - } - } - - pub fn get_name(&self) -> &String { - &self.name - } - - pub fn get_path(&self) -> &PathBuf { - &self.path - } - - pub fn get_format(&self) -> &DiskFormat { - &self.format - } - - pub fn get_size_in_gb(&self) -> f64 { - self.size as f64 / (1024.0 * 1024.0 * 1024.0) - } - - pub fn get_size_in_mb(&self) -> f64 { - self.size as f64 / (1024.0 * 1024.0) - } - - pub fn get_size_in_kb(&self) -> f64 { - self.size as f64 / 1024.0 - } - - pub fn get_size_in_bytes(&self) -> u64 { - self.size - } -} - -impl Display for Disk { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Disk({{ name: {}, path: {}, size: {}, format: {} }})", - self.name, - self.path.display(), - self.get_size_in_gb(), - self.format - ) - } -} - -impl TryFrom<&PathBuf> for Disk { - type Error = std::io::Error; - - fn try_from(path: &PathBuf) -> Result { - // Check if the file exists - path.try_exists()?; - - // Check if the file is a regular file - if !path.is_file() { - return Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - format!("Not a regular file: {}", path.display()), - )); - } - - // Check if the file is not empty - let metadata = path.metadata()?; - if metadata.len() == 0 { - return Err(std::io::Error::new( - std::io::ErrorKind::InvalidData, - format!("File is empty: {}", path.display()), - )); - } - - // Create the Disk object - let name = path - .file_name() - .and_then(|s| s.to_str()) - .unwrap_or("unknown") - .to_string(); - - let size = path.metadata()?.len(); - - let disk_extension = path - .extension() - .and_then(|s| s.to_str()) - .unwrap_or("raw") - .to_string(); - - let format = DiskFormat::from(disk_extension); - - Ok(Self { - name, - path: path.clone(), - size, - format, - }) - } -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn test_disk_creation() { - let disk = Disk::new( - "test_disk".to_string(), - PathBuf::from("/xenith/disks/test_disk.img"), - 1024 * 1024 * 1024, - DiskFormat::Raw, - ); - - assert_eq!(disk.get_name(), "test_disk"); - assert_eq!( - disk.get_path(), - &PathBuf::from("/xenith/disks/test_disk.img") - ); - assert_eq!(disk.get_size_in_gb(), 1.0); - assert_eq!(disk.get_format(), &DiskFormat::Raw); - } -} diff --git a/xenith-domain-management/src/configuration/domain.rs b/xenith-domain-management/src/configuration/domain.rs deleted file mode 100644 index 209d1e2..0000000 --- a/xenith-domain-management/src/configuration/domain.rs +++ /dev/null @@ -1,343 +0,0 @@ -/* -Xenith - Xen-based security hypervisor -Copyright (C) 2025-2026 Xenith contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -use std::fmt::Display; -use std::path::{Path, PathBuf}; - -use serde::{Deserialize, Serialize}; - -use crate::error::ConfigurationError; - -use super::Disk; -use super::Template; - -/// Domain configuration -#[derive(Debug, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] -pub struct Domain { - /// Name of the domain - name: String, - /// Path to the domain configuration directory - /// This is the directory where all domain configurations are stored. - path: PathBuf, - /// Path to the domain libvirt configuration file - /// This is the file that contains the domain configuration - /// in libvirt XML format. - /// It is used to create the domain in libvirt. - configuration_file: Option, - /// List of disks for the domain - /// This is the list of disks that are used by the domain. - disks: Vec, - /// List of disk snapshots for the domain - snapshots: Vec, - /// Packer templates for the domain - templates: Option