-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathmain.rs
More file actions
133 lines (110 loc) · 3.93 KB
/
Copy pathmain.rs
File metadata and controls
133 lines (110 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
//
// SPDX-License-Identifier: Apache-2.0
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use dstack_mr::Machine;
use dstack_types::ImageInfo;
use fs_err as fs;
use size_parser::parse_memory_size;
use std::path::PathBuf;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Measure a machine configuration
Measure(MachineConfig),
}
type Bool = bool;
#[derive(Parser)]
struct MachineConfig {
/// Number of CPUs
#[arg(short, long, default_value = "1")]
cpu: u32,
/// Memory size in bytes
#[arg(short, long, default_value = "2G", value_parser = parse_memory_size)]
memory: u64,
/// Path to dstack image metadata.json
metadata: PathBuf,
/// Enable two-pass add pages
#[arg(long, default_value = "true")]
two_pass_add_pages: Bool,
/// Enable PIC
#[arg(long, default_value = "true")]
pic: Bool,
/// Enable SMM
#[arg(long, default_value = "false")]
smm: Bool,
/// PCI hole64 size (accepts decimal or hex with 0x prefix)
#[arg(long, value_parser = parse_memory_size)]
pci_hole64_size: Option<u64>,
/// Enable hugepages
#[arg(long, default_value = "false")]
hugepages: bool,
/// Number of GPUs
#[arg(long, default_value = "0")]
num_gpus: u32,
/// Number of NVSwitches
#[arg(long, default_value = "0")]
num_nvswitches: u32,
/// Disable hotplug
#[arg(long, default_value = "false")]
hotplug_off: Bool,
/// Enable root verity
#[arg(long, default_value = "true")]
root_verity: Bool,
/// Output JSON
#[arg(long)]
json: bool,
}
fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let cli = Cli::parse();
match &cli.command {
Commands::Measure(config) => {
let metadata =
fs::read_to_string(&config.metadata).context("Failed to read image metadata")?;
let image_info: ImageInfo =
serde_json::from_str(&metadata).context("Failed to parse image metadata")?;
let parent_dir = config.metadata.parent().unwrap_or(".".as_ref());
let firmware_path = parent_dir.join(&image_info.bios).display().to_string();
let kernel_path = parent_dir.join(&image_info.kernel).display().to_string();
let initrd_path = parent_dir.join(&image_info.initrd).display().to_string();
let cmdline = image_info.cmdline + " initrd=initrd";
let machine = Machine::builder()
.cpu_count(config.cpu)
.memory_size(config.memory)
.firmware(&firmware_path)
.kernel(&kernel_path)
.initrd(&initrd_path)
.kernel_cmdline(&cmdline)
.two_pass_add_pages(config.two_pass_add_pages)
.pic(config.pic)
.smm(config.smm)
.maybe_pci_hole64_size(config.pci_hole64_size)
.hugepages(config.hugepages)
.num_gpus(config.num_gpus)
.num_nvswitches(config.num_nvswitches)
.hotplug_off(config.hotplug_off)
.root_verity(config.root_verity)
.build();
let measurements = machine
.measure()
.context("Failed to measure machine configuration")?;
if config.json {
println!("{}", serde_json::to_string_pretty(&measurements)?);
} else {
println!("Machine measurements:");
println!("MRTD: {}", hex::encode(measurements.mrtd));
println!("RTMR0: {}", hex::encode(measurements.rtmr0));
println!("RTMR1: {}", hex::encode(measurements.rtmr1));
println!("RTMR2: {}", hex::encode(measurements.rtmr2));
}
}
}
Ok(())
}