@@ -29,6 +29,7 @@ pub(crate) async fn fetch_hubris_artifacts(
2929 client : reqwest:: Client ,
3030 manifest_list : Utf8PathBuf ,
3131 output_dir : Utf8PathBuf ,
32+ name_check : & ' static str ,
3233) -> Result < ( ) > {
3334 macro_rules! zip {
3435 ( $expr: expr) => {
@@ -109,6 +110,7 @@ pub(crate) async fn fetch_hubris_artifacts(
109110 }
110111 }
111112
113+ workaround_check ( & manifest, name_check) ?;
112114 fs:: write (
113115 output_dir. join ( "manifest.toml" ) ,
114116 toml:: to_string_pretty ( & manifest) ?. into_bytes ( ) ,
@@ -117,6 +119,66 @@ pub(crate) async fn fetch_hubris_artifacts(
117119 Ok ( ( ) )
118120}
119121
122+ // omicron#9437 fixed an issue where an incorrect RoT image could be chosen.
123+ // Because the RoT is upgraded before any omicron components, the risk is
124+ // the incorrect RoT gets chosen and blocks the update with the fix in it.
125+ // For the purposes of working around the bug and making sure we can deploy
126+ // the fix, ensure our images are in the "correct" order
127+ fn workaround_check (
128+ manifest : & DeserializedManifest ,
129+ name_check : & ' static str ,
130+ ) -> Result < ( ) > {
131+ // This bug only affects `gimlet_rot` and `gimlet_rot_bootloader`
132+ // We search for these by name. This is ugly but temporary.
133+ let gimlet_artifacts =
134+ manifest. artifacts . get ( & KnownArtifactKind :: GimletRot ) . unwrap ( ) ;
135+
136+ let gimlet = gimlet_artifacts
137+ . iter ( )
138+ . position ( |x| x. name == format ! ( "oxide-rot-1-{}-gimlet" , name_check) )
139+ . expect ( "failed to find gimlet" ) ;
140+
141+ let cosmo = gimlet_artifacts
142+ . iter ( )
143+ . position ( |x| x. name == format ! ( "oxide-rot-1-{}-cosmo" , name_check) )
144+ . expect ( "failed to find cosmo" ) ;
145+
146+ // We need the indicies to be relative for each key set
147+ if gimlet > cosmo {
148+ anyhow:: bail!(
149+ "The gimlet entry for `GimletRot` comes after cosmo. This may cause problems."
150+ ) ;
151+ }
152+
153+ let gimlet_artifacts = manifest
154+ . artifacts
155+ . get ( & KnownArtifactKind :: GimletRotBootloader )
156+ . unwrap ( ) ;
157+
158+ let gimlet = gimlet_artifacts
159+ . iter ( )
160+ . position ( |x| {
161+ x. name == format ! ( "gimlet_rot_bootloader-{}-gimlet" , name_check)
162+ } )
163+ . expect ( "failed to find gimlet" ) ;
164+
165+ let cosmo = gimlet_artifacts
166+ . iter ( )
167+ . position ( |x| {
168+ x. name == format ! ( "gimlet_rot_bootloader-{}-cosmo" , name_check)
169+ } )
170+ . expect ( "failed to find cosmo" ) ;
171+
172+ // We need the indicies to be relative for each key set
173+ if gimlet > cosmo {
174+ anyhow:: bail!(
175+ "The gimlet entry for `GimletRotBootloader` comes after cosmo. This may cause problems."
176+ ) ;
177+ }
178+
179+ Ok ( ( ) )
180+ }
181+
120182async fn fetch_hash (
121183 logger : & Logger ,
122184 base_url : & ' static str ,
0 commit comments