Compare commits

...

2 Commits

Author SHA1 Message Date
Dustin 96ede2a407 backend: web: Begin JSON-RPC client impl
Starting work on the JSON-RPC client in the web server.

The `Context` structure, which is stored in Rocket's managed state and
available to route functions through the `State` request guard, provides
a method to get an RPC client.  Each request that needs to communicate
with the daemon will have its own RPC connection.  This ensures that a
valid connection is always available, even if the daemon has restarted
between web requests.  I had considered storing the connection in the
context, testing it each time it was needed, and reconnecting if the
connection was broken.  This proved very difficult, since the context is
passed to request handlers as an immutable reference.  Mutating its
state would require locking, and I could not make that work easily.
Besides, the overhead of "pinging" the server for every request is
probably greater than just reconnecting every time, so it would have
been a waste.

The *GET /status* operation returns a document that indicates the status
of the daemon and the web server.
2022-01-09 14:58:59 -06:00
Dustin 7806b67531 backend: daemon: Begin JSON-RPC implementation
Beginning the implementation of the JSON-RPC server in the privileged
daemon.  We're using *jsonrpc-core* for the JSON-RPC implementation,
which includes serialization, connection handling, and method dispatch.

The first RPC method is a simple status query, which returns the daemon
version and the number of seconds the daemon process has been running.
2022-01-09 12:49:19 -06:00
15 changed files with 655 additions and 27 deletions

481
backend/Cargo.lock generated
View File

@ -2,6 +2,12 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "aead" name = "aead"
version = "0.3.2" version = "0.3.2"
@ -56,6 +62,15 @@ dependencies = [
"opaque-debug", "opaque-debug",
] ]
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "ansi_term" name = "ansi_term"
version = "0.12.1" version = "0.12.1"
@ -185,12 +200,27 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.9.1" version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.1.0" version = "1.1.0"
@ -209,6 +239,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time 0.1.43",
"winapi",
]
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.2.5" version = "0.2.5"
@ -224,6 +267,12 @@ version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.15.1" version = "0.15.1"
@ -233,11 +282,11 @@ dependencies = [
"aes-gcm", "aes-gcm",
"base64", "base64",
"hkdf", "hkdf",
"percent-encoding", "percent-encoding 2.1.0",
"rand", "rand 0.8.4",
"sha2", "sha2",
"subtle", "subtle",
"time", "time 0.2.27",
"version_check", "version_check",
] ]
@ -256,6 +305,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
[[package]]
name = "crc32fast"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "crypto-mac" name = "crypto-mac"
version = "0.10.1" version = "0.10.1"
@ -275,6 +333,19 @@ dependencies = [
"cipher", "cipher",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version 0.4.0",
"syn",
]
[[package]] [[package]]
name = "devise" name = "devise"
version = "0.3.1" version = "0.3.1"
@ -352,12 +423,30 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "flate2"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
dependencies = [
"cfg-if",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "futures"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.19" version = "0.3.19"
@ -398,6 +487,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
"futures-util", "futures-util",
"num_cpus",
] ]
[[package]] [[package]]
@ -435,6 +525,7 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
dependencies = [ dependencies = [
"futures 0.1.31",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
@ -470,6 +561,17 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.3" version = "0.2.3"
@ -478,7 +580,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi 0.10.2+wasi-snapshot-preview1",
] ]
[[package]] [[package]]
@ -497,6 +599,19 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "globset"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
dependencies = [
"aho-corasick",
"bstr",
"fnv",
"log",
"regex",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.10" version = "0.3.10"
@ -540,6 +655,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.10.0" version = "0.10.0"
@ -618,6 +739,17 @@ dependencies = [
"want", "want",
] ]
[[package]]
name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.8.0" version = "1.8.0"
@ -665,6 +797,110 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "jsonrpc-client-transports"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a"
dependencies = [
"derive_more",
"futures 0.3.19",
"jsonrpc-core",
"jsonrpc-pubsub",
"jsonrpc-server-utils",
"log",
"parity-tokio-ipc",
"serde",
"serde_json",
"tokio",
"url",
]
[[package]]
name = "jsonrpc-core"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
dependencies = [
"futures 0.3.19",
"futures-executor",
"futures-util",
"log",
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "jsonrpc-core-client"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0"
dependencies = [
"futures 0.3.19",
"jsonrpc-client-transports",
]
[[package]]
name = "jsonrpc-derive"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "jsonrpc-ipc-server"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845"
dependencies = [
"futures 0.3.19",
"jsonrpc-core",
"jsonrpc-server-utils",
"log",
"parity-tokio-ipc",
"parking_lot",
"tower-service",
]
[[package]]
name = "jsonrpc-pubsub"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011"
dependencies = [
"futures 0.3.19",
"jsonrpc-core",
"lazy_static",
"log",
"parking_lot",
"rand 0.7.3",
"serde",
]
[[package]]
name = "jsonrpc-server-utils"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4"
dependencies = [
"bytes",
"futures 0.3.19",
"globset",
"jsonrpc-core",
"lazy_static",
"log",
"tokio",
"tokio-stream",
"tokio-util",
"unicase",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -719,6 +955,12 @@ dependencies = [
"regex-automata", "regex-automata",
] ]
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.1" version = "2.4.1"
@ -731,6 +973,16 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.7.14" version = "0.7.14"
@ -782,6 +1034,25 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.13.1" version = "1.13.1"
@ -804,6 +1075,20 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "parity-tokio-ipc"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
dependencies = [
"futures 0.3.19",
"libc",
"log",
"rand 0.7.3",
"tokio",
"winapi",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@ -852,6 +1137,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@ -887,6 +1178,15 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
dependencies = [
"toml",
]
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"
@ -915,6 +1215,21 @@ dependencies = [
"yansi", "yansi",
] ]
[[package]]
name = "procfs"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0941606b9934e2d98a3677759a971756eb821f75764d0e0d26946d08e74d9104"
dependencies = [
"bitflags",
"byteorder",
"chrono",
"flate2",
"hex",
"lazy_static",
"libc",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.14" version = "1.0.14"
@ -924,6 +1239,19 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.4" version = "0.8.4"
@ -931,9 +1259,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha", "rand_chacha 0.3.1",
"rand_core", "rand_core 0.6.3",
"rand_hc", "rand_hc 0.3.1",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
] ]
[[package]] [[package]]
@ -943,7 +1281,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.6.3",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
] ]
[[package]] [[package]]
@ -952,7 +1299,16 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.3",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
] ]
[[package]] [[package]]
@ -961,7 +1317,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.6.3",
] ]
[[package]] [[package]]
@ -999,6 +1355,8 @@ version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [ dependencies = [
"aho-corasick",
"memchr",
"regex-syntax", "regex-syntax",
] ]
@ -1055,7 +1413,7 @@ dependencies = [
"bytes", "bytes",
"either", "either",
"figment", "figment",
"futures", "futures 0.3.19",
"indexmap", "indexmap",
"log", "log",
"memchr", "memchr",
@ -1063,7 +1421,7 @@ dependencies = [
"num_cpus", "num_cpus",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"rand", "rand 0.8.4",
"ref-cast", "ref-cast",
"rocket_codegen", "rocket_codegen",
"rocket_http", "rocket_http",
@ -1071,7 +1429,7 @@ dependencies = [
"serde_json", "serde_json",
"state", "state",
"tempfile", "tempfile",
"time", "time 0.2.27",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tokio-util", "tokio-util",
@ -1112,14 +1470,14 @@ dependencies = [
"mime", "mime",
"parking_lot", "parking_lot",
"pear", "pear",
"percent-encoding", "percent-encoding 2.1.0",
"pin-project-lite", "pin-project-lite",
"ref-cast", "ref-cast",
"serde", "serde",
"smallvec", "smallvec",
"stable-pattern", "stable-pattern",
"state", "state",
"time", "time 0.2.27",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"uncased", "uncased",
@ -1131,7 +1489,16 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [ dependencies = [
"semver", "semver 0.9.0",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver 1.0.4",
] ]
[[package]] [[package]]
@ -1190,6 +1557,12 @@ dependencies = [
"semver-parser", "semver-parser",
] ]
[[package]]
name = "semver"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]] [[package]]
name = "semver-parser" name = "semver-parser"
version = "0.7.0" version = "0.7.0"
@ -1332,7 +1705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [ dependencies = [
"discard", "discard",
"rustc_version", "rustc_version 0.2.3",
"stdweb-derive", "stdweb-derive",
"stdweb-internal-macros", "stdweb-internal-macros",
"stdweb-internal-runtime", "stdweb-internal-runtime",
@ -1399,7 +1772,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"rand", "rand 0.8.4",
"redox_syscall", "redox_syscall",
"remove_dir_all", "remove_dir_all",
"winapi", "winapi",
@ -1414,6 +1787,16 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.2.27" version = "0.2.27"
@ -1452,6 +1835,21 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tinyvec"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.15.0" version = "1.15.0"
@ -1624,6 +2022,30 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.8.0"
@ -1652,6 +2074,17 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
dependencies = [
"idna",
"matches",
"percent-encoding 1.0.1",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -1668,6 +2101,12 @@ dependencies = [
"try-lock", "try-lock",
] ]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.2+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"
@ -1753,7 +2192,13 @@ name = "weywot"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"argh", "argh",
"chrono",
"figment", "figment",
"jsonrpc-core",
"jsonrpc-core-client",
"jsonrpc-derive",
"jsonrpc-ipc-server",
"procfs",
"rocket", "rocket",
"serde", "serde",
] ]

View File

@ -5,9 +5,21 @@ edition = "2018"
[dependencies] [dependencies]
argh = "^0.1" argh = "^0.1"
chrono = "*"
figment = "^0.10" figment = "^0.10"
jsonrpc-core = "~18.0"
jsonrpc-derive = "~18.0"
jsonrpc-ipc-server = "~18.0"
serde = "^1.0" serde = "^1.0"
[dependencies.jsonrpc-core-client]
version = "~18.0"
features = ["ipc"]
[dependencies.procfs]
version = "^0.12"
features = ["chrono"]
[dependencies.rocket] [dependencies.rocket]
version = "^0.5.0-rc.1" version = "^0.5.0-rc.1"
features = ["json", "secrets", "tls"] features = ["json", "secrets", "tls"]

31
backend/src/daemon/mod.rs Normal file
View File

@ -0,0 +1,31 @@
mod rpc;
use crate::rpc::WeywotRpc;
use argh::FromArgs;
use jsonrpc_core::IoHandler;
use jsonrpc_ipc_server::ServerBuilder;
use std::env;
#[derive(Debug, FromArgs)]
/// Weywot privileged daemon
struct Arguments {
#[argh(option, short = 's')]
/// socket path
socket: Option<String>,
}
pub fn main() {
let args: Arguments = argh::from_env();
let socket = if let Ok(v) = env::var("WEYWOT_SOCKET") {
v
} else {
if let Some(v) = args.socket {
v
} else {
"weywot.sock".into()
}
};
let mut io = IoHandler::new();
io.extend_with(rpc::RpcDaemon.to_delegate());
let server = ServerBuilder::new(io).start(&socket).unwrap();
server.wait();
}

27
backend/src/daemon/rpc.rs Normal file
View File

@ -0,0 +1,27 @@
use crate::models::status::DaemonStatus;
use crate::rpc::WeywotRpc;
use chrono::Local;
use jsonrpc_core::Result as JsonRpcResult;
use procfs::process::Process;
use std::convert::TryInto;
use std::error::Error;
use std::process;
pub struct RpcDaemon;
impl WeywotRpc for RpcDaemon {
fn status(&self) -> JsonRpcResult<DaemonStatus> {
Ok(DaemonStatus {
version: env!("CARGO_PKG_VERSION").into(),
runtime: proc_runtime().unwrap_or(0),
})
}
}
fn proc_runtime() -> Result<i64, Box<dyn Error>> {
let pid: i32 = process::id().try_into()?;
let proc = Process::new(pid)?;
let starttime = proc.stat.starttime()?;
let now = Local::now();
Ok((now - starttime).num_seconds())
}

View File

@ -1,3 +1,6 @@
mod daemon;
mod models;
mod rpc;
mod server; mod server;
use std::env; use std::env;
@ -20,7 +23,7 @@ fn main() {
/// Main entry point for the privileged daemon /// Main entry point for the privileged daemon
fn daemon_main() { fn daemon_main() {
/* start the privileged daemon */ daemon::main();
} }
/// Main entry point for the web server /// Main entry point for the web server

View File

@ -0,0 +1 @@
pub mod status;

View File

@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct DaemonStatus {
pub version: String,
pub runtime: i64,
}
#[derive(Debug, Serialize)]
pub struct WebServerStatus {
pub version: String,
}
#[derive(Debug, Serialize)]
pub struct StatusResponse {
pub daemon: DaemonStatus,
pub web: WebServerStatus,
}

9
backend/src/rpc.rs Normal file
View File

@ -0,0 +1,9 @@
use crate::models::status::DaemonStatus;
use jsonrpc_core::Result;
use jsonrpc_derive::rpc;
#[rpc]
pub trait WeywotRpc {
#[rpc(name = "status")]
fn status(&self) -> Result<DaemonStatus>;
}

View File

@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
pub struct Config { pub struct Config {
pub address: String, pub address: String,
pub port: u16, pub port: u16,
pub socket: String
} }
impl Default for Config { impl Default for Config {
@ -11,6 +12,7 @@ impl Default for Config {
Config { Config {
address: "::".into(), address: "::".into(),
port: 8998, port: 8998,
socket: "weywot.sock".into(),
} }
} }
} }

View File

@ -0,0 +1,31 @@
use crate::rpc::gen_client::Client;
use crate::server::error::{ApiError, ErrorResponse};
use jsonrpc_core_client::transports::ipc::connect;
use rocket::http::Status as HttpStatus;
use rocket::serde::json::Json;
use std::path::PathBuf;
pub struct Context {
socket_path: PathBuf,
}
impl Context {
pub fn new<P: Into<PathBuf>>(socket: P) -> Self {
Self {
socket_path: socket.into(),
}
}
pub async fn client(&self) -> Result<Client, ApiError> {
match connect(&self.socket_path).await {
Ok(client) => Ok(client),
Err(e) => Err((
HttpStatus::ServiceUnavailable,
Json(ErrorResponse::new(format!(
"Cannot connect to daemon: {}",
e
))),
)),
}
}
}

View File

@ -0,0 +1,18 @@
use rocket::http::Status as HttpStatus;
use rocket::serde::json::Json;
use rocket::serde::Serialize;
#[derive(Serialize)]
pub struct ErrorResponse {
pub error: String,
}
pub type ApiError = (HttpStatus, Json<ErrorResponse>);
impl ErrorResponse {
pub fn new<S: Into<String>>(message: S) -> Self {
Self {
error: message.into(),
}
}
}

View File

@ -1,8 +1,11 @@
mod config; mod config;
mod context;
mod error;
mod routes; mod routes;
use config::Config; use config::Config;
use argh::FromArgs; use argh::FromArgs;
use context::Context;
use rocket; use rocket;
use rocket::fairing::AdHoc; use rocket::fairing::AdHoc;
use rocket::figment::providers::{Env, Format, Serialized, Toml}; use rocket::figment::providers::{Env, Format, Serialized, Toml};
@ -24,6 +27,10 @@ struct Arguments {
/// configuration file /// configuration file
#[argh(option, short = 'c')] #[argh(option, short = 'c')]
config: Option<String>, config: Option<String>,
/// weywot daemon socket path
#[argh(option, short = 's')]
socket: Option<String>,
} }
#[rocket::main] #[rocket::main]
@ -42,10 +49,22 @@ pub async fn main() -> Result<(), rocket::Error> {
if let Some(port) = args.port { if let Some(port) = args.port {
figment = figment.merge(("port", port)); figment = figment.merge(("port", port));
} }
if let Some(socket) = args.socket {
figment = figment.merge(("socket", socket));
}
let context = Context::new(
figment
.find_value("socket")
.expect("No daemon socket path configured")
.as_str()
.expect("Invalid daemon socket path"),
);
rocket::custom(figment) rocket::custom(figment)
.mount("/", rocket::routes![routes::hello::hello]) .mount("/", rocket::routes![routes::status::get_status])
.attach(AdHoc::config::<Config>()) .attach(AdHoc::config::<Config>())
.manage(context)
.ignite() .ignite()
.await? .await?
.launch() .launch()

View File

@ -1,6 +0,0 @@
use rocket;
#[rocket::get("/")]
pub async fn hello() -> &'static str {
"Hello, world!"
}

View File

@ -1 +1 @@
pub mod hello; pub mod status;

View File

@ -0,0 +1,18 @@
use crate::models::status::{StatusResponse, WebServerStatus};
use crate::server::context::Context;
use crate::server::error::ApiError;
use rocket::serde::json::Json;
use rocket::State;
#[rocket::get("/status")]
pub async fn get_status(
state: &State<Context>,
) -> Result<Json<StatusResponse>, ApiError> {
let client = state.client().await?;
Ok(Json(StatusResponse {
daemon: client.status().await.unwrap(),
web: WebServerStatus {
version: env!("CARGO_PKG_VERSION").into(),
},
}))
}