Skip to content

Commit 6bb047d

Browse files
authored
[installinator] Only use installinator doc (#9410)
We're now past the check point for deprecating non-installinator doc updates.
1 parent 3eaaad5 commit 6bb047d

File tree

3 files changed

+130
-251
lines changed

3 files changed

+130
-251
lines changed

installinator/src/artifact.rs

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use std::{net::SocketAddr, time::Duration};
66

7-
use anyhow::{Context, Result};
7+
use anyhow::{Context, Result, bail};
88
use clap::Args;
99
use futures::StreamExt;
1010
use installinator_client::ClientError;
@@ -23,7 +23,7 @@ pub(crate) struct ArtifactIdOpts {
2323
/// Retrieve artifact ID from IPCC
2424
#[clap(
2525
long,
26-
required_unless_present_any = ["update_id", "host_phase_2", "control_plane", "installinator_doc"]
26+
required_unless_present_any = ["update_id", "installinator_doc"]
2727
)]
2828
from_ipcc: bool,
2929

@@ -36,22 +36,8 @@ pub(crate) struct ArtifactIdOpts {
3636

3737
#[clap(
3838
long,
39-
conflicts_with_all = ["from_ipcc", "installinator_doc"],
40-
required_unless_present_any = ["from_ipcc", "installinator_doc"],
41-
)]
42-
host_phase_2: Option<ArtifactHash>,
43-
44-
#[clap(
45-
long,
46-
conflicts_with_all = ["from_ipcc", "installinator_doc"],
47-
required_unless_present_any = ["from_ipcc", "installinator_doc"],
48-
)]
49-
control_plane: Option<ArtifactHash>,
50-
51-
#[clap(
52-
long,
53-
conflicts_with_all = ["from_ipcc", "host_phase_2", "control_plane"],
54-
required_unless_present_any = ["from_ipcc", "host_phase_2", "control_plane"],
39+
conflicts_with_all = ["from_ipcc"],
40+
required_unless_present_any = ["from_ipcc"],
5541
)]
5642
installinator_doc: Option<ArtifactHash>,
5743
}
@@ -63,52 +49,38 @@ impl ArtifactIdOpts {
6349
let image_id = ipcc
6450
.installinator_image_id()
6551
.context("error retrieving installinator image ID")?;
66-
Ok(LookupId::from_image_id(&image_id))
52+
LookupId::from_image_id(&image_id)
6753
} else {
6854
let update_id = self.update_id.unwrap();
69-
let kind =
70-
if let Some(installinator_doc_hash) = self.installinator_doc {
71-
LookupIdKind::Document(installinator_doc_hash)
72-
} else {
73-
LookupIdKind::Hashes {
74-
host_phase_2: self.host_phase_2.unwrap(),
75-
control_plane: self.control_plane.unwrap(),
76-
}
77-
};
78-
79-
Ok(LookupId { update_id, kind })
55+
let document = self
56+
.installinator_doc
57+
.context("error retrieving installinator doc hash")?;
58+
59+
Ok(LookupId { update_id, document })
8060
}
8161
}
8262
}
8363

8464
/// Identifiers used by installinator to retrieve artifacts.
8565
pub(crate) struct LookupId {
8666
pub(crate) update_id: MupdateUuid,
87-
pub(crate) kind: LookupIdKind,
67+
pub(crate) document: ArtifactHash,
8868
}
8969

9070
impl LookupId {
91-
fn from_image_id(image_id: &InstallinatorImageId) -> Self {
71+
fn from_image_id(image_id: &InstallinatorImageId) -> Result<Self> {
9272
// This sentinel hash is used to indicate that the host phase 2 hash is
9373
// actually the hash to the installinator document.
94-
let kind = if image_id.control_plane == ArtifactHash([0; 32]) {
95-
LookupIdKind::Document(image_id.host_phase_2)
96-
} else {
97-
LookupIdKind::Hashes {
98-
host_phase_2: image_id.host_phase_2,
99-
control_plane: image_id.control_plane,
100-
}
101-
};
10274

103-
Self { update_id: image_id.update_id, kind }
104-
}
105-
}
75+
if image_id.control_plane != ArtifactHash([0; 32]) {
76+
bail!("non-zero control plane hash, this isn't using doc format");
77+
}
10678

107-
/// Either an installinator document hash, or host phase 2 and control plane
108-
/// hashes.
109-
pub(crate) enum LookupIdKind {
110-
Document(ArtifactHash),
111-
Hashes { host_phase_2: ArtifactHash, control_plane: ArtifactHash },
79+
Ok(Self {
80+
update_id: image_id.update_id,
81+
document: image_id.host_phase_2,
82+
})
83+
}
11284
}
11385

11486
/// The host phase 2 and control plane hashes to download.

installinator/src/dispatch.rs

Lines changed: 90 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use update_engine::StepResult;
2525

2626
use crate::{
2727
ArtifactWriter, WriteDestination,
28-
artifact::{ArtifactIdOpts, ArtifactsToDownload, LookupIdKind},
28+
artifact::{ArtifactIdOpts, ArtifactsToDownload},
2929
fetch::{FetchArtifactBackend, FetchedArtifact, HttpFetchBackend},
3030
peers::DiscoveryMechanism,
3131
reporter::{HttpProgressBackend, ProgressReporter, ReportProgressBackend},
@@ -209,121 +209,102 @@ impl InstallOpts {
209209

210210
let engine = UpdateEngine::new(log, event_sender);
211211

212-
let to_download = match lookup_id.kind {
213-
LookupIdKind::Document(hash) => {
214-
engine
215-
.new_step(
216-
InstallinatorComponent::InstallinatorDocument,
217-
InstallinatorStepId::Download,
218-
"Downloading installinator document",
219-
async move |cx| {
220-
let installinator_doc_id = ArtifactHashId {
221-
kind: KnownArtifactKind::InstallinatorDocument
222-
.into(),
223-
hash,
224-
};
225-
let installinator_doc = fetch_artifact(
226-
&cx,
227-
&installinator_doc_id,
228-
discovery,
229-
log,
230-
)
231-
.await?;
212+
let to_download = engine
213+
.new_step(
214+
InstallinatorComponent::InstallinatorDocument,
215+
InstallinatorStepId::Download,
216+
"Downloading installinator document",
217+
async move |cx| {
218+
let installinator_doc_id = ArtifactHashId {
219+
kind: KnownArtifactKind::InstallinatorDocument.into(),
220+
hash: lookup_id.document,
221+
};
222+
let installinator_doc = fetch_artifact(
223+
&cx,
224+
&installinator_doc_id,
225+
discovery,
226+
log,
227+
)
228+
.await?;
232229

233-
// Check that the sha256 of the data we got from
234-
// wicket matches the data we asked for.
235-
//
236-
// If this fails, we fail the entire installation
237-
// rather than trying to fetch the artifact again,
238-
// because we're fetching data from wicketd (cached
239-
// in a temp dir) over TCP to ourselves (in memory),
240-
// so the only cases where this could fail are
241-
// disturbing enough (memory corruption, corruption
242-
// under TCP, or wicketd gave us something other
243-
// than what we requested) we want to know
244-
// immediately and not retry: it's likely an
245-
// operator could miss any warnings we emit if a
246-
// retry succeeds.
247-
check_downloaded_artifact_hash(
248-
"installinator document",
249-
installinator_doc.artifact.clone(),
250-
installinator_doc_id.hash,
251-
)
252-
.await?;
230+
// Check that the sha256 of the data we got from
231+
// wicket matches the data we asked for.
232+
//
233+
// If this fails, we fail the entire installation
234+
// rather than trying to fetch the artifact again,
235+
// because we're fetching data from wicketd (cached
236+
// in a temp dir) over TCP to ourselves (in memory),
237+
// so the only cases where this could fail are
238+
// disturbing enough (memory corruption, corruption
239+
// under TCP, or wicketd gave us something other
240+
// than what we requested) we want to know
241+
// immediately and not retry: it's likely an
242+
// operator could miss any warnings we emit if a
243+
// retry succeeds.
244+
check_downloaded_artifact_hash(
245+
"installinator document",
246+
installinator_doc.artifact.clone(),
247+
installinator_doc_id.hash,
248+
)
249+
.await?;
253250

254-
// Read the document as JSON.
255-
//
256-
// Going via the reader is slightly less efficient
257-
// than operating purely in-memory, but serde_json
258-
// doesn't have a good way to pass in a BufList
259-
// directly.
260-
let json: InstallinatorDocument =
261-
serde_json::from_reader(buf_list::Cursor::new(
262-
&installinator_doc.artifact,
263-
))
264-
.context(
265-
"error deserializing \
251+
// Read the document as JSON.
252+
//
253+
// Going via the reader is slightly less efficient
254+
// than operating purely in-memory, but serde_json
255+
// doesn't have a good way to pass in a BufList
256+
// directly.
257+
let json: InstallinatorDocument = serde_json::from_reader(
258+
buf_list::Cursor::new(&installinator_doc.artifact),
259+
)
260+
.context(
261+
"error deserializing \
266262
installinator document",
267-
)?;
268-
269-
// Every valid installinator document must have the
270-
// host phase 2 and control plane hashes.
271-
let mut host_phase_2_hash = None;
272-
let mut control_plane_hash = None;
273-
for artifact in &json.artifacts {
274-
match artifact.kind {
275-
InstallinatorArtifactKind::HostPhase2 => {
276-
host_phase_2_hash = Some(artifact.hash);
277-
}
278-
InstallinatorArtifactKind::ControlPlane => {
279-
control_plane_hash =
280-
Some(artifact.hash);
281-
}
282-
}
283-
}
284-
285-
// Return an error if either the host phase 2 or the
286-
// control plane artifacts are missing.
287-
let mut missing = Vec::new();
288-
if host_phase_2_hash.is_none() {
289-
missing.push(
290-
InstallinatorArtifactKind::HostPhase2,
291-
);
263+
)?;
264+
265+
// Every valid installinator document must have the
266+
// host phase 2 and control plane hashes.
267+
let mut host_phase_2_hash = None;
268+
let mut control_plane_hash = None;
269+
for artifact in &json.artifacts {
270+
match artifact.kind {
271+
InstallinatorArtifactKind::HostPhase2 => {
272+
host_phase_2_hash = Some(artifact.hash);
292273
}
293-
if control_plane_hash.is_none() {
294-
missing.push(
295-
InstallinatorArtifactKind::ControlPlane,
296-
);
274+
InstallinatorArtifactKind::ControlPlane => {
275+
control_plane_hash = Some(artifact.hash);
297276
}
298-
if !missing.is_empty() {
299-
bail!(
300-
"installinator document missing \
277+
}
278+
}
279+
280+
// Return an error if either the host phase 2 or the
281+
// control plane artifacts are missing.
282+
let mut missing = Vec::new();
283+
if host_phase_2_hash.is_none() {
284+
missing.push(InstallinatorArtifactKind::HostPhase2);
285+
}
286+
if control_plane_hash.is_none() {
287+
missing.push(InstallinatorArtifactKind::ControlPlane);
288+
}
289+
if !missing.is_empty() {
290+
bail!(
291+
"installinator document missing \
301292
required artifacts: {:?}",
302-
missing
303-
);
304-
}
293+
missing
294+
);
295+
}
305296

306-
StepSuccess::new(ArtifactsToDownload {
307-
host_phase_2: host_phase_2_hash.expect(
308-
"host phase 2 is Some, checked above",
309-
),
310-
control_plane: control_plane_hash.expect(
311-
"control plane is Some, checked above",
312-
),
313-
})
314-
.into()
315-
},
316-
)
317-
.register()
318-
}
319-
LookupIdKind::Hashes { host_phase_2, control_plane } => {
320-
StepHandle::ready(ArtifactsToDownload {
321-
host_phase_2,
322-
control_plane,
323-
})
324-
}
325-
}
326-
.into_shared();
297+
StepSuccess::new(ArtifactsToDownload {
298+
host_phase_2: host_phase_2_hash
299+
.expect("host phase 2 is Some, checked above"),
300+
control_plane: control_plane_hash
301+
.expect("control plane is Some, checked above"),
302+
})
303+
.into()
304+
},
305+
)
306+
.register()
307+
.into_shared();
327308

328309
let to_download_2 = to_download.clone();
329310
let to_download_3 = to_download_2.clone();

0 commit comments

Comments
 (0)