Compare commits
11 Commits
9c5dd8b850
...
2568c9be39
| Author | SHA1 | Date | |
|---|---|---|---|
| 2568c9be39 | |||
| 9f740e94e5 | |||
| fa6bc6424f | |||
| d44d256567 | |||
| 4746a31a09 | |||
| 9a5387b931 | |||
| bf7d8707f4 | |||
| 07de221c62 | |||
| f5cb2e0925 | |||
| 7fb7904418 | |||
| f0407edacc |
151
Cargo.lock
generated
151
Cargo.lock
generated
@ -732,6 +732,38 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver 1.0.24",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.11"
|
||||
@ -853,6 +885,26 @@ version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@ -1081,6 +1133,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"shadow-rs",
|
||||
"tabled",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
@ -1554,6 +1607,19 @@ version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5220b8ba44c68a9a7f7a7659e864dd73692e417ef0211bea133c7b74e031eeb9"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
@ -1994,6 +2060,12 @@ version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "is_debug"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
@ -2102,6 +2174,18 @@ version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.18.1+1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.6"
|
||||
@ -2129,6 +2213,18 @@ dependencies = [
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
@ -2265,6 +2361,15 @@ dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
@ -3111,6 +3216,9 @@ name = "semver"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
@ -3221,6 +3329,21 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shadow-rs"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d5625ed609cf66d7e505e7d487aca815626dc4ebb6c0dd07637ca61a44651a6"
|
||||
dependencies = [
|
||||
"cargo_metadata",
|
||||
"const_format",
|
||||
"git2",
|
||||
"is_debug",
|
||||
"serde_json",
|
||||
"time",
|
||||
"tzdb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
@ -3491,7 +3614,9 @@ checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
@ -3791,6 +3916,32 @@ version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "tz-rs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1450bf2b99397e72070e7935c89facaa80092ac812502200375f1f7d33c71a1"
|
||||
|
||||
[[package]]
|
||||
name = "tzdb"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0be2ea5956f295449f47c0b825c5e109022ff1a6a53bb4f77682a87c2341fbf5"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"tz-rs",
|
||||
"tzdb_data",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdb_data"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0604b35c1f390a774fdb138cac75a99981078895d24bcab175987440bbff803b"
|
||||
dependencies = [
|
||||
"tz-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.7"
|
||||
|
||||
@ -32,9 +32,11 @@ hyper-rustls = { version = "0.27.5", features = ["http2"] }
|
||||
openssl = { version = "0.10.71", features = ["vendored"] }
|
||||
tokio-retry = "0.3.0"
|
||||
detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch = "hratls", features=["hratls", "qvl"] }
|
||||
shadow-rs = { version = "1.1.1", features = ["metadata"] }
|
||||
|
||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "feat_dir_support_dtpm_config" }
|
||||
# detee-shared = { path = "../detee-shared" }
|
||||
|
||||
[build-dependencies]
|
||||
shadow-rs = "1.1.1"
|
||||
tonic-build = "0.12"
|
||||
|
||||
5
build.rs
Normal file
5
build.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use shadow_rs::ShadowBuilder;
|
||||
|
||||
fn main() {
|
||||
ShadowBuilder::builder().deny_const(Default::default()).build().unwrap();
|
||||
}
|
||||
@ -56,11 +56,14 @@ snpguest --help > /dev/null \
|
||||
}
|
||||
|
||||
try_countdown=20;
|
||||
echo -n Trying $server
|
||||
while [[ $try_countdown -gt 0 ]]; do
|
||||
echo -n .
|
||||
curl --max-time 1 -k "https://$server" > /dev/null 2>&1 && break
|
||||
sleep 1
|
||||
((try_countdown--))
|
||||
done
|
||||
echo
|
||||
|
||||
openssl s_client -connect "$server" </dev/null \
|
||||
| sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > "$server_crt"
|
||||
@ -100,9 +103,9 @@ echo_blue "Verifying AMD signature in attestation report..."
|
||||
chip_id_hash=$( snpguest display report "$server_report" \
|
||||
| grep "Chip ID:" -A 4 | tail -3 | tr '\n' ' ' | sed 's/\s//g' \
|
||||
| md5sum | awk '{ print $1 }')
|
||||
microcode=$( snpguest display report "$server_report" |
|
||||
grep "Launch TCB:" -A 6 | grep "Microcode:" | awk '{ print $2 }' )
|
||||
vcek_path="${cert_dir}/${chip_id_hash}-${microcode}.vcek.pem"
|
||||
tcb_hash=$(grep -e "Committed TCB" -e "Reported TCB" -A 10 "$server_report" |
|
||||
md5sum | awk '{ print $1 }')
|
||||
vcek_path="${cert_dir}/${chip_id_hash}-${tcb_hash}.vcek.pem"
|
||||
amd_certs_dir="${cert_dir}/amd_certs_${server}"
|
||||
mkdir -p "$amd_certs_dir"
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ More information can be found at https://detee.ltd
|
||||
|
||||
Feel free to browser applications bundles or VM disks available for immediate deployment."#;
|
||||
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
fn main() {
|
||||
// TODO: figure if there is a more elegant way to solve this than calling default_provider in main
|
||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||
@ -50,7 +52,7 @@ fn main() {
|
||||
|
||||
fn clap_cmd() -> Command {
|
||||
Command::new("detee-cli")
|
||||
.version("0.0.1")
|
||||
.version(build::CLAP_LONG_VERSION)
|
||||
.author("https://detee.ltd")
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
@ -282,7 +284,6 @@ fn clap_cmd() -> Command {
|
||||
.required(true)
|
||||
)
|
||||
)
|
||||
/*
|
||||
.subcommand(Command::new("report").about("report a node for poor performance")
|
||||
.arg(
|
||||
Arg::new("pubkey")
|
||||
@ -302,7 +303,6 @@ fn clap_cmd() -> Command {
|
||||
.help("detail the performance issue you experienced")
|
||||
)
|
||||
)
|
||||
*/
|
||||
)
|
||||
.subcommand(Command::new("vm")
|
||||
.about("virtual machines that run on AMD SEV-SNP nodes")
|
||||
|
||||
@ -13,6 +13,8 @@ It allows you to:
|
||||
|
||||
The admin pubkeys are hardcoded in the brain."#;
|
||||
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
fn main() {
|
||||
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
|
||||
let log_level = match std::env::var("LOG_LEVEL") {
|
||||
@ -26,7 +28,7 @@ fn main() {
|
||||
env_logger::builder().filter_level(log_level).format_timestamp(None).init();
|
||||
|
||||
let cmd = Command::new("super-detee-cli")
|
||||
.version("0.0.1")
|
||||
.version(build::CLAP_LONG_VERSION)
|
||||
.author("https://detee.ltd")
|
||||
.about(ABOUT)
|
||||
.subcommand(
|
||||
|
||||
@ -39,11 +39,13 @@ pub fn handle_app_nodes(matches: &ArgMatches) {
|
||||
let ip: String = subcom_args.get_one::<String>("ip").unwrap().clone();
|
||||
cli_print(inspect_node(ip).map_err(Into::into));
|
||||
}
|
||||
Some(("report", _)) => {
|
||||
// let node_pubkey: String = path_subcommand.get_one::<String>("pubkey").unwrap().clone();
|
||||
// let contract_uuid: String = path_subcommand.get_one::<String>("contract").unwrap().clone();
|
||||
// let reason: String = path_subcommand.get_one::<String>("reason").unwrap().clone();
|
||||
todo!()
|
||||
Some(("report", subcom_args)) => {
|
||||
let node_pubkey: String = subcom_args.get_one::<String>("pubkey").unwrap().clone();
|
||||
let contract_uuid: String = subcom_args.get_one::<String>("contract").unwrap().clone();
|
||||
let reason: String = subcom_args.get_one::<String>("reason").unwrap().clone();
|
||||
cli_print(
|
||||
crate::general::report_node(node_pubkey, contract_uuid, reason).map_err(Into::into),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
eprintln!("Available commands are search, inspec and report. Use --help for more information.")
|
||||
|
||||
@ -398,32 +398,32 @@ pub fn calculate_nanolp(
|
||||
|
||||
lazy_static! {
|
||||
static ref DEFAULT_DTRFS: Dtrfs = Dtrfs {
|
||||
name: "dtrfs-6.13.8-arch1-1".to_string(),
|
||||
name: "dtrfs-6.14.2-arch1-1".to_string(),
|
||||
vendor: "ghe0".to_string(),
|
||||
dtrfs_url: "http://registry.detee.ltd/detee-archtop-6.13.8-arch1-1.cpio.gz".to_string(),
|
||||
dtrfs_sha: "b5f408d00e2b93dc594fed3a7f2466a9878802ff1c7ae502247471cd06728a45".to_string(),
|
||||
kernel_url: "http://registry.detee.ltd/vmlinuz-linux-6.13.8-arch1-1".to_string(),
|
||||
kernel_sha: "e49c8587287b21df7600c04326fd7393524453918c14d67f73757dc769a13542".to_string()
|
||||
dtrfs_url: "http://registry.detee.ltd/detee-archtop-6.14.2-arch1-1.cpio.gz".to_string(),
|
||||
dtrfs_sha: "d207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990".to_string(),
|
||||
kernel_url: "http://registry.detee.ltd/vmlinuz-linux-6.14.2-arch1-1".to_string(),
|
||||
kernel_sha: "e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919".to_string()
|
||||
};
|
||||
static ref DEFAULT_ARCHLINUX: Distro = Distro {
|
||||
name: "archlinux_2025-02-21".to_string(),
|
||||
name: "archlinux_2025-04-03".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_arch_2025-02-21.fsa".to_string(),
|
||||
template_sha: "257edbf1e3b949b895c422befc8890c85dfae1ad3d35661010c9aaa173ba9fc4"
|
||||
template_url: "http://registry.detee.ltd/detee_arch_2025-04-03.fsa".to_string(),
|
||||
template_sha: "7fdb19d9325c63d246140c984dc3764538f6ea329ed877e947993ea7bc8c2067"
|
||||
.to_string()
|
||||
};
|
||||
static ref DEFAULT_UBUNTU: Distro = Distro {
|
||||
name: "ubuntu_2025-02-28".to_string(),
|
||||
name: "ubuntu_2025-04-03".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_ubuntu_2025-02-28.fsa".to_string(),
|
||||
template_sha: "faa8bd38d02ca9b6ee69d7f5128ed9ccab42bdbfa69f688b9947e8e5c9e5d133"
|
||||
template_url: "http://registry.detee.ltd/detee_ubuntu_2025-04-03.fsa".to_string(),
|
||||
template_sha: "324895a7a1788e43253cf9699aa446df1a5519fe072917cedcc4ed356546e34a"
|
||||
.to_string()
|
||||
};
|
||||
static ref DEFAULT_FEDORA: Distro = Distro {
|
||||
name: "fedora_2025-02-21".to_string(),
|
||||
name: "fedora_2025-04-03".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_fedora_2025-02-21.fsa".to_string(),
|
||||
template_sha: "c0fdd08d465939077ef8ed746903005fc190af12cdf70917cc8c6f872da85777"
|
||||
template_url: "http://registry.detee.ltd/detee_fedora_2025-04-03.fsa".to_string(),
|
||||
template_sha: "75a98c3744552bbf5f8e9c6a271cd0f382e1d9a846f5d577767b39293b8efda9"
|
||||
.to_string()
|
||||
};
|
||||
static ref ALTERNATIVE_INIT: Vec<Dtrfs> = vec![
|
||||
@ -438,36 +438,36 @@ lazy_static! {
|
||||
.to_string()
|
||||
},
|
||||
Dtrfs {
|
||||
name: "dtrfs-6.13.6-arch1-1".to_string(),
|
||||
name: "dtrfs-6.13.8-arch1-1".to_string(),
|
||||
vendor: "ghe0".to_string(),
|
||||
dtrfs_url: "http://registry.detee.ltd/detee-archtop-6.13.6-arch1-1.cpio.gz".to_string(),
|
||||
dtrfs_sha: "de48048fb42fe4054611f14e51ce175ca90645734fe41349642f036b8bca8fcd"
|
||||
dtrfs_url: "http://registry.detee.ltd/detee-archtop-6.13.8-arch1-1.cpio.gz".to_string(),
|
||||
dtrfs_sha: "b5f408d00e2b93dc594fed3a7f2466a9878802ff1c7ae502247471cd06728a45"
|
||||
.to_string(),
|
||||
kernel_url: "http://registry.detee.ltd/vmlinuz-linux-6.13.6-arch1-1".to_string(),
|
||||
kernel_sha: "7efaca6c348cd4136afe3ece0beec346da713029347a0d4e71e12a0b91570de7"
|
||||
kernel_url: "http://registry.detee.ltd/vmlinuz-linux-6.13.8-arch1-1".to_string(),
|
||||
kernel_sha: "e49c8587287b21df7600c04326fd7393524453918c14d67f73757dc769a13542"
|
||||
.to_string()
|
||||
},
|
||||
];
|
||||
static ref ALTERNATIVE_DISTROS: Vec<Distro> = vec![
|
||||
Distro {
|
||||
name: "archlinux_2025-01-27".to_string(),
|
||||
name: "archlinux_2025-02-21".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_arch_2025-01-27.fsa".to_string(),
|
||||
template_sha: "c8cc8ef611380c2d1fbab36e44ccfd8d666e344c7aaefe763f7dd6136b672c97"
|
||||
template_url: "http://registry.detee.ltd/detee_arch_2025-02-21.fsa".to_string(),
|
||||
template_sha: "257edbf1e3b949b895c422befc8890c85dfae1ad3d35661010c9aaa173ba9fc4"
|
||||
.to_string()
|
||||
},
|
||||
Distro {
|
||||
name: "ubuntu_2025-02-21".to_string(),
|
||||
name: "ubuntu_2025-02-28".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_ubuntu_2025-02-21.fsa".to_string(),
|
||||
template_sha: "180e43c46494c8b5cf2b19067995755ade1bbd80396e1fd5e1c4b164ed2fe8cf"
|
||||
template_url: "http://registry.detee.ltd/detee_ubuntu_2025-02-28.fsa".to_string(),
|
||||
template_sha: "faa8bd38d02ca9b6ee69d7f5128ed9ccab42bdbfa69f688b9947e8e5c9e5d133"
|
||||
.to_string()
|
||||
},
|
||||
Distro {
|
||||
name: "fedora_2025-01-28".to_string(),
|
||||
name: "fedora_2025-02-21".to_string(),
|
||||
vendor: "gheorghe".to_string(),
|
||||
template_url: "http://registry.detee.ltd/detee_fedora_2025-01-28.fsa".to_string(),
|
||||
template_sha: "68c5be46d668a12e8ff78692843a922315bd5cd9c2bb53accf2685ec3be1fa31"
|
||||
template_url: "http://registry.detee.ltd/detee_fedora_2025-02-21.fsa".to_string(),
|
||||
template_sha: "c0fdd08d465939077ef8ed746903005fc190af12cdf70917cc8c6f872da85777"
|
||||
.to_string()
|
||||
}
|
||||
];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user