Skip to content

Commit d32f152

Browse files
committed
faux-mgs: Updates expect a hubris archive instead of a raw binary
1 parent 631e6d7 commit d32f152

File tree

4 files changed

+103
-7
lines changed

4 files changed

+103
-7
lines changed

Cargo.lock

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gateway/faux-mgs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ slog-term = "2.9"
1313
termios = "0.3"
1414
thiserror = "1.0"
1515
tokio = { version = "1.20", features = ["full"] }
16+
zip = { version = "0.6.2", default-features = false, features = ["deflate","bzip2"] }
1617

1718
gateway-messages = { path = "../../gateway-messages", features = ["std"] }
1819
gateway-sp-comms = { path = "../../gateway-sp-comms" }
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
// Copyright 2022 Oxide Computer Company
6+
7+
//! Minimal parsing of Hubris archives.
8+
9+
use anyhow::Context;
10+
use anyhow::Result;
11+
use std::fs;
12+
use std::io::Cursor;
13+
use std::io::Read;
14+
use std::path::Path;
15+
use std::path::PathBuf;
16+
use zip::ZipArchive;
17+
18+
pub struct HubrisArchive {
19+
archive: ZipArchive<Cursor<Vec<u8>>>,
20+
path: PathBuf,
21+
}
22+
23+
impl HubrisArchive {
24+
pub fn open(path: &Path) -> Result<Self> {
25+
let data = fs::read(path)
26+
.with_context(|| format!("failed to read {}", path.display()))?;
27+
let cursor = Cursor::new(data);
28+
let archive = ZipArchive::new(cursor).with_context(|| {
29+
format!(
30+
"failed to open {} as a zip file - is it a hubris archive?",
31+
path.display()
32+
)
33+
})?;
34+
Ok(Self { archive, path: path.to_owned() })
35+
}
36+
37+
pub fn final_bin(&mut self) -> Result<Vec<u8>> {
38+
self.extract_by_name("img/final.bin")
39+
}
40+
41+
fn extract_by_name(&mut self, name: &str) -> Result<Vec<u8>> {
42+
let mut f = self.archive.by_name(name).with_context(|| {
43+
format!(
44+
"failed to find `{}` within {} - is it a hubris archive?",
45+
name,
46+
self.path.display()
47+
)
48+
})?;
49+
let mut data = Vec::new();
50+
f.read_to_end(&mut data).with_context(|| {
51+
format!(
52+
"failed to extract `{}` within {}",
53+
name,
54+
self.path.display()
55+
)
56+
})?;
57+
Ok(data)
58+
}
59+
}

gateway/faux-mgs/src/main.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ use slog::o;
1616
use slog::Drain;
1717
use slog::Level;
1818
use slog::Logger;
19-
use std::fs;
2019
use std::net::SocketAddrV6;
2120
use std::path::PathBuf;
2221
use std::time::Duration;
2322
use tokio::net::UdpSocket;
2423

24+
mod hubris_archive;
2525
mod usart;
2626

27+
use self::hubris_archive::HubrisArchive;
28+
2729
/// Command line program that can send MGS messages to a single SP.
2830
#[derive(Parser, Debug)]
2931
struct Args {
@@ -103,7 +105,7 @@ enum SpCommand {
103105
},
104106

105107
/// Upload a new image to the SP and have it swap banks (requires reset)
106-
Update { image: PathBuf },
108+
Update { hubris_archive: PathBuf },
107109

108110
/// Instruct the SP to reset.
109111
Reset,
@@ -187,12 +189,11 @@ async fn main() -> Result<()> {
187189
)
188190
.await?;
189191
}
190-
Some(SpCommand::Update { image }) => {
191-
let data = fs::read(&image).with_context(|| {
192-
format!("failed to read image {}", image.display())
193-
})?;
192+
Some(SpCommand::Update { hubris_archive }) => {
193+
let mut archive = HubrisArchive::open(&hubris_archive)?;
194+
let data = archive.final_bin()?;
194195
sp.update(data).await.with_context(|| {
195-
format!("updating to {} failed", image.display())
196+
format!("updating to {} failed", hubris_archive.display())
196197
})?;
197198
}
198199
Some(SpCommand::Reset) => {

0 commit comments

Comments
 (0)