Skip to content

Commit 0833495

Browse files
committed
dbus: rauc: use a UpdateRequest object instead of a simple URL for install
Right now the UpdateRequest object also only contains the URL, just like before, but in the future we will at least add a `manifest_hash` field that ensures that the user gets exactly the update bundle they agreed to install. The change is backwards-compatible. Incoming requests to the `/v1/tac/update/install` endpoint are first parsed as JSON object (the new UpdateRequest object) and if that fails as simple string (the old URL string) and then transformed transparently. Signed-off-by: Leonard Göhrs <[email protected]>
1 parent a164327 commit 0833495

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

openapi.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,12 +827,12 @@ paths:
827827
content:
828828
application/json:
829829
schema:
830-
type: string
830+
$ref: '#/components/schemas/UpdateRequest'
831831
responses:
832832
'204':
833-
description: The value was parsed as string and will be tried
833+
description: The value was parsed successfully and will be tried
834834
'400':
835-
description: The value could not be parsed as string
835+
description: The value could not be parsed
836836

837837
/v1/tac/update/channels:
838838
get:
@@ -1102,6 +1102,12 @@ components:
11021102
nesting_depth:
11031103
type: number
11041104

1105+
UpdateRequest:
1106+
type: object
1107+
properties:
1108+
url:
1109+
type: string
1110+
11051111
UpdateChannels:
11061112
type: array
11071113
items:

src/dbus/rauc.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,30 @@ impl From<(i32, String, i32)> for Progress {
114114
}
115115
}
116116

117+
#[derive(Serialize, Deserialize, Clone)]
118+
#[serde(from = "UpdateRequestDe")]
119+
pub struct UpdateRequest {
120+
pub url: Option<String>,
121+
}
122+
123+
#[derive(Deserialize)]
124+
#[serde(untagged)]
125+
enum UpdateRequestDe {
126+
UrlObject { url: Option<String> },
127+
UrlOnly(String),
128+
}
129+
130+
impl From<UpdateRequestDe> for UpdateRequest {
131+
fn from(de: UpdateRequestDe) -> Self {
132+
// Provide API backward compatibility by allowing either just a String
133+
// as argument or a map with url and manifest hash inside.
134+
match de {
135+
UpdateRequestDe::UrlObject { url } => Self { url },
136+
UpdateRequestDe::UrlOnly(url) => Self { url: Some(url) },
137+
}
138+
}
139+
}
140+
117141
type SlotStatus = HashMap<String, HashMap<String, String>>;
118142

119143
pub struct Rauc {
@@ -123,7 +147,7 @@ pub struct Rauc {
123147
#[cfg_attr(feature = "demo_mode", allow(dead_code))]
124148
pub primary: Arc<Topic<String>>,
125149
pub last_error: Arc<Topic<String>>,
126-
pub install: Arc<Topic<String>>,
150+
pub install: Arc<Topic<UpdateRequest>>,
127151
pub channels: Arc<Topic<Channels>>,
128152
pub reload: Arc<Topic<bool>>,
129153
pub should_reboot: Arc<Topic<bool>>,
@@ -336,7 +360,7 @@ impl Rauc {
336360
slot_status: bb.topic_ro("/v1/tac/update/slots", None),
337361
primary: bb.topic_ro("/v1/tac/update/primary", None),
338362
last_error: bb.topic_ro("/v1/tac/update/last_error", None),
339-
install: bb.topic_wo("/v1/tac/update/install", Some("".to_string())),
363+
install: bb.topic_wo("/v1/tac/update/install", None),
340364
channels: bb.topic_ro("/v1/tac/update/channels", None),
341365
reload: bb.topic_wo("/v1/tac/update/channels/reload", Some(true)),
342366
should_reboot: bb.topic_ro("/v1/tac/update/should_reboot", Some(false)),
@@ -546,7 +570,12 @@ impl Rauc {
546570
wtb.spawn_task("rauc-forward-install", async move {
547571
let proxy = InstallerProxy::new(&conn_task).await.unwrap();
548572

549-
while let Some(url) = install_stream.next().await {
573+
while let Some(update_request) = install_stream.next().await {
574+
let url = match update_request.url {
575+
Some(url) => url,
576+
None => continue,
577+
};
578+
550579
// Poor-mans validation. It feels wrong to let someone point to any
551580
// file on the TAC from the web interface.
552581
if url.starts_with("http://") || url.starts_with("https://") {

src/ui/screens/update_available.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use super::{
3030
InputEvent, Screen, Ui,
3131
};
3232
use crate::broker::Topic;
33-
use crate::dbus::rauc::{Channel, Channels};
33+
use crate::dbus::rauc::{Channel, Channels, UpdateRequest};
3434
use crate::watched_tasks::WatchedTasksBuilder;
3535

3636
const SCREEN_TYPE: AlertScreen = AlertScreen::UpdateAvailable;
@@ -121,9 +121,15 @@ impl Selection {
121121
}
122122
}
123123

124-
fn perform(&self, alerts: &Arc<Topic<AlertList>>, install: &Arc<Topic<String>>) {
124+
fn perform(&self, alerts: &Arc<Topic<AlertList>>, install: &Arc<Topic<UpdateRequest>>) {
125125
match self.highlight {
126-
Highlight::Channel(ch) => install.set(self.channels[ch].url.clone()),
126+
Highlight::Channel(ch) => {
127+
let req = UpdateRequest {
128+
url: Some(self.channels[ch].url.clone()),
129+
};
130+
131+
install.set(req);
132+
}
127133
Highlight::Dismiss => alerts.deassert(SCREEN_TYPE),
128134
}
129135
}
@@ -136,7 +142,7 @@ pub struct UpdateAvailableScreen {
136142
struct Active {
137143
widgets: WidgetContainer,
138144
alerts: Arc<Topic<AlertList>>,
139-
install: Arc<Topic<String>>,
145+
install: Arc<Topic<UpdateRequest>>,
140146
selection: Arc<Topic<Selection>>,
141147
}
142148

0 commit comments

Comments
 (0)