From a7c02949f35a47533841d14a6729e5dcc059da91 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 13:37:21 +0000 Subject: [PATCH 001/641] Initial stub --- .gitignore | 1 + Cargo.lock | 5 ++ Cargo.toml | 9 ++ LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++++ code-of-conduct.md | 61 ++++++++++++++ src/main.rs | 3 + 6 files changed, 281 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 code-of-conduct.md create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..0d30bb43b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bootupd" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..e04722c61 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "bootupd" +version = "0.1.0" +authors = ["Colin Walters "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..8f71f43fe --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 000000000..a234f3609 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,61 @@ +## CoreOS Community Code of Conduct + +### Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing others' private information, such as physical or electronic addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct. By adopting this Code of Conduct, +project maintainers commit themselves to fairly and consistently applying these +principles to every aspect of managing this project. Project maintainers who do +not follow or enforce the Code of Conduct may be permanently removed from the +project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer, Brandon Philips +, and/or Rithu John . + +This Code of Conduct is adapted from the Contributor Covenant +(http://contributor-covenant.org), version 1.2.0, available at +http://contributor-covenant.org/version/1/2/0/ + +### CoreOS Events Code of Conduct + +CoreOS events are working conferences intended for professional networking and +collaboration in the CoreOS community. Attendees are expected to behave +according to professional standards and in accordance with their employer’s +policies on appropriate workplace behavior. + +While at CoreOS events or related social networking opportunities, attendees +should not engage in discriminatory or offensive speech or actions including +but not limited to gender, sexuality, race, age, disability, or religion. +Speakers should be especially aware of these concerns. + +CoreOS does not condone any statements by speakers contrary to these standards. +CoreOS reserves the right to deny entrance and/or eject from an event (without +refund) any individual found to be engaging in discriminatory or offensive +speech or actions. + +Please bring any concerns to the immediate attention of designated on-site +staff, Brandon Philips , and/or Rithu John . diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From e351a847f1d93759414dd040a9a4d5465027db51 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 15:26:13 +0000 Subject: [PATCH 002/641] Initial import from rpm-ostree prototype --- .gitignore | 1 + Cargo.lock | 5 - Cargo.toml | 33 +- src/main.rs | 893 ++++++++++++++++++++++++++++++++++++++- tests/libtest.sh | 68 +++ tests/unpriv-blackbox.sh | 84 ++++ 6 files changed, 1075 insertions(+), 9 deletions(-) delete mode 100644 Cargo.lock create mode 100644 tests/libtest.sh create mode 100755 tests/unpriv-blackbox.sh diff --git a/.gitignore b/.gitignore index ea8c4bf7f..96ef6c0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 0d30bb43b..000000000 --- a/Cargo.lock +++ /dev/null @@ -1,5 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "bootupd" -version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index e04722c61..868432a5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,35 @@ version = "0.1.0" authors = ["Colin Walters "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +anyhow = "1.0" +serde = "1.0.112" +serde_derive = "1.0.112" +serde_json = "1.0" +serde_yaml = "0.8" +libc = "0.2" +nix = "0.17.0" +glib-sys = "0.9.1" +gio-sys = "0.9.1" +glib = "0.9" +gio = "0.8" +tempfile = "3.0.3" +clap = "~2.33" +structopt = "0.3" +openat = "0.1.19" +openat-ext = "0.1.0" +openssl = "^0.10" +hex = "0.4.2" +bs58 = "0.3.1" +byteorder = "1" +rayon = "1.0" +c_utf8 = "0.1.0" +lazy_static = "1.1.0" +serde_plain = "0.3.0" +chrono = { version = "0.4.11", features = ["serde"] } +# Can't bump to 2020_1 or beyond due to https://github.com/ostreedev/ostree/pull/2137 +ostree = { version = "0.7.0", features = ["v2019_6"] } + +[patch.crates-io] +ostree = { git = "https://gitlab.com/cgwalters/ostree-rs", branch = "walters-master" } +#ostree = { path = "/var/srv/walters/src/gitlab/fkrull/ostree-rs" } diff --git a/src/main.rs b/src/main.rs index e7a11a969..78dce36f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,892 @@ -fn main() { - println!("Hello, world!"); +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +//! See: https://github.com/coreos/fedora-coreos-tracker/issues/510 +//! This is an early prototype hidden/not-yet-standardized mechanism +//! which just updates EFI for now (x86_64/aarch64 only). +//! +//! But in the future will hopefully gain some independence from +//! ostree and also support e.g. updating the MBR etc. + +// To run the unit tests for this code, use `make check TESTS=tests/check/test-ex-boot-update.sh` + +use anyhow::{bail, Context, Result}; +use byteorder::ByteOrder; +use chrono::prelude::*; +use gio::NONE_CANCELLABLE; +use nix; +use openat_ext::OpenatDirExt; +use openssl::hash::{Hasher, MessageDigest}; +use serde_derive::{Deserialize, Serialize}; +use serde_json; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::fmt; +use std::io::prelude::*; +use std::path::Path; +use structopt::StructOpt; + +/// Stored in /boot to describe our state; think of it like +/// a tiny rpm/dpkg database. +pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; +/// The path to the ESP mount +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; + +/// The prefix we apply to our temporary files. +pub(crate) const TMP_PREFIX: &'static str = ".btmp."; + +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) struct SHA512String(String); + +impl fmt::Display for SHA512String { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +/// Metadata for a single file +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) enum ComponentType { + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + EFI, + #[cfg(target_arch = "x86_64")] + BIOS, +} + +/// Metadata for a single file +#[derive(Serialize, Debug, Hash, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileMetadata { + /// File size in bytes + size: u64, + /// Content checksum; chose SHA-512 because there are not a lot of files here + /// and it's ok if the checksum is large. + sha512: SHA512String, +} + +#[derive(Serialize, Debug, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileTree { + timestamp: NaiveDateTime, + children: BTreeMap, +} + +/// Describes data that is at the block level or the filesystem level. +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct InstalledContent { + /// sha512 of the state of the content + digest: SHA512String, + timestamp: NaiveDateTime, + filesystem: Option>, +} + +/// A versioned description of something we can update, +/// whether that is a BIOS MBR or an ESP +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContentVersion { + content_timestamp: NaiveDateTime, + content: InstalledContent, + ostree_commit: Option, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentInstalled { + Unknown(InstalledContent), + Tracked { + disk: InstalledContent, + saved: SavedComponent, + drift: bool, + }, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentState { + #[allow(dead_code)] + NotInstalled, + NotImplemented, + Found(ComponentInstalled), +} + +/// The state of a particular managed component +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentUpdate { + LatestUpdateInstalled, + Available { + update: ContentVersion, + diff: Option, + }, +} + +/// A component along with a possible update +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Component { + ctype: ComponentType, + installed: ComponentState, + pending: Option, + update: Option, +} + +/// Our total view of the world at a point in time +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Status { + supported_architecture: bool, + components: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedPendingUpdate { + /// The value of /proc/sys/kernel/random/boot_id + boot_id: String, + /// The value of /etc/machine-id from the OS trying to update + machineid: String, + /// The new version we're trying to install + digest: SHA512String, + timestamp: NaiveDateTime, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedComponent { + adopted: bool, + digest: SHA512String, + timestamp: NaiveDateTime, + pending: Option, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedState { + components: BTreeMap, +} + +/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct UpgradeEdge { + /// Set to true if we should upgrade from an unknown state + #[serde(default)] + from_unknown: bool, + /// Upgrade from content past this timestamp + from_timestamp: Option, +} + +#[derive(Debug, StructOpt)] +#[structopt(rename_all = "kebab-case")] +struct UpdateOptions { + /// The system root + #[structopt(default_value = "/", long)] + sysroot: String, + + // Perform an update even if there is no state transition + #[structopt(long)] + force: bool, + + /// The destination ESP mount point + #[structopt( + default_value = "/usr/share/rpm-ostree/bootupdate-transition.json", + long + )] + state_transition_file: String, +} + +#[derive(Debug, StructOpt)] +#[structopt(rename_all = "kebab-case")] +struct StatusOptions { + /// System root + #[structopt(default_value = "/", long)] + sysroot: String, + + #[structopt(long = "component")] + components: Option>, + + // Output JSON + #[structopt(long)] + json: bool, +} + +#[derive(Debug, StructOpt)] +#[structopt(name = "boot-update")] +#[structopt(rename_all = "kebab-case")] +enum Opt { + /// Install data into the EFI System Partition + Install { + /// Physical root mountpoint + #[structopt(long)] + sysroot: String, + }, + /// Start tracking current data found in the EFI System Partition + Adopt { + /// Physical root mountpoint + #[structopt(long)] + sysroot: String, + }, + /// Update the EFI System Partition + Update(UpdateOptions), + Status(StatusOptions), +} + +impl SHA512String { + fn from_hasher(hasher: &mut Hasher) -> Self { + Self(format!( + "sha512:{}", + bs58::encode(hasher.finish().expect("completing hash")).into_string() + )) + } + + fn digest_bs58(&self) -> &str { + self.0.splitn(2, ":").next().unwrap() + } + + fn digest_bytes(&self) -> Vec { + bs58::decode(self.digest_bs58()) + .into_vec() + .expect("decoding bs58 hash") + } +} + +impl FileMetadata { + pub(crate) fn new_from_path( + dir: &openat::Dir, + name: P, + ) -> Result { + let mut r = dir.open_file(name)?; + let meta = r.metadata()?; + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + std::io::copy(&mut r, &mut hasher)?; + let digest = SHA512String::from_hasher(&mut hasher); + Ok(FileMetadata { + size: meta.len(), + sha512: digest, + }) + } + + pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { + let mut lenbuf = [0; 8]; + byteorder::BigEndian::write_u64(&mut lenbuf, self.size); + hasher.update(&lenbuf).unwrap(); + hasher.update(&self.sha512.digest_bytes()).unwrap(); + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct FileTreeDiff { + additions: HashSet, + removals: HashSet, + changes: HashSet, +} + +impl FileTree { + // Internal helper to generate a sub-tree + fn unsorted_from_dir(dir: &openat::Dir) -> Result> { + let mut ret = HashMap::new(); + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) + }; + if name.starts_with(TMP_PREFIX) { + bail!("File {} contains our temporary prefix!", name); + } + match dir.get_file_type(&entry)? { + openat::SimpleType::File => { + let meta = FileMetadata::new_from_path(dir, name)?; + ret.insert(name.to_string(), meta); + } + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + for (mut k, v) in FileTree::unsorted_from_dir(&child)?.drain() { + k.reserve(name.len() + 1); + k.insert(0, '/'); + k.insert_str(0, name); + ret.insert(k, v); + } + } + openat::SimpleType::Symlink => { + bail!("Unsupported symbolic link {:?}", entry.file_name()) + } + openat::SimpleType::Other => { + bail!("Unsupported non-file/directory {:?}", entry.file_name()) + } + } + } + Ok(ret) + } + + fn digest(&self) -> SHA512String { + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + for (k, v) in self.children.iter() { + hasher.update(k.as_bytes()).unwrap(); + v.extend_hash(&mut hasher); + } + SHA512String::from_hasher(&mut hasher) + } + + /// Create a FileTree from the target directory. + fn new_from_dir(dir: &openat::Dir) -> Result { + let mut children = BTreeMap::new(); + for (k, v) in Self::unsorted_from_dir(dir)?.drain() { + children.insert(k, v); + } + + let meta = dir.metadata(".")?; + let stat = meta.stat(); + + Ok(Self { + timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), + children: children, + }) + } + + /// Determine the changes *from* self to the updated tree + fn diff(&self, updated: &Self) -> Result { + let mut additions = HashSet::new(); + let mut removals = HashSet::new(); + let mut changes = HashSet::new(); + + for (k, v1) in self.children.iter() { + if let Some(v2) = updated.children.get(k) { + if v1 != v2 { + changes.insert(k.clone()); + } + } else { + removals.insert(k.clone()); + } + } + for k in updated.children.keys() { + if let Some(_) = self.children.get(k) { + continue; + } + additions.insert(k.clone()); + } + Ok(FileTreeDiff { + additions: additions, + removals: removals, + changes: changes, + }) + } +} + +impl InstalledContent { + fn from_file_tree(ft: FileTree) -> InstalledContent { + InstalledContent { + digest: ft.digest(), + timestamp: ft.timestamp, + filesystem: Some(Box::new(ft)), + } + } +} + +impl ComponentInstalled { + fn get_disk_content(&self) -> &InstalledContent { + match self { + Self::Unknown(i) => i, + Self::Tracked { disk, .. } => disk, + } + } +} + +// Recursively remove all files in the directory that start with our TMP_PREFIX +fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + // Skip invalid UTF-8 for now, we will barf on it later though. + continue; + }; + + match dir.get_file_type(&entry)? { + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + cleanup_tmp(&child)?; + } + openat::SimpleType::File => { + if name.starts_with(TMP_PREFIX) { + dir.remove_file(name)?; + } + } + _ => {} + } + } + Ok(()) +} + +// struct ApplyUpdateOptions { +// skip_removals: bool, +// } + +// fn apply_update_from_diff( +// src: &openat::Dir, +// dest: &openat::Dir, +// diff: FileTreeDiff, +// opts: Option, +// ) -> Result<()> { +// Ok(()) +// } + +fn running_in_test_suite() -> bool { + !nix::unistd::getuid().is_root() +} + +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +pub(crate) fn validate_esp>(mnt: P) -> Result<()> { + if running_in_test_suite() { + return Ok(()); + } + let mnt = mnt.as_ref(); + let stat = nix::sys::statfs::statfs(mnt)?; + let fstype = stat.filesystem_type(); + if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { + bail!( + "Mount {} is not a msdos filesystem, but is {:?}", + mnt.display(), + fstype + ); + }; + Ok(()) +} + +mod install { + use super::*; + + fn find_deployed_commit(sysroot_path: &str) -> Result { + // ostree_sysroot_get_deployments() isn't bound + // https://gitlab.com/fkrull/ostree-rs/-/issues/3 + let ls = std::process::Command::new("/bin/sh") + .arg("-c") + .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) + .output()?; + if !ls.status.success() { + bail!("failed to find deployment") + } + let mut lines = ls.stdout.lines(); + let deployment = if let Some(line) = lines.next() { + let line = line?; + let deploypath = Path::new(line.trim()); + let parts: Vec<_> = deploypath + .file_name() + .unwrap() + .to_str() + .unwrap() + .splitn(2, ".0") + .collect(); + assert!(parts.len() == 2); + parts[0].to_string() + } else { + bail!("failed to find deployment"); + }; + if let Some(_) = lines.next() { + bail!("multiple deployments found") + } + Ok(deployment) + } + + pub(crate) fn install(sysroot_path: &str) -> Result<()> { + let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); + sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; + + let _commit = find_deployed_commit(sysroot_path)?; + + let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); + if statepath.exists() { + bail!("{:?} already exists, cannot re-install", statepath); + } + + let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); + validate_esp(&bootefi)?; + + Ok(()) + } +} + +fn update(opts: &UpdateOptions) -> Result<()> { + let esp = Path::new(&opts.sysroot).join(EFI_MOUNT); + validate_esp(&esp)?; + let esp_dir = openat::Dir::open(&esp)?; + + // First remove any temporary files + cleanup_tmp(&esp_dir)?; + + Ok(()) +} + +fn adopt(sysroot_path: &str) -> Result<()> { + let status = compute_status(sysroot_path)?; + let mut new_saved_components = BTreeMap::new(); + let mut adopted = std::collections::BTreeSet::new(); + for component in status.components { + let installed = match component.installed { + ComponentState::NotInstalled => continue, + ComponentState::NotImplemented => continue, + ComponentState::Found(installed) => installed, + }; + let disk = match installed { + ComponentInstalled::Unknown(state) => { + println!("Adopting: {:?}", component.ctype); + adopted.insert(component.ctype.clone()); + state + } + ComponentInstalled::Tracked { + disk: _, + saved, + drift, + } => { + if drift { + eprintln!("Warning: Skipping drifted component: {:?}", component.ctype); + } + new_saved_components.insert(component.ctype.clone(), saved.clone()); + continue; + } + }; + let saved = SavedComponent { + adopted: true, + digest: disk.digest, + timestamp: disk.timestamp, + pending: None, + }; + new_saved_components.insert(component.ctype, saved); + } + if adopted.len() == 0 { + println!("Nothing to do."); + return Ok(()); + } + + let new_saved_state = SavedState { + components: new_saved_components, + }; + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let f = { + let f = sysroot_dir.new_unnamed_file(0o644)?; + let mut buff = std::io::BufWriter::new(f); + serde_json::to_writer(&mut buff, &new_saved_state)?; + buff.flush()?; + buff.into_inner()? + }; + let dest = Path::new(STATEFILE_PATH); + let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); + let dest_tmp = dest.with_file_name(dest_tmp_name); + sysroot_dir.link_file_at(&f, &dest_tmp)?; + sysroot_dir.local_rename(&dest_tmp, dest)?; + Ok(()) +} + +fn timestamp_and_commit_from_sysroot( + sysroot_path: &str, +) -> Result<(chrono::naive::NaiveDateTime, String)> { + // Until we have list_deployments + assert!(sysroot_path == "/"); + let ostree_sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); + ostree_sysroot + .load(NONE_CANCELLABLE) + .context("loading sysroot")?; + let booted_deployment = if let Some(booted) = ostree_sysroot.get_booted_deployment() { + booted + } else { + bail!("Not booted into an OSTree system") + }; + + let repo = ostree_sysroot.repo().expect("repo"); + let csum = booted_deployment.get_csum().expect("booted csum"); + let csum = csum.as_str(); + let (commit, _) = repo.load_commit(csum)?; + let ts = ostree::commit_get_timestamp(&commit); + let ts = chrono::naive::NaiveDateTime::from_timestamp(ts as i64, 0); + Ok((ts, csum.to_string())) +} + +/// Parse an environment variable as UTF-8 +fn getenv_utf8(n: &str) -> Result> { + if let Some(v) = std::env::var_os(n) { + Ok(Some( + v.to_str() + .ok_or_else(|| anyhow::anyhow!("{} is invalid UTF-8", n))? + .to_string(), + )) + } else { + Ok(None) + } +} + +fn efi_content_version_from_ostree(sysroot_path: &str) -> Result { + let (ts, commit) = if let Some(timestamp_str) = getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? { + let ts = chrono::NaiveDateTime::parse_from_str(×tamp_str, "%+")?; + (ts, None) + } else { + let (ts, commit) = timestamp_and_commit_from_sysroot(sysroot_path)?; + (ts, Some(commit)) + }; + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let update_esp_dir = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; + let ft = FileTree::new_from_dir(&update_esp_dir)?; + Ok(ContentVersion { + content_timestamp: ts, + content: InstalledContent::from_file_tree(ft), + ostree_commit: commit, + }) +} + +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +fn compute_status_efi( + sysroot_path: &str, + saved_components: Option<&SavedState>, +) -> Result { + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let espdir = sysroot_dir.sub_dir("boot/efi")?; + let content = InstalledContent::from_file_tree(FileTree::new_from_dir(&espdir)?); + let digest = content.digest.clone(); + let saved_state = saved_components + .map(|s| s.components.get(&ComponentType::EFI)) + .flatten(); + let installed_state = if let Some(saved) = saved_state { + dbg!(&saved); + let drift = saved.digest != content.digest; + ComponentInstalled::Tracked { + disk: content, + saved: saved.clone(), + drift: drift, + } + } else { + ComponentInstalled::Unknown(content) + }; + let installed_tree = installed_state + .get_disk_content() + .filesystem + .as_ref() + .unwrap(); + + let update_esp = efi_content_version_from_ostree(sysroot_path)?; + let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); + let update = if update_esp.content.digest == digest { + ComponentUpdate::LatestUpdateInstalled + } else { + let diff = installed_tree.diff(update_esp_tree)?; + ComponentUpdate::Available { + update: update_esp, + diff: Some(diff), + } + }; + + Ok(Component { + ctype: ComponentType::EFI, + installed: ComponentState::Found(installed_state), + pending: saved_state.map(|x| x.pending.clone()).flatten(), + update: Some(update), + }) +} + +fn compute_status(sysroot_path: &str) -> Result { + let sysroot_dir = openat::Dir::open(sysroot_path)?; + + let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(STATEFILE_PATH)? { + let bufr = std::io::BufReader::new(statusf); + let saved_state: SavedState = serde_json::from_reader(bufr)?; + Some(saved_state) + } else { + None + }; + + let mut components = Vec::new(); + + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + components.push(compute_status_efi(&sysroot_path, saved_state.as_ref())?); + + #[cfg(target_arch = "x86_64")] + { + components.push(Component { + ctype: ComponentType::BIOS, + installed: ComponentState::NotImplemented, + pending: None, + update: None, + }); + } + Ok(Status { + supported_architecture: components.len() > 0, + components: components, + }) +} + +fn print_component(component: &Component) { + let name = serde_plain::to_string(&component.ctype).expect("serde"); + println!("Component {}", name); + let installed = match &component.installed { + ComponentState::NotInstalled => { + println!(" Not installed."); + return; + } + ComponentState::NotImplemented => { + println!(" Not implemented."); + return; + } + ComponentState::Found(installed) => installed, + }; + match installed { + ComponentInstalled::Unknown(disk) => { + println!(" Unmanaged: digest={}", disk.digest); + } + ComponentInstalled::Tracked { disk, saved, drift } => { + if !*drift { + println!(" Installed: {}", disk.digest); + if saved.adopted { + println!(" Adopted: true") + } + } else { + println!(" Installed; warning: drift detected"); + println!(" Recorded: {}", saved.digest); + println!(" Actual: {}", disk.digest); + } + } + } + if let Some(update) = component.update.as_ref() { + match update { + ComponentUpdate::LatestUpdateInstalled => { + println!(" Update: At latest version"); + } + ComponentUpdate::Available { update, diff } => { + let ts_str = update.content_timestamp.format("%Y-%m-%dT%H:%M:%S+00:00"); + println!(" Update: Available: {}", ts_str); + if let Some(diff) = diff { + println!( + " Diff: changed={} added={} removed={}", + diff.changes.len(), + diff.additions.len(), + diff.removals.len() + ); + } + } + } + } +} + +fn status(opts: &StatusOptions) -> Result<()> { + let status = compute_status(&opts.sysroot)?; + if opts.json { + serde_json::to_writer_pretty(std::io::stdout(), &status)?; + } else { + if !status.supported_architecture { + eprintln!("This architecture is not supported.") + } else { + let specified_components = if let Some(components) = &opts.components { + let r: std::result::Result, _> = components + .iter() + .map(|c| serde_plain::from_str(c)) + .collect(); + Some(r?) + } else { + None + }; + for component in &status.components { + if let Some(specified_components) = specified_components.as_ref() { + if !specified_components.contains(&component.ctype) { + continue; + } + } + print_component(component); + } + } + } + Ok(()) +} + +/// Main entrypoint +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +fn boot_update_main(args: &Vec) -> Result<()> { + let opt = Opt::from_iter(args.iter()); + match opt { + Opt::Install { sysroot } => { + install::install(&sysroot).context("boot data installation failed")? + } + Opt::Adopt { sysroot } => adopt(&sysroot)?, + Opt::Update(ref opts) => update(opts).context("boot data update failed")?, + Opt::Status(ref opts) => status(opts).context("status failed")?, + }; + Ok(()) +} + +#[cfg(not(any(target_arch = "x86_64", target_arch = "arm")))] +fn boot_update_main(args: &Vec) -> Result<()> { + bail!("This command is only supported on x86_64") +} + +#[cfg(test)] +mod tests { + use super::*; + + fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { + let ta = FileTree::new_from_dir(&a)?; + let tb = FileTree::new_from_dir(&b)?; + let diff = ta.diff(&tb)?; + Ok(diff) + } + + #[test] + fn test_diff() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let p = tmpd.path(); + let a = p.join("a"); + let b = p.join("b"); + std::fs::create_dir(&a)?; + std::fs::create_dir(&b)?; + let a = openat::Dir::open(&a)?; + let b = openat::Dir::open(&b)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + a.create_dir("foo", 0o755)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar = a.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 1); + assert_eq!(diff.changes.len(), 0); + b.create_dir("foo", 0o755)?; + { + let mut bar = b.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar2 = b.write_file("foo/bar", 0o644)?; + bar2.write("foobarcontents2".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 1); + Ok(()) + } +} + +fn main() -> Result<()> { + let args: Vec<_> = std::env::args().collect(); + boot_update_main(&args) } diff --git a/tests/libtest.sh b/tests/libtest.sh new file mode 100644 index 000000000..a582a87b1 --- /dev/null +++ b/tests/libtest.sh @@ -0,0 +1,68 @@ +# Source library for shell script tests + +runv() { + (set -x && "$@") +} + +N_TESTS=0 +ok() { + echo "ok " $@ + N_TESTS=$((N_TESTS + 1)) +} + +tap_finish() { + echo "Completing TAP test with:" + echo "1..${N_TESTS}" +} + +fatal() { + echo error: $@ 1>&2; exit 1 +} + +# Dump ls -al + file contents to stderr, then fatal() +_fatal_print_file() { + file="$1" + shift + ls -al "$file" >&2 + sed -e 's/^/# /' < "$file" >&2 + fatal "$@" +} + +assert_file_has_content () { + fpath=$1 + shift + for re in "$@"; do + if ! grep -q -e "$re" "$fpath"; then + _fatal_print_file "$fpath" "File '$fpath' doesn't match regexp '$re'" + fi + done +} + +assert_file_has_content_literal () { + fpath=$1; shift + for s in "$@"; do + if ! grep -q -F -e "$s" "$fpath"; then + _fatal_print_file "$fpath" "File '$fpath' doesn't match fixed string list '$s'" + fi + done +} + +assert_not_file_has_content () { + fpath=$1 + shift + for re in "$@"; do + if grep -q -e "$re" "$fpath"; then + _fatal_print_file "$fpath" "File '$fpath' matches regexp '$re'" + fi + done +} + +assert_not_file_has_content_literal () { + fpath=$1; shift + for s in "$@"; do + if grep -q -F -e "$s" "$fpath"; then + _fatal_print_file "$fpath" "File '$fpath' matches fixed string list '$s'" + fi + done +} + diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh new file mode 100755 index 000000000..1e912abc9 --- /dev/null +++ b/tests/unpriv-blackbox.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# Copyright (C) 2020 Colin Walters +# +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail +dn=$(cd $(dirname $0) && pwd) + +. ${dn}/libtest.sh + +tmpdir=$(mktemp -d) +cd ${tmpdir} +echo "using tmpdir: ${tmpdir}" +touch .testtmp +trap cleanup EXIT +function cleanup () { + if test -z "${TEST_SKIP_CLEANUP:-}"; then + if test -f "${tmpdir}"/.testtmp; then + cd / + rm "${tmpdir}" -rf + fi + else + echo "Skipping cleanup of ${test_tmpdir}" + fi +} + +bootupd() { + runv ${dn}/../target/release/bootupd "$@" +} + +bootefi=root/boot/efi +ostefi=root/usr/lib/ostree-boot/efi +mkdir -p "${bootefi}" "${ostefi}" +for dir in "${bootefi}" "${ostefi}"; do + (cd ${dir} + mkdir -p EFI/fedora + cd EFI/fedora + for x in grubx64.efi shim.efi shimx64.efi; do + echo "some code for ${x}" > ${x} + done + ) +done + +v0_digest="sha512:4vbqyRvLYPyPtVaD3VexZQ9FBzhh1MFNsK4A5t1Ju7bVvj3YEDZfrrBQ7CTNjgwj8PhRBPvxHJ5v3x28fQZxCKBL" + +validate_v0() { + bootupd status --sysroot=root --component=EFI | tee out.txt + assert_file_has_content_literal out.txt 'Component EFI' + assert_file_has_content_literal out.txt ' Unmanaged: digest='${v0_digest} + assert_file_has_content_literal out.txt 'Update: At latest version' + assert_not_file_has_content out.txt 'Component BIOS' +} + +# This hack avoids us depending on having an ostree sysroot set up for now +export BOOT_UPDATE_TEST_TIMESTAMP=$(date -u --iso-8601=seconds) +validate_v0 + +echo 'v2 code for grubx64.efi' > "${ostefi}"/EFI/fedora/grubx64.efi +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Update: Available: '${BOOT_UPDATE_TEST_TIMESTAMP} +assert_file_has_content_literal out.txt ' Diff: changed=1 added=0 removed=0' + +# Revert back +echo 'some code for grubx64.efi' > "${ostefi}"/EFI/fedora/grubx64.efi +validate_v0 + +bootupd adopt --sysroot=root | tee out.txt +assert_file_has_content_literal out.txt "Adopting: EFI" +ok 'rerunning adoption' + +bootupd adopt --sysroot=root | tee out.txt +assert_not_file_has_content_literal out.txt "Adopting: EFI" +assert_file_has_content_literal out.txt "Nothing to do" +ok '"rerunning adopt is idempotent' + +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Installed: '${v0_digest} +assert_file_has_content_literal out.txt ' Adopted: true' +assert_file_has_content_literal out.txt 'Update: At latest version' +ok 'adoption status' + +tap_finish From 291b6856ec08c069afe6778f46afb3c5165516fd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 15:30:34 +0000 Subject: [PATCH 003/641] Split up into modules --- src/main.rs | 162 ++------------------------------------------ src/model.rs | 149 ++++++++++++++++++++++++++++++++++++++++ src/sha512string.rs | 11 +++ 3 files changed, 165 insertions(+), 157 deletions(-) create mode 100644 src/model.rs create mode 100644 src/sha512string.rs diff --git a/src/main.rs b/src/main.rs index 78dce36f1..6eb119577 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,19 +15,21 @@ use anyhow::{bail, Context, Result}; use byteorder::ByteOrder; -use chrono::prelude::*; use gio::NONE_CANCELLABLE; use nix; use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; -use serde_derive::{Deserialize, Serialize}; use serde_json; use std::collections::{BTreeMap, HashMap, HashSet}; -use std::fmt; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; +mod sha512string; +use sha512string::SHA512String; +mod model; +use model::*; + /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; @@ -38,153 +40,6 @@ pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; /// The prefix we apply to our temporary files. pub(crate) const TMP_PREFIX: &'static str = ".btmp."; -#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) struct SHA512String(String); - -impl fmt::Display for SHA512String { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -/// Metadata for a single file -#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) enum ComponentType { - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - EFI, - #[cfg(target_arch = "x86_64")] - BIOS, -} - -/// Metadata for a single file -#[derive(Serialize, Debug, Hash, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileMetadata { - /// File size in bytes - size: u64, - /// Content checksum; chose SHA-512 because there are not a lot of files here - /// and it's ok if the checksum is large. - sha512: SHA512String, -} - -#[derive(Serialize, Debug, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileTree { - timestamp: NaiveDateTime, - children: BTreeMap, -} - -/// Describes data that is at the block level or the filesystem level. -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct InstalledContent { - /// sha512 of the state of the content - digest: SHA512String, - timestamp: NaiveDateTime, - filesystem: Option>, -} - -/// A versioned description of something we can update, -/// whether that is a BIOS MBR or an ESP -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct ContentVersion { - content_timestamp: NaiveDateTime, - content: InstalledContent, - ostree_commit: Option, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentInstalled { - Unknown(InstalledContent), - Tracked { - disk: InstalledContent, - saved: SavedComponent, - drift: bool, - }, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentState { - #[allow(dead_code)] - NotInstalled, - NotImplemented, - Found(ComponentInstalled), -} - -/// The state of a particular managed component -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentUpdate { - LatestUpdateInstalled, - Available { - update: ContentVersion, - diff: Option, - }, -} - -/// A component along with a possible update -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Component { - ctype: ComponentType, - installed: ComponentState, - pending: Option, - update: Option, -} - -/// Our total view of the world at a point in time -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Status { - supported_architecture: bool, - components: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedPendingUpdate { - /// The value of /proc/sys/kernel/random/boot_id - boot_id: String, - /// The value of /etc/machine-id from the OS trying to update - machineid: String, - /// The new version we're trying to install - digest: SHA512String, - timestamp: NaiveDateTime, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedComponent { - adopted: bool, - digest: SHA512String, - timestamp: NaiveDateTime, - pending: Option, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedState { - components: BTreeMap, -} - -/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct UpgradeEdge { - /// Set to true if we should upgrade from an unknown state - #[serde(default)] - from_unknown: bool, - /// Upgrade from content past this timestamp - from_timestamp: Option, -} - #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { @@ -284,13 +139,6 @@ impl FileMetadata { } } -#[derive(Debug, Serialize, Deserialize)] -pub(crate) struct FileTreeDiff { - additions: HashSet, - removals: HashSet, - changes: HashSet, -} - impl FileTree { // Internal helper to generate a sub-tree fn unsorted_from_dir(dir: &openat::Dir) -> Result> { diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 000000000..77d3140c4 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,149 @@ +use crate::sha512string::SHA512String; +use chrono::prelude::*; +use serde_derive::{Deserialize, Serialize}; +use std::collections::{BTreeMap, HashSet}; + +/// Metadata for a single file +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) enum ComponentType { + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + EFI, + #[cfg(target_arch = "x86_64")] + BIOS, +} + +/// Metadata for a single file +#[derive(Serialize, Debug, Hash, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileMetadata { + /// File size in bytes + pub(crate) size: u64, + /// Content checksum; chose SHA-512 because there are not a lot of files here + /// and it's ok if the checksum is large. + pub(crate) sha512: SHA512String, +} + +#[derive(Serialize, Debug, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileTree { + pub(crate) timestamp: NaiveDateTime, + pub(crate) children: BTreeMap, +} + +/// Describes data that is at the block level or the filesystem level. +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct InstalledContent { + /// sha512 of the state of the content + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) filesystem: Option>, +} + +/// A versioned description of something we can update, +/// whether that is a BIOS MBR or an ESP +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContentVersion { + pub(crate) content_timestamp: NaiveDateTime, + pub(crate) content: InstalledContent, + pub(crate) ostree_commit: Option, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentInstalled { + Unknown(InstalledContent), + Tracked { + disk: InstalledContent, + saved: SavedComponent, + drift: bool, + }, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentState { + #[allow(dead_code)] + NotInstalled, + NotImplemented, + Found(ComponentInstalled), +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct FileTreeDiff { + pub(crate) additions: HashSet, + pub(crate) removals: HashSet, + pub(crate) changes: HashSet, +} + +/// The state of a particular managed component +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentUpdate { + LatestUpdateInstalled, + Available { + update: ContentVersion, + diff: Option, + }, +} + +/// A component along with a possible update +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Component { + pub(crate) ctype: ComponentType, + pub(crate) installed: ComponentState, + pub(crate) pending: Option, + pub(crate) update: Option, +} + +/// Our total view of the world at a point in time +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Status { + pub(crate) supported_architecture: bool, + pub(crate) components: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedPendingUpdate { + /// The value of /proc/sys/kernel/random/boot_id + pub(crate) boot_id: String, + /// The value of /etc/machine-id from the OS trying to update + pub(crate) machineid: String, + /// The new version we're trying to install + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedComponent { + pub(crate) adopted: bool, + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) pending: Option, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedState { + pub(crate) components: BTreeMap, +} + +/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct UpgradeEdge { + /// Set to true if we should upgrade from an unknown state + #[serde(default)] + pub(crate) from_unknown: bool, + /// Upgrade from content past this timestamp + pub(crate) from_timestamp: Option, +} diff --git a/src/sha512string.rs b/src/sha512string.rs new file mode 100644 index 000000000..b35f0c449 --- /dev/null +++ b/src/sha512string.rs @@ -0,0 +1,11 @@ +use serde_derive::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) struct SHA512String(pub(crate) String); + +impl fmt::Display for SHA512String { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} From 7da2181131b06ded32c75d5d04d88b6d74205e26 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 15:45:37 +0000 Subject: [PATCH 004/641] Split into library with tiny wrapper binary This way the library can be cleanly consumed by rpm-ostree if we find it difficult to ship as a separate package. --- Cargo.toml | 8 + src/bootupd.rs | 865 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 723 +---------------------------------------- src/model.rs | 149 --------- 4 files changed, 875 insertions(+), 870 deletions(-) create mode 100644 src/bootupd.rs delete mode 100644 src/model.rs diff --git a/Cargo.toml b/Cargo.toml index 868432a5d..ce3970e9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,14 @@ version = "0.1.0" authors = ["Colin Walters "] edition = "2018" +[lib] +name = "bootupd" +path = "src/bootupd.rs" + +[[bin]] +name = "bootupd" +path = "src/main.rs" + [dependencies] anyhow = "1.0" serde = "1.0.112" diff --git a/src/bootupd.rs b/src/bootupd.rs new file mode 100644 index 000000000..996c7417c --- /dev/null +++ b/src/bootupd.rs @@ -0,0 +1,865 @@ +use anyhow::{bail, Context, Result}; +use byteorder::ByteOrder; +use chrono::prelude::*; +use gio::NONE_CANCELLABLE; +use nix; +use openat_ext::OpenatDirExt; +use openssl::hash::{Hasher, MessageDigest}; +use serde_derive::{Deserialize, Serialize}; +use serde_json; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::io::prelude::*; +use std::path::Path; +use structopt::StructOpt; + +mod sha512string; +use sha512string::SHA512String; + +/// Metadata for a single file +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) enum ComponentType { + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + EFI, + #[cfg(target_arch = "x86_64")] + BIOS, +} + +/// Metadata for a single file +#[derive(Serialize, Debug, Hash, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileMetadata { + /// File size in bytes + pub(crate) size: u64, + /// Content checksum; chose SHA-512 because there are not a lot of files here + /// and it's ok if the checksum is large. + pub(crate) sha512: SHA512String, +} + +#[derive(Serialize, Debug, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileTree { + pub(crate) timestamp: NaiveDateTime, + pub(crate) children: BTreeMap, +} + +/// Describes data that is at the block level or the filesystem level. +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct InstalledContent { + /// sha512 of the state of the content + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) filesystem: Option>, +} + +/// A versioned description of something we can update, +/// whether that is a BIOS MBR or an ESP +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContentVersion { + pub(crate) content_timestamp: NaiveDateTime, + pub(crate) content: InstalledContent, + pub(crate) ostree_commit: Option, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentInstalled { + Unknown(InstalledContent), + Tracked { + disk: InstalledContent, + saved: SavedComponent, + drift: bool, + }, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentState { + #[allow(dead_code)] + NotInstalled, + NotImplemented, + Found(ComponentInstalled), +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct FileTreeDiff { + pub(crate) additions: HashSet, + pub(crate) removals: HashSet, + pub(crate) changes: HashSet, +} + +/// The state of a particular managed component +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentUpdate { + LatestUpdateInstalled, + Available { + update: ContentVersion, + diff: Option, + }, +} + +/// A component along with a possible update +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Component { + pub(crate) ctype: ComponentType, + pub(crate) installed: ComponentState, + pub(crate) pending: Option, + pub(crate) update: Option, +} + +/// Our total view of the world at a point in time +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Status { + pub(crate) supported_architecture: bool, + pub(crate) components: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedPendingUpdate { + /// The value of /proc/sys/kernel/random/boot_id + pub(crate) boot_id: String, + /// The value of /etc/machine-id from the OS trying to update + pub(crate) machineid: String, + /// The new version we're trying to install + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedComponent { + pub(crate) adopted: bool, + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) pending: Option, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedState { + pub(crate) components: BTreeMap, +} + +/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct UpgradeEdge { + /// Set to true if we should upgrade from an unknown state + #[serde(default)] + pub(crate) from_unknown: bool, + /// Upgrade from content past this timestamp + pub(crate) from_timestamp: Option, +} + +/// Stored in /boot to describe our state; think of it like +/// a tiny rpm/dpkg database. +pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; +/// The path to the ESP mount +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; + +/// The prefix we apply to our temporary files. +pub(crate) const TMP_PREFIX: &'static str = ".btmp."; + +#[derive(Debug, StructOpt)] +#[structopt(rename_all = "kebab-case")] +struct UpdateOptions { + /// The system root + #[structopt(default_value = "/", long)] + sysroot: String, + + // Perform an update even if there is no state transition + #[structopt(long)] + force: bool, + + /// The destination ESP mount point + #[structopt( + default_value = "/usr/share/rpm-ostree/bootupdate-transition.json", + long + )] + state_transition_file: String, +} + +#[derive(Debug, StructOpt)] +#[structopt(rename_all = "kebab-case")] +struct StatusOptions { + /// System root + #[structopt(default_value = "/", long)] + sysroot: String, + + #[structopt(long = "component")] + components: Option>, + + // Output JSON + #[structopt(long)] + json: bool, +} + +#[derive(Debug, StructOpt)] +#[structopt(name = "boot-update")] +#[structopt(rename_all = "kebab-case")] +enum Opt { + /// Install data into the EFI System Partition + Install { + /// Physical root mountpoint + #[structopt(long)] + sysroot: String, + }, + /// Start tracking current data found in the EFI System Partition + Adopt { + /// Physical root mountpoint + #[structopt(long)] + sysroot: String, + }, + /// Update the EFI System Partition + Update(UpdateOptions), + Status(StatusOptions), +} + +impl SHA512String { + fn from_hasher(hasher: &mut Hasher) -> Self { + Self(format!( + "sha512:{}", + bs58::encode(hasher.finish().expect("completing hash")).into_string() + )) + } + + fn digest_bs58(&self) -> &str { + self.0.splitn(2, ":").next().unwrap() + } + + fn digest_bytes(&self) -> Vec { + bs58::decode(self.digest_bs58()) + .into_vec() + .expect("decoding bs58 hash") + } +} + +impl FileMetadata { + pub(crate) fn new_from_path( + dir: &openat::Dir, + name: P, + ) -> Result { + let mut r = dir.open_file(name)?; + let meta = r.metadata()?; + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + std::io::copy(&mut r, &mut hasher)?; + let digest = SHA512String::from_hasher(&mut hasher); + Ok(FileMetadata { + size: meta.len(), + sha512: digest, + }) + } + + pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { + let mut lenbuf = [0; 8]; + byteorder::BigEndian::write_u64(&mut lenbuf, self.size); + hasher.update(&lenbuf).unwrap(); + hasher.update(&self.sha512.digest_bytes()).unwrap(); + } +} + +impl FileTree { + // Internal helper to generate a sub-tree + fn unsorted_from_dir(dir: &openat::Dir) -> Result> { + let mut ret = HashMap::new(); + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) + }; + if name.starts_with(TMP_PREFIX) { + bail!("File {} contains our temporary prefix!", name); + } + match dir.get_file_type(&entry)? { + openat::SimpleType::File => { + let meta = FileMetadata::new_from_path(dir, name)?; + ret.insert(name.to_string(), meta); + } + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + for (mut k, v) in FileTree::unsorted_from_dir(&child)?.drain() { + k.reserve(name.len() + 1); + k.insert(0, '/'); + k.insert_str(0, name); + ret.insert(k, v); + } + } + openat::SimpleType::Symlink => { + bail!("Unsupported symbolic link {:?}", entry.file_name()) + } + openat::SimpleType::Other => { + bail!("Unsupported non-file/directory {:?}", entry.file_name()) + } + } + } + Ok(ret) + } + + fn digest(&self) -> SHA512String { + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + for (k, v) in self.children.iter() { + hasher.update(k.as_bytes()).unwrap(); + v.extend_hash(&mut hasher); + } + SHA512String::from_hasher(&mut hasher) + } + + /// Create a FileTree from the target directory. + fn new_from_dir(dir: &openat::Dir) -> Result { + let mut children = BTreeMap::new(); + for (k, v) in Self::unsorted_from_dir(dir)?.drain() { + children.insert(k, v); + } + + let meta = dir.metadata(".")?; + let stat = meta.stat(); + + Ok(Self { + timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), + children: children, + }) + } + + /// Determine the changes *from* self to the updated tree + fn diff(&self, updated: &Self) -> Result { + let mut additions = HashSet::new(); + let mut removals = HashSet::new(); + let mut changes = HashSet::new(); + + for (k, v1) in self.children.iter() { + if let Some(v2) = updated.children.get(k) { + if v1 != v2 { + changes.insert(k.clone()); + } + } else { + removals.insert(k.clone()); + } + } + for k in updated.children.keys() { + if let Some(_) = self.children.get(k) { + continue; + } + additions.insert(k.clone()); + } + Ok(FileTreeDiff { + additions: additions, + removals: removals, + changes: changes, + }) + } +} + +impl InstalledContent { + fn from_file_tree(ft: FileTree) -> InstalledContent { + InstalledContent { + digest: ft.digest(), + timestamp: ft.timestamp, + filesystem: Some(Box::new(ft)), + } + } +} + +impl ComponentInstalled { + fn get_disk_content(&self) -> &InstalledContent { + match self { + Self::Unknown(i) => i, + Self::Tracked { disk, .. } => disk, + } + } +} + +// Recursively remove all files in the directory that start with our TMP_PREFIX +fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + // Skip invalid UTF-8 for now, we will barf on it later though. + continue; + }; + + match dir.get_file_type(&entry)? { + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + cleanup_tmp(&child)?; + } + openat::SimpleType::File => { + if name.starts_with(TMP_PREFIX) { + dir.remove_file(name)?; + } + } + _ => {} + } + } + Ok(()) +} + +// struct ApplyUpdateOptions { +// skip_removals: bool, +// } + +// fn apply_update_from_diff( +// src: &openat::Dir, +// dest: &openat::Dir, +// diff: FileTreeDiff, +// opts: Option, +// ) -> Result<()> { +// Ok(()) +// } + +fn running_in_test_suite() -> bool { + !nix::unistd::getuid().is_root() +} + +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +pub(crate) fn validate_esp>(mnt: P) -> Result<()> { + if running_in_test_suite() { + return Ok(()); + } + let mnt = mnt.as_ref(); + let stat = nix::sys::statfs::statfs(mnt)?; + let fstype = stat.filesystem_type(); + if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { + bail!( + "Mount {} is not a msdos filesystem, but is {:?}", + mnt.display(), + fstype + ); + }; + Ok(()) +} + +mod install { + use super::*; + + fn find_deployed_commit(sysroot_path: &str) -> Result { + // ostree_sysroot_get_deployments() isn't bound + // https://gitlab.com/fkrull/ostree-rs/-/issues/3 + let ls = std::process::Command::new("/bin/sh") + .arg("-c") + .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) + .output()?; + if !ls.status.success() { + bail!("failed to find deployment") + } + let mut lines = ls.stdout.lines(); + let deployment = if let Some(line) = lines.next() { + let line = line?; + let deploypath = Path::new(line.trim()); + let parts: Vec<_> = deploypath + .file_name() + .unwrap() + .to_str() + .unwrap() + .splitn(2, ".0") + .collect(); + assert!(parts.len() == 2); + parts[0].to_string() + } else { + bail!("failed to find deployment"); + }; + if let Some(_) = lines.next() { + bail!("multiple deployments found") + } + Ok(deployment) + } + + pub(crate) fn install(sysroot_path: &str) -> Result<()> { + let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); + sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; + + let _commit = find_deployed_commit(sysroot_path)?; + + let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); + if statepath.exists() { + bail!("{:?} already exists, cannot re-install", statepath); + } + + let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); + validate_esp(&bootefi)?; + + Ok(()) + } +} + +fn update(opts: &UpdateOptions) -> Result<()> { + let esp = Path::new(&opts.sysroot).join(EFI_MOUNT); + validate_esp(&esp)?; + let esp_dir = openat::Dir::open(&esp)?; + + // First remove any temporary files + cleanup_tmp(&esp_dir)?; + + Ok(()) +} + +fn adopt(sysroot_path: &str) -> Result<()> { + let status = compute_status(sysroot_path)?; + let mut new_saved_components = BTreeMap::new(); + let mut adopted = std::collections::BTreeSet::new(); + for component in status.components { + let installed = match component.installed { + ComponentState::NotInstalled => continue, + ComponentState::NotImplemented => continue, + ComponentState::Found(installed) => installed, + }; + let disk = match installed { + ComponentInstalled::Unknown(state) => { + println!("Adopting: {:?}", component.ctype); + adopted.insert(component.ctype.clone()); + state + } + ComponentInstalled::Tracked { + disk: _, + saved, + drift, + } => { + if drift { + eprintln!("Warning: Skipping drifted component: {:?}", component.ctype); + } + new_saved_components.insert(component.ctype.clone(), saved.clone()); + continue; + } + }; + let saved = SavedComponent { + adopted: true, + digest: disk.digest, + timestamp: disk.timestamp, + pending: None, + }; + new_saved_components.insert(component.ctype, saved); + } + if adopted.len() == 0 { + println!("Nothing to do."); + return Ok(()); + } + + let new_saved_state = SavedState { + components: new_saved_components, + }; + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let f = { + let f = sysroot_dir.new_unnamed_file(0o644)?; + let mut buff = std::io::BufWriter::new(f); + serde_json::to_writer(&mut buff, &new_saved_state)?; + buff.flush()?; + buff.into_inner()? + }; + let dest = Path::new(STATEFILE_PATH); + let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); + let dest_tmp = dest.with_file_name(dest_tmp_name); + sysroot_dir.link_file_at(&f, &dest_tmp)?; + sysroot_dir.local_rename(&dest_tmp, dest)?; + Ok(()) +} + +fn timestamp_and_commit_from_sysroot( + sysroot_path: &str, +) -> Result<(chrono::naive::NaiveDateTime, String)> { + // Until we have list_deployments + assert!(sysroot_path == "/"); + let ostree_sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); + ostree_sysroot + .load(NONE_CANCELLABLE) + .context("loading sysroot")?; + let booted_deployment = if let Some(booted) = ostree_sysroot.get_booted_deployment() { + booted + } else { + bail!("Not booted into an OSTree system") + }; + + let repo = ostree_sysroot.repo().expect("repo"); + let csum = booted_deployment.get_csum().expect("booted csum"); + let csum = csum.as_str(); + let (commit, _) = repo.load_commit(csum)?; + let ts = ostree::commit_get_timestamp(&commit); + let ts = chrono::naive::NaiveDateTime::from_timestamp(ts as i64, 0); + Ok((ts, csum.to_string())) +} + +/// Parse an environment variable as UTF-8 +fn getenv_utf8(n: &str) -> Result> { + if let Some(v) = std::env::var_os(n) { + Ok(Some( + v.to_str() + .ok_or_else(|| anyhow::anyhow!("{} is invalid UTF-8", n))? + .to_string(), + )) + } else { + Ok(None) + } +} + +fn efi_content_version_from_ostree(sysroot_path: &str) -> Result { + let (ts, commit) = if let Some(timestamp_str) = getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? { + let ts = chrono::NaiveDateTime::parse_from_str(×tamp_str, "%+")?; + (ts, None) + } else { + let (ts, commit) = timestamp_and_commit_from_sysroot(sysroot_path)?; + (ts, Some(commit)) + }; + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let update_esp_dir = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; + let ft = FileTree::new_from_dir(&update_esp_dir)?; + Ok(ContentVersion { + content_timestamp: ts, + content: InstalledContent::from_file_tree(ft), + ostree_commit: commit, + }) +} + +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +fn compute_status_efi( + sysroot_path: &str, + saved_components: Option<&SavedState>, +) -> Result { + let sysroot_dir = openat::Dir::open(sysroot_path)?; + let espdir = sysroot_dir.sub_dir("boot/efi")?; + let content = InstalledContent::from_file_tree(FileTree::new_from_dir(&espdir)?); + let digest = content.digest.clone(); + let saved_state = saved_components + .map(|s| s.components.get(&ComponentType::EFI)) + .flatten(); + let installed_state = if let Some(saved) = saved_state { + dbg!(&saved); + let drift = saved.digest != content.digest; + ComponentInstalled::Tracked { + disk: content, + saved: saved.clone(), + drift: drift, + } + } else { + ComponentInstalled::Unknown(content) + }; + let installed_tree = installed_state + .get_disk_content() + .filesystem + .as_ref() + .unwrap(); + + let update_esp = efi_content_version_from_ostree(sysroot_path)?; + let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); + let update = if update_esp.content.digest == digest { + ComponentUpdate::LatestUpdateInstalled + } else { + let diff = installed_tree.diff(update_esp_tree)?; + ComponentUpdate::Available { + update: update_esp, + diff: Some(diff), + } + }; + + Ok(Component { + ctype: ComponentType::EFI, + installed: ComponentState::Found(installed_state), + pending: saved_state.map(|x| x.pending.clone()).flatten(), + update: Some(update), + }) +} + +fn compute_status(sysroot_path: &str) -> Result { + let sysroot_dir = openat::Dir::open(sysroot_path)?; + + let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(STATEFILE_PATH)? { + let bufr = std::io::BufReader::new(statusf); + let saved_state: SavedState = serde_json::from_reader(bufr)?; + Some(saved_state) + } else { + None + }; + + let mut components = Vec::new(); + + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + components.push(compute_status_efi(&sysroot_path, saved_state.as_ref())?); + + #[cfg(target_arch = "x86_64")] + { + components.push(Component { + ctype: ComponentType::BIOS, + installed: ComponentState::NotImplemented, + pending: None, + update: None, + }); + } + Ok(Status { + supported_architecture: components.len() > 0, + components: components, + }) +} + +fn print_component(component: &Component) { + let name = serde_plain::to_string(&component.ctype).expect("serde"); + println!("Component {}", name); + let installed = match &component.installed { + ComponentState::NotInstalled => { + println!(" Not installed."); + return; + } + ComponentState::NotImplemented => { + println!(" Not implemented."); + return; + } + ComponentState::Found(installed) => installed, + }; + match installed { + ComponentInstalled::Unknown(disk) => { + println!(" Unmanaged: digest={}", disk.digest); + } + ComponentInstalled::Tracked { disk, saved, drift } => { + if !*drift { + println!(" Installed: {}", disk.digest); + if saved.adopted { + println!(" Adopted: true") + } + } else { + println!(" Installed; warning: drift detected"); + println!(" Recorded: {}", saved.digest); + println!(" Actual: {}", disk.digest); + } + } + } + if let Some(update) = component.update.as_ref() { + match update { + ComponentUpdate::LatestUpdateInstalled => { + println!(" Update: At latest version"); + } + ComponentUpdate::Available { update, diff } => { + let ts_str = update.content_timestamp.format("%Y-%m-%dT%H:%M:%S+00:00"); + println!(" Update: Available: {}", ts_str); + if let Some(diff) = diff { + println!( + " Diff: changed={} added={} removed={}", + diff.changes.len(), + diff.additions.len(), + diff.removals.len() + ); + } + } + } + } +} + +fn status(opts: &StatusOptions) -> Result<()> { + let status = compute_status(&opts.sysroot)?; + if opts.json { + serde_json::to_writer_pretty(std::io::stdout(), &status)?; + } else { + if !status.supported_architecture { + eprintln!("This architecture is not supported.") + } else { + let specified_components = if let Some(components) = &opts.components { + let r: std::result::Result, _> = components + .iter() + .map(|c| serde_plain::from_str(c)) + .collect(); + Some(r?) + } else { + None + }; + for component in &status.components { + if let Some(specified_components) = specified_components.as_ref() { + if !specified_components.contains(&component.ctype) { + continue; + } + } + print_component(component); + } + } + } + Ok(()) +} + +/// Main entrypoint +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +pub fn boot_update_main(args: &Vec) -> Result<()> { + let opt = Opt::from_iter(args.iter()); + match opt { + Opt::Install { sysroot } => { + install::install(&sysroot).context("boot data installation failed")? + } + Opt::Adopt { sysroot } => adopt(&sysroot)?, + Opt::Update(ref opts) => update(opts).context("boot data update failed")?, + Opt::Status(ref opts) => status(opts).context("status failed")?, + }; + Ok(()) +} + +#[cfg(not(any(target_arch = "x86_64", target_arch = "arm")))] +pub fn boot_update_main(args: &Vec) -> Result<()> { + bail!("This command is only supported on x86_64") +} + +#[cfg(test)] +mod tests { + use super::*; + + fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { + let ta = FileTree::new_from_dir(&a)?; + let tb = FileTree::new_from_dir(&b)?; + let diff = ta.diff(&tb)?; + Ok(diff) + } + + #[test] + fn test_diff() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let p = tmpd.path(); + let a = p.join("a"); + let b = p.join("b"); + std::fs::create_dir(&a)?; + std::fs::create_dir(&b)?; + let a = openat::Dir::open(&a)?; + let b = openat::Dir::open(&b)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + a.create_dir("foo", 0o755)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar = a.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 1); + assert_eq!(diff.changes.len(), 0); + b.create_dir("foo", 0o755)?; + { + let mut bar = b.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar2 = b.write_file("foo/bar", 0o644)?; + bar2.write("foobarcontents2".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 1); + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 6eb119577..f34ce184c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,728 +13,9 @@ // To run the unit tests for this code, use `make check TESTS=tests/check/test-ex-boot-update.sh` -use anyhow::{bail, Context, Result}; -use byteorder::ByteOrder; -use gio::NONE_CANCELLABLE; -use nix; -use openat_ext::OpenatDirExt; -use openssl::hash::{Hasher, MessageDigest}; -use serde_json; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::io::prelude::*; -use std::path::Path; -use structopt::StructOpt; - -mod sha512string; -use sha512string::SHA512String; -mod model; -use model::*; - -/// Stored in /boot to describe our state; think of it like -/// a tiny rpm/dpkg database. -pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; -/// The path to the ESP mount -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; - -/// The prefix we apply to our temporary files. -pub(crate) const TMP_PREFIX: &'static str = ".btmp."; - -#[derive(Debug, StructOpt)] -#[structopt(rename_all = "kebab-case")] -struct UpdateOptions { - /// The system root - #[structopt(default_value = "/", long)] - sysroot: String, - - // Perform an update even if there is no state transition - #[structopt(long)] - force: bool, - - /// The destination ESP mount point - #[structopt( - default_value = "/usr/share/rpm-ostree/bootupdate-transition.json", - long - )] - state_transition_file: String, -} - -#[derive(Debug, StructOpt)] -#[structopt(rename_all = "kebab-case")] -struct StatusOptions { - /// System root - #[structopt(default_value = "/", long)] - sysroot: String, - - #[structopt(long = "component")] - components: Option>, - - // Output JSON - #[structopt(long)] - json: bool, -} - -#[derive(Debug, StructOpt)] -#[structopt(name = "boot-update")] -#[structopt(rename_all = "kebab-case")] -enum Opt { - /// Install data into the EFI System Partition - Install { - /// Physical root mountpoint - #[structopt(long)] - sysroot: String, - }, - /// Start tracking current data found in the EFI System Partition - Adopt { - /// Physical root mountpoint - #[structopt(long)] - sysroot: String, - }, - /// Update the EFI System Partition - Update(UpdateOptions), - Status(StatusOptions), -} - -impl SHA512String { - fn from_hasher(hasher: &mut Hasher) -> Self { - Self(format!( - "sha512:{}", - bs58::encode(hasher.finish().expect("completing hash")).into_string() - )) - } - - fn digest_bs58(&self) -> &str { - self.0.splitn(2, ":").next().unwrap() - } - - fn digest_bytes(&self) -> Vec { - bs58::decode(self.digest_bs58()) - .into_vec() - .expect("decoding bs58 hash") - } -} - -impl FileMetadata { - pub(crate) fn new_from_path( - dir: &openat::Dir, - name: P, - ) -> Result { - let mut r = dir.open_file(name)?; - let meta = r.metadata()?; - let mut hasher = - Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - std::io::copy(&mut r, &mut hasher)?; - let digest = SHA512String::from_hasher(&mut hasher); - Ok(FileMetadata { - size: meta.len(), - sha512: digest, - }) - } - - pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { - let mut lenbuf = [0; 8]; - byteorder::BigEndian::write_u64(&mut lenbuf, self.size); - hasher.update(&lenbuf).unwrap(); - hasher.update(&self.sha512.digest_bytes()).unwrap(); - } -} - -impl FileTree { - // Internal helper to generate a sub-tree - fn unsorted_from_dir(dir: &openat::Dir) -> Result> { - let mut ret = HashMap::new(); - for entry in dir.list_dir(".")? { - let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { - bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) - }; - if name.starts_with(TMP_PREFIX) { - bail!("File {} contains our temporary prefix!", name); - } - match dir.get_file_type(&entry)? { - openat::SimpleType::File => { - let meta = FileMetadata::new_from_path(dir, name)?; - ret.insert(name.to_string(), meta); - } - openat::SimpleType::Dir => { - let child = dir.sub_dir(name)?; - for (mut k, v) in FileTree::unsorted_from_dir(&child)?.drain() { - k.reserve(name.len() + 1); - k.insert(0, '/'); - k.insert_str(0, name); - ret.insert(k, v); - } - } - openat::SimpleType::Symlink => { - bail!("Unsupported symbolic link {:?}", entry.file_name()) - } - openat::SimpleType::Other => { - bail!("Unsupported non-file/directory {:?}", entry.file_name()) - } - } - } - Ok(ret) - } - - fn digest(&self) -> SHA512String { - let mut hasher = - Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - for (k, v) in self.children.iter() { - hasher.update(k.as_bytes()).unwrap(); - v.extend_hash(&mut hasher); - } - SHA512String::from_hasher(&mut hasher) - } - - /// Create a FileTree from the target directory. - fn new_from_dir(dir: &openat::Dir) -> Result { - let mut children = BTreeMap::new(); - for (k, v) in Self::unsorted_from_dir(dir)?.drain() { - children.insert(k, v); - } - - let meta = dir.metadata(".")?; - let stat = meta.stat(); - - Ok(Self { - timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), - children: children, - }) - } - - /// Determine the changes *from* self to the updated tree - fn diff(&self, updated: &Self) -> Result { - let mut additions = HashSet::new(); - let mut removals = HashSet::new(); - let mut changes = HashSet::new(); - - for (k, v1) in self.children.iter() { - if let Some(v2) = updated.children.get(k) { - if v1 != v2 { - changes.insert(k.clone()); - } - } else { - removals.insert(k.clone()); - } - } - for k in updated.children.keys() { - if let Some(_) = self.children.get(k) { - continue; - } - additions.insert(k.clone()); - } - Ok(FileTreeDiff { - additions: additions, - removals: removals, - changes: changes, - }) - } -} - -impl InstalledContent { - fn from_file_tree(ft: FileTree) -> InstalledContent { - InstalledContent { - digest: ft.digest(), - timestamp: ft.timestamp, - filesystem: Some(Box::new(ft)), - } - } -} - -impl ComponentInstalled { - fn get_disk_content(&self) -> &InstalledContent { - match self { - Self::Unknown(i) => i, - Self::Tracked { disk, .. } => disk, - } - } -} - -// Recursively remove all files in the directory that start with our TMP_PREFIX -fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { - for entry in dir.list_dir(".")? { - let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { - // Skip invalid UTF-8 for now, we will barf on it later though. - continue; - }; - - match dir.get_file_type(&entry)? { - openat::SimpleType::Dir => { - let child = dir.sub_dir(name)?; - cleanup_tmp(&child)?; - } - openat::SimpleType::File => { - if name.starts_with(TMP_PREFIX) { - dir.remove_file(name)?; - } - } - _ => {} - } - } - Ok(()) -} - -// struct ApplyUpdateOptions { -// skip_removals: bool, -// } - -// fn apply_update_from_diff( -// src: &openat::Dir, -// dest: &openat::Dir, -// diff: FileTreeDiff, -// opts: Option, -// ) -> Result<()> { -// Ok(()) -// } - -fn running_in_test_suite() -> bool { - !nix::unistd::getuid().is_root() -} - -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub(crate) fn validate_esp>(mnt: P) -> Result<()> { - if running_in_test_suite() { - return Ok(()); - } - let mnt = mnt.as_ref(); - let stat = nix::sys::statfs::statfs(mnt)?; - let fstype = stat.filesystem_type(); - if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { - bail!( - "Mount {} is not a msdos filesystem, but is {:?}", - mnt.display(), - fstype - ); - }; - Ok(()) -} - -mod install { - use super::*; - - fn find_deployed_commit(sysroot_path: &str) -> Result { - // ostree_sysroot_get_deployments() isn't bound - // https://gitlab.com/fkrull/ostree-rs/-/issues/3 - let ls = std::process::Command::new("/bin/sh") - .arg("-c") - .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) - .output()?; - if !ls.status.success() { - bail!("failed to find deployment") - } - let mut lines = ls.stdout.lines(); - let deployment = if let Some(line) = lines.next() { - let line = line?; - let deploypath = Path::new(line.trim()); - let parts: Vec<_> = deploypath - .file_name() - .unwrap() - .to_str() - .unwrap() - .splitn(2, ".0") - .collect(); - assert!(parts.len() == 2); - parts[0].to_string() - } else { - bail!("failed to find deployment"); - }; - if let Some(_) = lines.next() { - bail!("multiple deployments found") - } - Ok(deployment) - } - - pub(crate) fn install(sysroot_path: &str) -> Result<()> { - let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); - sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; - - let _commit = find_deployed_commit(sysroot_path)?; - - let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); - if statepath.exists() { - bail!("{:?} already exists, cannot re-install", statepath); - } - - let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); - validate_esp(&bootefi)?; - - Ok(()) - } -} - -fn update(opts: &UpdateOptions) -> Result<()> { - let esp = Path::new(&opts.sysroot).join(EFI_MOUNT); - validate_esp(&esp)?; - let esp_dir = openat::Dir::open(&esp)?; - - // First remove any temporary files - cleanup_tmp(&esp_dir)?; - - Ok(()) -} - -fn adopt(sysroot_path: &str) -> Result<()> { - let status = compute_status(sysroot_path)?; - let mut new_saved_components = BTreeMap::new(); - let mut adopted = std::collections::BTreeSet::new(); - for component in status.components { - let installed = match component.installed { - ComponentState::NotInstalled => continue, - ComponentState::NotImplemented => continue, - ComponentState::Found(installed) => installed, - }; - let disk = match installed { - ComponentInstalled::Unknown(state) => { - println!("Adopting: {:?}", component.ctype); - adopted.insert(component.ctype.clone()); - state - } - ComponentInstalled::Tracked { - disk: _, - saved, - drift, - } => { - if drift { - eprintln!("Warning: Skipping drifted component: {:?}", component.ctype); - } - new_saved_components.insert(component.ctype.clone(), saved.clone()); - continue; - } - }; - let saved = SavedComponent { - adopted: true, - digest: disk.digest, - timestamp: disk.timestamp, - pending: None, - }; - new_saved_components.insert(component.ctype, saved); - } - if adopted.len() == 0 { - println!("Nothing to do."); - return Ok(()); - } - - let new_saved_state = SavedState { - components: new_saved_components, - }; - let sysroot_dir = openat::Dir::open(sysroot_path)?; - let f = { - let f = sysroot_dir.new_unnamed_file(0o644)?; - let mut buff = std::io::BufWriter::new(f); - serde_json::to_writer(&mut buff, &new_saved_state)?; - buff.flush()?; - buff.into_inner()? - }; - let dest = Path::new(STATEFILE_PATH); - let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); - let dest_tmp = dest.with_file_name(dest_tmp_name); - sysroot_dir.link_file_at(&f, &dest_tmp)?; - sysroot_dir.local_rename(&dest_tmp, dest)?; - Ok(()) -} - -fn timestamp_and_commit_from_sysroot( - sysroot_path: &str, -) -> Result<(chrono::naive::NaiveDateTime, String)> { - // Until we have list_deployments - assert!(sysroot_path == "/"); - let ostree_sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); - ostree_sysroot - .load(NONE_CANCELLABLE) - .context("loading sysroot")?; - let booted_deployment = if let Some(booted) = ostree_sysroot.get_booted_deployment() { - booted - } else { - bail!("Not booted into an OSTree system") - }; - - let repo = ostree_sysroot.repo().expect("repo"); - let csum = booted_deployment.get_csum().expect("booted csum"); - let csum = csum.as_str(); - let (commit, _) = repo.load_commit(csum)?; - let ts = ostree::commit_get_timestamp(&commit); - let ts = chrono::naive::NaiveDateTime::from_timestamp(ts as i64, 0); - Ok((ts, csum.to_string())) -} - -/// Parse an environment variable as UTF-8 -fn getenv_utf8(n: &str) -> Result> { - if let Some(v) = std::env::var_os(n) { - Ok(Some( - v.to_str() - .ok_or_else(|| anyhow::anyhow!("{} is invalid UTF-8", n))? - .to_string(), - )) - } else { - Ok(None) - } -} - -fn efi_content_version_from_ostree(sysroot_path: &str) -> Result { - let (ts, commit) = if let Some(timestamp_str) = getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? { - let ts = chrono::NaiveDateTime::parse_from_str(×tamp_str, "%+")?; - (ts, None) - } else { - let (ts, commit) = timestamp_and_commit_from_sysroot(sysroot_path)?; - (ts, Some(commit)) - }; - let sysroot_dir = openat::Dir::open(sysroot_path)?; - let update_esp_dir = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; - let ft = FileTree::new_from_dir(&update_esp_dir)?; - Ok(ContentVersion { - content_timestamp: ts, - content: InstalledContent::from_file_tree(ft), - ostree_commit: commit, - }) -} - -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -fn compute_status_efi( - sysroot_path: &str, - saved_components: Option<&SavedState>, -) -> Result { - let sysroot_dir = openat::Dir::open(sysroot_path)?; - let espdir = sysroot_dir.sub_dir("boot/efi")?; - let content = InstalledContent::from_file_tree(FileTree::new_from_dir(&espdir)?); - let digest = content.digest.clone(); - let saved_state = saved_components - .map(|s| s.components.get(&ComponentType::EFI)) - .flatten(); - let installed_state = if let Some(saved) = saved_state { - dbg!(&saved); - let drift = saved.digest != content.digest; - ComponentInstalled::Tracked { - disk: content, - saved: saved.clone(), - drift: drift, - } - } else { - ComponentInstalled::Unknown(content) - }; - let installed_tree = installed_state - .get_disk_content() - .filesystem - .as_ref() - .unwrap(); - - let update_esp = efi_content_version_from_ostree(sysroot_path)?; - let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); - let update = if update_esp.content.digest == digest { - ComponentUpdate::LatestUpdateInstalled - } else { - let diff = installed_tree.diff(update_esp_tree)?; - ComponentUpdate::Available { - update: update_esp, - diff: Some(diff), - } - }; - - Ok(Component { - ctype: ComponentType::EFI, - installed: ComponentState::Found(installed_state), - pending: saved_state.map(|x| x.pending.clone()).flatten(), - update: Some(update), - }) -} - -fn compute_status(sysroot_path: &str) -> Result { - let sysroot_dir = openat::Dir::open(sysroot_path)?; - - let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(STATEFILE_PATH)? { - let bufr = std::io::BufReader::new(statusf); - let saved_state: SavedState = serde_json::from_reader(bufr)?; - Some(saved_state) - } else { - None - }; - - let mut components = Vec::new(); - - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - components.push(compute_status_efi(&sysroot_path, saved_state.as_ref())?); - - #[cfg(target_arch = "x86_64")] - { - components.push(Component { - ctype: ComponentType::BIOS, - installed: ComponentState::NotImplemented, - pending: None, - update: None, - }); - } - Ok(Status { - supported_architecture: components.len() > 0, - components: components, - }) -} - -fn print_component(component: &Component) { - let name = serde_plain::to_string(&component.ctype).expect("serde"); - println!("Component {}", name); - let installed = match &component.installed { - ComponentState::NotInstalled => { - println!(" Not installed."); - return; - } - ComponentState::NotImplemented => { - println!(" Not implemented."); - return; - } - ComponentState::Found(installed) => installed, - }; - match installed { - ComponentInstalled::Unknown(disk) => { - println!(" Unmanaged: digest={}", disk.digest); - } - ComponentInstalled::Tracked { disk, saved, drift } => { - if !*drift { - println!(" Installed: {}", disk.digest); - if saved.adopted { - println!(" Adopted: true") - } - } else { - println!(" Installed; warning: drift detected"); - println!(" Recorded: {}", saved.digest); - println!(" Actual: {}", disk.digest); - } - } - } - if let Some(update) = component.update.as_ref() { - match update { - ComponentUpdate::LatestUpdateInstalled => { - println!(" Update: At latest version"); - } - ComponentUpdate::Available { update, diff } => { - let ts_str = update.content_timestamp.format("%Y-%m-%dT%H:%M:%S+00:00"); - println!(" Update: Available: {}", ts_str); - if let Some(diff) = diff { - println!( - " Diff: changed={} added={} removed={}", - diff.changes.len(), - diff.additions.len(), - diff.removals.len() - ); - } - } - } - } -} - -fn status(opts: &StatusOptions) -> Result<()> { - let status = compute_status(&opts.sysroot)?; - if opts.json { - serde_json::to_writer_pretty(std::io::stdout(), &status)?; - } else { - if !status.supported_architecture { - eprintln!("This architecture is not supported.") - } else { - let specified_components = if let Some(components) = &opts.components { - let r: std::result::Result, _> = components - .iter() - .map(|c| serde_plain::from_str(c)) - .collect(); - Some(r?) - } else { - None - }; - for component in &status.components { - if let Some(specified_components) = specified_components.as_ref() { - if !specified_components.contains(&component.ctype) { - continue; - } - } - print_component(component); - } - } - } - Ok(()) -} - -/// Main entrypoint -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -fn boot_update_main(args: &Vec) -> Result<()> { - let opt = Opt::from_iter(args.iter()); - match opt { - Opt::Install { sysroot } => { - install::install(&sysroot).context("boot data installation failed")? - } - Opt::Adopt { sysroot } => adopt(&sysroot)?, - Opt::Update(ref opts) => update(opts).context("boot data update failed")?, - Opt::Status(ref opts) => status(opts).context("status failed")?, - }; - Ok(()) -} - -#[cfg(not(any(target_arch = "x86_64", target_arch = "arm")))] -fn boot_update_main(args: &Vec) -> Result<()> { - bail!("This command is only supported on x86_64") -} - -#[cfg(test)] -mod tests { - use super::*; - - fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { - let ta = FileTree::new_from_dir(&a)?; - let tb = FileTree::new_from_dir(&b)?; - let diff = ta.diff(&tb)?; - Ok(diff) - } - - #[test] - fn test_diff() -> Result<()> { - let tmpd = tempfile::tempdir()?; - let p = tmpd.path(); - let a = p.join("a"); - let b = p.join("b"); - std::fs::create_dir(&a)?; - std::fs::create_dir(&b)?; - let a = openat::Dir::open(&a)?; - let b = openat::Dir::open(&b)?; - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - a.create_dir("foo", 0o755)?; - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - { - let mut bar = a.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 1); - assert_eq!(diff.changes.len(), 0); - b.create_dir("foo", 0o755)?; - { - let mut bar = b.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - { - let mut bar2 = b.write_file("foo/bar", 0o644)?; - bar2.write("foobarcontents2".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 1); - Ok(()) - } -} +use anyhow::Result; fn main() -> Result<()> { let args: Vec<_> = std::env::args().collect(); - boot_update_main(&args) + bootupd::boot_update_main(&args) } diff --git a/src/model.rs b/src/model.rs deleted file mode 100644 index 77d3140c4..000000000 --- a/src/model.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::sha512string::SHA512String; -use chrono::prelude::*; -use serde_derive::{Deserialize, Serialize}; -use std::collections::{BTreeMap, HashSet}; - -/// Metadata for a single file -#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) enum ComponentType { - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - EFI, - #[cfg(target_arch = "x86_64")] - BIOS, -} - -/// Metadata for a single file -#[derive(Serialize, Debug, Hash, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileMetadata { - /// File size in bytes - pub(crate) size: u64, - /// Content checksum; chose SHA-512 because there are not a lot of files here - /// and it's ok if the checksum is large. - pub(crate) sha512: SHA512String, -} - -#[derive(Serialize, Debug, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileTree { - pub(crate) timestamp: NaiveDateTime, - pub(crate) children: BTreeMap, -} - -/// Describes data that is at the block level or the filesystem level. -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct InstalledContent { - /// sha512 of the state of the content - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, - pub(crate) filesystem: Option>, -} - -/// A versioned description of something we can update, -/// whether that is a BIOS MBR or an ESP -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct ContentVersion { - pub(crate) content_timestamp: NaiveDateTime, - pub(crate) content: InstalledContent, - pub(crate) ostree_commit: Option, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentInstalled { - Unknown(InstalledContent), - Tracked { - disk: InstalledContent, - saved: SavedComponent, - drift: bool, - }, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentState { - #[allow(dead_code)] - NotInstalled, - NotImplemented, - Found(ComponentInstalled), -} - -#[derive(Debug, Serialize, Deserialize)] -pub(crate) struct FileTreeDiff { - pub(crate) additions: HashSet, - pub(crate) removals: HashSet, - pub(crate) changes: HashSet, -} - -/// The state of a particular managed component -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentUpdate { - LatestUpdateInstalled, - Available { - update: ContentVersion, - diff: Option, - }, -} - -/// A component along with a possible update -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Component { - pub(crate) ctype: ComponentType, - pub(crate) installed: ComponentState, - pub(crate) pending: Option, - pub(crate) update: Option, -} - -/// Our total view of the world at a point in time -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Status { - pub(crate) supported_architecture: bool, - pub(crate) components: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedPendingUpdate { - /// The value of /proc/sys/kernel/random/boot_id - pub(crate) boot_id: String, - /// The value of /etc/machine-id from the OS trying to update - pub(crate) machineid: String, - /// The new version we're trying to install - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedComponent { - pub(crate) adopted: bool, - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, - pub(crate) pending: Option, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedState { - pub(crate) components: BTreeMap, -} - -/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct UpgradeEdge { - /// Set to true if we should upgrade from an unknown state - #[serde(default)] - pub(crate) from_unknown: bool, - /// Upgrade from content past this timestamp - pub(crate) from_timestamp: Option, -} From 553ce3b1ef49506b6f9b5a5367e9def28f992718 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 17:29:13 +0000 Subject: [PATCH 005/641] README.md: Initial version --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..7c0b9c33a --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# bootupd: Distribution-independent updates for bootloaders + +Today many Linux systems handle updates for bootloader data +in an inconsistent and ad-hoc way. For example, on +Fedora and Debian, a package manager update will update UEFI +binaries in `/boot/efi`, but not the BIOS MBR data. + +Transactional update systems like [OSTree](https://github.com/ostreedev/ostree/) and others +normally cover kernel/userspace but not bootloaders, because +performing bootloader updates in an "A/B" fashion requires +completely separate nontrivial logic. Today OSTree e.g. +makes the choice that it does not update `/boot/efi`. + +The goal of this project is to be a cross-distribution, +OS update system agnostic tool to manage updates for things like: + +- `/boot/efi` +- x86 BIOS MBR +- Other architecture bootloaders + +This project originated in [this Fedora CoreOS github issue](https://github.com/coreos/fedora-coreos-tracker/issues/510). + +## Status + +Currently a work in progress and is not ready to ship for production +updates, but early feedback on the design is appreciated! From 184df7488bb7ffae20f64b9b4a711905225ac7a5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 17:30:26 +0000 Subject: [PATCH 006/641] Add more license headers --- src/bootupd.rs | 6 ++++++ src/sha512string.rs | 8 +++++++- tests/libtest.sh | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 996c7417c..455bbdc81 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,3 +1,9 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + use anyhow::{bail, Context, Result}; use byteorder::ByteOrder; use chrono::prelude::*; diff --git a/src/sha512string.rs b/src/sha512string.rs index b35f0c449..d8419a79a 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -1,4 +1,10 @@ -use serde_derive::{Deserialize, Serialize}; +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + use serde_derive::{Deserialize, Serialize}; use std::fmt; #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] diff --git a/tests/libtest.sh b/tests/libtest.sh index a582a87b1..3b0498d8f 100644 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -1,4 +1,6 @@ # Source library for shell script tests +# Copyright (C) 2020 Red Hat, Inc. +# SPDX-License-Identifier: Apache-2.0 runv() { (set -x && "$@") From a68a1384be0db4abd51e9281aaefe29d2747ae40 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 17:42:33 +0000 Subject: [PATCH 007/641] More module reorganization --- src/bootupd.rs | 249 ++------------------------------------------ src/filetree.rs | 224 +++++++++++++++++++++++++++++++++++++++ src/sha512string.rs | 22 +++- src/util.rs | 14 +++ 4 files changed, 265 insertions(+), 244 deletions(-) create mode 100644 src/filetree.rs create mode 100644 src/util.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 455bbdc81..4d53151d7 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -5,21 +5,22 @@ */ use anyhow::{bail, Context, Result}; -use byteorder::ByteOrder; use chrono::prelude::*; use gio::NONE_CANCELLABLE; use nix; use openat_ext::OpenatDirExt; -use openssl::hash::{Hasher, MessageDigest}; use serde_derive::{Deserialize, Serialize}; use serde_json; -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{BTreeMap, HashSet}; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; +mod filetree; +use filetree::*; mod sha512string; use sha512string::SHA512String; +mod util; /// Metadata for a single file #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] @@ -30,24 +31,6 @@ pub(crate) enum ComponentType { BIOS, } -/// Metadata for a single file -#[derive(Serialize, Debug, Hash, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileMetadata { - /// File size in bytes - pub(crate) size: u64, - /// Content checksum; chose SHA-512 because there are not a lot of files here - /// and it's ok if the checksum is large. - pub(crate) sha512: SHA512String, -} - -#[derive(Serialize, Debug, PartialEq)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct FileTree { - pub(crate) timestamp: NaiveDateTime, - pub(crate) children: BTreeMap, -} - /// Describes data that is at the block level or the filesystem level. #[derive(Serialize, Debug)] #[serde(rename_all = "kebab-case")] @@ -90,13 +73,6 @@ pub(crate) enum ComponentState { Found(ComponentInstalled), } -#[derive(Debug, Serialize, Deserialize)] -pub(crate) struct FileTreeDiff { - pub(crate) additions: HashSet, - pub(crate) removals: HashSet, - pub(crate) changes: HashSet, -} - /// The state of a particular managed component #[derive(Serialize, Debug)] #[serde(rename_all = "kebab-case")] @@ -173,9 +149,6 @@ pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.js #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; -/// The prefix we apply to our temporary files. -pub(crate) const TMP_PREFIX: &'static str = ".btmp."; - #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { @@ -231,144 +204,6 @@ enum Opt { Status(StatusOptions), } -impl SHA512String { - fn from_hasher(hasher: &mut Hasher) -> Self { - Self(format!( - "sha512:{}", - bs58::encode(hasher.finish().expect("completing hash")).into_string() - )) - } - - fn digest_bs58(&self) -> &str { - self.0.splitn(2, ":").next().unwrap() - } - - fn digest_bytes(&self) -> Vec { - bs58::decode(self.digest_bs58()) - .into_vec() - .expect("decoding bs58 hash") - } -} - -impl FileMetadata { - pub(crate) fn new_from_path( - dir: &openat::Dir, - name: P, - ) -> Result { - let mut r = dir.open_file(name)?; - let meta = r.metadata()?; - let mut hasher = - Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - std::io::copy(&mut r, &mut hasher)?; - let digest = SHA512String::from_hasher(&mut hasher); - Ok(FileMetadata { - size: meta.len(), - sha512: digest, - }) - } - - pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { - let mut lenbuf = [0; 8]; - byteorder::BigEndian::write_u64(&mut lenbuf, self.size); - hasher.update(&lenbuf).unwrap(); - hasher.update(&self.sha512.digest_bytes()).unwrap(); - } -} - -impl FileTree { - // Internal helper to generate a sub-tree - fn unsorted_from_dir(dir: &openat::Dir) -> Result> { - let mut ret = HashMap::new(); - for entry in dir.list_dir(".")? { - let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { - bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) - }; - if name.starts_with(TMP_PREFIX) { - bail!("File {} contains our temporary prefix!", name); - } - match dir.get_file_type(&entry)? { - openat::SimpleType::File => { - let meta = FileMetadata::new_from_path(dir, name)?; - ret.insert(name.to_string(), meta); - } - openat::SimpleType::Dir => { - let child = dir.sub_dir(name)?; - for (mut k, v) in FileTree::unsorted_from_dir(&child)?.drain() { - k.reserve(name.len() + 1); - k.insert(0, '/'); - k.insert_str(0, name); - ret.insert(k, v); - } - } - openat::SimpleType::Symlink => { - bail!("Unsupported symbolic link {:?}", entry.file_name()) - } - openat::SimpleType::Other => { - bail!("Unsupported non-file/directory {:?}", entry.file_name()) - } - } - } - Ok(ret) - } - - fn digest(&self) -> SHA512String { - let mut hasher = - Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - for (k, v) in self.children.iter() { - hasher.update(k.as_bytes()).unwrap(); - v.extend_hash(&mut hasher); - } - SHA512String::from_hasher(&mut hasher) - } - - /// Create a FileTree from the target directory. - fn new_from_dir(dir: &openat::Dir) -> Result { - let mut children = BTreeMap::new(); - for (k, v) in Self::unsorted_from_dir(dir)?.drain() { - children.insert(k, v); - } - - let meta = dir.metadata(".")?; - let stat = meta.stat(); - - Ok(Self { - timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), - children: children, - }) - } - - /// Determine the changes *from* self to the updated tree - fn diff(&self, updated: &Self) -> Result { - let mut additions = HashSet::new(); - let mut removals = HashSet::new(); - let mut changes = HashSet::new(); - - for (k, v1) in self.children.iter() { - if let Some(v2) = updated.children.get(k) { - if v1 != v2 { - changes.insert(k.clone()); - } - } else { - removals.insert(k.clone()); - } - } - for k in updated.children.keys() { - if let Some(_) = self.children.get(k) { - continue; - } - additions.insert(k.clone()); - } - Ok(FileTreeDiff { - additions: additions, - removals: removals, - changes: changes, - }) - } -} - impl InstalledContent { fn from_file_tree(ft: FileTree) -> InstalledContent { InstalledContent { @@ -598,21 +433,9 @@ fn timestamp_and_commit_from_sysroot( Ok((ts, csum.to_string())) } -/// Parse an environment variable as UTF-8 -fn getenv_utf8(n: &str) -> Result> { - if let Some(v) = std::env::var_os(n) { - Ok(Some( - v.to_str() - .ok_or_else(|| anyhow::anyhow!("{} is invalid UTF-8", n))? - .to_string(), - )) - } else { - Ok(None) - } -} - fn efi_content_version_from_ostree(sysroot_path: &str) -> Result { - let (ts, commit) = if let Some(timestamp_str) = getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? { + let (ts, commit) = if let Some(timestamp_str) = util::getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? + { let ts = chrono::NaiveDateTime::parse_from_str(×tamp_str, "%+")?; (ts, None) } else { @@ -642,7 +465,6 @@ fn compute_status_efi( .map(|s| s.components.get(&ComponentType::EFI)) .flatten(); let installed_state = if let Some(saved) = saved_state { - dbg!(&saved); let drift = saved.digest != content.digest; ComponentInstalled::Tracked { disk: content, @@ -810,62 +632,3 @@ pub fn boot_update_main(args: &Vec) -> Result<()> { pub fn boot_update_main(args: &Vec) -> Result<()> { bail!("This command is only supported on x86_64") } - -#[cfg(test)] -mod tests { - use super::*; - - fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { - let ta = FileTree::new_from_dir(&a)?; - let tb = FileTree::new_from_dir(&b)?; - let diff = ta.diff(&tb)?; - Ok(diff) - } - - #[test] - fn test_diff() -> Result<()> { - let tmpd = tempfile::tempdir()?; - let p = tmpd.path(); - let a = p.join("a"); - let b = p.join("b"); - std::fs::create_dir(&a)?; - std::fs::create_dir(&b)?; - let a = openat::Dir::open(&a)?; - let b = openat::Dir::open(&b)?; - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - a.create_dir("foo", 0o755)?; - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - { - let mut bar = a.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 1); - assert_eq!(diff.changes.len(), 0); - b.create_dir("foo", 0o755)?; - { - let mut bar = b.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); - { - let mut bar2 = b.write_file("foo/bar", 0o644)?; - bar2.write("foobarcontents2".as_bytes())?; - } - let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 1); - Ok(()) - } -} diff --git a/src/filetree.rs b/src/filetree.rs new file mode 100644 index 000000000..d028a9d53 --- /dev/null +++ b/src/filetree.rs @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::{bail, Result}; +use byteorder::ByteOrder; +use chrono::prelude::*; +use openat_ext::OpenatDirExt; +use openssl::hash::{Hasher, MessageDigest}; +use serde_derive::{Deserialize, Serialize}; +use std::collections::{BTreeMap, HashMap, HashSet}; +// Seems like a rust-analyzer bug? +#[allow(unused_imports)] +use std::io::Write; + +/// The prefix we apply to our temporary files. +pub(crate) const TMP_PREFIX: &'static str = ".btmp."; + +use crate::sha512string::SHA512String; + +/// Metadata for a single file +#[derive(Serialize, Debug, Hash, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileMetadata { + /// File size in bytes + pub(crate) size: u64, + /// Content checksum; chose SHA-512 because there are not a lot of files here + /// and it's ok if the checksum is large. + pub(crate) sha512: SHA512String, +} + +#[derive(Serialize, Debug, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct FileTree { + pub(crate) timestamp: NaiveDateTime, + pub(crate) children: BTreeMap, +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) struct FileTreeDiff { + pub(crate) additions: HashSet, + pub(crate) removals: HashSet, + pub(crate) changes: HashSet, +} + +impl FileMetadata { + pub(crate) fn new_from_path( + dir: &openat::Dir, + name: P, + ) -> Result { + let mut r = dir.open_file(name)?; + let meta = r.metadata()?; + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + std::io::copy(&mut r, &mut hasher)?; + let digest = SHA512String::from_hasher(&mut hasher); + Ok(FileMetadata { + size: meta.len(), + sha512: digest, + }) + } + + pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { + let mut lenbuf = [0; 8]; + byteorder::BigEndian::write_u64(&mut lenbuf, self.size); + hasher.update(&lenbuf).unwrap(); + hasher.update(&self.sha512.digest_bytes()).unwrap(); + } +} + +impl FileTree { + // Internal helper to generate a sub-tree + fn unsorted_from_dir(dir: &openat::Dir) -> Result> { + let mut ret = HashMap::new(); + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) + }; + if name.starts_with(TMP_PREFIX) { + bail!("File {} contains our temporary prefix!", name); + } + match dir.get_file_type(&entry)? { + openat::SimpleType::File => { + let meta = FileMetadata::new_from_path(dir, name)?; + ret.insert(name.to_string(), meta); + } + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + for (mut k, v) in FileTree::unsorted_from_dir(&child)?.drain() { + k.reserve(name.len() + 1); + k.insert(0, '/'); + k.insert_str(0, name); + ret.insert(k, v); + } + } + openat::SimpleType::Symlink => { + bail!("Unsupported symbolic link {:?}", entry.file_name()) + } + openat::SimpleType::Other => { + bail!("Unsupported non-file/directory {:?}", entry.file_name()) + } + } + } + Ok(ret) + } + + pub(crate) fn digest(&self) -> SHA512String { + let mut hasher = + Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + for (k, v) in self.children.iter() { + hasher.update(k.as_bytes()).unwrap(); + v.extend_hash(&mut hasher); + } + SHA512String::from_hasher(&mut hasher) + } + + /// Create a FileTree from the target directory. + pub(crate) fn new_from_dir(dir: &openat::Dir) -> Result { + let mut children = BTreeMap::new(); + for (k, v) in Self::unsorted_from_dir(dir)?.drain() { + children.insert(k, v); + } + + let meta = dir.metadata(".")?; + let stat = meta.stat(); + + Ok(Self { + timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), + children: children, + }) + } + + /// Determine the changes *from* self to the updated tree + pub(crate) fn diff(&self, updated: &Self) -> Result { + let mut additions = HashSet::new(); + let mut removals = HashSet::new(); + let mut changes = HashSet::new(); + + for (k, v1) in self.children.iter() { + if let Some(v2) = updated.children.get(k) { + if v1 != v2 { + changes.insert(k.clone()); + } + } else { + removals.insert(k.clone()); + } + } + for k in updated.children.keys() { + if let Some(_) = self.children.get(k) { + continue; + } + additions.insert(k.clone()); + } + Ok(FileTreeDiff { + additions: additions, + removals: removals, + changes: changes, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { + let ta = FileTree::new_from_dir(&a)?; + let tb = FileTree::new_from_dir(&b)?; + let diff = ta.diff(&tb)?; + Ok(diff) + } + + #[test] + fn test_diff() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let p = tmpd.path(); + let a = p.join("a"); + let b = p.join("b"); + std::fs::create_dir(&a)?; + std::fs::create_dir(&b)?; + let a = openat::Dir::open(&a)?; + let b = openat::Dir::open(&b)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + a.create_dir("foo", 0o755)?; + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar = a.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 1); + assert_eq!(diff.changes.len(), 0); + b.create_dir("foo", 0o755)?; + { + let mut bar = b.write_file("foo/bar", 0o644)?; + bar.write("foobarcontents".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 0); + { + let mut bar2 = b.write_file("foo/bar", 0o644)?; + bar2.write("foobarcontents2".as_bytes())?; + } + let diff = run_diff(&a, &b)?; + assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.changes.len(), 1); + Ok(()) + } +} diff --git a/src/sha512string.rs b/src/sha512string.rs index d8419a79a..b8de12edb 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -4,7 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ - use serde_derive::{Deserialize, Serialize}; +use openssl::hash::Hasher; +use serde_derive::{Deserialize, Serialize}; use std::fmt; #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] @@ -15,3 +16,22 @@ impl fmt::Display for SHA512String { write!(f, "{}", self.0) } } + +impl SHA512String { + pub(crate) fn from_hasher(hasher: &mut Hasher) -> Self { + Self(format!( + "sha512:{}", + bs58::encode(hasher.finish().expect("completing hash")).into_string() + )) + } + + pub(crate) fn digest_bs58(&self) -> &str { + self.0.splitn(2, ":").next().unwrap() + } + + pub(crate) fn digest_bytes(&self) -> Vec { + bs58::decode(self.digest_bs58()) + .into_vec() + .expect("decoding bs58 hash") + } +} diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 000000000..e861ba8f3 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,14 @@ +use anyhow::Result; + +/// Parse an environment variable as UTF-8 +pub(crate) fn getenv_utf8(n: &str) -> Result> { + if let Some(v) = std::env::var_os(n) { + Ok(Some( + v.to_str() + .ok_or_else(|| anyhow::anyhow!("{} is invalid UTF-8", n))? + .to_string(), + )) + } else { + Ok(None) + } +} From cd8b8f4d71fa0021acb0801845fa865ecec91f8c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 17:55:30 +0000 Subject: [PATCH 008/641] Even more modularization --- src/bootupd.rs | 207 ++++------------------------------------------ src/model.rs | 151 +++++++++++++++++++++++++++++++++ src/ostreeutil.rs | 41 +++++++++ 3 files changed, 207 insertions(+), 192 deletions(-) create mode 100644 src/model.rs create mode 100644 src/ostreeutil.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 4d53151d7..e0361abe7 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -5,11 +5,9 @@ */ use anyhow::{bail, Context, Result}; -use chrono::prelude::*; use gio::NONE_CANCELLABLE; use nix; use openat_ext::OpenatDirExt; -use serde_derive::{Deserialize, Serialize}; use serde_json; use std::collections::{BTreeMap, HashSet}; use std::io::prelude::*; @@ -18,130 +16,12 @@ use structopt::StructOpt; mod filetree; use filetree::*; +mod model; +use model::*; +mod ostreeutil; mod sha512string; -use sha512string::SHA512String; mod util; -/// Metadata for a single file -#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) enum ComponentType { - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - EFI, - #[cfg(target_arch = "x86_64")] - BIOS, -} - -/// Describes data that is at the block level or the filesystem level. -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct InstalledContent { - /// sha512 of the state of the content - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, - pub(crate) filesystem: Option>, -} - -/// A versioned description of something we can update, -/// whether that is a BIOS MBR or an ESP -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct ContentVersion { - pub(crate) content_timestamp: NaiveDateTime, - pub(crate) content: InstalledContent, - pub(crate) ostree_commit: Option, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentInstalled { - Unknown(InstalledContent), - Tracked { - disk: InstalledContent, - saved: SavedComponent, - drift: bool, - }, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentState { - #[allow(dead_code)] - NotInstalled, - NotImplemented, - Found(ComponentInstalled), -} - -/// The state of a particular managed component -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentUpdate { - LatestUpdateInstalled, - Available { - update: ContentVersion, - diff: Option, - }, -} - -/// A component along with a possible update -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Component { - pub(crate) ctype: ComponentType, - pub(crate) installed: ComponentState, - pub(crate) pending: Option, - pub(crate) update: Option, -} - -/// Our total view of the world at a point in time -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Status { - pub(crate) supported_architecture: bool, - pub(crate) components: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedPendingUpdate { - /// The value of /proc/sys/kernel/random/boot_id - pub(crate) boot_id: String, - /// The value of /etc/machine-id from the OS trying to update - pub(crate) machineid: String, - /// The new version we're trying to install - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedComponent { - pub(crate) adopted: bool, - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, - pub(crate) pending: Option, -} - -/// Will be serialized into /boot/rpmostree-bootupd-state.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedState { - pub(crate) components: BTreeMap, -} - -/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct UpgradeEdge { - /// Set to true if we should upgrade from an unknown state - #[serde(default)] - pub(crate) from_unknown: bool, - /// Upgrade from content past this timestamp - pub(crate) from_timestamp: Option, -} - /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; @@ -204,25 +84,6 @@ enum Opt { Status(StatusOptions), } -impl InstalledContent { - fn from_file_tree(ft: FileTree) -> InstalledContent { - InstalledContent { - digest: ft.digest(), - timestamp: ft.timestamp, - filesystem: Some(Box::new(ft)), - } - } -} - -impl ComponentInstalled { - fn get_disk_content(&self) -> &InstalledContent { - match self { - Self::Unknown(i) => i, - Self::Tracked { disk, .. } => disk, - } - } -} - // Recursively remove all files in the directory that start with our TMP_PREFIX fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { for entry in dir.list_dir(".")? { @@ -285,57 +146,21 @@ pub(crate) fn validate_esp>(mnt: P) -> Result<()> { Ok(()) } -mod install { - use super::*; - - fn find_deployed_commit(sysroot_path: &str) -> Result { - // ostree_sysroot_get_deployments() isn't bound - // https://gitlab.com/fkrull/ostree-rs/-/issues/3 - let ls = std::process::Command::new("/bin/sh") - .arg("-c") - .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) - .output()?; - if !ls.status.success() { - bail!("failed to find deployment") - } - let mut lines = ls.stdout.lines(); - let deployment = if let Some(line) = lines.next() { - let line = line?; - let deploypath = Path::new(line.trim()); - let parts: Vec<_> = deploypath - .file_name() - .unwrap() - .to_str() - .unwrap() - .splitn(2, ".0") - .collect(); - assert!(parts.len() == 2); - parts[0].to_string() - } else { - bail!("failed to find deployment"); - }; - if let Some(_) = lines.next() { - bail!("multiple deployments found") - } - Ok(deployment) - } - - pub(crate) fn install(sysroot_path: &str) -> Result<()> { - let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); - sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; +pub(crate) fn install(sysroot_path: &str) -> Result<()> { + let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); + sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; - let _commit = find_deployed_commit(sysroot_path)?; + let _commit = ostreeutil::find_deployed_commit(sysroot_path)?; - let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); - if statepath.exists() { - bail!("{:?} already exists, cannot re-install", statepath); - } + let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); + if statepath.exists() { + bail!("{:?} already exists, cannot re-install", statepath); + } - let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); - validate_esp(&bootefi)?; + let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); + validate_esp(&bootefi)?; - Ok(()) - } + Ok(()) } fn update(opts: &UpdateOptions) -> Result<()> { @@ -618,9 +443,7 @@ fn status(opts: &StatusOptions) -> Result<()> { pub fn boot_update_main(args: &Vec) -> Result<()> { let opt = Opt::from_iter(args.iter()); match opt { - Opt::Install { sysroot } => { - install::install(&sysroot).context("boot data installation failed")? - } + Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, Opt::Adopt { sysroot } => adopt(&sysroot)?, Opt::Update(ref opts) => update(opts).context("boot data update failed")?, Opt::Status(ref opts) => status(opts).context("status failed")?, diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 000000000..0675ca8bd --- /dev/null +++ b/src/model.rs @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use chrono::prelude::*; +use serde_derive::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +use crate::filetree::*; +use crate::sha512string::SHA512String; + +/// Metadata for a single file +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +pub(crate) enum ComponentType { + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + EFI, + #[cfg(target_arch = "x86_64")] + BIOS, +} + +/// Describes data that is at the block level or the filesystem level. +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct InstalledContent { + /// sha512 of the state of the content + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) filesystem: Option>, +} + +/// A versioned description of something we can update, +/// whether that is a BIOS MBR or an ESP +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContentVersion { + pub(crate) content_timestamp: NaiveDateTime, + pub(crate) content: InstalledContent, + pub(crate) ostree_commit: Option, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentInstalled { + Unknown(InstalledContent), + Tracked { + disk: InstalledContent, + saved: SavedComponent, + drift: bool, + }, +} + +/// The state of a particular managed component as found on disk +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentState { + #[allow(dead_code)] + NotInstalled, + NotImplemented, + Found(ComponentInstalled), +} + +/// The state of a particular managed component +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentUpdate { + LatestUpdateInstalled, + Available { + update: ContentVersion, + diff: Option, + }, +} + +/// A component along with a possible update +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Component { + pub(crate) ctype: ComponentType, + pub(crate) installed: ComponentState, + pub(crate) pending: Option, + pub(crate) update: Option, +} + +/// Our total view of the world at a point in time +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Status { + pub(crate) supported_architecture: bool, + pub(crate) components: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedPendingUpdate { + /// The value of /proc/sys/kernel/random/boot_id + pub(crate) boot_id: String, + /// The value of /etc/machine-id from the OS trying to update + pub(crate) machineid: String, + /// The new version we're trying to install + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedComponent { + pub(crate) adopted: bool, + pub(crate) digest: SHA512String, + pub(crate) timestamp: NaiveDateTime, + pub(crate) pending: Option, +} + +/// Will be serialized into /boot/rpmostree-bootupd-state.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct SavedState { + pub(crate) components: BTreeMap, +} + +/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct UpgradeEdge { + /// Set to true if we should upgrade from an unknown state + #[serde(default)] + pub(crate) from_unknown: bool, + /// Upgrade from content past this timestamp + pub(crate) from_timestamp: Option, +} + +impl InstalledContent { + pub(crate) fn from_file_tree(ft: FileTree) -> InstalledContent { + InstalledContent { + digest: ft.digest(), + timestamp: ft.timestamp, + filesystem: Some(Box::new(ft)), + } + } +} + +impl ComponentInstalled { + pub(crate) fn get_disk_content(&self) -> &InstalledContent { + match self { + Self::Unknown(i) => i, + Self::Tracked { disk, .. } => disk, + } + } +} diff --git a/src/ostreeutil.rs b/src/ostreeutil.rs new file mode 100644 index 000000000..211eea979 --- /dev/null +++ b/src/ostreeutil.rs @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::{bail, Result}; +use std::io::BufRead; +use std::path::Path; + +pub(crate) fn find_deployed_commit(sysroot_path: &str) -> Result { + // ostree_sysroot_get_deployments() isn't bound + // https://gitlab.com/fkrull/ostree-rs/-/issues/3 + let ls = std::process::Command::new("/bin/sh") + .arg("-c") + .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) + .output()?; + if !ls.status.success() { + bail!("failed to find deployment") + } + let mut lines = ls.stdout.lines(); + let deployment = if let Some(line) = lines.next() { + let line = line?; + let deploypath = Path::new(line.trim()); + let parts: Vec<_> = deploypath + .file_name() + .unwrap() + .to_str() + .unwrap() + .splitn(2, ".0") + .collect(); + assert!(parts.len() == 2); + parts[0].to_string() + } else { + bail!("failed to find deployment"); + }; + if let Some(_) = lines.next() { + bail!("multiple deployments found") + } + Ok(deployment) +} From c6728bf896919c7cd35771934325f8da51bdd957 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 20 Jun 2020 18:50:48 +0000 Subject: [PATCH 009/641] Initial filetree update implementation --- src/bootupd.rs | 129 +++++++++++++------------ src/filetree.rs | 245 +++++++++++++++++++++++++++++++++++++++++++----- src/model.rs | 13 ++- 3 files changed, 300 insertions(+), 87 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index e0361abe7..46524a7d3 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -84,46 +84,6 @@ enum Opt { Status(StatusOptions), } -// Recursively remove all files in the directory that start with our TMP_PREFIX -fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { - for entry in dir.list_dir(".")? { - let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { - // Skip invalid UTF-8 for now, we will barf on it later though. - continue; - }; - - match dir.get_file_type(&entry)? { - openat::SimpleType::Dir => { - let child = dir.sub_dir(name)?; - cleanup_tmp(&child)?; - } - openat::SimpleType::File => { - if name.starts_with(TMP_PREFIX) { - dir.remove_file(name)?; - } - } - _ => {} - } - } - Ok(()) -} - -// struct ApplyUpdateOptions { -// skip_removals: bool, -// } - -// fn apply_update_from_diff( -// src: &openat::Dir, -// dest: &openat::Dir, -// diff: FileTreeDiff, -// opts: Option, -// ) -> Result<()> { -// Ok(()) -// } - fn running_in_test_suite() -> bool { !nix::unistd::getuid().is_root() } @@ -163,14 +123,67 @@ pub(crate) fn install(sysroot_path: &str) -> Result<()> { Ok(()) } +fn update_component_filesystem_at( + _component: &Component, + src: &openat::Dir, + dest: &openat::Dir, + update: &ComponentUpdateAvailable, +) -> Result<()> { + let diff = update.diff.as_ref().expect("diff"); + + // FIXME change this to only be true if we adopted + let opts = ApplyUpdateOptions { + skip_removals: true, + ..Default::default() + }; + filetree::apply_diff(src, dest, diff, Some(&opts))?; + + Ok(()) +} + fn update(opts: &UpdateOptions) -> Result<()> { - let esp = Path::new(&opts.sysroot).join(EFI_MOUNT); - validate_esp(&esp)?; - let esp_dir = openat::Dir::open(&esp)?; + let status = compute_status(&opts.sysroot)?; + let sysroot_dir = openat::Dir::open(opts.sysroot.as_str())?; - // First remove any temporary files - cleanup_tmp(&esp_dir)?; + for component in status.components.iter() { + if let Some(update) = component.update.as_ref() { + match update { + ComponentUpdate::LatestUpdateInstalled => { + println!("{:?}: At the latest version", component.ctype); + } + ComponentUpdate::Available(update) => match &component.ctype { + // Yeah we need to have components be a trait with methods like update() + ComponentType::EFI => { + let src = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; + let dest = sysroot_dir.sub_dir("boot/efi")?; + update_component_filesystem_at(component, &src, &dest, update)?; + } + ctype => { + panic!("Unhandled update for component {:?}", ctype); + } + }, + } + } else { + println!("{:?}: No updates available", component.ctype); + }; + } + Ok(()) +} +fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { + let f = { + let f = sysroot_dir.new_unnamed_file(0o644)?; + let mut buff = std::io::BufWriter::new(f); + serde_json::to_writer(&mut buff, state)?; + buff.flush()?; + buff.into_inner()? + }; + let dest = Path::new(STATEFILE_PATH); + let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); + let dest_tmp = dest.with_file_name(dest_tmp_name); + sysroot_dir.link_file_at(&f, &dest_tmp)?; + f.sync_all()?; + sysroot_dir.local_rename(&dest_tmp, dest)?; Ok(()) } @@ -219,18 +232,7 @@ fn adopt(sysroot_path: &str) -> Result<()> { components: new_saved_components, }; let sysroot_dir = openat::Dir::open(sysroot_path)?; - let f = { - let f = sysroot_dir.new_unnamed_file(0o644)?; - let mut buff = std::io::BufWriter::new(f); - serde_json::to_writer(&mut buff, &new_saved_state)?; - buff.flush()?; - buff.into_inner()? - }; - let dest = Path::new(STATEFILE_PATH); - let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); - let dest_tmp = dest.with_file_name(dest_tmp_name); - sysroot_dir.link_file_at(&f, &dest_tmp)?; - sysroot_dir.local_rename(&dest_tmp, dest)?; + update_state(&sysroot_dir, &new_saved_state)?; Ok(()) } @@ -311,10 +313,10 @@ fn compute_status_efi( ComponentUpdate::LatestUpdateInstalled } else { let diff = installed_tree.diff(update_esp_tree)?; - ComponentUpdate::Available { + ComponentUpdate::Available(ComponentUpdateAvailable { update: update_esp, diff: Some(diff), - } + }) }; Ok(Component { @@ -392,10 +394,13 @@ fn print_component(component: &Component) { ComponentUpdate::LatestUpdateInstalled => { println!(" Update: At latest version"); } - ComponentUpdate::Available { update, diff } => { - let ts_str = update.content_timestamp.format("%Y-%m-%dT%H:%M:%S+00:00"); + ComponentUpdate::Available(update) => { + let ts_str = update + .update + .content_timestamp + .format("%Y-%m-%dT%H:%M:%S+00:00"); println!(" Update: Available: {}", ts_str); - if let Some(diff) = diff { + if let Some(diff) = &update.diff { println!( " Diff: changed={} added={} removed={}", diff.changes.len(), diff --git a/src/filetree.rs b/src/filetree.rs index d028a9d53..ab8a5adca 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -4,13 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use byteorder::ByteOrder; use chrono::prelude::*; use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; use serde_derive::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet}; +use std::os::linux::fs::MetadataExt; +use std::os::unix::io::AsRawFd; +use std::os::unix::process::CommandExt; +use std::path::Path; // Seems like a rust-analyzer bug? #[allow(unused_imports)] use std::io::Write; @@ -45,6 +49,13 @@ pub(crate) struct FileTreeDiff { pub(crate) changes: HashSet, } +impl FileTreeDiff { + #[allow(dead_code)] // Used for testing + pub(crate) fn count(&self) -> usize { + self.additions.len() + self.removals.len() + self.changes.len() + } +} + impl FileMetadata { pub(crate) fn new_from_path( dir: &openat::Dir, @@ -164,6 +175,144 @@ impl FileTree { } } +// Recursively remove all files in the directory that start with our TMP_PREFIX +fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + // Skip invalid UTF-8 for now, we will barf on it later though. + continue; + }; + + match dir.get_file_type(&entry)? { + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + cleanup_tmp(&child)?; + } + openat::SimpleType::File => { + if name.starts_with(TMP_PREFIX) { + dir.remove_file(name)?; + } + } + _ => {} + } + } + Ok(()) +} + +#[derive(Default, Clone)] +pub(crate) struct ApplyUpdateOptions { + pub(crate) skip_removals: bool, + pub(crate) skip_sync: bool, +} + +/// A bit like std::fs::copy but operates dirfd-relative +fn copy_file_at, DP: AsRef>( + srcdir: &openat::Dir, + destdir: &openat::Dir, + srcp: SP, + destp: DP, +) -> Result<()> { + let srcp = srcp.as_ref(); + let srcf = srcdir.open_file(srcp)?; + let srcmeta = srcf.metadata()?; + let mode = srcmeta.st_mode(); + let mut srcf = std::io::BufReader::new(srcf); + let mut destf = destdir.write_file(destp.as_ref(), mode)?; + { + let mut destf_buf = std::io::BufWriter::new(&mut destf); + let _ = std::io::copy(&mut srcf, &mut destf_buf)?; + destf_buf.flush()?; + } + destf.flush()?; + + Ok(()) +} + +// syncfs() is a Linux-specific system call, which doesn't seem +// to be bound in nix today. I found https://github.com/XuShaohua/nc +// but that's a nontrivial dependency with not a lot of code review. +// Let's just fork off a helper process for now. +pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { + let d = d.sub_dir(".").expect("subdir"); + let mut c = std::process::Command::new("sync"); + let c = c.args(&["-f", "."]); + unsafe { + c.pre_exec(move || { + nix::unistd::fchdir(d.as_raw_fd()).expect("fchdir"); + Ok(()) + }) + }; + let r = c.status().context("syncfs failed")?; + if !r.success() { + bail!("syncfs failed"); + } + Ok(()) +} + +fn tmpname_for_path>(path: P) -> std::path::PathBuf { + let path = path.as_ref(); + let basename = path.file_name().expect("filename"); + path.with_file_name(format!( + "{}{}", + TMP_PREFIX, + basename.to_str().expect("UTF-8 filename") + )) +} + +/// Given two directories, apply a diff generated from srcdir to destdir +pub(crate) fn apply_diff( + srcdir: &openat::Dir, + destdir: &openat::Dir, + diff: &FileTreeDiff, + opts: Option<&ApplyUpdateOptions>, +) -> Result<()> { + let default_opts = ApplyUpdateOptions { + ..Default::default() + }; + let opts = opts.unwrap_or(&default_opts); + cleanup_tmp(destdir).context("cleaning up temporary files")?; + + // Write new and changed files + for pathstr in diff.additions.iter().chain(diff.changes.iter()) { + let path = Path::new(pathstr); + if let Some(parent) = path.parent() { + // TODO: care about directory modes? Eh. + std::fs::create_dir_all(parent)?; + } + let destp = tmpname_for_path(path); + copy_file_at(srcdir, destdir, path, destp.as_path()) + .with_context(|| format!("writing {}", &pathstr))?; + } + // Ensure all of the new files are written persistently to disk + if !opts.skip_sync { + syncfs(destdir)?; + } + // Now move them all into place (TODO track interruption) + for path in diff.additions.iter().chain(diff.changes.iter()) { + let pathtmp = tmpname_for_path(path); + destdir + .local_rename(&pathtmp, path) + .with_context(|| format!("renaming {}", path))?; + } + if !opts.skip_removals { + for path in diff.removals.iter() { + destdir + .remove_file(path) + .with_context(|| format!("removing {}", path))?; + } + } + // A second full filesystem sync to narrow any races rather than + // waiting for writeback to kick in. + if !opts.skip_sync { + syncfs(destdir)?; + } + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; @@ -175,50 +324,104 @@ mod tests { Ok(diff) } + fn test_one_apply, BP: AsRef>( + a: AP, + b: BP, + opts: Option<&ApplyUpdateOptions>, + ) -> Result<()> { + let a = a.as_ref(); + let b = b.as_ref(); + let t = tempfile::tempdir()?; + let c = t.path().join("c"); + let r = std::process::Command::new("cp") + .arg("-rp") + .args(&[a, &c]) + .status()?; + if !r.success() { + bail!("failed to cp"); + }; + let c = openat::Dir::open(&c)?; + let da = openat::Dir::open(a)?; + let db = openat::Dir::open(b)?; + let ta = FileTree::new_from_dir(&da)?; + let tb = FileTree::new_from_dir(&db)?; + let diff = ta.diff(&tb)?; + let rdiff = tb.diff(&ta)?; + assert_eq!(diff.count(), rdiff.count()); + assert_eq!(diff.additions.len(), rdiff.removals.len()); + assert_eq!(diff.changes.len(), rdiff.changes.len()); + apply_diff(&db, &c, &diff, opts)?; + let tc = FileTree::new_from_dir(&c)?; + let newdiff = tb.diff(&tc)?; + let skip_removals = opts.map(|o| o.skip_removals).unwrap_or(false); + if skip_removals { + let n = newdiff.count(); + if n != 0 { + assert_eq!(n, diff.removals.len()); + } + for f in diff.removals.iter() { + assert!(c.exists(f)?); + assert!(da.exists(f)?); + } + } else { + assert_eq!(newdiff.count(), 0); + } + Ok(()) + } + + fn test_apply, BP: AsRef>(a: AP, b: BP) -> Result<()> { + let a = a.as_ref(); + let b = b.as_ref(); + let skip_removals = ApplyUpdateOptions { + skip_removals: true, + ..Default::default() + }; + test_one_apply(&a, &b, None).context("testing apply (with removals)")?; + test_one_apply(&a, &b, Some(&skip_removals)) + .context("testing apply (skipping removals)")?; + Ok(()) + } + #[test] - fn test_diff() -> Result<()> { + fn test_filetree() -> Result<()> { let tmpd = tempfile::tempdir()?; let p = tmpd.path(); - let a = p.join("a"); - let b = p.join("b"); - std::fs::create_dir(&a)?; - std::fs::create_dir(&b)?; - let a = openat::Dir::open(&a)?; - let b = openat::Dir::open(&b)?; + let pa = p.join("a"); + let pb = p.join("b"); + std::fs::create_dir(&pa)?; + std::fs::create_dir(&pb)?; + let a = openat::Dir::open(&pa)?; + let b = openat::Dir::open(&pb)?; let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); + assert_eq!(diff.count(), 0); a.create_dir("foo", 0o755)?; let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); + assert_eq!(diff.count(), 0); { let mut bar = a.write_file("foo/bar", 0o644)?; bar.write("foobarcontents".as_bytes())?; } let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); + assert_eq!(diff.count(), 1); assert_eq!(diff.removals.len(), 1); - assert_eq!(diff.changes.len(), 0); + test_apply(&pa, &pb).context("testing apply 1")?; + b.create_dir("foo", 0o755)?; { let mut bar = b.write_file("foo/bar", 0o644)?; bar.write("foobarcontents".as_bytes())?; } let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); - assert_eq!(diff.changes.len(), 0); + assert_eq!(diff.count(), 0); + test_apply(&pa, &pb).context("testing apply 2")?; { let mut bar2 = b.write_file("foo/bar", 0o644)?; bar2.write("foobarcontents2".as_bytes())?; } let diff = run_diff(&a, &b)?; - assert_eq!(diff.additions.len(), 0); - assert_eq!(diff.removals.len(), 0); + assert_eq!(diff.count(), 1); assert_eq!(diff.changes.len(), 1); + test_apply(&pa, &pb).context("testing apply 3")?; Ok(()) } } diff --git a/src/model.rs b/src/model.rs index 0675ca8bd..605472e4c 100644 --- a/src/model.rs +++ b/src/model.rs @@ -62,15 +62,20 @@ pub(crate) enum ComponentState { Found(ComponentInstalled), } +/// The state of a particular managed component +#[derive(Serialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ComponentUpdateAvailable { + pub(crate) update: ContentVersion, + pub(crate) diff: Option, +} + /// The state of a particular managed component #[derive(Serialize, Debug)] #[serde(rename_all = "kebab-case")] pub(crate) enum ComponentUpdate { LatestUpdateInstalled, - Available { - update: ContentVersion, - diff: Option, - }, + Available(ComponentUpdateAvailable), } /// A component along with a possible update From fc90cba8bf925a9e74daf05d6579244cf24f02b0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 21 Jun 2020 21:09:47 +0000 Subject: [PATCH 010/641] Plumb through and fix bugs in updates, add more e2e testing I am thinking adopted components should only be tracked by timestamp or so; the digest stuff is just misleading. --- src/bootupd.rs | 283 ++++++++++++++++++++++++++++----------- src/filetree.rs | 8 +- src/model.rs | 3 +- tests/libtest.sh | 2 +- tests/unpriv-blackbox.sh | 111 ++++++++++++--- 5 files changed, 308 insertions(+), 99 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 46524a7d3..873c6bb2d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -9,7 +9,7 @@ use gio::NONE_CANCELLABLE; use nix; use openat_ext::OpenatDirExt; use serde_json; -use std::collections::{BTreeMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; @@ -29,6 +29,9 @@ pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.js #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; +/// Where rpm-ostree rewrites data that goes in /boot +pub(crate) const OSTREE_BOOT_DATA: &'static str = "usr/lib/ostree-boot"; + #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { @@ -46,6 +49,9 @@ struct UpdateOptions { long )] state_transition_file: String, + + /// Only upgrade these components + components: Vec, } #[derive(Debug, StructOpt)] @@ -124,28 +130,93 @@ pub(crate) fn install(sysroot_path: &str) -> Result<()> { } fn update_component_filesystem_at( - _component: &Component, + saved: &SavedComponent, src: &openat::Dir, dest: &openat::Dir, update: &ComponentUpdateAvailable, -) -> Result<()> { +) -> Result { let diff = update.diff.as_ref().expect("diff"); - // FIXME change this to only be true if we adopted + // For components which were adopted, we don't prune files that we don't know + // about. let opts = ApplyUpdateOptions { - skip_removals: true, + skip_removals: saved.adopted, ..Default::default() }; filetree::apply_diff(src, dest, diff, Some(&opts))?; - Ok(()) + Ok(SavedComponent { + adopted: saved.adopted, + filesystem: update.update.content.filesystem.clone(), + digest: update.update.content.digest.clone(), + timestamp: update.update.content_timestamp, + pending: None, + }) +} + +fn parse_componentlist(components: &Vec) -> Result>> { + if components.len() == 0 { + return Ok(None); + } + let r: std::result::Result, _> = components + .iter() + .map(|c| serde_plain::from_str(c)) + .collect(); + Ok(Some(r?)) } fn update(opts: &UpdateOptions) -> Result<()> { - let status = compute_status(&opts.sysroot)?; - let sysroot_dir = openat::Dir::open(opts.sysroot.as_str())?; + let (status, mut new_saved_state) = + compute_status(&opts.sysroot).context("computing status")?; + let sysroot_dir = openat::Dir::open(opts.sysroot.as_str()) + .with_context(|| format!("opening sysroot {}", opts.sysroot))?; + + let specified_components = parse_componentlist(&opts.components)?; + for (ctype, component) in status.components.iter() { + let is_specified = if let Some(specified) = specified_components.as_ref() { + if !specified.contains(ctype) { + continue; + } + true + } else { + false + }; + let saved = match &component.installed { + ComponentState::NotImplemented => { + if is_specified { + bail!("Component {:?} is not implemented", &ctype); + } else { + continue; + } + } + ComponentState::NotInstalled => { + if is_specified { + bail!("Component {:?} is not installed", &ctype); + } else { + continue; + } + } + ComponentState::Found(installed) => match installed { + ComponentInstalled::Unknown(_) => { + if is_specified { + bail!( + "Component {:?} is not tracked and must be adopted before update", + ctype + ); + } else { + println!( + "Skipping component {:?} which is found but not adopted", + ctype + ); + continue; + } + } + ComponentInstalled::Tracked { disk: _, saved, .. } => saved, + }, + }; + // If we get here, there must be saved state + let new_saved_state = new_saved_state.as_mut().expect("saved state"); - for component in status.components.iter() { if let Some(update) = component.update.as_ref() { match update { ComponentUpdate::LatestUpdateInstalled => { @@ -154,9 +225,19 @@ fn update(opts: &UpdateOptions) -> Result<()> { ComponentUpdate::Available(update) => match &component.ctype { // Yeah we need to have components be a trait with methods like update() ComponentType::EFI => { - let src = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; - let dest = sysroot_dir.sub_dir("boot/efi")?; - update_component_filesystem_at(component, &src, &dest, update)?; + let src = sysroot_dir + .sub_dir(&Path::new(OSTREE_BOOT_DATA).join("efi")) + .context("opening ostree boot data")?; + let dest = sysroot_dir.sub_dir(EFI_MOUNT).context(EFI_MOUNT)?; + let updated_component = + update_component_filesystem_at(saved, &src, &dest, update) + .with_context(|| format!("updating component {:?}", ctype))?; + let updated_digest = updated_component.digest.clone(); + new_saved_state + .components + .insert(ComponentType::EFI, updated_component); + update_state(&sysroot_dir, new_saved_state)?; + println!("{:?}: Updated to digest={}", ctype, updated_digest); } ctype => { panic!("Unhandled update for component {:?}", ctype); @@ -188,11 +269,13 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { } fn adopt(sysroot_path: &str) -> Result<()> { - let status = compute_status(sysroot_path)?; - let mut new_saved_components = BTreeMap::new(); + let (status, saved_state) = compute_status(sysroot_path)?; let mut adopted = std::collections::BTreeSet::new(); - for component in status.components { - let installed = match component.installed { + let mut saved_state = saved_state.unwrap_or_else(|| SavedState { + components: BTreeMap::new(), + }); + for (ctype, component) in status.components.iter() { + let installed = match &component.installed { ComponentState::NotInstalled => continue, ComponentState::NotImplemented => continue, ComponentState::Found(installed) => installed, @@ -205,34 +288,33 @@ fn adopt(sysroot_path: &str) -> Result<()> { } ComponentInstalled::Tracked { disk: _, - saved, + saved: _, drift, } => { - if drift { - eprintln!("Warning: Skipping drifted component: {:?}", component.ctype); + if *drift { + eprintln!("Warning: Skipping drifted component: {:?}", ctype); } - new_saved_components.insert(component.ctype.clone(), saved.clone()); continue; } }; let saved = SavedComponent { adopted: true, - digest: disk.digest, + digest: disk.digest.clone(), + filesystem: disk.filesystem.clone(), timestamp: disk.timestamp, pending: None, }; - new_saved_components.insert(component.ctype, saved); + saved_state + .components + .insert(component.ctype.clone(), saved); } if adopted.len() == 0 { println!("Nothing to do."); return Ok(()); } - - let new_saved_state = SavedState { - components: new_saved_components, - }; + // Must have saved state if we get here let sysroot_dir = openat::Dir::open(sysroot_path)?; - update_state(&sysroot_dir, &new_saved_state)?; + update_state(&sysroot_dir, &saved_state)?; Ok(()) } @@ -285,50 +367,84 @@ fn compute_status_efi( saved_components: Option<&SavedState>, ) -> Result { let sysroot_dir = openat::Dir::open(sysroot_path)?; - let espdir = sysroot_dir.sub_dir("boot/efi")?; - let content = InstalledContent::from_file_tree(FileTree::new_from_dir(&espdir)?); - let digest = content.digest.clone(); - let saved_state = saved_components + let espdir = sysroot_dir.sub_dir(EFI_MOUNT).context(EFI_MOUNT)?; + let esptree = FileTree::new_from_dir(&espdir).context("computing filetree for efi")?; + let saved = saved_components .map(|s| s.components.get(&ComponentType::EFI)) .flatten(); - let installed_state = if let Some(saved) = saved_state { - let drift = saved.digest != content.digest; - ComponentInstalled::Tracked { - disk: content, - saved: saved.clone(), - drift: drift, - } + let saved = if let Some(saved) = saved { + saved + } else { + return Ok(Component { + ctype: ComponentType::EFI, + installed: ComponentState::Found(ComponentInstalled::Unknown( + InstalledContent::from_file_tree(esptree), + )), + pending: None, + update: None, + }); + }; + let fsdiff = if let Some(saved_filesystem) = saved.filesystem.as_ref() { + Some(esptree.diff(&saved_filesystem)?) } else { - ComponentInstalled::Unknown(content) + None }; - let installed_tree = installed_state - .get_disk_content() - .filesystem - .as_ref() - .unwrap(); + let fsdiff = fsdiff.as_ref(); + let (installed, installed_digest) = { + let content = InstalledContent::from_file_tree(esptree); + let drift = if let Some(fsdiff) = fsdiff { + if saved.adopted { + !fsdiff.is_only_removals() + } else { + fsdiff.count() > 0 + } + } else { + // TODO detect state outside of filesystem tree + false + }; + let digest = if saved.adopted && !drift { + saved.digest.clone() + } else { + content.digest.clone() + }; + ( + ComponentInstalled::Tracked { + disk: content, + saved: saved.clone(), + drift: drift, + }, + digest, + ) + }; + let installed_tree = installed.get_disk_content().filesystem.as_ref().unwrap(); let update_esp = efi_content_version_from_ostree(sysroot_path)?; let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); - let update = if update_esp.content.digest == digest { + let update = if !saved.adopted && update_esp.content.digest == installed_digest { ComponentUpdate::LatestUpdateInstalled } else { let diff = installed_tree.diff(update_esp_tree)?; - ComponentUpdate::Available(ComponentUpdateAvailable { - update: update_esp, - diff: Some(diff), - }) + if saved.adopted && diff.is_only_removals() { + ComponentUpdate::LatestUpdateInstalled + } else { + ComponentUpdate::Available(ComponentUpdateAvailable { + update: update_esp, + diff: Some(diff), + }) + } }; Ok(Component { ctype: ComponentType::EFI, - installed: ComponentState::Found(installed_state), - pending: saved_state.map(|x| x.pending.clone()).flatten(), + installed: ComponentState::Found(installed), + pending: saved.pending.clone(), update: Some(update), }) } -fn compute_status(sysroot_path: &str) -> Result { - let sysroot_dir = openat::Dir::open(sysroot_path)?; +fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { + let sysroot_dir = openat::Dir::open(sysroot_path) + .with_context(|| format!("opening sysroot {}", sysroot_path))?; let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(STATEFILE_PATH)? { let bufr = std::io::BufReader::new(statusf); @@ -338,24 +454,33 @@ fn compute_status(sysroot_path: &str) -> Result { None }; - let mut components = Vec::new(); + let mut components = BTreeMap::new(); #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - components.push(compute_status_efi(&sysroot_path, saved_state.as_ref())?); + components.insert( + ComponentType::EFI, + compute_status_efi(&sysroot_path, saved_state.as_ref())?, + ); #[cfg(target_arch = "x86_64")] { - components.push(Component { - ctype: ComponentType::BIOS, - installed: ComponentState::NotImplemented, - pending: None, - update: None, - }); + components.insert( + ComponentType::BIOS, + Component { + ctype: ComponentType::BIOS, + installed: ComponentState::NotImplemented, + pending: None, + update: None, + }, + ); } - Ok(Status { - supported_architecture: components.len() > 0, - components: components, - }) + Ok(( + Status { + supported_architecture: components.len() > 0, + components: components, + }, + saved_state, + )) } fn print_component(component: &Component) { @@ -378,14 +503,14 @@ fn print_component(component: &Component) { } ComponentInstalled::Tracked { disk, saved, drift } => { if !*drift { - println!(" Installed: {}", disk.digest); - if saved.adopted { - println!(" Adopted: true") - } + println!(" Installed: {}", saved.digest); } else { println!(" Installed; warning: drift detected"); - println!(" Recorded: {}", saved.digest); - println!(" Actual: {}", disk.digest); + println!(" Recorded: {}", saved.digest); + println!(" Actual: {}", disk.digest); + } + if saved.adopted { + println!(" Adopted: true") } } } @@ -399,8 +524,10 @@ fn print_component(component: &Component) { .update .content_timestamp .format("%Y-%m-%dT%H:%M:%S+00:00"); - println!(" Update: Available: {}", ts_str); - if let Some(diff) = &update.diff { + println!(" Update: Available"); + println!(" Timestamp: {}", ts_str); + println!(" Digest: {}", update.update.content.digest); + if let Some(diff) = &update.diff { println!( " Diff: changed={} added={} removed={}", diff.changes.len(), @@ -414,7 +541,7 @@ fn print_component(component: &Component) { } fn status(opts: &StatusOptions) -> Result<()> { - let status = compute_status(&opts.sysroot)?; + let (status, _) = compute_status(&opts.sysroot)?; if opts.json { serde_json::to_writer_pretty(std::io::stdout(), &status)?; } else { @@ -430,9 +557,9 @@ fn status(opts: &StatusOptions) -> Result<()> { } else { None }; - for component in &status.components { + for (ctype, component) in status.components.iter() { if let Some(specified_components) = specified_components.as_ref() { - if !specified_components.contains(&component.ctype) { + if !specified_components.contains(ctype) { continue; } } @@ -450,8 +577,8 @@ pub fn boot_update_main(args: &Vec) -> Result<()> { match opt { Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, Opt::Adopt { sysroot } => adopt(&sysroot)?, - Opt::Update(ref opts) => update(opts).context("boot data update failed")?, - Opt::Status(ref opts) => status(opts).context("status failed")?, + Opt::Update(ref opts) => update(opts)?, + Opt::Status(ref opts) => status(opts)?, }; Ok(()) } diff --git a/src/filetree.rs b/src/filetree.rs index ab8a5adca..328ba6fc3 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -25,7 +25,7 @@ pub(crate) const TMP_PREFIX: &'static str = ".btmp."; use crate::sha512string::SHA512String; /// Metadata for a single file -#[derive(Serialize, Debug, Hash, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, Hash, PartialEq)] #[serde(rename_all = "kebab-case")] pub(crate) struct FileMetadata { /// File size in bytes @@ -35,7 +35,7 @@ pub(crate) struct FileMetadata { pub(crate) sha512: SHA512String, } -#[derive(Serialize, Debug, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "kebab-case")] pub(crate) struct FileTree { pub(crate) timestamp: NaiveDateTime, @@ -54,6 +54,10 @@ impl FileTreeDiff { pub(crate) fn count(&self) -> usize { self.additions.len() + self.removals.len() + self.changes.len() } + + pub(crate) fn is_only_removals(&self) -> bool { + self.count() == self.removals.len() + } } impl FileMetadata { diff --git a/src/model.rs b/src/model.rs index 605472e4c..9ab16a2ed 100644 --- a/src/model.rs +++ b/src/model.rs @@ -93,7 +93,7 @@ pub(crate) struct Component { #[serde(rename_all = "kebab-case")] pub(crate) struct Status { pub(crate) supported_architecture: bool, - pub(crate) components: Vec, + pub(crate) components: BTreeMap, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -113,6 +113,7 @@ pub(crate) struct SavedPendingUpdate { #[serde(rename_all = "kebab-case")] pub(crate) struct SavedComponent { pub(crate) adopted: bool, + pub(crate) filesystem: Option>, pub(crate) digest: SHA512String, pub(crate) timestamp: NaiveDateTime, pub(crate) pending: Option, diff --git a/tests/libtest.sh b/tests/libtest.sh index 3b0498d8f..80844bf9e 100644 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -8,7 +8,7 @@ runv() { N_TESTS=0 ok() { - echo "ok " $@ + echo "ok" $@ N_TESTS=$((N_TESTS + 1)) } diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh index 1e912abc9..b90a7f4af 100755 --- a/tests/unpriv-blackbox.sh +++ b/tests/unpriv-blackbox.sh @@ -21,7 +21,7 @@ function cleanup () { rm "${tmpdir}" -rf fi else - echo "Skipping cleanup of ${test_tmpdir}" + echo "Skipping cleanup of ${tmpdir}" fi } @@ -31,48 +31,79 @@ bootupd() { bootefi=root/boot/efi ostefi=root/usr/lib/ostree-boot/efi -mkdir -p "${bootefi}" "${ostefi}" -for dir in "${bootefi}" "${ostefi}"; do - (cd ${dir} - mkdir -p EFI/fedora - cd EFI/fedora - for x in grubx64.efi shim.efi shimx64.efi; do +initefiroot() { + d=$1 + shift + echo "Initializing EFI root $d" + rm "${d}" -rf + mkdir -p "${d}" + (cd ${d} + mkdir -p EFI/fedora + cd EFI/fedora + echo unchanging > shouldnotchange.efi + echo unchanging2 > shouldnotchange2.efi + for x in grubx64.efi shim.efi shimx64.efi; do echo "some code for ${x}" > ${x} - done + done ) -done +} -v0_digest="sha512:4vbqyRvLYPyPtVaD3VexZQ9FBzhh1MFNsK4A5t1Ju7bVvj3YEDZfrrBQ7CTNjgwj8PhRBPvxHJ5v3x28fQZxCKBL" +v0_digest="sha512:2rLmU783U9VowCdmCDpBdvdQV7N751vhz3d3kMYCDS9FdufhUkCX5Gf66Yia1UcTwYAXHcudR7D5tmGUcTt5hqBZ" validate_v0() { bootupd status --sysroot=root --component=EFI | tee out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Unmanaged: digest='${v0_digest} - assert_file_has_content_literal out.txt 'Update: At latest version' + assert_not_file_has_content_literal out.txt 'Update: Available: ' assert_not_file_has_content out.txt 'Component BIOS' } +update_shipped() { + local v + v=$1 + shift + for x in grubx64.efi shim.efi shimx64.efi; do + test -f ${ostefi}/EFI/fedora/${x} + echo "version ${v} code for ${x}" > ${ostefi}/EFI/fedora/${x} + done +} + # This hack avoids us depending on having an ostree sysroot set up for now export BOOT_UPDATE_TEST_TIMESTAMP=$(date -u --iso-8601=seconds) +initefiroot "${bootefi}" +initefiroot "${ostefi}" validate_v0 +ok 'first validate' + +bootupd update --sysroot=root | tee out.txt +assert_file_has_content_literal out.txt 'Skipping component EFI which is found but not adopted' +ok 'no changes' -echo 'v2 code for grubx64.efi' > "${ostefi}"/EFI/fedora/grubx64.efi +update_shipped 1 +rm -v ${ostefi}/EFI/fedora/shim.efi bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'Update: Available: '${BOOT_UPDATE_TEST_TIMESTAMP} -assert_file_has_content_literal out.txt ' Diff: changed=1 added=0 removed=0' +validate_v0 +ok 'still no avail changes if unmanaged' # Revert back -echo 'some code for grubx64.efi' > "${ostefi}"/EFI/fedora/grubx64.efi +initefiroot "${ostefi}" validate_v0 +ok 'revert' + +if bootupd update --sysroot=root EFI 2>err.txt; then + fatal "performed an update without adopting" +fi +assert_file_has_content_literal err.txt 'Component EFI is not tracked and must be adopted before update' +ok cannot update without adoption bootupd adopt --sysroot=root | tee out.txt assert_file_has_content_literal out.txt "Adopting: EFI" -ok 'rerunning adoption' +ok 'adoption' bootupd adopt --sysroot=root | tee out.txt assert_not_file_has_content_literal out.txt "Adopting: EFI" assert_file_has_content_literal out.txt "Nothing to do" -ok '"rerunning adopt is idempotent' +ok 'rerunning adopt is idempotent' bootupd status --sysroot=root --component=EFI | tee out.txt assert_file_has_content_literal out.txt 'Component EFI' @@ -81,4 +112,50 @@ assert_file_has_content_literal out.txt ' Adopted: true' assert_file_has_content_literal out.txt 'Update: At latest version' ok 'adoption status' +# Re-initialize and adopt with extra state +rm -v root/boot/rpmostree-bootupd-state.json +initefiroot "${bootefi}" +initefiroot "${ostefi}" + +v1_digest="sha512:5LjsojQNor5tntzx6KBFxVGL3LjYXGg7imGttnb194J8Zb1j4HVLDMjFiZUi777x6dyx8RFjZe9wpvkdUeLAUoyr" + +echo 'unmanaged grub config' > "${bootefi}"/EFI/fedora/grub.cfg +bootupd adopt --sysroot=root | tee out.txt +assert_file_has_content_literal out.txt "Adopting: EFI" +export BOOT_UPDATE_TEST_TIMESTAMP=$(date -u --iso-8601=seconds) +ok adopt 2 + +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Installed: '${v1_digest} +assert_file_has_content_literal out.txt ' Adopted: true' +assert_file_has_content_literal out.txt 'Update: At latest version' +ok 'adoption status 2' + +v2_digest="sha512:4SoabM7zw6x9CsY64u6G9RFbEocVEQfhCDtVKUJeTPgyCUHTfZPKQacJNw5B23LGpFeFKVqABGJVnSzuLNynFscy" + + +update_shipped t2 +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Update: Available' +assert_file_has_content_literal out.txt ' Timestamp: '${BOOT_UPDATE_TEST_TIMESTAMP} +assert_file_has_content_literal out.txt ' Digest: '${v2_digest} +assert_file_has_content_literal out.txt ' Diff: changed=3 added=0 removed=1' +ok 'avail update v2' + +bootupd update --sysroot=root EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'warning: drift detected' +assert_file_has_content_literal out.txt 'EFI: Updated to digest='${v2_digest} +if ! test -f "${bootefi}/EFI/fedora/grub.cfg"; then + fatal "missing unmanaged grub cfg" +fi +ok 'update v2' + +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Installed: '${v2_digest} +assert_file_has_content_literal out.txt ' Adopted: true' +assert_file_has_content_literal out.txt 'Update: At latest version' +ok 'update v2 status' + tap_finish From a8db5a92618b8cf274fa47ac9f5d403f7c7daf0a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 22 Jun 2020 21:06:08 +0000 Subject: [PATCH 011/641] Add README-design.md --- README-design.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README-design.md diff --git a/README-design.md b/README-design.md new file mode 100644 index 000000000..3caad8a79 --- /dev/null +++ b/README-design.md @@ -0,0 +1,26 @@ +Overall design +--- + +The initial focus here is updating the [ESP](https://en.wikipedia.org/wiki/EFI_system_partition), but the overall design of bootupd contains a lot of abstraction to support different "components". + +# Ideal case + +In the ideal case, an OS builder uses `bootupd install` to install all bootloader data, +and thereafter it is fully (exclusively) managed by bootupd. It would e.g. be a bug/error +for an administrator to manually invoke `grub2-install` e.g. again. + +In other words, an end user system would simply invoke `bootupd update` as desired. + +However, we're not in that ideal case. Thus bootupd has the concept of "adoption" where +we start tracking the installed state as we find it. + +# Handling adoption + +For Fedora CoreOS, currently the `EFI/fedora/grub.cfg` file is created outside of the ostree inside `create_disk.sh`. So we aren't including any updates for it in the OSTree. + +This type of problem is exactly what bootupd should be solving. + +However, we need to be very cautious in handling this because we basically can't +assume we own all of the state. We shouldn't touch any files that we +don't know about. + From adbce2928184e21c7af6c30b12771cda5703e6c2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 22 Jun 2020 21:55:05 +0000 Subject: [PATCH 012/641] A few more README updates --- README-design.md | 11 +++++++++++ README.md | 28 +++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README-design.md b/README-design.md index 3caad8a79..b22dc6b02 100644 --- a/README-design.md +++ b/README-design.md @@ -24,3 +24,14 @@ However, we need to be very cautious in handling this because we basically can't assume we own all of the state. We shouldn't touch any files that we don't know about. +# Upgrade edges + +We don't necessarily want to update the bootloader data, even if a new update happens to be provided. +For example, Fedora does "mass rebuilds" usually once a release, but it's not strictly necessary +to update users' bootloaders then. + +A common policy in fact might be "only update bootloader for security issue or if it's strictly necessary". + +A "strictly necessary" upgrade would be one like the GRUB BLS parsing support. + +There is not yet any support for upgrade edges in the code apart from a stub structure. \ No newline at end of file diff --git a/README.md b/README.md index 7c0b9c33a..3f4621782 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,16 @@ in an inconsistent and ad-hoc way. For example, on Fedora and Debian, a package manager update will update UEFI binaries in `/boot/efi`, but not the BIOS MBR data. -Transactional update systems like [OSTree](https://github.com/ostreedev/ostree/) and others -normally cover kernel/userspace but not bootloaders, because -performing bootloader updates in an "A/B" fashion requires -completely separate nontrivial logic. Today OSTree e.g. -makes the choice that it does not update `/boot/efi`. +Many transactional update systems like [OSTree](https://github.com/ostreedev/ostree/) +and dual-partition systems like the Container Linux update system +are more consistent: they normally cover kernel/userspace but not anything +related to bootloaders. + +The reason for this is straightforward: performing bootloader +updates in an "A/B" fashion requires completely separate nontrivial +logic from managing the kernel and root filesystem. Today OSTree e.g. +makes the choice that it does not update `/boot/efi` (and also doesn't +update the BIOS MBR). The goal of this project is to be a cross-distribution, OS update system agnostic tool to manage updates for things like: @@ -24,3 +29,16 @@ This project originated in [this Fedora CoreOS github issue](https://github.com/ Currently a work in progress and is not ready to ship for production updates, but early feedback on the design is appreciated! + +## Relationship to other projects + +bootupd could be compared to [fwupd](https://github.com/fwupd/fwupd/) which is +project that exists today to update hardware device firmware - things not managed +by e.g. `apt/zypper/yum/rpm-ostree update` today. + +fwupd comes as a UEFI binary today, so bootupd would actually take care of updating fwupd itself. + +The end result is that a system administrator would have 3 projects to monitor +(one for hardware devices and 2 for the bootloader and OS state) but each +would be clearly focused on its domain and handle it well. This stands +in contrast with e.g. having an RPM `%post` script try to regenerate the BIOS MBR. From 0aad67cee044cabe057f35c445ac50cdeed6ca4c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 01:25:05 +0000 Subject: [PATCH 013/641] Fix `cargo clippy` lints The one about boxing variants of differing size is great. --- src/bootupd.rs | 68 +++++++++++++++++++++------------------------ src/filetree.rs | 12 ++++---- src/model.rs | 2 +- src/ostreeutil.rs | 2 +- src/sha512string.rs | 2 +- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 873c6bb2d..8c6f12cdc 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -6,9 +6,7 @@ use anyhow::{bail, Context, Result}; use gio::NONE_CANCELLABLE; -use nix; use openat_ext::OpenatDirExt; -use serde_json; use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::io::prelude::*; use std::path::Path; @@ -24,13 +22,13 @@ mod util; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. -pub(crate) const STATEFILE_PATH: &'static str = "boot/rpmostree-bootupd-state.json"; +pub(crate) const STATEFILE_PATH: &str = "boot/rpmostree-bootupd-state.json"; /// The path to the ESP mount #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub(crate) const EFI_MOUNT: &'static str = "boot/efi"; +pub(crate) const EFI_MOUNT: &str = "boot/efi"; /// Where rpm-ostree rewrites data that goes in /boot -pub(crate) const OSTREE_BOOT_DATA: &'static str = "usr/lib/ostree-boot"; +pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] @@ -154,8 +152,8 @@ fn update_component_filesystem_at( }) } -fn parse_componentlist(components: &Vec) -> Result>> { - if components.len() == 0 { +fn parse_componentlist(components: &[String]) -> Result>> { + if components.is_empty() { return Ok(None); } let r: std::result::Result, _> = components @@ -308,7 +306,7 @@ fn adopt(sysroot_path: &str) -> Result<()> { .components .insert(component.ctype.clone(), saved); } - if adopted.len() == 0 { + if adopted.is_empty() { println!("Nothing to do."); return Ok(()); } @@ -402,7 +400,7 @@ fn compute_status_efi( // TODO detect state outside of filesystem tree false }; - let digest = if saved.adopted && !drift { + let digest = if saved.adopted && !drift { saved.digest.clone() } else { content.digest.clone() @@ -411,7 +409,7 @@ fn compute_status_efi( ComponentInstalled::Tracked { disk: content, saved: saved.clone(), - drift: drift, + drift, }, digest, ) @@ -427,10 +425,10 @@ fn compute_status_efi( if saved.adopted && diff.is_only_removals() { ComponentUpdate::LatestUpdateInstalled } else { - ComponentUpdate::Available(ComponentUpdateAvailable { + ComponentUpdate::Available(Box::new(ComponentUpdateAvailable { update: update_esp, diff: Some(diff), - }) + })) } }; @@ -476,8 +474,8 @@ fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { } Ok(( Status { - supported_architecture: components.len() > 0, - components: components, + supported_architecture: !components.is_empty(), + components, }, saved_state, )) @@ -524,10 +522,10 @@ fn print_component(component: &Component) { .update .content_timestamp .format("%Y-%m-%dT%H:%M:%S+00:00"); - println!(" Update: Available"); - println!(" Timestamp: {}", ts_str); - println!(" Digest: {}", update.update.content.digest); - if let Some(diff) = &update.diff { + println!(" Update: Available"); + println!(" Timestamp: {}", ts_str); + println!(" Digest: {}", update.update.content.digest); + if let Some(diff) = &update.diff { println!( " Diff: changed={} added={} removed={}", diff.changes.len(), @@ -544,27 +542,25 @@ fn status(opts: &StatusOptions) -> Result<()> { let (status, _) = compute_status(&opts.sysroot)?; if opts.json { serde_json::to_writer_pretty(std::io::stdout(), &status)?; + } else if !status.supported_architecture { + eprintln!("This architecture is not supported.") } else { - if !status.supported_architecture { - eprintln!("This architecture is not supported.") + let specified_components = if let Some(components) = &opts.components { + let r: std::result::Result, _> = components + .iter() + .map(|c| serde_plain::from_str(c)) + .collect(); + Some(r?) } else { - let specified_components = if let Some(components) = &opts.components { - let r: std::result::Result, _> = components - .iter() - .map(|c| serde_plain::from_str(c)) - .collect(); - Some(r?) - } else { - None - }; - for (ctype, component) in status.components.iter() { - if let Some(specified_components) = specified_components.as_ref() { - if !specified_components.contains(ctype) { - continue; - } + None + }; + for (ctype, component) in status.components.iter() { + if let Some(specified_components) = specified_components.as_ref() { + if !specified_components.contains(ctype) { + continue; } - print_component(component); } + print_component(component); } } Ok(()) @@ -572,7 +568,7 @@ fn status(opts: &StatusOptions) -> Result<()> { /// Main entrypoint #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub fn boot_update_main(args: &Vec) -> Result<()> { +pub fn boot_update_main(args: &[String]) -> Result<()> { let opt = Opt::from_iter(args.iter()); match opt { Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, diff --git a/src/filetree.rs b/src/filetree.rs index 328ba6fc3..2430583f3 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -20,7 +20,7 @@ use std::path::Path; use std::io::Write; /// The prefix we apply to our temporary files. -pub(crate) const TMP_PREFIX: &'static str = ".btmp."; +pub(crate) const TMP_PREFIX: &str = ".btmp."; use crate::sha512string::SHA512String; @@ -146,7 +146,7 @@ impl FileTree { Ok(Self { timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), - children: children, + children, }) } @@ -166,15 +166,15 @@ impl FileTree { } } for k in updated.children.keys() { - if let Some(_) = self.children.get(k) { + if self.children.get(k).is_some() { continue; } additions.insert(k.clone()); } Ok(FileTreeDiff { - additions: additions, - removals: removals, - changes: changes, + additions, + removals, + changes, }) } } diff --git a/src/model.rs b/src/model.rs index 9ab16a2ed..0630de88d 100644 --- a/src/model.rs +++ b/src/model.rs @@ -75,7 +75,7 @@ pub(crate) struct ComponentUpdateAvailable { #[serde(rename_all = "kebab-case")] pub(crate) enum ComponentUpdate { LatestUpdateInstalled, - Available(ComponentUpdateAvailable), + Available(Box), } /// A component along with a possible update diff --git a/src/ostreeutil.rs b/src/ostreeutil.rs index 211eea979..89a922504 100644 --- a/src/ostreeutil.rs +++ b/src/ostreeutil.rs @@ -34,7 +34,7 @@ pub(crate) fn find_deployed_commit(sysroot_path: &str) -> Result { } else { bail!("failed to find deployment"); }; - if let Some(_) = lines.next() { + if lines.next().is_some() { bail!("multiple deployments found") } Ok(deployment) diff --git a/src/sha512string.rs b/src/sha512string.rs index b8de12edb..1e35f468b 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -26,7 +26,7 @@ impl SHA512String { } pub(crate) fn digest_bs58(&self) -> &str { - self.0.splitn(2, ":").next().unwrap() + self.0.splitn(2, ':').next().unwrap() } pub(crate) fn digest_bytes(&self) -> Vec { From ded61b35c104a8dbfada855122575fe7f0b06ed2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 01:34:02 +0000 Subject: [PATCH 014/641] Split out an efi module Some more cleanup to reduce the `bootupd.rs` size. --- src/bootupd.rs | 45 +++++++++++++-------------------------------- src/efi.rs | 27 +++++++++++++++++++++++++++ src/util.rs | 4 ++++ 3 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 src/efi.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 8c6f12cdc..c9ffae4e8 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -12,6 +12,8 @@ use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; +#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +mod efi; mod filetree; use filetree::*; mod model; @@ -23,9 +25,6 @@ mod util; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. pub(crate) const STATEFILE_PATH: &str = "boot/rpmostree-bootupd-state.json"; -/// The path to the ESP mount -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub(crate) const EFI_MOUNT: &str = "boot/efi"; /// Where rpm-ostree rewrites data that goes in /boot pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; @@ -71,45 +70,23 @@ struct StatusOptions { #[structopt(name = "boot-update")] #[structopt(rename_all = "kebab-case")] enum Opt { - /// Install data into the EFI System Partition + /// Install data from available components into a disk image Install { /// Physical root mountpoint #[structopt(long)] sysroot: String, }, - /// Start tracking current data found in the EFI System Partition + /// Start tracking current data found in available components Adopt { /// Physical root mountpoint #[structopt(long)] sysroot: String, }, - /// Update the EFI System Partition + /// Update available components Update(UpdateOptions), Status(StatusOptions), } -fn running_in_test_suite() -> bool { - !nix::unistd::getuid().is_root() -} - -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -pub(crate) fn validate_esp>(mnt: P) -> Result<()> { - if running_in_test_suite() { - return Ok(()); - } - let mnt = mnt.as_ref(); - let stat = nix::sys::statfs::statfs(mnt)?; - let fstype = stat.filesystem_type(); - if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { - bail!( - "Mount {} is not a msdos filesystem, but is {:?}", - mnt.display(), - fstype - ); - }; - Ok(()) -} - pub(crate) fn install(sysroot_path: &str) -> Result<()> { let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; @@ -121,8 +98,8 @@ pub(crate) fn install(sysroot_path: &str) -> Result<()> { bail!("{:?} already exists, cannot re-install", statepath); } - let bootefi = Path::new(sysroot_path).join(EFI_MOUNT); - validate_esp(&bootefi)?; + let bootefi = Path::new(sysroot_path).join(efi::MOUNT_PATH); + efi::validate_esp(&bootefi)?; Ok(()) } @@ -226,7 +203,9 @@ fn update(opts: &UpdateOptions) -> Result<()> { let src = sysroot_dir .sub_dir(&Path::new(OSTREE_BOOT_DATA).join("efi")) .context("opening ostree boot data")?; - let dest = sysroot_dir.sub_dir(EFI_MOUNT).context(EFI_MOUNT)?; + let dest = sysroot_dir + .sub_dir(efi::MOUNT_PATH) + .context(efi::MOUNT_PATH)?; let updated_component = update_component_filesystem_at(saved, &src, &dest, update) .with_context(|| format!("updating component {:?}", ctype))?; @@ -365,7 +344,9 @@ fn compute_status_efi( saved_components: Option<&SavedState>, ) -> Result { let sysroot_dir = openat::Dir::open(sysroot_path)?; - let espdir = sysroot_dir.sub_dir(EFI_MOUNT).context(EFI_MOUNT)?; + let espdir = sysroot_dir + .sub_dir(efi::MOUNT_PATH) + .context(efi::MOUNT_PATH)?; let esptree = FileTree::new_from_dir(&espdir).context("computing filetree for efi")?; let saved = saved_components .map(|s| s.components.get(&ComponentType::EFI)) diff --git a/src/efi.rs b/src/efi.rs new file mode 100644 index 000000000..9abe4bcf0 --- /dev/null +++ b/src/efi.rs @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::{bail, Result}; + +/// The path to the ESP mount +pub(crate) const MOUNT_PATH: &str = "boot/efi"; + +pub(crate) fn validate_esp>(mnt: P) -> Result<()> { + if crate::util::running_in_test_suite() { + return Ok(()); + } + let mnt = mnt.as_ref(); + let stat = nix::sys::statfs::statfs(mnt)?; + let fstype = stat.filesystem_type(); + if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { + bail!( + "Mount {} is not a msdos filesystem, but is {:?}", + mnt.display(), + fstype + ); + }; + Ok(()) +} diff --git a/src/util.rs b/src/util.rs index e861ba8f3..e2d9e9ce3 100644 --- a/src/util.rs +++ b/src/util.rs @@ -12,3 +12,7 @@ pub(crate) fn getenv_utf8(n: &str) -> Result> { Ok(None) } } + +pub(crate) fn running_in_test_suite() -> bool { + !nix::unistd::getuid().is_root() +} From a528ee04eeca4e3443f451cae31a11cdb618ee77 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 01:45:50 +0000 Subject: [PATCH 015/641] Drop rpm-ostree from statefile path Now that this is split out. --- src/bootupd.rs | 2 +- src/model.rs | 23 +++++++++++------------ tests/unpriv-blackbox.sh | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index c9ffae4e8..ece96a949 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -24,7 +24,7 @@ mod util; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. -pub(crate) const STATEFILE_PATH: &str = "boot/rpmostree-bootupd-state.json"; +pub(crate) const STATEFILE_PATH: &str = "boot/bootupd-state.json"; /// Where rpm-ostree rewrites data that goes in /boot pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; diff --git a/src/model.rs b/src/model.rs index 0630de88d..97d2f303f 100644 --- a/src/model.rs +++ b/src/model.rs @@ -108,7 +108,6 @@ pub(crate) struct SavedPendingUpdate { pub(crate) timestamp: NaiveDateTime, } -/// Will be serialized into /boot/rpmostree-bootupd-state.json #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "kebab-case")] pub(crate) struct SavedComponent { @@ -119,23 +118,23 @@ pub(crate) struct SavedComponent { pub(crate) pending: Option, } -/// Will be serialized into /boot/rpmostree-bootupd-state.json +/// Will be serialized into /boot/bootupd-state.json #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] pub(crate) struct SavedState { pub(crate) components: BTreeMap, } -/// Should be stored in /usr/lib/rpm-ostree/bootupdate-edge.json -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct UpgradeEdge { - /// Set to true if we should upgrade from an unknown state - #[serde(default)] - pub(crate) from_unknown: bool, - /// Upgrade from content past this timestamp - pub(crate) from_timestamp: Option, -} +// Should be stored in /usr/lib/bootupd/edges.json +//#[derive(Serialize, Deserialize, Debug)] +// #[serde(rename_all = "kebab-case")] +// pub(crate) struct UpgradeEdge { +// /// Set to true if we should upgrade from an unknown state +// #[serde(default)] +// pub(crate) from_unknown: bool, +// /// Upgrade from content past this timestamp +// pub(crate) from_timestamp: Option, +// } impl InstalledContent { pub(crate) fn from_file_tree(ft: FileTree) -> InstalledContent { diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh index b90a7f4af..689a3739d 100755 --- a/tests/unpriv-blackbox.sh +++ b/tests/unpriv-blackbox.sh @@ -113,7 +113,7 @@ assert_file_has_content_literal out.txt 'Update: At latest version' ok 'adoption status' # Re-initialize and adopt with extra state -rm -v root/boot/rpmostree-bootupd-state.json +rm -v root/boot/bootupd-state.json initefiroot "${bootefi}" initefiroot "${ostefi}" From 8dbf405381bf7abf7e333bf82d3f820a1a65227a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 14:12:03 +0000 Subject: [PATCH 016/641] Use saved state for digest, add drift test --- src/bootupd.rs | 7 +------ tests/unpriv-blackbox.sh | 7 +++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index ece96a949..efb5ab1dc 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -381,18 +381,13 @@ fn compute_status_efi( // TODO detect state outside of filesystem tree false }; - let digest = if saved.adopted && !drift { - saved.digest.clone() - } else { - content.digest.clone() - }; ( ComponentInstalled::Tracked { disk: content, saved: saved.clone(), drift, }, - digest, + saved.digest.clone(), ) }; let installed_tree = installed.get_disk_content().filesystem.as_ref().unwrap(); diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh index 689a3739d..9d8b40505 100755 --- a/tests/unpriv-blackbox.sh +++ b/tests/unpriv-blackbox.sh @@ -112,6 +112,13 @@ assert_file_has_content_literal out.txt ' Adopted: true' assert_file_has_content_literal out.txt 'Update: At latest version' ok 'adoption status' +echo 'oops state drift' >> "${bootefi}"/EFI/fedora/shimx64.efi +bootupd status --sysroot=root --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'warning: drift detected' +assert_file_has_content_literal out.txt 'Recorded: '${v0_digest} +assert_file_has_content_literal out.txt 'Actual: sha512:5Dfb6bjpfgxMN1KDAmNFnbzcQxZidiCwdZHwgQrdTrUZvExHrMCKoEnQ9muTowVkW7t4QJHve1APpwa6dLi5WDKF' +ok 'drift detected' + # Re-initialize and adopt with extra state rm -v root/boot/bootupd-state.json initefiroot "${bootefi}" From f6a53bbafc5c74811cee15cb1861e412ef8f74bf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 14:22:33 +0000 Subject: [PATCH 017/641] Use OsString when generating filenames Removes some assertions around UTF-8, dropping unwrap/expect. --- src/bootupd.rs | 7 ++++++- src/filetree.rs | 9 +++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index efb5ab1dc..32a11d281 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -237,7 +237,12 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { buff.into_inner()? }; let dest = Path::new(STATEFILE_PATH); - let dest_tmp_name = format!("{}.tmp", dest.file_name().unwrap().to_str().unwrap()); + let dest_tmp_name = { + // expect OK because we just created the filename above from a constant + let mut buf = dest.file_name().expect("filename").to_os_string(); + buf.push(".tmp"); + buf + }; let dest_tmp = dest.with_file_name(dest_tmp_name); sysroot_dir.link_file_at(&f, &dest_tmp)?; f.sync_all()?; diff --git a/src/filetree.rs b/src/filetree.rs index 2430583f3..2b701157e 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -258,12 +258,9 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { fn tmpname_for_path>(path: P) -> std::path::PathBuf { let path = path.as_ref(); - let basename = path.file_name().expect("filename"); - path.with_file_name(format!( - "{}{}", - TMP_PREFIX, - basename.to_str().expect("UTF-8 filename") - )) + let mut buf = path.file_name().expect("filename").to_os_string(); + buf.push(TMP_PREFIX); + path.with_file_name(buf) } /// Given two directories, apply a diff generated from srcdir to destdir From 8a2824a1c466a7c6826f99f00cfa2615b5797dfd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 18:42:12 +0000 Subject: [PATCH 018/641] Add systemd unit, fix state saving Also add a lock file to protect the system against admins running bootupd concurrently. This gets us running when run as root in FCOS. --- .gitignore | 1 + Cargo.toml | 1 + Makefile | 25 +++++++++++++++++++++++ src/bootupd.rs | 44 ++++++++++++++++++++++++++++++----------- systemd/bootupd.service | 11 +++++++++++ 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 Makefile create mode 100644 systemd/bootupd.service diff --git a/.gitignore b/.gitignore index 96ef6c0b9..7393c06ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +fastbuild*.qcow2 diff --git a/Cargo.toml b/Cargo.toml index ce3970e9c..32ea42fce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ serde_derive = "1.0.112" serde_json = "1.0" serde_yaml = "0.8" libc = "0.2" +fs2 = "0.4.3" nix = "0.17.0" glib-sys = "0.9.1" gio-sys = "0.9.1" diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..c271db6c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +DESTDIR ?= +PREFIX ?= /usr +RELEASE ?= 1 + +ifeq ($(RELEASE),1) + PROFILE ?= release + CARGO_ARGS = --release +else + PROFILE ?= debug + CARGO_ARGS = +endif + +units = $(addprefix systemd/, bootupd.service) + +.PHONY: all +all: $(units) + cargo build ${CARGO_ARGS} + +.PHONY: install-units +install-units: $(units) + for unit in $(units); do install -D -m 644 --target-directory=$(DESTDIR)$(PREFIX)/lib/systemd/system/ $$unit; done + +.PHONY: install +install: install-units + install -D -t ${DESTDIR}$(PREFIX)/bin target/${PROFILE}/bootupd diff --git a/src/bootupd.rs b/src/bootupd.rs index 32a11d281..86a546a68 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -5,6 +5,7 @@ */ use anyhow::{bail, Context, Result}; +use fs2::FileExt; use gio::NONE_CANCELLABLE; use openat_ext::OpenatDirExt; use std::collections::{BTreeMap, BTreeSet, HashSet}; @@ -23,8 +24,10 @@ mod sha512string; mod util; /// Stored in /boot to describe our state; think of it like -/// a tiny rpm/dpkg database. -pub(crate) const STATEFILE_PATH: &str = "boot/bootupd-state.json"; +/// a tiny rpm/dpkg database. It's stored in /boot +pub(crate) const STATEFILE_DIR: &str = "boot"; +pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; +pub(crate) const WRITE_LOCK_PATH: &str = "/run/bootupd-lock"; /// Where rpm-ostree rewrites data that goes in /boot pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; @@ -79,7 +82,7 @@ enum Opt { /// Start tracking current data found in available components Adopt { /// Physical root mountpoint - #[structopt(long)] + #[structopt(default_value = "/", long)] sysroot: String, }, /// Update available components @@ -93,7 +96,9 @@ pub(crate) fn install(sysroot_path: &str) -> Result<()> { let _commit = ostreeutil::find_deployed_commit(sysroot_path)?; - let statepath = Path::new(sysroot_path).join(STATEFILE_PATH); + let statepath = Path::new(sysroot_path) + .join(STATEFILE_DIR) + .join(STATEFILE_NAME); if statepath.exists() { bail!("{:?} already exists, cannot re-install", statepath); } @@ -140,7 +145,19 @@ fn parse_componentlist(components: &[String]) -> Result Result { + let mut lockf = std::fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(WRITE_LOCK_PATH)?; + lockf.lock_exclusive()?; + writeln!(&mut lockf, "Acquired by pid {}", nix::unistd::getpid())?; + Ok(lockf) +} + fn update(opts: &UpdateOptions) -> Result<()> { + let _lockf = acquire_write_lock()?; let (status, mut new_saved_state) = compute_status(&opts.sysroot).context("computing status")?; let sysroot_dir = openat::Dir::open(opts.sysroot.as_str()) @@ -229,28 +246,32 @@ fn update(opts: &UpdateOptions) -> Result<()> { } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { + let subdir = sysroot_dir.sub_dir(STATEFILE_DIR)?; let f = { - let f = sysroot_dir.new_unnamed_file(0o644)?; + let f = subdir.new_unnamed_file(0o644)?; let mut buff = std::io::BufWriter::new(f); serde_json::to_writer(&mut buff, state)?; buff.flush()?; buff.into_inner()? }; - let dest = Path::new(STATEFILE_PATH); let dest_tmp_name = { // expect OK because we just created the filename above from a constant - let mut buf = dest.file_name().expect("filename").to_os_string(); + let mut buf = std::ffi::OsString::from(STATEFILE_NAME); buf.push(".tmp"); buf }; - let dest_tmp = dest.with_file_name(dest_tmp_name); - sysroot_dir.link_file_at(&f, &dest_tmp)?; + let dest_tmp_name = Path::new(&dest_tmp_name); + if subdir.exists(dest_tmp_name)? { + subdir.remove_file(dest_tmp_name)?; + } + subdir.link_file_at(&f, dest_tmp_name)?; f.sync_all()?; - sysroot_dir.local_rename(&dest_tmp, dest)?; + subdir.local_rename(dest_tmp_name, STATEFILE_NAME)?; Ok(()) } fn adopt(sysroot_path: &str) -> Result<()> { + let _lockf = acquire_write_lock()?; let (status, saved_state) = compute_status(sysroot_path)?; let mut adopted = std::collections::BTreeSet::new(); let mut saved_state = saved_state.unwrap_or_else(|| SavedState { @@ -425,7 +446,8 @@ fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { let sysroot_dir = openat::Dir::open(sysroot_path) .with_context(|| format!("opening sysroot {}", sysroot_path))?; - let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(STATEFILE_PATH)? { + let statefile_path = Path::new(STATEFILE_DIR).join(STATEFILE_NAME); + let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(&statefile_path)? { let bufr = std::io::BufReader::new(statusf); let saved_state: SavedState = serde_json::from_reader(bufr)?; Some(saved_state) diff --git a/systemd/bootupd.service b/systemd/bootupd.service new file mode 100644 index 000000000..822f4a25c --- /dev/null +++ b/systemd/bootupd.service @@ -0,0 +1,11 @@ +[Unit] +Description=EFI Bootloader Update +# Hardcoded to only update EFI right now +ConditionDirectoryNotEmpty=/sys/firmware/efi + +[Service] +Type=oneshot +ExecStart=/usr/libexec/bootupd update EFI + +[Install] +WantedBy=multi-user.target From 37c2f166f656d0d4050e47aa6936d205a7e96f80 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 19:20:44 +0000 Subject: [PATCH 019/641] Store lockfile correctly in sysroot --- src/bootupd.rs | 11 ++++++----- tests/unpriv-blackbox.sh | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 86a546a68..a8c1e6401 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -27,7 +27,7 @@ mod util; /// a tiny rpm/dpkg database. It's stored in /boot pub(crate) const STATEFILE_DIR: &str = "boot"; pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; -pub(crate) const WRITE_LOCK_PATH: &str = "/run/bootupd-lock"; +pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; /// Where rpm-ostree rewrites data that goes in /boot pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; @@ -145,19 +145,20 @@ fn parse_componentlist(components: &[String]) -> Result Result { +fn acquire_write_lock>(sysroot: P) -> Result { + let sysroot = sysroot.as_ref(); let mut lockf = std::fs::OpenOptions::new() .read(true) .write(true) .create(true) - .open(WRITE_LOCK_PATH)?; + .open(sysroot.join(WRITE_LOCK_PATH))?; lockf.lock_exclusive()?; writeln!(&mut lockf, "Acquired by pid {}", nix::unistd::getpid())?; Ok(lockf) } fn update(opts: &UpdateOptions) -> Result<()> { - let _lockf = acquire_write_lock()?; + let _lockf = acquire_write_lock(opts.sysroot.as_str())?; let (status, mut new_saved_state) = compute_status(&opts.sysroot).context("computing status")?; let sysroot_dir = openat::Dir::open(opts.sysroot.as_str()) @@ -271,7 +272,7 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { } fn adopt(sysroot_path: &str) -> Result<()> { - let _lockf = acquire_write_lock()?; + let _lockf = acquire_write_lock(sysroot_path)?; let (status, saved_state) = compute_status(sysroot_path)?; let mut adopted = std::collections::BTreeSet::new(); let mut saved_state = saved_state.unwrap_or_else(|| SavedState { diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh index 9d8b40505..3752629aa 100755 --- a/tests/unpriv-blackbox.sh +++ b/tests/unpriv-blackbox.sh @@ -29,6 +29,7 @@ bootupd() { runv ${dn}/../target/release/bootupd "$@" } +mkdir -p root/run bootefi=root/boot/efi ostefi=root/usr/lib/ostree-boot/efi initefiroot() { From e3ff407f9e9b6553c26e92388d61d8af698a455a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 22:01:43 +0000 Subject: [PATCH 020/641] Run inside FCOS with kola test --- .gitignore | 1 + Makefile | 2 +- README-devel.md | 16 ++++++++++++++++ tests/kola/data | 1 + tests/kola/test-bootupd | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 README-devel.md create mode 120000 tests/kola/data create mode 100755 tests/kola/test-bootupd diff --git a/.gitignore b/.gitignore index 7393c06ae..d02d3a0e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target Cargo.lock fastbuild*.qcow2 +_kola_temp diff --git a/Makefile b/Makefile index c271db6c5..dc1be15a3 100644 --- a/Makefile +++ b/Makefile @@ -22,4 +22,4 @@ install-units: $(units) .PHONY: install install: install-units - install -D -t ${DESTDIR}$(PREFIX)/bin target/${PROFILE}/bootupd + install -D -t ${DESTDIR}$(PREFIX)/libexec target/${PROFILE}/bootupd diff --git a/README-devel.md b/README-devel.md new file mode 100644 index 000000000..e7057c360 --- /dev/null +++ b/README-devel.md @@ -0,0 +1,16 @@ +# Developing bootupd + +Currently the focus is Fedora CoreOS. + +You can use the normal Rust tools to build and run the unit tests: + +`cargo build` and `cargo test` + +For real e2e testing, use e.g. +``` +export COSA_DIR=/path/to/fcos +cosa build-fast +kola run -E (pwd) --qemu-image fastbuild-fedora-coreos-bootupd-qemu.qcow2 --qemu-firmware uefi ext.bootupd +``` + +See also [the coreos-assembler docs](https://github.com/coreos/coreos-assembler/blob/master/README-devel.md#using-overrides). \ No newline at end of file diff --git a/tests/kola/data b/tests/kola/data new file mode 120000 index 000000000..a96aa0ea9 --- /dev/null +++ b/tests/kola/data @@ -0,0 +1 @@ +.. \ No newline at end of file diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd new file mode 100755 index 000000000..4309f4520 --- /dev/null +++ b/tests/kola/test-bootupd @@ -0,0 +1,33 @@ +#!/bin/bash +set -xeuo pipefail + +. ${KOLA_EXT_DATA}/libtest.sh + +tmpdir=$(mktemp -d) +cd ${tmpdir} +echo "using tmpdir: ${tmpdir}" +touch .testtmp +trap cleanup EXIT +function cleanup () { + if test -z "${TEST_SKIP_CLEANUP:-}"; then + if test -f "${tmpdir}"/.testtmp; then + cd / + rm "${tmpdir}" -rf + fi + else + echo "Skipping cleanup of ${tmpdir}" + fi +} + +# Shouldn't be started by default right now; distributions +# should only enable when it was used at build time. +runv systemctl show bootupd > out.txt +assert_file_has_content_literal out.txt 'ActiveState=inactive' + +runv /usr/libexec/bootupd status --component=EFI > out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Unmanaged: digest=' +assert_not_file_has_content_literal out.txt 'Update: Available:' + +ok bootupd status +tap_finish From b5ffe137365d43a71a1a2267b7852a4db258669d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Jun 2020 23:53:23 +0000 Subject: [PATCH 021/641] tests/kola: Extend a bit --- tests/kola/test-bootupd | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 4309f4520..ab39ba170 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,15 +19,46 @@ function cleanup () { fi } +efidir=/boot/efi/EFI/fedora + +bootupd() { + runv /usr/libexec/bootupd "$@" +} + # Shouldn't be started by default right now; distributions # should only enable when it was used at build time. runv systemctl show bootupd > out.txt assert_file_has_content_literal out.txt 'ActiveState=inactive' -runv /usr/libexec/bootupd status --component=EFI > out.txt +bootupd status --component=EFI > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Unmanaged: digest=' assert_not_file_has_content_literal out.txt 'Update: Available:' -ok bootupd status +if bootupd update EFI 2>err.txt; then + fatal "performed an update without adopting" +fi +assert_file_has_content_literal err.txt 'Component EFI is not tracked and must be adopted before update' +ok 'cannot update without adoption' + +bootupd adopt | tee out.txt +assert_file_has_content_literal out.txt "Adopting: EFI" +ok 'adoption' + +bootupd adopt | tee out.txt +assert_not_file_has_content_literal out.txt "Adopting: EFI" +assert_file_has_content_literal out.txt "Nothing to do" +ok 'rerunning adopt is idempotent' + +cp --reflink=auto ${efidir}/shimx64.efi . +echo 'oops state drift' >> ${efidir}/shimx64.efi +bootupd status --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'warning: drift detected' +assert_file_has_content_literal out.txt 'Recorded: ' +assert_file_has_content_literal out.txt 'Actual: sha512:' +mv shimx64.efi ${efidir}/shimx64.efi +bootupd status --component=EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'warning: drift detected' +ok 'drift detected' + tap_finish From 54adb363091bea2331ab6d50b70d048f929449dd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 13:03:30 +0000 Subject: [PATCH 022/641] Add a socket and daemon We really should run consistently as a daemon in the update case. This doesn't change the main functionality yet. --- Cargo.toml | 1 + Makefile | 2 +- src/bootupd.rs | 50 +++++++++++++++++++++++++++++++++++++++++ systemd/bootupd.service | 11 +++------ systemd/bootupd.socket | 9 ++++++++ 5 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 systemd/bootupd.socket diff --git a/Cargo.toml b/Cargo.toml index 32ea42fce..e294df6d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ structopt = "0.3" openat = "0.1.19" openat-ext = "0.1.0" openssl = "^0.10" +libsystemd = "^0.2" hex = "0.4.2" bs58 = "0.3.1" byteorder = "1" diff --git a/Makefile b/Makefile index dc1be15a3..74b964747 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ else CARGO_ARGS = endif -units = $(addprefix systemd/, bootupd.service) +units = $(addprefix systemd/, bootupd.service bootupd.socket) .PHONY: all all: $(units) diff --git a/src/bootupd.rs b/src/bootupd.rs index a8c1e6401..abc9aae02 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -23,6 +23,7 @@ mod ostreeutil; mod sha512string; mod util; +pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. It's stored in /boot pub(crate) const STATEFILE_DIR: &str = "boot"; @@ -88,6 +89,8 @@ enum Opt { /// Update available components Update(UpdateOptions), Status(StatusOptions), + Daemon, + PingDaemon, } pub(crate) fn install(sysroot_path: &str) -> Result<()> { @@ -570,6 +573,51 @@ fn status(opts: &StatusOptions) -> Result<()> { Ok(()) } +fn daemon() -> Result<()> { + use libsystemd::daemon::{self, NotifyState}; + use nix::sys::socket as nixsocket; + use std::os::unix::io::IntoRawFd; + use nix::sys::uio::IoVec; + if !daemon::booted() { + bail!("Not running systemd") + } + let mut fds = libsystemd::activation::receive_descriptors(true) + .map_err(|e| anyhow::anyhow!("Failed to receieve systemd descriptors: {}", e))?; + let srvsock_fd = if let Some(fd) = fds.pop() { + fd + } else { + bail!("No fd passed from systemd"); + }; + let srvsock_fd = srvsock_fd.into_raw_fd(); + let sent = daemon::notify(true, &[NotifyState::Ready]).expect("notify failed"); + if !sent { + bail!("Failed to notify systemd"); + } + let mut buf = [0u8; 1024]; + loop { + let fd = nixsocket::accept4(srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC)?; + dbg!("got connection"); + let iov = IoVec::from_mut_slice(buf.as_mut()); + let r = nixsocket::recvmsg(fd, &[iov], None, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + dbg!(String::from_utf8_lossy(&buf[0..r.bytes])); + } +} + +fn ping_daemon() -> Result<()> { + use nix::sys::socket as nixsocket; + let sock = nixsocket::socket( + nixsocket::AddressFamily::Unix, + nixsocket::SockType::SeqPacket, + nixsocket::SockFlag::SOCK_CLOEXEC, + None, + )?; + let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; + nixsocket::connect(sock, &addr)?; + nixsocket::send(sock, "ping".as_bytes(), nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + + Ok(()) +} + /// Main entrypoint #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub fn boot_update_main(args: &[String]) -> Result<()> { @@ -579,6 +627,8 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { Opt::Adopt { sysroot } => adopt(&sysroot)?, Opt::Update(ref opts) => update(opts)?, Opt::Status(ref opts) => status(opts)?, + Opt::Daemon => daemon()?, + Opt::PingDaemon => ping_daemon()?, }; Ok(()) } diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 822f4a25c..45491e7d2 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -1,11 +1,6 @@ [Unit] -Description=EFI Bootloader Update -# Hardcoded to only update EFI right now -ConditionDirectoryNotEmpty=/sys/firmware/efi +Description=bootloader update daemon [Service] -Type=oneshot -ExecStart=/usr/libexec/bootupd update EFI - -[Install] -WantedBy=multi-user.target +Type=notify +ExecStart=/usr/libexec/bootupd daemon diff --git a/systemd/bootupd.socket b/systemd/bootupd.socket new file mode 100644 index 000000000..7f8f558c0 --- /dev/null +++ b/systemd/bootupd.socket @@ -0,0 +1,9 @@ +[Unit] +ConditionDirectoryNotEmpty=/sys/firmware/efi + +[Socket] +ListenSequentialPacket=/run/bootupd.sock +SocketMode=0600 + +[Install] +WantedBy=sockets.target From c6bf680e986cc760af154faf41c64db691fec301 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 13:29:15 +0000 Subject: [PATCH 023/641] tests: Extend with updates --- tests/kola/test-bootupd | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ab39ba170..056345495 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,7 +19,15 @@ function cleanup () { fi } -efidir=/boot/efi/EFI/fedora +efibasedir=/boot/efi/ +ostbaseefi=/usr/lib/ostree-boot/efi/ +efisubdir=EFI/fedora +efidir=${efibasedir}/${efisubdir} +ostefi=${ostbaseefi}/${efisubdir} +shim=shimx64.efi + +test -f "${efidir}"/${shim} +test -f "${ostefi}"/${shim} bootupd() { runv /usr/libexec/bootupd "$@" @@ -50,15 +58,44 @@ assert_not_file_has_content_literal out.txt "Adopting: EFI" assert_file_has_content_literal out.txt "Nothing to do" ok 'rerunning adopt is idempotent' -cp --reflink=auto ${efidir}/shimx64.efi . +cp --reflink=auto ${efidir}/${shim} shimx64.backup echo 'oops state drift' >> ${efidir}/shimx64.efi bootupd status --component=EFI | tee out.txt assert_file_has_content_literal out.txt 'warning: drift detected' assert_file_has_content_literal out.txt 'Recorded: ' assert_file_has_content_literal out.txt 'Actual: sha512:' -mv shimx64.efi ${efidir}/shimx64.efi +mv shimx64.backup ${efidir}/shimx64.efi bootupd status --component=EFI | tee out.txt assert_not_file_has_content_literal out.txt 'warning: drift detected' ok 'drift detected' +# TODO do better tests that +rpm-ostree usroverlay + +bootupd status --component=EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'Update: Available' +cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup +echo 'updated shimx64.efi' > ${ostefi}/${shim} +bootupd status --component=EFI | tee out.txt +assert_file_has_content_literal out.txt 'Update: Available' +cp --reflink=auto shimx64.efi.backup ${ostefi}/${shim} +bootupd status --component=EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'Update: Available' +ok 'update available' + +bootupd status --component=EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'Update: Available' +cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup +echo 'updated shimx64.efi' > ${ostefi}/${shim} +bootupd update EFI +assert_file_has_content_literal out.txt 'EFI: Updated to digest=' +assert_not_file_has_content_literal out.txt 'EFI: no updates available' +bootupd status --component=EFI | tee out.txt +assert_not_file_has_content_literal out.txt 'warning: drift detected' +assert_not_file_has_content_literal out.txt 'Update: Available' +if ! test -f "${bootefi}/grub.cfg"; then + fatal "missing unmanaged grub cfg" +fi +ok 'update' + tap_finish From 2483a19f8f229c30670223a8ad27befbe094e948 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 16:59:52 +0000 Subject: [PATCH 024/641] Drop sysroot bits for update/adopt/status Because we run as a daemon now it doesn't make sense. And drop the old test. --- src/bootupd.rs | 31 +++---- tests/kola/test-bootupd | 4 +- tests/unpriv-blackbox.sh | 169 --------------------------------------- 3 files changed, 12 insertions(+), 192 deletions(-) delete mode 100755 tests/unpriv-blackbox.sh diff --git a/src/bootupd.rs b/src/bootupd.rs index abc9aae02..b689dd1fa 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -36,10 +36,6 @@ pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { - /// The system root - #[structopt(default_value = "/", long)] - sysroot: String, - // Perform an update even if there is no state transition #[structopt(long)] force: bool, @@ -58,10 +54,6 @@ struct UpdateOptions { #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] struct StatusOptions { - /// System root - #[structopt(default_value = "/", long)] - sysroot: String, - #[structopt(long = "component")] components: Option>, @@ -77,15 +69,10 @@ enum Opt { /// Install data from available components into a disk image Install { /// Physical root mountpoint - #[structopt(long)] sysroot: String, }, /// Start tracking current data found in available components - Adopt { - /// Physical root mountpoint - #[structopt(default_value = "/", long)] - sysroot: String, - }, + Adopt, /// Update available components Update(UpdateOptions), Status(StatusOptions), @@ -161,11 +148,12 @@ fn acquire_write_lock>(sysroot: P) -> Result { } fn update(opts: &UpdateOptions) -> Result<()> { - let _lockf = acquire_write_lock(opts.sysroot.as_str())?; + let sysroot = "/"; + let _lockf = acquire_write_lock(sysroot)?; let (status, mut new_saved_state) = - compute_status(&opts.sysroot).context("computing status")?; - let sysroot_dir = openat::Dir::open(opts.sysroot.as_str()) - .with_context(|| format!("opening sysroot {}", opts.sysroot))?; + compute_status(sysroot).context("computing status")?; + let sysroot_dir = openat::Dir::open(sysroot) + .with_context(|| format!("opening sysroot {}", sysroot))?; let specified_components = parse_componentlist(&opts.components)?; for (ctype, component) in status.components.iter() { @@ -274,7 +262,8 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { Ok(()) } -fn adopt(sysroot_path: &str) -> Result<()> { +fn adopt() -> Result<()> { + let sysroot_path = "/"; let _lockf = acquire_write_lock(sysroot_path)?; let (status, saved_state) = compute_status(sysroot_path)?; let mut adopted = std::collections::BTreeSet::new(); @@ -546,7 +535,7 @@ fn print_component(component: &Component) { } fn status(opts: &StatusOptions) -> Result<()> { - let (status, _) = compute_status(&opts.sysroot)?; + let (status, _) = compute_status("/")?; if opts.json { serde_json::to_writer_pretty(std::io::stdout(), &status)?; } else if !status.supported_architecture { @@ -624,7 +613,7 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { let opt = Opt::from_iter(args.iter()); match opt { Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, - Opt::Adopt { sysroot } => adopt(&sysroot)?, + Opt::Adopt => adopt()?, Opt::Update(ref opts) => update(opts)?, Opt::Status(ref opts) => status(opts)?, Opt::Daemon => daemon()?, diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 056345495..4233ecb93 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -87,13 +87,13 @@ bootupd status --component=EFI | tee out.txt assert_not_file_has_content_literal out.txt 'Update: Available' cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup echo 'updated shimx64.efi' > ${ostefi}/${shim} -bootupd update EFI +bootupd update EFI | tee out.txt assert_file_has_content_literal out.txt 'EFI: Updated to digest=' assert_not_file_has_content_literal out.txt 'EFI: no updates available' bootupd status --component=EFI | tee out.txt assert_not_file_has_content_literal out.txt 'warning: drift detected' assert_not_file_has_content_literal out.txt 'Update: Available' -if ! test -f "${bootefi}/grub.cfg"; then +if ! test -f "${efidir}/grub.cfg"; then fatal "missing unmanaged grub cfg" fi ok 'update' diff --git a/tests/unpriv-blackbox.sh b/tests/unpriv-blackbox.sh deleted file mode 100755 index 3752629aa..000000000 --- a/tests/unpriv-blackbox.sh +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2020 Colin Walters -# -# SPDX-License-Identifier: Apache-2.0 - -set -euo pipefail -dn=$(cd $(dirname $0) && pwd) - -. ${dn}/libtest.sh - -tmpdir=$(mktemp -d) -cd ${tmpdir} -echo "using tmpdir: ${tmpdir}" -touch .testtmp -trap cleanup EXIT -function cleanup () { - if test -z "${TEST_SKIP_CLEANUP:-}"; then - if test -f "${tmpdir}"/.testtmp; then - cd / - rm "${tmpdir}" -rf - fi - else - echo "Skipping cleanup of ${tmpdir}" - fi -} - -bootupd() { - runv ${dn}/../target/release/bootupd "$@" -} - -mkdir -p root/run -bootefi=root/boot/efi -ostefi=root/usr/lib/ostree-boot/efi -initefiroot() { - d=$1 - shift - echo "Initializing EFI root $d" - rm "${d}" -rf - mkdir -p "${d}" - (cd ${d} - mkdir -p EFI/fedora - cd EFI/fedora - echo unchanging > shouldnotchange.efi - echo unchanging2 > shouldnotchange2.efi - for x in grubx64.efi shim.efi shimx64.efi; do - echo "some code for ${x}" > ${x} - done - ) -} - -v0_digest="sha512:2rLmU783U9VowCdmCDpBdvdQV7N751vhz3d3kMYCDS9FdufhUkCX5Gf66Yia1UcTwYAXHcudR7D5tmGUcTt5hqBZ" - -validate_v0() { - bootupd status --sysroot=root --component=EFI | tee out.txt - assert_file_has_content_literal out.txt 'Component EFI' - assert_file_has_content_literal out.txt ' Unmanaged: digest='${v0_digest} - assert_not_file_has_content_literal out.txt 'Update: Available: ' - assert_not_file_has_content out.txt 'Component BIOS' -} - -update_shipped() { - local v - v=$1 - shift - for x in grubx64.efi shim.efi shimx64.efi; do - test -f ${ostefi}/EFI/fedora/${x} - echo "version ${v} code for ${x}" > ${ostefi}/EFI/fedora/${x} - done -} - -# This hack avoids us depending on having an ostree sysroot set up for now -export BOOT_UPDATE_TEST_TIMESTAMP=$(date -u --iso-8601=seconds) -initefiroot "${bootefi}" -initefiroot "${ostefi}" -validate_v0 -ok 'first validate' - -bootupd update --sysroot=root | tee out.txt -assert_file_has_content_literal out.txt 'Skipping component EFI which is found but not adopted' -ok 'no changes' - -update_shipped 1 -rm -v ${ostefi}/EFI/fedora/shim.efi -bootupd status --sysroot=root --component=EFI | tee out.txt -validate_v0 -ok 'still no avail changes if unmanaged' - -# Revert back -initefiroot "${ostefi}" -validate_v0 -ok 'revert' - -if bootupd update --sysroot=root EFI 2>err.txt; then - fatal "performed an update without adopting" -fi -assert_file_has_content_literal err.txt 'Component EFI is not tracked and must be adopted before update' -ok cannot update without adoption - -bootupd adopt --sysroot=root | tee out.txt -assert_file_has_content_literal out.txt "Adopting: EFI" -ok 'adoption' - -bootupd adopt --sysroot=root | tee out.txt -assert_not_file_has_content_literal out.txt "Adopting: EFI" -assert_file_has_content_literal out.txt "Nothing to do" -ok 'rerunning adopt is idempotent' - -bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'Component EFI' -assert_file_has_content_literal out.txt ' Installed: '${v0_digest} -assert_file_has_content_literal out.txt ' Adopted: true' -assert_file_has_content_literal out.txt 'Update: At latest version' -ok 'adoption status' - -echo 'oops state drift' >> "${bootefi}"/EFI/fedora/shimx64.efi -bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'warning: drift detected' -assert_file_has_content_literal out.txt 'Recorded: '${v0_digest} -assert_file_has_content_literal out.txt 'Actual: sha512:5Dfb6bjpfgxMN1KDAmNFnbzcQxZidiCwdZHwgQrdTrUZvExHrMCKoEnQ9muTowVkW7t4QJHve1APpwa6dLi5WDKF' -ok 'drift detected' - -# Re-initialize and adopt with extra state -rm -v root/boot/bootupd-state.json -initefiroot "${bootefi}" -initefiroot "${ostefi}" - -v1_digest="sha512:5LjsojQNor5tntzx6KBFxVGL3LjYXGg7imGttnb194J8Zb1j4HVLDMjFiZUi777x6dyx8RFjZe9wpvkdUeLAUoyr" - -echo 'unmanaged grub config' > "${bootefi}"/EFI/fedora/grub.cfg -bootupd adopt --sysroot=root | tee out.txt -assert_file_has_content_literal out.txt "Adopting: EFI" -export BOOT_UPDATE_TEST_TIMESTAMP=$(date -u --iso-8601=seconds) -ok adopt 2 - -bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'Component EFI' -assert_file_has_content_literal out.txt ' Installed: '${v1_digest} -assert_file_has_content_literal out.txt ' Adopted: true' -assert_file_has_content_literal out.txt 'Update: At latest version' -ok 'adoption status 2' - -v2_digest="sha512:4SoabM7zw6x9CsY64u6G9RFbEocVEQfhCDtVKUJeTPgyCUHTfZPKQacJNw5B23LGpFeFKVqABGJVnSzuLNynFscy" - - -update_shipped t2 -bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'Update: Available' -assert_file_has_content_literal out.txt ' Timestamp: '${BOOT_UPDATE_TEST_TIMESTAMP} -assert_file_has_content_literal out.txt ' Digest: '${v2_digest} -assert_file_has_content_literal out.txt ' Diff: changed=3 added=0 removed=1' -ok 'avail update v2' - -bootupd update --sysroot=root EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'warning: drift detected' -assert_file_has_content_literal out.txt 'EFI: Updated to digest='${v2_digest} -if ! test -f "${bootefi}/EFI/fedora/grub.cfg"; then - fatal "missing unmanaged grub cfg" -fi -ok 'update v2' - -bootupd status --sysroot=root --component=EFI | tee out.txt -assert_file_has_content_literal out.txt 'Component EFI' -assert_file_has_content_literal out.txt ' Installed: '${v2_digest} -assert_file_has_content_literal out.txt ' Adopted: true' -assert_file_has_content_literal out.txt 'Update: At latest version' -ok 'update v2 status' - -tap_finish From 9248adc01ca7cff5097caa2574f87ede007e8ba6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 17:02:36 +0000 Subject: [PATCH 025/641] Rename transition file Now that this isn't part of rpm-ostree. --- src/bootupd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index b689dd1fa..6223b3e80 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -42,7 +42,7 @@ struct UpdateOptions { /// The destination ESP mount point #[structopt( - default_value = "/usr/share/rpm-ostree/bootupdate-transition.json", + default_value = "/usr/share/bootd-transitions.json", long )] state_transition_file: String, From e635bfe2c336cd8a871eb078edd82f67973e2a7f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 17:03:27 +0000 Subject: [PATCH 026/641] cargo fmt+clippy --- src/bootupd.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 6223b3e80..75f2a90f9 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -41,10 +41,7 @@ struct UpdateOptions { force: bool, /// The destination ESP mount point - #[structopt( - default_value = "/usr/share/bootd-transitions.json", - long - )] + #[structopt(default_value = "/usr/share/bootd-transitions.json", long)] state_transition_file: String, /// Only upgrade these components @@ -150,10 +147,9 @@ fn acquire_write_lock>(sysroot: P) -> Result { fn update(opts: &UpdateOptions) -> Result<()> { let sysroot = "/"; let _lockf = acquire_write_lock(sysroot)?; - let (status, mut new_saved_state) = - compute_status(sysroot).context("computing status")?; - let sysroot_dir = openat::Dir::open(sysroot) - .with_context(|| format!("opening sysroot {}", sysroot))?; + let (status, mut new_saved_state) = compute_status(sysroot).context("computing status")?; + let sysroot_dir = + openat::Dir::open(sysroot).with_context(|| format!("opening sysroot {}", sysroot))?; let specified_components = parse_componentlist(&opts.components)?; for (ctype, component) in status.components.iter() { @@ -565,8 +561,8 @@ fn status(opts: &StatusOptions) -> Result<()> { fn daemon() -> Result<()> { use libsystemd::daemon::{self, NotifyState}; use nix::sys::socket as nixsocket; - use std::os::unix::io::IntoRawFd; use nix::sys::uio::IoVec; + use std::os::unix::io::IntoRawFd; if !daemon::booted() { bail!("Not running systemd") } @@ -602,7 +598,7 @@ fn ping_daemon() -> Result<()> { )?; let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; nixsocket::connect(sock, &addr)?; - nixsocket::send(sock, "ping".as_bytes(), nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + nixsocket::send(sock, b"ping", nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; Ok(()) } From f3be1de02345902e4a86583e85eba89e77eb0bfd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 17:41:21 +0000 Subject: [PATCH 027/641] Add socket authorization Our socket is mode 0600, but let's require credentials to be passed and validate that the message was sent from uid `0` to double check. --- src/bootupd.rs | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 75f2a90f9..283e70ff3 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -581,15 +581,38 @@ fn daemon() -> Result<()> { let mut buf = [0u8; 1024]; loop { let fd = nixsocket::accept4(srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC)?; - dbg!("got connection"); + nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; let iov = IoVec::from_mut_slice(buf.as_mut()); - let r = nixsocket::recvmsg(fd, &[iov], None, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; - dbg!(String::from_utf8_lossy(&buf[0..r.bytes])); + let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); + let msg = nixsocket::recvmsg( + fd, + &[iov], + Some(&mut cmsgspace), + nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + )?; + let mut uid = None; + for cmsg in msg.cmsgs() { + if let nixsocket::ControlMessageOwned::ScmCredentials(creds) = cmsg { + uid = Some(creds.uid()); + break; + } + } + if let Some(uid) = uid { + if uid != 0 { + eprintln!("Dropping connection from unauthorized uid: {}", uid); + continue; + } + } else { + eprintln!("No SCM rights provided"); + continue; + } + dbg!(String::from_utf8_lossy(&buf[0..msg.bytes])); } } fn ping_daemon() -> Result<()> { use nix::sys::socket as nixsocket; + use nix::sys::uio::IoVec; let sock = nixsocket::socket( nixsocket::AddressFamily::Unix, nixsocket::SockType::SeqPacket, @@ -598,7 +621,20 @@ fn ping_daemon() -> Result<()> { )?; let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; nixsocket::connect(sock, &addr)?; - nixsocket::send(sock, b"ping", nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + let creds = libc::ucred { + pid: nix::unistd::getpid().as_raw(), + uid: nix::unistd::getuid().as_raw(), + gid: nix::unistd::getgid().as_raw(), + }; + let creds = nixsocket::UnixCredentials::from(creds); + let creds = nixsocket::ControlMessage::ScmCredentials(&creds); + nixsocket::sendmsg( + sock, + &[IoVec::from_slice(b"ping")], + &[creds], + nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + None, + )?; Ok(()) } From 9f40c53984261699b13daa5a90956ff13a7dcce6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 19:21:12 +0000 Subject: [PATCH 028/641] README.md: Link systemd-boot --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 3f4621782..bb58518a5 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ updates, but early feedback on the design is appreciated! ## Relationship to other projects +### fwupd + bootupd could be compared to [fwupd](https://github.com/fwupd/fwupd/) which is project that exists today to update hardware device firmware - things not managed by e.g. `apt/zypper/yum/rpm-ostree update` today. @@ -42,3 +44,8 @@ The end result is that a system administrator would have 3 projects to monitor (one for hardware devices and 2 for the bootloader and OS state) but each would be clearly focused on its domain and handle it well. This stands in contrast with e.g. having an RPM `%post` script try to regenerate the BIOS MBR. + +### systemd bootctl + +[systemd bootctl](https://man7.org/linux/man-pages/man1/bootctl.1.html) can update itself; +this project would probably just proxy that if we detect systemd-boot is in use. From a4c46bacb76dc38f91843b9e436427f89f70fa8d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 19:16:47 +0000 Subject: [PATCH 029/641] Rework to have everything run via daemon A bit ugly (manual protocol over bincode, serializing our prints into a string buffer) but gets us closer to where we need to be. --- Cargo.toml | 1 + src/bootupd.rs | 348 +++++++++++++++++++++++++++++----------- tests/kola/test-bootupd | 2 + 3 files changed, 253 insertions(+), 98 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e294df6d4..c22650fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ openat-ext = "0.1.0" openssl = "^0.10" libsystemd = "^0.2" hex = "0.4.2" +bincode = "1.3.1" bs58 = "0.3.1" byteorder = "1" rayon = "1.0" diff --git a/src/bootupd.rs b/src/bootupd.rs index 283e70ff3..20025a89b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -7,9 +7,13 @@ use anyhow::{bail, Context, Result}; use fs2::FileExt; use gio::NONE_CANCELLABLE; +use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; +use serde_derive::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::fmt::Write as WriteFmt; use std::io::prelude::*; +use std::os::unix::io::RawFd; use std::path::Path; use structopt::StructOpt; @@ -24,6 +28,9 @@ mod sha512string; mod util; pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; +pub(crate) const MSGSIZE: usize = 1_048_576; +/// Sent between processes along with SCM credentials +pub(crate) const BOOTUPD_HELLO_MSG: &str = "bootupd-hello\n"; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. It's stored in /boot pub(crate) const STATEFILE_DIR: &str = "boot"; @@ -33,7 +40,7 @@ pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; /// Where rpm-ostree rewrites data that goes in /boot pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; -#[derive(Debug, StructOpt)] +#[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { // Perform an update even if there is no state transition @@ -48,7 +55,7 @@ struct UpdateOptions { components: Vec, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct StatusOptions { #[structopt(long = "component")] @@ -59,7 +66,13 @@ struct StatusOptions { json: bool, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Serialize, Deserialize, StructOpt)] +#[structopt(rename_all = "kebab-case")] +struct AdoptOptions { + components: Vec, +} + +#[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(name = "boot-update")] #[structopt(rename_all = "kebab-case")] enum Opt { @@ -69,12 +82,16 @@ enum Opt { sysroot: String, }, /// Start tracking current data found in available components - Adopt, + Adopt(AdoptOptions), /// Update available components Update(UpdateOptions), Status(StatusOptions), Daemon, - PingDaemon, +} +#[derive(Debug, Serialize, Deserialize)] +enum DaemonToClientReply { + Success(String), + Failure(String), } pub(crate) fn install(sysroot_path: &str) -> Result<()> { @@ -134,17 +151,17 @@ fn parse_componentlist(components: &[String]) -> Result>(sysroot: P) -> Result { let sysroot = sysroot.as_ref(); - let mut lockf = std::fs::OpenOptions::new() + let lockf = std::fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(sysroot.join(WRITE_LOCK_PATH))?; lockf.lock_exclusive()?; - writeln!(&mut lockf, "Acquired by pid {}", nix::unistd::getpid())?; Ok(lockf) } -fn update(opts: &UpdateOptions) -> Result<()> { +fn update(opts: &UpdateOptions) -> Result { + let mut r = String::new(); let sysroot = "/"; let _lockf = acquire_write_lock(sysroot)?; let (status, mut new_saved_state) = compute_status(sysroot).context("computing status")?; @@ -184,10 +201,12 @@ fn update(opts: &UpdateOptions) -> Result<()> { ctype ); } else { - println!( + writeln!( + r, "Skipping component {:?} which is found but not adopted", ctype - ); + ) + .unwrap(); continue; } } @@ -200,7 +219,7 @@ fn update(opts: &UpdateOptions) -> Result<()> { if let Some(update) = component.update.as_ref() { match update { ComponentUpdate::LatestUpdateInstalled => { - println!("{:?}: At the latest version", component.ctype); + writeln!(r, "{:?}: At the latest version", component.ctype).unwrap(); } ComponentUpdate::Available(update) => match &component.ctype { // Yeah we need to have components be a trait with methods like update() @@ -219,7 +238,7 @@ fn update(opts: &UpdateOptions) -> Result<()> { .components .insert(ComponentType::EFI, updated_component); update_state(&sysroot_dir, new_saved_state)?; - println!("{:?}: Updated to digest={}", ctype, updated_digest); + writeln!(r, "{:?}: Updated to digest={}", ctype, updated_digest).unwrap(); } ctype => { panic!("Unhandled update for component {:?}", ctype); @@ -227,10 +246,10 @@ fn update(opts: &UpdateOptions) -> Result<()> { }, } } else { - println!("{:?}: No updates available", component.ctype); + writeln!(r, "{:?}: No updates available", component.ctype).unwrap(); }; } - Ok(()) + Ok(r) } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { @@ -258,7 +277,8 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { Ok(()) } -fn adopt() -> Result<()> { +fn adopt() -> Result { + let mut r = String::new(); let sysroot_path = "/"; let _lockf = acquire_write_lock(sysroot_path)?; let (status, saved_state) = compute_status(sysroot_path)?; @@ -274,7 +294,7 @@ fn adopt() -> Result<()> { }; let disk = match installed { ComponentInstalled::Unknown(state) => { - println!("Adopting: {:?}", component.ctype); + writeln!(r, "Adopting: {:?}", component.ctype).unwrap(); adopted.insert(component.ctype.clone()); state } @@ -284,7 +304,7 @@ fn adopt() -> Result<()> { drift, } => { if *drift { - eprintln!("Warning: Skipping drifted component: {:?}", ctype); + writeln!(r, "Warning: Skipping drifted component: {:?}", ctype).unwrap(); } continue; } @@ -301,13 +321,13 @@ fn adopt() -> Result<()> { .insert(component.ctype.clone(), saved); } if adopted.is_empty() { - println!("Nothing to do."); - return Ok(()); + writeln!(r, "Nothing to do.").unwrap(); + return Ok(r); } // Must have saved state if we get here let sysroot_dir = openat::Dir::open(sysroot_path)?; update_state(&sysroot_dir, &saved_state)?; - Ok(()) + Ok(r) } fn timestamp_and_commit_from_sysroot( @@ -473,70 +493,74 @@ fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { )) } -fn print_component(component: &Component) { +fn print_component(component: &Component, r: &mut String) { let name = serde_plain::to_string(&component.ctype).expect("serde"); - println!("Component {}", name); + writeln!(r, "Component {}", name).unwrap(); let installed = match &component.installed { ComponentState::NotInstalled => { - println!(" Not installed."); + writeln!(r, " Not installed.").unwrap(); return; } ComponentState::NotImplemented => { - println!(" Not implemented."); + writeln!(r, " Not implemented.").unwrap(); return; } ComponentState::Found(installed) => installed, }; match installed { ComponentInstalled::Unknown(disk) => { - println!(" Unmanaged: digest={}", disk.digest); + writeln!(r, " Unmanaged: digest={}", disk.digest).unwrap(); } ComponentInstalled::Tracked { disk, saved, drift } => { if !*drift { - println!(" Installed: {}", saved.digest); + writeln!(r, " Installed: {}", saved.digest).unwrap(); } else { - println!(" Installed; warning: drift detected"); - println!(" Recorded: {}", saved.digest); - println!(" Actual: {}", disk.digest); + writeln!(r, " Installed; warning: drift detected").unwrap(); + writeln!(r, " Recorded: {}", saved.digest).unwrap(); + writeln!(r, " Actual: {}", disk.digest).unwrap(); } if saved.adopted { - println!(" Adopted: true") + writeln!(r, " Adopted: true").unwrap(); } } } if let Some(update) = component.update.as_ref() { match update { ComponentUpdate::LatestUpdateInstalled => { - println!(" Update: At latest version"); + writeln!(r, " Update: At latest version").unwrap(); } ComponentUpdate::Available(update) => { let ts_str = update .update .content_timestamp .format("%Y-%m-%dT%H:%M:%S+00:00"); - println!(" Update: Available"); - println!(" Timestamp: {}", ts_str); - println!(" Digest: {}", update.update.content.digest); + writeln!(r, " Update: Available").unwrap(); + writeln!(r, " Timestamp: {}", ts_str).unwrap(); + writeln!(r, " Digest: {}", update.update.content.digest).unwrap(); if let Some(diff) = &update.diff { - println!( + writeln!( + r, " Diff: changed={} added={} removed={}", diff.changes.len(), diff.additions.len(), diff.removals.len() - ); + ) + .unwrap(); } } } } } -fn status(opts: &StatusOptions) -> Result<()> { +fn status(opts: &StatusOptions) -> Result { let (status, _) = compute_status("/")?; if opts.json { - serde_json::to_writer_pretty(std::io::stdout(), &status)?; + let r = serde_json::to_string(&status)?; + Ok(r) } else if !status.supported_architecture { - eprintln!("This architecture is not supported.") + Ok("This architecture is not supported.".to_string()) } else { + let mut r = String::new(); let specified_components = if let Some(components) = &opts.components { let r: std::result::Result, _> = components .iter() @@ -552,7 +576,114 @@ fn status(opts: &StatusOptions) -> Result<()> { continue; } } - print_component(component); + print_component(component, &mut r); + } + Ok(r) + } +} + +struct UnauthenticatedClient { + fd: RawFd, +} + +impl UnauthenticatedClient { + fn new(fd: RawFd) -> Self { + Self { fd } + } + + fn authenticate(mut self) -> Result { + use nix::sys::uio::IoVec; + let fd = self.fd; + let mut buf = [0u8; 1024]; + + nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; + let iov = IoVec::from_mut_slice(buf.as_mut()); + let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); + let msg = nixsocket::recvmsg( + fd, + &[iov], + Some(&mut cmsgspace), + nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + )?; + let mut creds = None; + for cmsg in msg.cmsgs() { + if let nixsocket::ControlMessageOwned::ScmCredentials(c) = cmsg { + creds = Some(c); + break; + } + } + if let Some(creds) = creds { + if creds.uid() != 0 { + bail!("unauthorized pid:{} uid:{}", creds.pid(), creds.uid()) + } + println!("Connection from pid:{}", creds.pid()); + } else { + bail!("No SCM credentials provided"); + } + let hello = String::from_utf8_lossy(&buf[0..msg.bytes]); + if hello != BOOTUPD_HELLO_MSG { + bail!("Didn't receive correct hello message, found: {:?}", &hello); + } + let r = AuthenticatedClient { fd: self.fd }; + self.fd = -1; + Ok(r) + } +} + +impl Drop for UnauthenticatedClient { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} + +struct AuthenticatedClient { + fd: RawFd, +} + +impl Drop for AuthenticatedClient { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} + +fn daemon_process_one(client: &mut AuthenticatedClient) -> Result<()> { + let mut buf = [0u8; MSGSIZE]; + loop { + let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + let buf = &buf[0..n]; + if buf.len() == 0 { + println!("Client disconnected"); + break; + } + + let opt = bincode::deserialize(&buf)?; + let r = match opt { + Opt::Adopt(ref opts) => { + println!("Processing adopt"); + adopt() + } + Opt::Update(ref opts) => { + println!("Processing update"); + update(opts) + } + Opt::Status(ref opts) => { + println!("Processing status"); + status(opts) + } + _ => Err(anyhow::anyhow!("Invalid option")), + }; + let r = match r { + Ok(s) => DaemonToClientReply::Success(s), + Err(e) => DaemonToClientReply::Failure(e.to_string()), + }; + let r = bincode::serialize(&r)?; + let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + if written != r.len() { + bail!("Wrote {} bytes to client, expected {}", written, r.len()); } } Ok(()) @@ -560,8 +691,6 @@ fn status(opts: &StatusOptions) -> Result<()> { fn daemon() -> Result<()> { use libsystemd::daemon::{self, NotifyState}; - use nix::sys::socket as nixsocket; - use nix::sys::uio::IoVec; use std::os::unix::io::IntoRawFd; if !daemon::booted() { bail!("Not running systemd") @@ -578,78 +707,101 @@ fn daemon() -> Result<()> { if !sent { bail!("Failed to notify systemd"); } - let mut buf = [0u8; 1024]; loop { - let fd = nixsocket::accept4(srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC)?; - nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; - let iov = IoVec::from_mut_slice(buf.as_mut()); - let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); - let msg = nixsocket::recvmsg( - fd, - &[iov], - Some(&mut cmsgspace), + let client = UnauthenticatedClient::new(nixsocket::accept4( + srvsock_fd, + nixsocket::SockFlag::SOCK_CLOEXEC, + )?); + let mut client = client.authenticate()?; + daemon_process_one(&mut client)?; + } +} + +struct ClientToDaemonConnection { + fd: i32, +} + +impl Drop for ClientToDaemonConnection { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} + +impl ClientToDaemonConnection { + fn new() -> Self { + Self { fd: -1 } + } + + fn connect(&mut self) -> Result<()> { + use nix::sys::uio::IoVec; + self.fd = nixsocket::socket( + nixsocket::AddressFamily::Unix, + nixsocket::SockType::SeqPacket, + nixsocket::SockFlag::SOCK_CLOEXEC, + None, + )?; + let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; + nixsocket::connect(self.fd, &addr)?; + let creds = libc::ucred { + pid: nix::unistd::getpid().as_raw(), + uid: nix::unistd::getuid().as_raw(), + gid: nix::unistd::getgid().as_raw(), + }; + let creds = nixsocket::UnixCredentials::from(creds); + let creds = nixsocket::ControlMessage::ScmCredentials(&creds); + nixsocket::sendmsg( + self.fd, + &[IoVec::from_slice(BOOTUPD_HELLO_MSG.as_bytes())], + &[creds], nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + None, )?; - let mut uid = None; - for cmsg in msg.cmsgs() { - if let nixsocket::ControlMessageOwned::ScmCredentials(creds) = cmsg { - uid = Some(creds.uid()); - break; - } + Ok(()) + } + + fn send(&mut self, opt: &Opt) -> Result<()> { + { + let serialized = bincode::serialize(opt)?; + let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) + .context("client sending request")?; } - if let Some(uid) = uid { - if uid != 0 { - eprintln!("Dropping connection from unauthorized uid: {}", uid); - continue; + let reply: DaemonToClientReply = { + let mut buf = [0u8; MSGSIZE]; + let n = nixsocket::recv(self.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) + .context("client recv")?; + let buf = &buf[0..n]; + if buf.len() == 0 { + bail!("Server sent an empty reply"); + } + bincode::deserialize(&buf).context("client parsing reply")? + }; + match reply { + DaemonToClientReply::Success(buf) => { + print!("{}", buf); + } + DaemonToClientReply::Failure(buf) => { + bail!("error: {}", buf); } - } else { - eprintln!("No SCM rights provided"); - continue; } - dbg!(String::from_utf8_lossy(&buf[0..msg.bytes])); + nixsocket::shutdown(self.fd, nixsocket::Shutdown::Both)?; + Ok(()) } } -fn ping_daemon() -> Result<()> { - use nix::sys::socket as nixsocket; - use nix::sys::uio::IoVec; - let sock = nixsocket::socket( - nixsocket::AddressFamily::Unix, - nixsocket::SockType::SeqPacket, - nixsocket::SockFlag::SOCK_CLOEXEC, - None, - )?; - let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; - nixsocket::connect(sock, &addr)?; - let creds = libc::ucred { - pid: nix::unistd::getpid().as_raw(), - uid: nix::unistd::getuid().as_raw(), - gid: nix::unistd::getgid().as_raw(), - }; - let creds = nixsocket::UnixCredentials::from(creds); - let creds = nixsocket::ControlMessage::ScmCredentials(&creds); - nixsocket::sendmsg( - sock, - &[IoVec::from_slice(b"ping")], - &[creds], - nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, - None, - )?; - - Ok(()) -} - /// Main entrypoint #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub fn boot_update_main(args: &[String]) -> Result<()> { let opt = Opt::from_iter(args.iter()); match opt { Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, - Opt::Adopt => adopt()?, - Opt::Update(ref opts) => update(opts)?, - Opt::Status(ref opts) => status(opts)?, + o @ Opt::Adopt(_) | o @ Opt::Update(_) | o @ Opt::Status(_) => { + let mut c = ClientToDaemonConnection::new(); + c.connect()?; + c.send(&o)? + } Opt::Daemon => daemon()?, - Opt::PingDaemon => ping_daemon()?, }; Ok(()) } diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 4233ecb93..fcadef6ba 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -38,6 +38,8 @@ bootupd() { runv systemctl show bootupd > out.txt assert_file_has_content_literal out.txt 'ActiveState=inactive' +systemctl start bootupd.socket + bootupd status --component=EFI > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Unmanaged: digest=' From cfb673ab327d1d62f842edca1588f932cd747dfd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 22:18:32 +0000 Subject: [PATCH 030/641] Consistently accept components as non-option args We were inconsistent. --- src/bootupd.rs | 25 +++++++++++-------------- tests/kola/test-bootupd | 16 ++++++++-------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 20025a89b..54eb246f6 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -10,7 +10,7 @@ use gio::NONE_CANCELLABLE; use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; use serde_derive::{Deserialize, Serialize}; -use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write as WriteFmt; use std::io::prelude::*; use std::os::unix::io::RawFd; @@ -58,8 +58,7 @@ struct UpdateOptions { #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct StatusOptions { - #[structopt(long = "component")] - components: Option>, + components: Vec, // Output JSON #[structopt(long)] @@ -277,7 +276,7 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { Ok(()) } -fn adopt() -> Result { +fn adopt(opts: &AdoptOptions) -> Result { let mut r = String::new(); let sysroot_path = "/"; let _lockf = acquire_write_lock(sysroot_path)?; @@ -286,7 +285,13 @@ fn adopt() -> Result { let mut saved_state = saved_state.unwrap_or_else(|| SavedState { components: BTreeMap::new(), }); + let specified_components = parse_componentlist(&opts.components)?; for (ctype, component) in status.components.iter() { + if let Some(specified_components) = specified_components.as_ref() { + if !specified_components.contains(ctype) { + continue; + } + } let installed = match &component.installed { ComponentState::NotInstalled => continue, ComponentState::NotImplemented => continue, @@ -561,15 +566,7 @@ fn status(opts: &StatusOptions) -> Result { Ok("This architecture is not supported.".to_string()) } else { let mut r = String::new(); - let specified_components = if let Some(components) = &opts.components { - let r: std::result::Result, _> = components - .iter() - .map(|c| serde_plain::from_str(c)) - .collect(); - Some(r?) - } else { - None - }; + let specified_components = parse_componentlist(&opts.components)?; for (ctype, component) in status.components.iter() { if let Some(specified_components) = specified_components.as_ref() { if !specified_components.contains(ctype) { @@ -664,7 +661,7 @@ fn daemon_process_one(client: &mut AuthenticatedClient) -> Result<()> { let r = match opt { Opt::Adopt(ref opts) => { println!("Processing adopt"); - adopt() + adopt(opts) } Opt::Update(ref opts) => { println!("Processing update"); diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index fcadef6ba..6788d334c 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -40,7 +40,7 @@ assert_file_has_content_literal out.txt 'ActiveState=inactive' systemctl start bootupd.socket -bootupd status --component=EFI > out.txt +bootupd status EFI > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Unmanaged: digest=' assert_not_file_has_content_literal out.txt 'Update: Available:' @@ -62,37 +62,37 @@ ok 'rerunning adopt is idempotent' cp --reflink=auto ${efidir}/${shim} shimx64.backup echo 'oops state drift' >> ${efidir}/shimx64.efi -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_file_has_content_literal out.txt 'warning: drift detected' assert_file_has_content_literal out.txt 'Recorded: ' assert_file_has_content_literal out.txt 'Actual: sha512:' mv shimx64.backup ${efidir}/shimx64.efi -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_not_file_has_content_literal out.txt 'warning: drift detected' ok 'drift detected' # TODO do better tests that rpm-ostree usroverlay -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_not_file_has_content_literal out.txt 'Update: Available' cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup echo 'updated shimx64.efi' > ${ostefi}/${shim} -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_file_has_content_literal out.txt 'Update: Available' cp --reflink=auto shimx64.efi.backup ${ostefi}/${shim} -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_not_file_has_content_literal out.txt 'Update: Available' ok 'update available' -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_not_file_has_content_literal out.txt 'Update: Available' cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup echo 'updated shimx64.efi' > ${ostefi}/${shim} bootupd update EFI | tee out.txt assert_file_has_content_literal out.txt 'EFI: Updated to digest=' assert_not_file_has_content_literal out.txt 'EFI: no updates available' -bootupd status --component=EFI | tee out.txt +bootupd status EFI | tee out.txt assert_not_file_has_content_literal out.txt 'warning: drift detected' assert_not_file_has_content_literal out.txt 'Update: Available' if ! test -f "${efidir}/grub.cfg"; then From a4e5d9b5dd6d784d147e9f14f21ca30a445bc20f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Jun 2020 22:27:36 +0000 Subject: [PATCH 031/641] Spit off ipc into separate module Yeah the code is a mess, but it's improving. --- src/bootupd.rs | 177 +++++-------------------------------------------- src/ipc.rs | 158 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 159 deletions(-) create mode 100644 src/ipc.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 54eb246f6..cebda34f9 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -13,7 +13,6 @@ use serde_derive::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write as WriteFmt; use std::io::prelude::*; -use std::os::unix::io::RawFd; use std::path::Path; use structopt::StructOpt; @@ -21,16 +20,13 @@ use structopt::StructOpt; mod efi; mod filetree; use filetree::*; +mod ipc; mod model; use model::*; mod ostreeutil; mod sha512string; mod util; -pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; -pub(crate) const MSGSIZE: usize = 1_048_576; -/// Sent between processes along with SCM credentials -pub(crate) const BOOTUPD_HELLO_MSG: &str = "bootupd-hello\n"; /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. It's stored in /boot pub(crate) const STATEFILE_DIR: &str = "boot"; @@ -87,11 +83,6 @@ enum Opt { Status(StatusOptions), Daemon, } -#[derive(Debug, Serialize, Deserialize)] -enum DaemonToClientReply { - Success(String), - Failure(String), -} pub(crate) fn install(sysroot_path: &str) -> Result<()> { let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); @@ -579,80 +570,12 @@ fn status(opts: &StatusOptions) -> Result { } } -struct UnauthenticatedClient { - fd: RawFd, -} - -impl UnauthenticatedClient { - fn new(fd: RawFd) -> Self { - Self { fd } - } - - fn authenticate(mut self) -> Result { - use nix::sys::uio::IoVec; - let fd = self.fd; - let mut buf = [0u8; 1024]; - - nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; - let iov = IoVec::from_mut_slice(buf.as_mut()); - let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); - let msg = nixsocket::recvmsg( - fd, - &[iov], - Some(&mut cmsgspace), - nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, - )?; - let mut creds = None; - for cmsg in msg.cmsgs() { - if let nixsocket::ControlMessageOwned::ScmCredentials(c) = cmsg { - creds = Some(c); - break; - } - } - if let Some(creds) = creds { - if creds.uid() != 0 { - bail!("unauthorized pid:{} uid:{}", creds.pid(), creds.uid()) - } - println!("Connection from pid:{}", creds.pid()); - } else { - bail!("No SCM credentials provided"); - } - let hello = String::from_utf8_lossy(&buf[0..msg.bytes]); - if hello != BOOTUPD_HELLO_MSG { - bail!("Didn't receive correct hello message, found: {:?}", &hello); - } - let r = AuthenticatedClient { fd: self.fd }; - self.fd = -1; - Ok(r) - } -} - -impl Drop for UnauthenticatedClient { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} - -struct AuthenticatedClient { - fd: RawFd, -} - -impl Drop for AuthenticatedClient { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} - -fn daemon_process_one(client: &mut AuthenticatedClient) -> Result<()> { - let mut buf = [0u8; MSGSIZE]; +fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { + let mut buf = [0u8; ipc::MSGSIZE]; loop { let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; let buf = &buf[0..n]; - if buf.len() == 0 { + if buf.is_empty() { println!("Client disconnected"); break; } @@ -674,8 +597,8 @@ fn daemon_process_one(client: &mut AuthenticatedClient) -> Result<()> { _ => Err(anyhow::anyhow!("Invalid option")), }; let r = match r { - Ok(s) => DaemonToClientReply::Success(s), - Err(e) => DaemonToClientReply::Failure(e.to_string()), + Ok(s) => ipc::DaemonToClientReply::Success(s), + Err(e) => ipc::DaemonToClientReply::Failure(e.to_string()), }; let r = bincode::serialize(&r)?; let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; @@ -705,7 +628,7 @@ fn daemon() -> Result<()> { bail!("Failed to notify systemd"); } loop { - let client = UnauthenticatedClient::new(nixsocket::accept4( + let client = ipc::UnauthenticatedClient::new(nixsocket::accept4( srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC, )?); @@ -714,79 +637,6 @@ fn daemon() -> Result<()> { } } -struct ClientToDaemonConnection { - fd: i32, -} - -impl Drop for ClientToDaemonConnection { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} - -impl ClientToDaemonConnection { - fn new() -> Self { - Self { fd: -1 } - } - - fn connect(&mut self) -> Result<()> { - use nix::sys::uio::IoVec; - self.fd = nixsocket::socket( - nixsocket::AddressFamily::Unix, - nixsocket::SockType::SeqPacket, - nixsocket::SockFlag::SOCK_CLOEXEC, - None, - )?; - let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; - nixsocket::connect(self.fd, &addr)?; - let creds = libc::ucred { - pid: nix::unistd::getpid().as_raw(), - uid: nix::unistd::getuid().as_raw(), - gid: nix::unistd::getgid().as_raw(), - }; - let creds = nixsocket::UnixCredentials::from(creds); - let creds = nixsocket::ControlMessage::ScmCredentials(&creds); - nixsocket::sendmsg( - self.fd, - &[IoVec::from_slice(BOOTUPD_HELLO_MSG.as_bytes())], - &[creds], - nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, - None, - )?; - Ok(()) - } - - fn send(&mut self, opt: &Opt) -> Result<()> { - { - let serialized = bincode::serialize(opt)?; - let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) - .context("client sending request")?; - } - let reply: DaemonToClientReply = { - let mut buf = [0u8; MSGSIZE]; - let n = nixsocket::recv(self.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) - .context("client recv")?; - let buf = &buf[0..n]; - if buf.len() == 0 { - bail!("Server sent an empty reply"); - } - bincode::deserialize(&buf).context("client parsing reply")? - }; - match reply { - DaemonToClientReply::Success(buf) => { - print!("{}", buf); - } - DaemonToClientReply::Failure(buf) => { - bail!("error: {}", buf); - } - } - nixsocket::shutdown(self.fd, nixsocket::Shutdown::Both)?; - Ok(()) - } -} - /// Main entrypoint #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub fn boot_update_main(args: &[String]) -> Result<()> { @@ -794,9 +644,18 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { match opt { Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, o @ Opt::Adopt(_) | o @ Opt::Update(_) | o @ Opt::Status(_) => { - let mut c = ClientToDaemonConnection::new(); + let mut c = ipc::ClientToDaemonConnection::new(); c.connect()?; - c.send(&o)? + let r = c.send(&o)?; + match r { + ipc::DaemonToClientReply::Success(buf) => { + print!("{}", buf); + } + ipc::DaemonToClientReply::Failure(buf) => { + bail!("error: {}", buf); + } + } + c.shutdown()?; } Opt::Daemon => daemon()?, }; diff --git a/src/ipc.rs b/src/ipc.rs new file mode 100644 index 000000000..2d334d83b --- /dev/null +++ b/src/ipc.rs @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::{bail, Context, Result}; +use nix::sys::socket as nixsocket; +use serde_derive::{Deserialize, Serialize}; +use std::os::unix::io::RawFd; + +pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; +pub(crate) const MSGSIZE: usize = 1_048_576; +/// Sent between processes along with SCM credentials +pub(crate) const BOOTUPD_HELLO_MSG: &str = "bootupd-hello\n"; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum DaemonToClientReply { + Success(String), + Failure(String), +} + +pub(crate) struct ClientToDaemonConnection { + fd: i32, +} + +impl Drop for ClientToDaemonConnection { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} + +impl ClientToDaemonConnection { + pub(crate) fn new() -> Self { + Self { fd: -1 } + } + + pub(crate) fn connect(&mut self) -> Result<()> { + use nix::sys::uio::IoVec; + self.fd = nixsocket::socket( + nixsocket::AddressFamily::Unix, + nixsocket::SockType::SeqPacket, + nixsocket::SockFlag::SOCK_CLOEXEC, + None, + )?; + let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; + nixsocket::connect(self.fd, &addr)?; + let creds = libc::ucred { + pid: nix::unistd::getpid().as_raw(), + uid: nix::unistd::getuid().as_raw(), + gid: nix::unistd::getgid().as_raw(), + }; + let creds = nixsocket::UnixCredentials::from(creds); + let creds = nixsocket::ControlMessage::ScmCredentials(&creds); + nixsocket::sendmsg( + self.fd, + &[IoVec::from_slice(BOOTUPD_HELLO_MSG.as_bytes())], + &[creds], + nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + None, + )?; + Ok(()) + } + + pub(crate) fn send(&mut self, opt: &crate::Opt) -> Result { + { + let serialized = bincode::serialize(opt)?; + let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) + .context("client sending request")?; + } + let reply: DaemonToClientReply = { + let mut buf = [0u8; MSGSIZE]; + let n = nixsocket::recv(self.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) + .context("client recv")?; + let buf = &buf[0..n]; + if buf.is_empty() { + bail!("Server sent an empty reply"); + } + bincode::deserialize(&buf).context("client parsing reply")? + }; + Ok(reply) + } + + pub(crate) fn shutdown(&mut self) -> Result<()> { + nixsocket::shutdown(self.fd, nixsocket::Shutdown::Both)?; + Ok(()) + } +} + +pub(crate) struct UnauthenticatedClient { + fd: RawFd, +} + +impl UnauthenticatedClient { + pub(crate) fn new(fd: RawFd) -> Self { + Self { fd } + } + + pub(crate) fn authenticate(mut self) -> Result { + use nix::sys::uio::IoVec; + let fd = self.fd; + let mut buf = [0u8; 1024]; + + nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; + let iov = IoVec::from_mut_slice(buf.as_mut()); + let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); + let msg = nixsocket::recvmsg( + fd, + &[iov], + Some(&mut cmsgspace), + nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, + )?; + let mut creds = None; + for cmsg in msg.cmsgs() { + if let nixsocket::ControlMessageOwned::ScmCredentials(c) = cmsg { + creds = Some(c); + break; + } + } + if let Some(creds) = creds { + if creds.uid() != 0 { + bail!("unauthorized pid:{} uid:{}", creds.pid(), creds.uid()) + } + println!("Connection from pid:{}", creds.pid()); + } else { + bail!("No SCM credentials provided"); + } + let hello = String::from_utf8_lossy(&buf[0..msg.bytes]); + if hello != BOOTUPD_HELLO_MSG { + bail!("Didn't receive correct hello message, found: {:?}", &hello); + } + let r = AuthenticatedClient { fd: self.fd }; + self.fd = -1; + Ok(r) + } +} + +impl Drop for UnauthenticatedClient { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} + +pub(crate) struct AuthenticatedClient { + pub(crate) fd: RawFd, +} + +impl Drop for AuthenticatedClient { + fn drop(&mut self) { + if self.fd != -1 { + nix::unistd::close(self.fd).expect("close"); + } + } +} From 478c19cba1f73b0536d41dbc7dda23885bce4b01 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 26 Jun 2020 13:54:33 +0000 Subject: [PATCH 032/641] ci: Add build-test.sh to do a full cycle This is fast enough one can just run it to do things end to end. --- ci/build-test.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 ci/build-test.sh diff --git a/ci/build-test.sh b/ci/build-test.sh new file mode 100755 index 000000000..af3465337 --- /dev/null +++ b/ci/build-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -xeuo pipefail +test -n "${COSA_DIR:-}" +make +cosa build-fast +kola run -E $(pwd) --qemu-image fastbuild-*-qemu.qcow2 --qemu-firmware uefi ext.bootupd From b5036b322c8953f00a43e0102c4ab0bd2f9d1f23 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 26 Jun 2020 00:37:59 +0000 Subject: [PATCH 033/641] Don't exclusively own files in ESP I have gone back and forth on whether bootupd should *exclusively* own `/boot/efi` or not. In the "adopted" case, we clearly cannot. Let's be conservative for now and change the way we compute diffs to be "relative" - this is a cleaner approach than "compute diff but ignore removals". --- src/bootupd.rs | 16 +++++----------- src/filetree.rs | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index cebda34f9..b3d70becf 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -395,7 +395,7 @@ fn compute_status_efi( }); }; let fsdiff = if let Some(saved_filesystem) = saved.filesystem.as_ref() { - Some(esptree.diff(&saved_filesystem)?) + Some(saved_filesystem.changes(&esptree)?) } else { None }; @@ -403,11 +403,7 @@ fn compute_status_efi( let (installed, installed_digest) = { let content = InstalledContent::from_file_tree(esptree); let drift = if let Some(fsdiff) = fsdiff { - if saved.adopted { - !fsdiff.is_only_removals() - } else { - fsdiff.count() > 0 - } + fsdiff.count() > 0 } else { // TODO detect state outside of filesystem tree false @@ -425,11 +421,9 @@ fn compute_status_efi( let update_esp = efi_content_version_from_ostree(sysroot_path)?; let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); - let update = if !saved.adopted && update_esp.content.digest == installed_digest { - ComponentUpdate::LatestUpdateInstalled - } else { - let diff = installed_tree.diff(update_esp_tree)?; - if saved.adopted && diff.is_only_removals() { + let update = { + let diff = installed_tree.updates(&update_esp_tree)?; + if diff.count() == 0 { ComponentUpdate::LatestUpdateInstalled } else { ComponentUpdate::Available(Box::new(ComponentUpdateAvailable { diff --git a/src/filetree.rs b/src/filetree.rs index 2b701157e..bc1343c03 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -54,10 +54,6 @@ impl FileTreeDiff { pub(crate) fn count(&self) -> usize { self.additions.len() + self.removals.len() + self.changes.len() } - - pub(crate) fn is_only_removals(&self) -> bool { - self.count() == self.removals.len() - } } impl FileMetadata { @@ -151,7 +147,25 @@ impl FileTree { } /// Determine the changes *from* self to the updated tree + #[allow(dead_code)] // Used in tests and kept for completeness pub(crate) fn diff(&self, updated: &Self) -> Result { + self.diff_impl(updated, true) + } + + /// Determine any changes only using the files tracked in self as + /// a reference. In other words, this will ignore any unknown + /// files and not count them as additions. + pub(crate) fn changes(&self, current: &Self) -> Result { + self.diff_impl(current, false) + } + + /// The inverse of `changes` - determine if there are any files + /// changed or added in `current` compared to self. + pub(crate) fn updates(&self, current: &Self) -> Result { + current.diff_impl(self, false) + } + + fn diff_impl(&self, updated: &Self, check_additions: bool) -> Result { let mut additions = HashSet::new(); let mut removals = HashSet::new(); let mut changes = HashSet::new(); @@ -165,11 +179,13 @@ impl FileTree { removals.insert(k.clone()); } } - for k in updated.children.keys() { - if self.children.get(k).is_some() { - continue; + if check_additions { + for k in updated.children.keys() { + if self.children.get(k).is_some() { + continue; + } + additions.insert(k.clone()); } - additions.insert(k.clone()); } Ok(FileTreeDiff { additions, @@ -405,6 +421,13 @@ mod tests { let diff = run_diff(&a, &b)?; assert_eq!(diff.count(), 1); assert_eq!(diff.removals.len(), 1); + let ta = FileTree::new_from_dir(&a)?; + let tb = FileTree::new_from_dir(&b)?; + let cdiff = ta.changes(&tb)?; + assert_eq!(cdiff.count(), 1); + assert_eq!(cdiff.removals.len(), 1); + let udiff = ta.updates(&tb)?; + assert_eq!(udiff.count(), 0); test_apply(&pa, &pb).context("testing apply 1")?; b.create_dir("foo", 0o755)?; From f94e9269c1b02abf08875e21c78a64a37c6ba03a Mon Sep 17 00:00:00 2001 From: Steve Milner Date: Mon, 29 Jun 2020 16:40:44 -0400 Subject: [PATCH 034/641] Add Dockerfile.build Signed-off-by: Steve Milner --- Dockerfile.build | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Dockerfile.build diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 000000000..ef80691a7 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,9 @@ +FROM registry.fedoraproject.org/fedora:latest + +VOLUME /srv/bootupd + +WORKDIR /srv/bootupd + +RUN dnf update -y && \ + dnf install -y make cargo rust glib2-devel openssl-devel ostree-devel && \ + dnf clean all From 911f13848da6e26c579ef6f2c5d2d486f3ee8cdd Mon Sep 17 00:00:00 2001 From: Steve Milner Date: Mon, 29 Jun 2020 16:42:34 -0400 Subject: [PATCH 035/641] build: Add option for building in a container New make targets: - create-build-container: Uses the container runtime to make a build container - build-in-container: Executes make inside the build container New make variables: - CONTAINER_RUNTIME: Allows overriding what container runtime will be used - IMAGE_PREFIX: Prefix to use for image. podman defaults to localhost/ - IMAGE_NAME: Name of the image. Default is bootupd-build Signed-off-by: Steve Milner --- Makefile | 15 +++++++++++++++ README-devel.md | 29 ++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 74b964747..9ce2719f6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ DESTDIR ?= PREFIX ?= /usr RELEASE ?= 1 +CONTAINER_RUNTIME ?= podman +IMAGE_PREFIX ?= +IMAGE_NAME ?= bootupd-build ifeq ($(RELEASE),1) PROFILE ?= release @@ -10,12 +13,24 @@ else CARGO_ARGS = endif +ifeq ($(CONTAINER_RUNTIME), podman) + IMAGE_PREFIX = localhost/ +endif + units = $(addprefix systemd/, bootupd.service bootupd.socket) .PHONY: all all: $(units) cargo build ${CARGO_ARGS} +.PHONY: create-build-container +create-build-container: + ${CONTAINER_RUNTIME} build -t ${IMAGE_NAME} -f Dockerfile.build + +.PHONY: build-in-container +build-in-container: create-build-container + ${CONTAINER_RUNTIME} run -ti --rm -v .:/srv/bootupd:z ${IMAGE_PREFIX}${IMAGE_NAME} make + .PHONY: install-units install-units: $(units) for unit in $(units); do install -D -m 644 --target-directory=$(DESTDIR)$(PREFIX)/lib/systemd/system/ $$unit; done diff --git a/README-devel.md b/README-devel.md index e7057c360..f197c290d 100644 --- a/README-devel.md +++ b/README-devel.md @@ -13,4 +13,31 @@ cosa build-fast kola run -E (pwd) --qemu-image fastbuild-fedora-coreos-bootupd-qemu.qcow2 --qemu-firmware uefi ext.bootupd ``` -See also [the coreos-assembler docs](https://github.com/coreos/coreos-assembler/blob/master/README-devel.md#using-overrides). \ No newline at end of file +See also [the coreos-assembler docs](https://github.com/coreos/coreos-assembler/blob/master/README-devel.md#using-overrides). + +## Building With Containers + +Many folks use a pet container or toolbox to do development on immutable, partially mutabable, or non-Linux OS's. For those who don't use a pet/toolbox and you'd prefer not to modify your host system for development you can use the `build-in-container` make target to execute building inside a container. + +``` +$ make build-in-container +podman build -t bootupd-build -f Dockerfile.build +STEP 1: FROM registry.fedoraproject.org/fedora:latest +STEP 2: VOLUME /srv/bootupd +--> Using cache a033bf0e43d560e72d7187459d7fad65ab30a1d01c576e8257194d82836472f7 +STEP 3: WORKDIR /srv/bootupd +--> Using cache 756114416fb4a68e72b68a2097c57d9cb94c830f5b351401319baeafa062695e +STEP 4: RUN dnf update -y && dnf install -y make cargo rust glib2-devel openssl-devel ostree-devel +--> Using cache a8e2b525ff0701f735e01bb5703c63bb0e67683625093d34be34bf1123a7f954 +STEP 5: COMMIT bootupd-build +--> a8e2b525ff0 +a8e2b525ff0701f735e01bb5703c63bb0e67683625093d34be34bf1123a7f954 +podman run -ti --rm -v .:/srv/bootupd:z localhost/bootupd-build make +cargo build --release + Updating git repository `https://gitlab.com/cgwalters/ostree-rs` + Updating crates.io index +[...] +$ ls target/release/bootupd +target/release/bootupd +$ +``` From 8c53933f4253ba2716a0bf9cf19eb91641c99061 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 26 Jun 2020 21:50:40 +0000 Subject: [PATCH 036/641] Major rewrite/simplification The previous code ended up being fairly wrong in various ways. It was trying to be too abstract - let's keep *some* level of abstraction but just implement EFI for now. Among other changes, this now correctly works when inserted into the rpm-ostree flow and also the coreos-assembler flow. --- Cargo.toml | 13 +- packaging/bootupd.spec | 56 ++++ src/bootupd.rs | 544 +++++++------------------------ src/component.rs | 73 +++++ src/efi.rs | 150 +++++++++ src/filetree.rs | 61 ++-- src/ipc.rs | 5 +- src/main.rs | 13 +- src/model.rs | 145 ++------ src/ostreeutil.rs | 45 +-- src/sha512string.rs | 16 +- src/util.rs | 55 +++- systemd/bootupd.socket | 3 - tests/kola/data | 1 - tests/{ => kola/data}/libtest.sh | 0 tests/kola/test-bootupd | 75 +---- 16 files changed, 559 insertions(+), 696 deletions(-) create mode 100644 packaging/bootupd.spec create mode 100644 src/component.rs delete mode 120000 tests/kola/data rename tests/{ => kola/data}/libtest.sh (100%) diff --git a/Cargo.toml b/Cargo.toml index c22650fbc..44a49a592 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,10 +21,6 @@ serde_yaml = "0.8" libc = "0.2" fs2 = "0.4.3" nix = "0.17.0" -glib-sys = "0.9.1" -gio-sys = "0.9.1" -glib = "0.9" -gio = "0.8" tempfile = "3.0.3" clap = "~2.33" structopt = "0.3" @@ -36,14 +32,11 @@ hex = "0.4.2" bincode = "1.3.1" bs58 = "0.3.1" byteorder = "1" -rayon = "1.0" c_utf8 = "0.1.0" lazy_static = "1.1.0" serde_plain = "0.3.0" chrono = { version = "0.4.11", features = ["serde"] } -# Can't bump to 2020_1 or beyond due to https://github.com/ostreedev/ostree/pull/2137 -ostree = { version = "0.7.0", features = ["v2019_6"] } -[patch.crates-io] -ostree = { git = "https://gitlab.com/cgwalters/ostree-rs", branch = "walters-master" } -#ostree = { path = "/var/srv/walters/src/gitlab/fkrull/ostree-rs" } +[profile.release] +# We assume we're being delivered via e.g. RPM which supports split debuginfo +debug = true diff --git a/packaging/bootupd.spec b/packaging/bootupd.spec new file mode 100644 index 000000000..a74726796 --- /dev/null +++ b/packaging/bootupd.spec @@ -0,0 +1,56 @@ +%bcond_without check +%global __cargo_skip_build 0 + +%global crate bootupd + +Name: %{crate} +Version: 0.1.0 +Release: 1%{?dist} +Summary: Bootloader updater + +License: ASL 2.0 +URL: https://crates.io/crates/bootupd +Source0: https://crates.io/api/v1/crates/%{crate}/%{version}/download#/%{crate}-%{version}.crate +Source1: https://github.com/coreos/bootupd/releases/download/v%{version}/%{crate}-%{version}-vendor.tar.gz + +# For now, see upstream +ExclusiveArch: x86_64 +BuildRequires: openssl-devel +%if 0%{?rhel} && !0%{?eln} +BuildRequires: rust-toolset +%else +BuildRequires: cargo +BuildRequires: rust +%endif +BuildRequires: systemd + +%description +%{summary} + +%files +%license LICENSE +%doc README.md +%{_libexecdir}/bootupd +%{_unitdir}/* + +%prep +# FIXME shouldn't both source0/source be extracted with this? +%autosetup -n %{crate}-%{version} -p1 +%autosetup -n %{crate}-%{version} -p1 -a 1 +# https://github.com/rust-lang-nursery/error-chain/pull/289 +find -name '*.rs' -executable -exec chmod a-x {} \; +mkdir -p .cargo +cat >.cargo/config << 'EOF' +[source.crates-io] +registry = 'https://github.com/rust-lang/crates.io-index' +replace-with = 'vendored-sources' + +[source.vendored-sources] +directory = './vendor' +EOF + +%build +%cargo_build + +%install +%make_install INSTALL="install -p -c" diff --git a/src/bootupd.rs b/src/bootupd.rs index b3d70becf..31264b46f 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -4,23 +4,26 @@ * SPDX-License-Identifier: Apache-2.0 */ +#![deny(unused_must_use)] + use anyhow::{bail, Context, Result}; use fs2::FileExt; -use gio::NONE_CANCELLABLE; use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; use serde_derive::{Deserialize, Serialize}; -use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write as WriteFmt; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; +// #[cfg(any(target_arch = "x86_64"))] +// mod bios; +mod component; #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] mod efi; mod filetree; -use filetree::*; mod ipc; +use component::*; mod model; use model::*; mod ostreeutil; @@ -33,9 +36,6 @@ pub(crate) const STATEFILE_DIR: &str = "boot"; pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; -/// Where rpm-ostree rewrites data that goes in /boot -pub(crate) const OSTREE_BOOT_DATA: &str = "usr/lib/ostree-boot"; - #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct UpdateOptions { @@ -46,9 +46,6 @@ struct UpdateOptions { /// The destination ESP mount point #[structopt(default_value = "/usr/share/bootd-transitions.json", long)] state_transition_file: String, - - /// Only upgrade these components - components: Vec, } #[derive(Debug, Serialize, Deserialize, StructOpt)] @@ -61,82 +58,74 @@ struct StatusOptions { json: bool, } -#[derive(Debug, Serialize, Deserialize, StructOpt)] -#[structopt(rename_all = "kebab-case")] -struct AdoptOptions { - components: Vec, -} - #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(name = "boot-update")] #[structopt(rename_all = "kebab-case")] enum Opt { /// Install data from available components into a disk image Install { + /// Source root + #[structopt(long, default_value = "/")] + src_root: String, + /// Target root + dest_root: String, + }, + /// Install data from available components into a filesystem tree + GenerateUpdateMetadata { /// Physical root mountpoint sysroot: String, }, - /// Start tracking current data found in available components - Adopt(AdoptOptions), /// Update available components Update(UpdateOptions), + /// Print the current state Status(StatusOptions), - Daemon, } -pub(crate) fn install(sysroot_path: &str) -> Result<()> { - let sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); - sysroot.load(NONE_CANCELLABLE).context("loading sysroot")?; - - let _commit = ostreeutil::find_deployed_commit(sysroot_path)?; - - let statepath = Path::new(sysroot_path) +pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { + let statepath = Path::new(dest_root) .join(STATEFILE_DIR) .join(STATEFILE_NAME); if statepath.exists() { bail!("{:?} already exists, cannot re-install", statepath); } - let bootefi = Path::new(sysroot_path).join(efi::MOUNT_PATH); - efi::validate_esp(&bootefi)?; + let components = get_components(); + if components.is_empty() { + println!("No components available for this platform."); + return Ok(()); + } + let mut state = SavedState { + installed: Default::default(), + }; + for component in components { + let meta = component.install(source_root, dest_root)?; + state.installed.insert(component.name().into(), meta); + } + + let sysroot = openat::Dir::open(dest_root)?; + update_state(&sysroot, &state)?; Ok(()) } -fn update_component_filesystem_at( - saved: &SavedComponent, - src: &openat::Dir, - dest: &openat::Dir, - update: &ComponentUpdateAvailable, -) -> Result { - let diff = update.diff.as_ref().expect("diff"); - - // For components which were adopted, we don't prune files that we don't know - // about. - let opts = ApplyUpdateOptions { - skip_removals: saved.adopted, - ..Default::default() - }; - filetree::apply_diff(src, dest, diff, Some(&opts))?; - - Ok(SavedComponent { - adopted: saved.adopted, - filesystem: update.update.content.filesystem.clone(), - digest: update.update.content.digest.clone(), - timestamp: update.update.content_timestamp, - pending: None, - }) +pub(crate) fn get_components() -> Vec> { + let mut components: Vec> = Vec::new(); + + #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + components.push(Box::new(efi::EFI::new())); + + // #[cfg(target_arch = "x86_64")] + // components.push(Box::new(bios::BIOS::new())); + + components } -fn parse_componentlist(components: &[String]) -> Result>> { - if components.is_empty() { - return Ok(None); +pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { + for component in get_components() { + let _ = component.generate_update_metadata(sysroot_path)?; } - let r: std::result::Result, _> = components - .iter() - .map(|c| serde_plain::from_str(c)) - .collect(); - Ok(Some(r?)) + + Ok(()) } fn acquire_write_lock>(sysroot: P) -> Result { @@ -150,96 +139,35 @@ fn acquire_write_lock>(sysroot: P) -> Result { Ok(lockf) } -fn update(opts: &UpdateOptions) -> Result { +fn update(_opts: &UpdateOptions) -> Result { + let _lock = acquire_write_lock("/")?; let mut r = String::new(); - let sysroot = "/"; - let _lockf = acquire_write_lock(sysroot)?; - let (status, mut new_saved_state) = compute_status(sysroot).context("computing status")?; - let sysroot_dir = - openat::Dir::open(sysroot).with_context(|| format!("opening sysroot {}", sysroot))?; - - let specified_components = parse_componentlist(&opts.components)?; - for (ctype, component) in status.components.iter() { - let is_specified = if let Some(specified) = specified_components.as_ref() { - if !specified.contains(ctype) { - continue; - } - true + let state = get_saved_state("/")?.unwrap_or_else(|| SavedState { + ..Default::default() + }); + for component in get_components() { + let installed = if let Some(i) = state.installed.get(component.name()) { + i } else { - false - }; - let saved = match &component.installed { - ComponentState::NotImplemented => { - if is_specified { - bail!("Component {:?} is not implemented", &ctype); - } else { - continue; - } - } - ComponentState::NotInstalled => { - if is_specified { - bail!("Component {:?} is not installed", &ctype); - } else { - continue; - } - } - ComponentState::Found(installed) => match installed { - ComponentInstalled::Unknown(_) => { - if is_specified { - bail!( - "Component {:?} is not tracked and must be adopted before update", - ctype - ); - } else { - writeln!( - r, - "Skipping component {:?} which is found but not adopted", - ctype - ) - .unwrap(); - continue; - } - } - ComponentInstalled::Tracked { disk: _, saved, .. } => saved, - }, + writeln!(r, "Component {} is not installed", component.name()).unwrap(); + continue; }; - // If we get here, there must be saved state - let new_saved_state = new_saved_state.as_mut().expect("saved state"); - - if let Some(update) = component.update.as_ref() { - match update { - ComponentUpdate::LatestUpdateInstalled => { - writeln!(r, "{:?}: At the latest version", component.ctype).unwrap(); - } - ComponentUpdate::Available(update) => match &component.ctype { - // Yeah we need to have components be a trait with methods like update() - ComponentType::EFI => { - let src = sysroot_dir - .sub_dir(&Path::new(OSTREE_BOOT_DATA).join("efi")) - .context("opening ostree boot data")?; - let dest = sysroot_dir - .sub_dir(efi::MOUNT_PATH) - .context(efi::MOUNT_PATH)?; - let updated_component = - update_component_filesystem_at(saved, &src, &dest, update) - .with_context(|| format!("updating component {:?}", ctype))?; - let updated_digest = updated_component.digest.clone(); - new_saved_state - .components - .insert(ComponentType::EFI, updated_component); - update_state(&sysroot_dir, new_saved_state)?; - writeln!(r, "{:?}: Updated to digest={}", ctype, updated_digest).unwrap(); - } - ctype => { - panic!("Unhandled update for component {:?}", ctype); - } - }, - } + if let Some(update) = component.query_update()? { + component + .run_update(&installed) + .with_context(|| format!("Failed to update {}", component.name()))?; + writeln!(r, "Updated {}: {:?}", component.name(), update).unwrap(); } else { - writeln!(r, "{:?}: No updates available", component.ctype).unwrap(); - }; + writeln!( + r, + "No update available for {}: {:?}", + component.name(), + installed + ) + .unwrap(); + } } - Ok(r) + Ok("".into()) } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { @@ -267,181 +195,7 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { Ok(()) } -fn adopt(opts: &AdoptOptions) -> Result { - let mut r = String::new(); - let sysroot_path = "/"; - let _lockf = acquire_write_lock(sysroot_path)?; - let (status, saved_state) = compute_status(sysroot_path)?; - let mut adopted = std::collections::BTreeSet::new(); - let mut saved_state = saved_state.unwrap_or_else(|| SavedState { - components: BTreeMap::new(), - }); - let specified_components = parse_componentlist(&opts.components)?; - for (ctype, component) in status.components.iter() { - if let Some(specified_components) = specified_components.as_ref() { - if !specified_components.contains(ctype) { - continue; - } - } - let installed = match &component.installed { - ComponentState::NotInstalled => continue, - ComponentState::NotImplemented => continue, - ComponentState::Found(installed) => installed, - }; - let disk = match installed { - ComponentInstalled::Unknown(state) => { - writeln!(r, "Adopting: {:?}", component.ctype).unwrap(); - adopted.insert(component.ctype.clone()); - state - } - ComponentInstalled::Tracked { - disk: _, - saved: _, - drift, - } => { - if *drift { - writeln!(r, "Warning: Skipping drifted component: {:?}", ctype).unwrap(); - } - continue; - } - }; - let saved = SavedComponent { - adopted: true, - digest: disk.digest.clone(), - filesystem: disk.filesystem.clone(), - timestamp: disk.timestamp, - pending: None, - }; - saved_state - .components - .insert(component.ctype.clone(), saved); - } - if adopted.is_empty() { - writeln!(r, "Nothing to do.").unwrap(); - return Ok(r); - } - // Must have saved state if we get here - let sysroot_dir = openat::Dir::open(sysroot_path)?; - update_state(&sysroot_dir, &saved_state)?; - Ok(r) -} - -fn timestamp_and_commit_from_sysroot( - sysroot_path: &str, -) -> Result<(chrono::naive::NaiveDateTime, String)> { - // Until we have list_deployments - assert!(sysroot_path == "/"); - let ostree_sysroot = ostree::Sysroot::new(Some(&gio::File::new_for_path(sysroot_path))); - ostree_sysroot - .load(NONE_CANCELLABLE) - .context("loading sysroot")?; - let booted_deployment = if let Some(booted) = ostree_sysroot.get_booted_deployment() { - booted - } else { - bail!("Not booted into an OSTree system") - }; - - let repo = ostree_sysroot.repo().expect("repo"); - let csum = booted_deployment.get_csum().expect("booted csum"); - let csum = csum.as_str(); - let (commit, _) = repo.load_commit(csum)?; - let ts = ostree::commit_get_timestamp(&commit); - let ts = chrono::naive::NaiveDateTime::from_timestamp(ts as i64, 0); - Ok((ts, csum.to_string())) -} - -fn efi_content_version_from_ostree(sysroot_path: &str) -> Result { - let (ts, commit) = if let Some(timestamp_str) = util::getenv_utf8("BOOT_UPDATE_TEST_TIMESTAMP")? - { - let ts = chrono::NaiveDateTime::parse_from_str(×tamp_str, "%+")?; - (ts, None) - } else { - let (ts, commit) = timestamp_and_commit_from_sysroot(sysroot_path)?; - (ts, Some(commit)) - }; - let sysroot_dir = openat::Dir::open(sysroot_path)?; - let update_esp_dir = sysroot_dir.sub_dir("usr/lib/ostree-boot/efi")?; - let ft = FileTree::new_from_dir(&update_esp_dir)?; - Ok(ContentVersion { - content_timestamp: ts, - content: InstalledContent::from_file_tree(ft), - ostree_commit: commit, - }) -} - -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] -fn compute_status_efi( - sysroot_path: &str, - saved_components: Option<&SavedState>, -) -> Result { - let sysroot_dir = openat::Dir::open(sysroot_path)?; - let espdir = sysroot_dir - .sub_dir(efi::MOUNT_PATH) - .context(efi::MOUNT_PATH)?; - let esptree = FileTree::new_from_dir(&espdir).context("computing filetree for efi")?; - let saved = saved_components - .map(|s| s.components.get(&ComponentType::EFI)) - .flatten(); - let saved = if let Some(saved) = saved { - saved - } else { - return Ok(Component { - ctype: ComponentType::EFI, - installed: ComponentState::Found(ComponentInstalled::Unknown( - InstalledContent::from_file_tree(esptree), - )), - pending: None, - update: None, - }); - }; - let fsdiff = if let Some(saved_filesystem) = saved.filesystem.as_ref() { - Some(saved_filesystem.changes(&esptree)?) - } else { - None - }; - let fsdiff = fsdiff.as_ref(); - let (installed, installed_digest) = { - let content = InstalledContent::from_file_tree(esptree); - let drift = if let Some(fsdiff) = fsdiff { - fsdiff.count() > 0 - } else { - // TODO detect state outside of filesystem tree - false - }; - ( - ComponentInstalled::Tracked { - disk: content, - saved: saved.clone(), - drift, - }, - saved.digest.clone(), - ) - }; - let installed_tree = installed.get_disk_content().filesystem.as_ref().unwrap(); - - let update_esp = efi_content_version_from_ostree(sysroot_path)?; - let update_esp_tree = update_esp.content.filesystem.as_ref().unwrap(); - let update = { - let diff = installed_tree.updates(&update_esp_tree)?; - if diff.count() == 0 { - ComponentUpdate::LatestUpdateInstalled - } else { - ComponentUpdate::Available(Box::new(ComponentUpdateAvailable { - update: update_esp, - diff: Some(diff), - })) - } - }; - - Ok(Component { - ctype: ComponentType::EFI, - installed: ComponentState::Found(installed), - pending: saved.pending.clone(), - update: Some(update), - }) -} - -fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { +fn get_saved_state(sysroot_path: &str) -> Result> { let sysroot_dir = openat::Dir::open(sysroot_path) .with_context(|| format!("opening sysroot {}", sysroot_path))?; @@ -453,114 +207,56 @@ fn compute_status(sysroot_path: &str) -> Result<(Status, Option)> { } else { None }; + Ok(saved_state) +} - let mut components = BTreeMap::new(); - - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - components.insert( - ComponentType::EFI, - compute_status_efi(&sysroot_path, saved_state.as_ref())?, - ); - - #[cfg(target_arch = "x86_64")] - { - components.insert( - ComponentType::BIOS, - Component { - ctype: ComponentType::BIOS, - installed: ComponentState::NotImplemented, - pending: None, - update: None, - }, - ); +fn format_version(meta: &ContentMetadata) -> String { + if let Some(version) = meta.version.as_ref() { + version.into() + } else { + meta.timestamp.format("%Y-%m-%dT%H:%M:%S+00:00").to_string() } - Ok(( - Status { - supported_architecture: !components.is_empty(), - components, - }, - saved_state, - )) } -fn print_component(component: &Component, r: &mut String) { - let name = serde_plain::to_string(&component.ctype).expect("serde"); +fn print_component( + component: &dyn Component, + installed: &ContentMetadata, + r: &mut String, +) -> Result<()> { + let name = component.name(); writeln!(r, "Component {}", name).unwrap(); - let installed = match &component.installed { - ComponentState::NotInstalled => { - writeln!(r, " Not installed.").unwrap(); - return; - } - ComponentState::NotImplemented => { - writeln!(r, " Not implemented.").unwrap(); - return; - } - ComponentState::Found(installed) => installed, + writeln!(r, " Installed: {}", format_version(installed)).unwrap(); + let pending = component.query_update()?; + let update = match pending.as_ref() { + Some(p) if !p.compare(installed) => Some(p), + _ => None, }; - match installed { - ComponentInstalled::Unknown(disk) => { - writeln!(r, " Unmanaged: digest={}", disk.digest).unwrap(); - } - ComponentInstalled::Tracked { disk, saved, drift } => { - if !*drift { - writeln!(r, " Installed: {}", saved.digest).unwrap(); - } else { - writeln!(r, " Installed; warning: drift detected").unwrap(); - writeln!(r, " Recorded: {}", saved.digest).unwrap(); - writeln!(r, " Actual: {}", disk.digest).unwrap(); - } - if saved.adopted { - writeln!(r, " Adopted: true").unwrap(); - } - } - } - if let Some(update) = component.update.as_ref() { - match update { - ComponentUpdate::LatestUpdateInstalled => { - writeln!(r, " Update: At latest version").unwrap(); - } - ComponentUpdate::Available(update) => { - let ts_str = update - .update - .content_timestamp - .format("%Y-%m-%dT%H:%M:%S+00:00"); - writeln!(r, " Update: Available").unwrap(); - writeln!(r, " Timestamp: {}", ts_str).unwrap(); - writeln!(r, " Digest: {}", update.update.content.digest).unwrap(); - if let Some(diff) = &update.diff { - writeln!( - r, - " Diff: changed={} added={} removed={}", - diff.changes.len(), - diff.additions.len(), - diff.removals.len() - ) - .unwrap(); - } - } - } + dbg!(&pending); + dbg!(&update); + if let Some(update) = update { + writeln!(r, " Update: Available: {}", format_version(&update)).unwrap(); + } else { + writeln!(r, " Update: At latest version").unwrap(); } + + Ok(()) } fn status(opts: &StatusOptions) -> Result { - let (status, _) = compute_status("/")?; + let state = get_saved_state("/")?; if opts.json { - let r = serde_json::to_string(&status)?; + let r = serde_json::to_string(&state)?; Ok(r) - } else if !status.supported_architecture { - Ok("This architecture is not supported.".to_string()) - } else { + } else if let Some(state) = state { let mut r = String::new(); - let specified_components = parse_componentlist(&opts.components)?; - for (ctype, component) in status.components.iter() { - if let Some(specified_components) = specified_components.as_ref() { - if !specified_components.contains(ctype) { - continue; - } - } - print_component(component, &mut r); + for (name, ic) in state.installed.iter() { + let component = component::new_from_name(&name)?; + let component = component.as_ref(); + print_component(component, &ic.meta, &mut r)?; } Ok(r) + } else { + Ok("No components installed.".to_string()) } } @@ -576,10 +272,6 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { let opt = bincode::deserialize(&buf)?; let r = match opt { - Opt::Adopt(ref opts) => { - println!("Processing adopt"); - adopt(opts) - } Opt::Update(ref opts) => { println!("Processing update"); update(opts) @@ -632,12 +324,22 @@ fn daemon() -> Result<()> { } /// Main entrypoint -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] pub fn boot_update_main(args: &[String]) -> Result<()> { + if let Some(arg1) = args.get(1) { + if arg1 == "daemon" { + return daemon(); + } + } let opt = Opt::from_iter(args.iter()); match opt { - Opt::Install { sysroot } => install(&sysroot).context("boot data installation failed")?, - o @ Opt::Adopt(_) | o @ Opt::Update(_) | o @ Opt::Status(_) => { + Opt::Install { + src_root, + dest_root, + } => install(&src_root, &dest_root).context("boot data installation failed")?, + Opt::GenerateUpdateMetadata { sysroot } => { + generate_update_metadata(&sysroot).context("generating metadata failed")? + } + o @ Opt::Update(_) | o @ Opt::Status(_) => { let mut c = ipc::ClientToDaemonConnection::new(); c.connect()?; let r = c.send(&o)?; @@ -651,12 +353,6 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { } c.shutdown()?; } - Opt::Daemon => daemon()?, }; Ok(()) } - -#[cfg(not(any(target_arch = "x86_64", target_arch = "arm")))] -pub fn boot_update_main(args: &Vec) -> Result<()> { - bail!("This command is only supported on x86_64") -} diff --git a/src/component.rs b/src/component.rs new file mode 100644 index 000000000..90814c04b --- /dev/null +++ b/src/component.rs @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::Result; +use std::fs::File; +use std::io::Write as IoWrite; +use std::path::{Path, PathBuf}; + +use crate::model::*; + +/// A component along with a possible update +pub(crate) trait Component { + fn name(&self) -> &'static str; + + fn install(&self, src_root: &str, dest_root: &str) -> Result; + + fn generate_update_metadata(&self, sysroot: &str) -> Result; + + fn query_update(&self) -> Result>; + + fn run_update(&self, current: &InstalledContent) -> Result<()>; +} + +pub(crate) fn new_from_name(name: &str) -> Result> { + let r: Box = match name { + "EFI" => Box::new(crate::efi::EFI::new()), + _ => anyhow::bail!("No component {}", name), + }; + Ok(r) +} + +pub(crate) fn component_update_metapath(sysroot: &str, component: &dyn Component) -> PathBuf { + Path::new(sysroot) + .join(BOOTUPD_UPDATES_DIR) + .join(format!("{}.json", component.name())) + .to_path_buf() +} + +pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { + Path::new(sysroot) + .join(BOOTUPD_UPDATES_DIR) + .join(component.name()) + .to_path_buf() +} + +/// Helper method for writing an update file +pub(crate) fn write_update_metadata( + sysroot: &str, + component: &dyn Component, + meta: &ContentMetadata, +) -> Result<()> { + let metap = component_update_metapath(sysroot, component); + let mut f = std::io::BufWriter::new(std::fs::File::create(&metap)?); + serde_json::to_writer(&mut f, &meta)?; + f.flush()?; + Ok(()) +} + +pub(crate) fn get_component_update( + sysroot: &str, + component: &dyn Component, +) -> Result> { + let metap = component_update_metapath(sysroot, component); + if !metap.exists() { + return Ok(None); + } + let mut f = std::io::BufReader::new(File::open(&metap)?); + let u = serde_json::from_reader(&mut f)?; + Ok(Some(u)) +} diff --git a/src/efi.rs b/src/efi.rs index 9abe4bcf0..71db40eb5 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -4,11 +4,161 @@ * SPDX-License-Identifier: Apache-2.0 */ +use std::collections::{BTreeMap, BTreeSet}; +use std::io::prelude::*; +use std::path::Path; +use std::process::Command; + use anyhow::{bail, Result}; +use serde_derive::{Deserialize, Serialize}; + +use chrono::NaiveDateTime; + +use crate::component::*; +use crate::filetree; +use crate::model::*; +use crate::ostreeutil; +use crate::util; +use crate::util::CommandRunExt; /// The path to the ESP mount pub(crate) const MOUNT_PATH: &str = "boot/efi"; +#[derive(Serialize, Deserialize)] +pub(crate) struct EFI {} + +impl EFI { + pub(crate) fn new() -> Self { + Self {} + } +} + +impl Component for EFI { + fn name(&self) -> &'static str { + "EFI" + } + + fn install(&self, src_root: &str, dest_root: &str) -> Result { + let meta = if let Some(meta) = get_component_update(src_root, self)? { + meta + } else { + anyhow::bail!("No update metadata for component {} found", self.name()); + }; + let srcdir = component_updatedir(src_root, self); + let srcd = openat::Dir::open(&srcdir)?; + let ft = crate::filetree::FileTree::new_from_dir(&srcd)?; + let destdir = Path::new(dest_root).join(MOUNT_PATH); + let r = std::process::Command::new("cp") + .args(&["-rp", "--reflink=auto"]) + .arg(&srcdir) + .arg(&destdir) + .status()?; + if !r.success() { + anyhow::bail!("Failed to copy"); + } + Ok(InstalledContent { + meta: meta, + filetree: Some(ft), + }) + } + + fn run_update(&self, current: &InstalledContent) -> Result<()> { + let currentf = current + .filetree + .as_ref() + .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; + let updated = openat::Dir::open(&component_updatedir("/", self))?; + let updatef = filetree::FileTree::new_from_dir(&updated)?; + let diff = currentf.diff(&updatef)?; + let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH))?; + filetree::apply_diff(&updated, &destdir, &diff, None)?; + Ok(()) + } + + fn generate_update_metadata(&self, sysroot_path: &str) -> Result { + let ostreebootdir = Path::new(sysroot_path).join(ostreeutil::BOOT_PREFIX); + let dest_efidir = component_updatedir(sysroot_path, self); + + if ostreebootdir.exists() { + let cruft = ["loader", "grub2"]; + for p in cruft.iter() { + let p = ostreebootdir.join(p); + if p.exists() { + std::fs::remove_dir_all(&p)?; + } + } + + let efisrc = ostreebootdir.join("efi/EFI"); + if !efisrc.exists() { + bail!("Failed to find {:?}", &efisrc); + } + + // Fork off mv() because on overlayfs one can't rename() a lower level + // directory today, and this will handle the copy fallback. + let parent = dest_efidir + .parent() + .ok_or(anyhow::anyhow!("Expected parent directory"))?; + std::fs::create_dir_all(&parent)?; + Command::new("mv").args(&[&efisrc, &dest_efidir]).run()?; + } + + let src_efidir = openat::Dir::open(&dest_efidir)?; + // Query the rpm database and list the package and build times for all the + // files in the EFI system partition. If any files are not owned it is considered + // and error condition. + let rpmout = { + let mut c = ostreeutil::rpm_cmd(sysroot_path); + c.args(&["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); + c.args(util::filenames(&src_efidir)?.drain().map(|mut f| { + f.insert_str(0, "/boot/efi/EFI/"); + f + })); + c + } + .output()?; + if !rpmout.status.success() { + std::io::stderr().write_all(&rpmout.stderr)?; + bail!("Failed to invoke rpm -qf"); + } + let pkgs = std::str::from_utf8(&rpmout.stdout)? + .split_whitespace() + .map(|s| -> Result<_> { + let parts: Vec<_> = s.splitn(2, ',').collect(); + let name = parts[0]; + if let Some(ts) = parts.get(1) { + Ok((name, NaiveDateTime::parse_from_str(ts, "%s")?)) + } else { + bail!("Failed to parse: {}", s); + } + }) + .collect::>>()?; + if pkgs.is_empty() { + bail!("Failed to find any RPM packages matching files in source efidir"); + } + let timestamps: BTreeSet<&NaiveDateTime> = pkgs.values().collect(); + let largest_timestamp = timestamps.iter().last().unwrap(); + let version = pkgs.keys().fold("".to_string(), |mut s, n| { + if !s.is_empty() { + s.push(','); + } + s.push_str(n); + s + }); + + let meta = ContentMetadata { + timestamp: **largest_timestamp, + version: Some(version), + }; + write_update_metadata(sysroot_path, self, &meta)?; + Ok(meta) + } + + fn query_update(&self) -> Result> { + get_component_update("/", self) + } +} + +#[allow(dead_code)] pub(crate) fn validate_esp>(mnt: P) -> Result<()> { if crate::util::running_in_test_suite() { return Ok(()); diff --git a/src/filetree.rs b/src/filetree.rs index bc1343c03..c3f92d67b 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -5,7 +5,6 @@ */ use anyhow::{bail, Context, Result}; -use byteorder::ByteOrder; use chrono::prelude::*; use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; @@ -20,6 +19,7 @@ use std::path::Path; use std::io::Write; /// The prefix we apply to our temporary files. +#[allow(dead_code)] // Used for testing pub(crate) const TMP_PREFIX: &str = ".btmp."; use crate::sha512string::SHA512String; @@ -56,6 +56,7 @@ impl FileTreeDiff { } } +#[allow(dead_code)] // Used for testing impl FileMetadata { pub(crate) fn new_from_path( dir: &openat::Dir, @@ -65,7 +66,7 @@ impl FileMetadata { let meta = r.metadata()?; let mut hasher = Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - std::io::copy(&mut r, &mut hasher)?; + let _ = std::io::copy(&mut r, &mut hasher)?; let digest = SHA512String::from_hasher(&mut hasher); Ok(FileMetadata { size: meta.len(), @@ -73,14 +74,15 @@ impl FileMetadata { }) } - pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { - let mut lenbuf = [0; 8]; - byteorder::BigEndian::write_u64(&mut lenbuf, self.size); - hasher.update(&lenbuf).unwrap(); - hasher.update(&self.sha512.digest_bytes()).unwrap(); - } + // pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { + // let mut lenbuf = [0; 8]; + // byteorder::BigEndian::write_u64(&mut lenbuf, self.size); + // hasher.update(&lenbuf).unwrap(); + // hasher.update(&self.sha512.digest_bytes()).unwrap(); + // } } +#[allow(dead_code)] // Used for testing impl FileTree { // Internal helper to generate a sub-tree fn unsorted_from_dir(dir: &openat::Dir) -> Result> { @@ -98,7 +100,7 @@ impl FileTree { match dir.get_file_type(&entry)? { openat::SimpleType::File => { let meta = FileMetadata::new_from_path(dir, name)?; - ret.insert(name.to_string(), meta); + let _ = ret.insert(name.to_string(), meta); } openat::SimpleType::Dir => { let child = dir.sub_dir(name)?; @@ -106,7 +108,7 @@ impl FileTree { k.reserve(name.len() + 1); k.insert(0, '/'); k.insert_str(0, name); - ret.insert(k, v); + let _ = ret.insert(k, v); } } openat::SimpleType::Symlink => { @@ -120,15 +122,15 @@ impl FileTree { Ok(ret) } - pub(crate) fn digest(&self) -> SHA512String { - let mut hasher = - Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - for (k, v) in self.children.iter() { - hasher.update(k.as_bytes()).unwrap(); - v.extend_hash(&mut hasher); - } - SHA512String::from_hasher(&mut hasher) - } + // pub(crate) fn digest(&self) -> SHA512String { + // let mut hasher = + // Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); + // for (k, v) in self.children.iter() { + // hasher.update(k.as_bytes()).unwrap(); + // v.extend_hash(&mut hasher); + // } + // SHA512String::from_hasher(&mut hasher) + // } /// Create a FileTree from the target directory. pub(crate) fn new_from_dir(dir: &openat::Dir) -> Result { @@ -161,6 +163,7 @@ impl FileTree { /// The inverse of `changes` - determine if there are any files /// changed or added in `current` compared to self. + #[allow(dead_code)] pub(crate) fn updates(&self, current: &Self) -> Result { current.diff_impl(self, false) } @@ -223,30 +226,25 @@ fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { } #[derive(Default, Clone)] +#[allow(dead_code)] // Used for testing pub(crate) struct ApplyUpdateOptions { pub(crate) skip_removals: bool, pub(crate) skip_sync: bool, } /// A bit like std::fs::copy but operates dirfd-relative +#[allow(dead_code)] // Used for testing fn copy_file_at, DP: AsRef>( srcdir: &openat::Dir, destdir: &openat::Dir, srcp: SP, destp: DP, ) -> Result<()> { + use openat_ext::FileExt as OpenatFileExt; let srcp = srcp.as_ref(); let srcf = srcdir.open_file(srcp)?; - let srcmeta = srcf.metadata()?; - let mode = srcmeta.st_mode(); - let mut srcf = std::io::BufReader::new(srcf); - let mut destf = destdir.write_file(destp.as_ref(), mode)?; - { - let mut destf_buf = std::io::BufWriter::new(&mut destf); - let _ = std::io::copy(&mut srcf, &mut destf_buf)?; - destf_buf.flush()?; - } - destf.flush()?; + let mut destf = destdir.write_file(destp.as_ref(), srcf.metadata()?.st_mode())?; + srcf.copy_to(&mut destf)?; Ok(()) } @@ -255,6 +253,7 @@ fn copy_file_at, DP: AsRef>( // to be bound in nix today. I found https://github.com/XuShaohua/nc // but that's a nontrivial dependency with not a lot of code review. // Let's just fork off a helper process for now. +#[allow(dead_code)] // Used for testing pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { let d = d.sub_dir(".").expect("subdir"); let mut c = std::process::Command::new("sync"); @@ -272,6 +271,7 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { Ok(()) } +#[allow(dead_code)] // Used for testing fn tmpname_for_path>(path: P) -> std::path::PathBuf { let path = path.as_ref(); let mut buf = path.file_name().expect("filename").to_os_string(); @@ -280,6 +280,7 @@ fn tmpname_for_path>(path: P) -> std::path::PathBuf { } /// Given two directories, apply a diff generated from srcdir to destdir +#[allow(dead_code)] // Used for testing pub(crate) fn apply_diff( srcdir: &openat::Dir, destdir: &openat::Dir, @@ -296,7 +297,7 @@ pub(crate) fn apply_diff( for pathstr in diff.additions.iter().chain(diff.changes.iter()) { let path = Path::new(pathstr); if let Some(parent) = path.parent() { - // TODO: care about directory modes? Eh. + // TODO: care about directory modes? We don't for FAT. std::fs::create_dir_all(parent)?; } let destp = tmpname_for_path(path); diff --git a/src/ipc.rs b/src/ipc.rs index 2d334d83b..46d04a82d 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -46,7 +46,8 @@ impl ClientToDaemonConnection { None, )?; let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; - nixsocket::connect(self.fd, &addr)?; + nixsocket::connect(self.fd, &addr) + .with_context(|| format!("connecting to {}", BOOTUPD_SOCKET))?; let creds = libc::ucred { pid: nix::unistd::getpid().as_raw(), uid: nix::unistd::getuid().as_raw(), @@ -54,7 +55,7 @@ impl ClientToDaemonConnection { }; let creds = nixsocket::UnixCredentials::from(creds); let creds = nixsocket::ControlMessage::ScmCredentials(&creds); - nixsocket::sendmsg( + let _ = nixsocket::sendmsg( self.fd, &[IoVec::from_slice(BOOTUPD_HELLO_MSG.as_bytes())], &[creds], diff --git a/src/main.rs b/src/main.rs index f34ce184c..44d82d1a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,14 @@ // To run the unit tests for this code, use `make check TESTS=tests/check/test-ex-boot-update.sh` -use anyhow::Result; - -fn main() -> Result<()> { +fn main() { let args: Vec<_> = std::env::args().collect(); - bootupd::boot_update_main(&args) + match bootupd::boot_update_main(&args) { + Ok(_) => {} + Err(e) => { + // Use the alternative formatter to get everything on a single line...it reads better. + eprintln!("error: {:#}", e); + std::process::exit(1); + } + } } diff --git a/src/model.rs b/src/model.rs index 97d2f303f..eaf55e506 100644 --- a/src/model.rs +++ b/src/model.rs @@ -8,121 +8,39 @@ use chrono::prelude::*; use serde_derive::{Deserialize, Serialize}; use std::collections::BTreeMap; -use crate::filetree::*; -use crate::sha512string::SHA512String; +/// The directory where updates are stored +pub(crate) const BOOTUPD_UPDATES_DIR: &str = "usr/lib/bootupd/updates"; -/// Metadata for a single file -#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] -pub(crate) enum ComponentType { - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] - EFI, - #[cfg(target_arch = "x86_64")] - BIOS, -} - -/// Describes data that is at the block level or the filesystem level. -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct InstalledContent { - /// sha512 of the state of the content - pub(crate) digest: SHA512String, +#[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq)] +pub(crate) struct ContentMetadata { + /// The timestamp, which is used to determine update availability pub(crate) timestamp: NaiveDateTime, - pub(crate) filesystem: Option>, -} - -/// A versioned description of something we can update, -/// whether that is a BIOS MBR or an ESP -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct ContentVersion { - pub(crate) content_timestamp: NaiveDateTime, - pub(crate) content: InstalledContent, - pub(crate) ostree_commit: Option, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentInstalled { - Unknown(InstalledContent), - Tracked { - disk: InstalledContent, - saved: SavedComponent, - drift: bool, - }, -} - -/// The state of a particular managed component as found on disk -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentState { - #[allow(dead_code)] - NotInstalled, - NotImplemented, - Found(ComponentInstalled), -} - -/// The state of a particular managed component -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct ComponentUpdateAvailable { - pub(crate) update: ContentVersion, - pub(crate) diff: Option, -} - -/// The state of a particular managed component -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum ComponentUpdate { - LatestUpdateInstalled, - Available(Box), -} - -/// A component along with a possible update -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Component { - pub(crate) ctype: ComponentType, - pub(crate) installed: ComponentState, - pub(crate) pending: Option, - pub(crate) update: Option, -} - -/// Our total view of the world at a point in time -#[derive(Serialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct Status { - pub(crate) supported_architecture: bool, - pub(crate) components: BTreeMap, + /// Human readable version number, like ostree it is not ever parsed, just displayed + pub(crate) version: Option, } -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedPendingUpdate { - /// The value of /proc/sys/kernel/random/boot_id - pub(crate) boot_id: String, - /// The value of /etc/machine-id from the OS trying to update - pub(crate) machineid: String, - /// The new version we're trying to install - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, +impl ContentMetadata { + pub(crate) fn compare(&self, other: &Self) -> bool { + match (self.version.as_ref(), other.version.as_ref()) { + (Some(a), Some(b)) => a.as_str() == b.as_str(), + _ => self.timestamp == other.timestamp, + } + } } -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "kebab-case")] -pub(crate) struct SavedComponent { - pub(crate) adopted: bool, - pub(crate) filesystem: Option>, - pub(crate) digest: SHA512String, - pub(crate) timestamp: NaiveDateTime, - pub(crate) pending: Option, +#[derive(Serialize, Deserialize, Clone, Debug)] +pub(crate) struct InstalledContent { + /// Associated metadata + pub(crate) meta: ContentMetadata, + /// Human readable version number, like ostree it is not ever parsed, just displayed + pub(crate) filetree: Option, } /// Will be serialized into /boot/bootupd-state.json -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Default, Debug)] #[serde(rename_all = "kebab-case")] pub(crate) struct SavedState { - pub(crate) components: BTreeMap, + pub(crate) installed: BTreeMap, } // Should be stored in /usr/lib/bootupd/edges.json @@ -135,22 +53,3 @@ pub(crate) struct SavedState { // /// Upgrade from content past this timestamp // pub(crate) from_timestamp: Option, // } - -impl InstalledContent { - pub(crate) fn from_file_tree(ft: FileTree) -> InstalledContent { - InstalledContent { - digest: ft.digest(), - timestamp: ft.timestamp, - filesystem: Some(Box::new(ft)), - } - } -} - -impl ComponentInstalled { - pub(crate) fn get_disk_content(&self) -> &InstalledContent { - match self { - Self::Unknown(i) => i, - Self::Tracked { disk, .. } => disk, - } - } -} diff --git a/src/ostreeutil.rs b/src/ostreeutil.rs index 89a922504..4f4624f0d 100644 --- a/src/ostreeutil.rs +++ b/src/ostreeutil.rs @@ -4,38 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -use anyhow::{bail, Result}; -use std::io::BufRead; use std::path::Path; -pub(crate) fn find_deployed_commit(sysroot_path: &str) -> Result { - // ostree_sysroot_get_deployments() isn't bound - // https://gitlab.com/fkrull/ostree-rs/-/issues/3 - let ls = std::process::Command::new("/bin/sh") - .arg("-c") - .arg(format!("ls -d {}/ostree/deploy/*/deploy/*.0", sysroot_path)) - .output()?; - if !ls.status.success() { - bail!("failed to find deployment") - } - let mut lines = ls.stdout.lines(); - let deployment = if let Some(line) = lines.next() { - let line = line?; - let deploypath = Path::new(line.trim()); - let parts: Vec<_> = deploypath - .file_name() - .unwrap() - .to_str() - .unwrap() - .splitn(2, ".0") - .collect(); - assert!(parts.len() == 2); - parts[0].to_string() - } else { - bail!("failed to find deployment"); +/// https://github.com/coreos/rpm-ostree/pull/969/commits/dc0e8db5bd92e1f478a0763d1a02b48e57022b59 +pub(crate) const BOOT_PREFIX: &str = "usr/lib/ostree-boot"; + +pub(crate) fn rpm_cmd>(sysroot: P) -> std::process::Command { + let sysroot = sysroot.as_ref(); + let dbpath = sysroot.join("usr/share/rpm"); + let dbpath_arg = { + let mut s = std::ffi::OsString::new(); + s.push("--dbpath="); + s.push(dbpath.as_os_str()); + s }; - if lines.next().is_some() { - bail!("multiple deployments found") - } - Ok(deployment) + let mut c = std::process::Command::new("rpm"); + c.arg(&dbpath_arg); + c } diff --git a/src/sha512string.rs b/src/sha512string.rs index 1e35f468b..c086fa3a0 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -25,13 +25,13 @@ impl SHA512String { )) } - pub(crate) fn digest_bs58(&self) -> &str { - self.0.splitn(2, ':').next().unwrap() - } + // pub(crate) fn digest_bs58(&self) -> &str { + // self.0.splitn(2, ':').next().unwrap() + // } - pub(crate) fn digest_bytes(&self) -> Vec { - bs58::decode(self.digest_bs58()) - .into_vec() - .expect("decoding bs58 hash") - } + // pub(crate) fn digest_bytes(&self) -> Vec { + // bs58::decode(self.digest_bs58()) + // .into_vec() + // .expect("decoding bs58 hash") + // } } diff --git a/src/util.rs b/src/util.rs index e2d9e9ce3..d02b45375 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,26 @@ -use anyhow::Result; +use std::collections::HashSet; + +use anyhow::{bail, Result}; +use openat_ext::OpenatDirExt; + +use std::process::Command; + +pub(crate) trait CommandRunExt { + fn run(&mut self) -> Result<()>; +} + +impl CommandRunExt for Command { + fn run(&mut self) -> Result<()> { + let r = self.status()?; + if !r.success() { + bail!("Child [{:?}] exited: {}", self, r); + } + Ok(()) + } +} /// Parse an environment variable as UTF-8 +#[allow(dead_code)] pub(crate) fn getenv_utf8(n: &str) -> Result> { if let Some(v) = std::env::var_os(n) { Ok(Some( @@ -16,3 +36,36 @@ pub(crate) fn getenv_utf8(n: &str) -> Result> { pub(crate) fn running_in_test_suite() -> bool { !nix::unistd::getuid().is_root() } + +pub(crate) fn filenames(dir: &openat::Dir) -> Result> { + let mut ret = HashSet::new(); + for entry in dir.list_dir(".")? { + let entry = entry?; + let name = if let Some(name) = entry.file_name().to_str() { + name + } else { + bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) + }; + match dir.get_file_type(&entry)? { + openat::SimpleType::File => { + ret.insert(format!("/{}", name)); + } + openat::SimpleType::Dir => { + let child = dir.sub_dir(name)?; + for mut k in filenames(&child)?.drain() { + k.reserve(name.len() + 1); + k.insert_str(0, name); + k.insert(0, '/'); + ret.insert(k); + } + } + openat::SimpleType::Symlink => { + bail!("Unsupported symbolic link {:?}", entry.file_name()) + } + openat::SimpleType::Other => { + bail!("Unsupported non-file/directory {:?}", entry.file_name()) + } + } + } + Ok(ret) +} diff --git a/systemd/bootupd.socket b/systemd/bootupd.socket index 7f8f558c0..c3f2269bc 100644 --- a/systemd/bootupd.socket +++ b/systemd/bootupd.socket @@ -1,6 +1,3 @@ -[Unit] -ConditionDirectoryNotEmpty=/sys/firmware/efi - [Socket] ListenSequentialPacket=/run/bootupd.sock SocketMode=0600 diff --git a/tests/kola/data b/tests/kola/data deleted file mode 120000 index a96aa0ea9..000000000 --- a/tests/kola/data +++ /dev/null @@ -1 +0,0 @@ -.. \ No newline at end of file diff --git a/tests/libtest.sh b/tests/kola/data/libtest.sh similarity index 100% rename from tests/libtest.sh rename to tests/kola/data/libtest.sh diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 6788d334c..d67e690c7 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -20,9 +20,11 @@ function cleanup () { } efibasedir=/boot/efi/ +bootupdir=/usr/lib/bootupd/updates +efiupdir=${bootupdir}/EFI ostbaseefi=/usr/lib/ostree-boot/efi/ efisubdir=EFI/fedora -efidir=${efibasedir}/${efisubdir} +efidir=${efiupdir}/${efisubdir} ostefi=${ostbaseefi}/${efisubdir} shim=shimx64.efi @@ -33,71 +35,26 @@ bootupd() { runv /usr/libexec/bootupd "$@" } -# Shouldn't be started by default right now; distributions -# should only enable when it was used at build time. -runv systemctl show bootupd > out.txt -assert_file_has_content_literal out.txt 'ActiveState=inactive' +prepare_efi_update() { + test -w /usr + cp -a ${efiupdir}.orig ${ostbaseefi} + rm -rf ${efiupdir} ${bootupdir}/EFI.json +} systemctl start bootupd.socket -bootupd status EFI > out.txt +bootupd status > out.txt assert_file_has_content_literal out.txt 'Component EFI' -assert_file_has_content_literal out.txt ' Unmanaged: digest=' -assert_not_file_has_content_literal out.txt 'Update: Available:' - -if bootupd update EFI 2>err.txt; then - fatal "performed an update without adopting" -fi -assert_file_has_content_literal err.txt 'Component EFI is not tracked and must be adopted before update' -ok 'cannot update without adoption' - -bootupd adopt | tee out.txt -assert_file_has_content_literal out.txt "Adopting: EFI" -ok 'adoption' - -bootupd adopt | tee out.txt -assert_not_file_has_content_literal out.txt "Adopting: EFI" -assert_file_has_content_literal out.txt "Nothing to do" -ok 'rerunning adopt is idempotent' - -cp --reflink=auto ${efidir}/${shim} shimx64.backup -echo 'oops state drift' >> ${efidir}/shimx64.efi -bootupd status EFI | tee out.txt -assert_file_has_content_literal out.txt 'warning: drift detected' -assert_file_has_content_literal out.txt 'Recorded: ' -assert_file_has_content_literal out.txt 'Actual: sha512:' -mv shimx64.backup ${efidir}/shimx64.efi -bootupd status EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'warning: drift detected' -ok 'drift detected' +assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' +assert_file_has_content_literal out.txt 'Update: At latest version' -# TODO do better tests that +# From here we'll fake updates rpm-ostree usroverlay +# Save a backup copy of the update dir +cp -a ${efiupdir}{,.orig} -bootupd status EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'Update: Available' -cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup -echo 'updated shimx64.efi' > ${ostefi}/${shim} -bootupd status EFI | tee out.txt -assert_file_has_content_literal out.txt 'Update: Available' -cp --reflink=auto shimx64.efi.backup ${ostefi}/${shim} -bootupd status EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'Update: Available' -ok 'update available' +prepare_efi_update -bootupd status EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'Update: Available' -cp --reflink=auto ${ostefi}/${shim} shimx64.efi.backup -echo 'updated shimx64.efi' > ${ostefi}/${shim} -bootupd update EFI | tee out.txt -assert_file_has_content_literal out.txt 'EFI: Updated to digest=' -assert_not_file_has_content_literal out.txt 'EFI: no updates available' -bootupd status EFI | tee out.txt -assert_not_file_has_content_literal out.txt 'warning: drift detected' -assert_not_file_has_content_literal out.txt 'Update: Available' -if ! test -f "${efidir}/grub.cfg"; then - fatal "missing unmanaged grub cfg" -fi -ok 'update' +# FIXME need to generate RPMs to sanely test updates tap_finish From 06ddc7add2e0d950b70fbd92459706eec2ed1c30 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 3 Sep 2020 12:59:04 +0000 Subject: [PATCH 037/641] README.md: Various updates Various bits. Closes: https://github.com/coreos/bootupd/issues/1 --- README.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb58518a5..95db16dcc 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ OS update system agnostic tool to manage updates for things like: This project originated in [this Fedora CoreOS github issue](https://github.com/coreos/fedora-coreos-tracker/issues/510). +The scope is otherwise limited; for example, bootupd will not +manage anything related to the kernel such as kernel arguments; +that's for tools like `grubby` and `ostree`. + ## Status Currently a work in progress and is not ready to ship for production @@ -32,20 +36,30 @@ updates, but early feedback on the design is appreciated! ## Relationship to other projects +### dbxtool + +[dbxtool](https://github.com/rhboot/dbxtool) manages updates +to the Secure Boot database - `bootupd` will likely need to +perform any updates to the `shimx64.efi` binary +*before* `dbxtool.service` starts. But otherwise they are independent. + ### fwupd bootupd could be compared to [fwupd](https://github.com/fwupd/fwupd/) which is project that exists today to update hardware device firmware - things not managed by e.g. `apt/zypper/yum/rpm-ostree update` today. -fwupd comes as a UEFI binary today, so bootupd would actually take care of updating fwupd itself. - -The end result is that a system administrator would have 3 projects to monitor -(one for hardware devices and 2 for the bootloader and OS state) but each -would be clearly focused on its domain and handle it well. This stands -in contrast with e.g. having an RPM `%post` script try to regenerate the BIOS MBR. +fwupd comes as a UEFI binary today, so bootupd *could* take care of updating `fwupd` +but today fwupd handles that itself. So it's likely that bootupd would only take +care of GRUB and shim. See discussion in [this issue](https://github.com/coreos/bootupd/issues/1). ### systemd bootctl [systemd bootctl](https://man7.org/linux/man-pages/man1/bootctl.1.html) can update itself; this project would probably just proxy that if we detect systemd-boot is in use. + +## Other goals + +One idea is that bootupd could help support [redundant bootable disks](https://github.com/coreos/fedora-coreos-tracker/issues/581). +For various reasons it doesn't really work to try to use RAID1 for an entire disk; the ESP must be handled +specially. `bootupd` could learn how to synchronize multiple EFI system partitions from a primary. From 5c23caf0ddcda38099255ac842758c21e3ab45b2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Sep 2020 21:44:19 +0000 Subject: [PATCH 038/641] Fix update, clippy warnings, and start passing test suite The test suite now passes again and has somewhat basic reasonable coverage. --- src/bootupd.rs | 45 ++++++++++++++++++++----------- src/component.rs | 4 +-- src/efi.rs | 15 +++++++---- src/filetree.rs | 21 ++------------- src/sha512string.rs | 10 ------- tests/kola/test-bootupd | 59 ++++++++++++++++++++++++++++++++++------- 6 files changed, 92 insertions(+), 62 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 31264b46f..02647e25e 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -140,34 +140,49 @@ fn acquire_write_lock>(sysroot: P) -> Result { } fn update(_opts: &UpdateOptions) -> Result { + let sysroot = openat::Dir::open("/")?; let _lock = acquire_write_lock("/")?; let mut r = String::new(); - let state = get_saved_state("/")?.unwrap_or_else(|| SavedState { + let mut state = get_saved_state("/")?.unwrap_or_else(|| SavedState { ..Default::default() }); for component in get_components() { let installed = if let Some(i) = state.installed.get(component.name()) { i } else { - writeln!(r, "Component {} is not installed", component.name()).unwrap(); + writeln!(r, "Component {} is not installed", component.name())?; continue; }; - if let Some(update) = component.query_update()? { - component + let pending = component.query_update()?; + let update = match pending.as_ref() { + Some(p) if !p.compare(&installed.meta) => Some(p), + _ => None, + }; + if let Some(update) = update { + // FIXME make this more transactional by recording the fact that + // we're starting an update at least so we can detect if we + // were interrupted. + let newinst = component .run_update(&installed) .with_context(|| format!("Failed to update {}", component.name()))?; - writeln!(r, "Updated {}: {:?}", component.name(), update).unwrap(); + writeln!( + r, + "Updated {}: {}", + component.name(), + format_version(&update) + )?; + state.installed.insert(component.name().into(), newinst); + update_state(&sysroot, &state)?; } else { writeln!( r, "No update available for {}: {:?}", component.name(), installed - ) - .unwrap(); + )?; } } - Ok("".into()) + Ok(r) } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { @@ -224,19 +239,17 @@ fn print_component( r: &mut String, ) -> Result<()> { let name = component.name(); - writeln!(r, "Component {}", name).unwrap(); - writeln!(r, " Installed: {}", format_version(installed)).unwrap(); + writeln!(r, "Component {}", name)?; + writeln!(r, " Installed: {}", format_version(installed))?; let pending = component.query_update()?; let update = match pending.as_ref() { Some(p) if !p.compare(installed) => Some(p), _ => None, }; - dbg!(&pending); - dbg!(&update); if let Some(update) = update { - writeln!(r, " Update: Available: {}", format_version(&update)).unwrap(); + writeln!(r, " Update: Available: {}", format_version(&update))?; } else { - writeln!(r, " Update: At latest version").unwrap(); + writeln!(r, " Update: At latest version")?; } Ok(()) @@ -284,7 +297,7 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { }; let r = match r { Ok(s) => ipc::DaemonToClientReply::Success(s), - Err(e) => ipc::DaemonToClientReply::Failure(e.to_string()), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), }; let r = bincode::serialize(&r)?; let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; @@ -348,7 +361,7 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { print!("{}", buf); } ipc::DaemonToClientReply::Failure(buf) => { - bail!("error: {}", buf); + bail!("{}", buf); } } c.shutdown()?; diff --git a/src/component.rs b/src/component.rs index 90814c04b..788be54ac 100644 --- a/src/component.rs +++ b/src/component.rs @@ -21,7 +21,7 @@ pub(crate) trait Component { fn query_update(&self) -> Result>; - fn run_update(&self, current: &InstalledContent) -> Result<()>; + fn run_update(&self, current: &InstalledContent) -> Result; } pub(crate) fn new_from_name(name: &str) -> Result> { @@ -36,14 +36,12 @@ pub(crate) fn component_update_metapath(sysroot: &str, component: &dyn Component Path::new(sysroot) .join(BOOTUPD_UPDATES_DIR) .join(format!("{}.json", component.name())) - .to_path_buf() } pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { Path::new(sysroot) .join(BOOTUPD_UPDATES_DIR) .join(component.name()) - .to_path_buf() } /// Helper method for writing an update file diff --git a/src/efi.rs b/src/efi.rs index 71db40eb5..973285317 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -57,22 +57,26 @@ impl Component for EFI { anyhow::bail!("Failed to copy"); } Ok(InstalledContent { - meta: meta, + meta, filetree: Some(ft), }) } - fn run_update(&self, current: &InstalledContent) -> Result<()> { + fn run_update(&self, current: &InstalledContent) -> Result { let currentf = current .filetree .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; + let updatemeta = self.query_update()?.expect("update available"); let updated = openat::Dir::open(&component_updatedir("/", self))?; let updatef = filetree::FileTree::new_from_dir(&updated)?; let diff = currentf.diff(&updatef)?; - let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH))?; + let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI"))?; filetree::apply_diff(&updated, &destdir, &diff, None)?; - Ok(()) + Ok(InstalledContent { + meta: updatemeta, + filetree: Some(updatef), + }) } fn generate_update_metadata(&self, sysroot_path: &str) -> Result { @@ -97,7 +101,7 @@ impl Component for EFI { // directory today, and this will handle the copy fallback. let parent = dest_efidir .parent() - .ok_or(anyhow::anyhow!("Expected parent directory"))?; + .ok_or_else(|| anyhow::anyhow!("Expected parent directory"))?; std::fs::create_dir_all(&parent)?; Command::new("mv").args(&[&efisrc, &dest_efidir]).run()?; } @@ -136,6 +140,7 @@ impl Component for EFI { bail!("Failed to find any RPM packages matching files in source efidir"); } let timestamps: BTreeSet<&NaiveDateTime> = pkgs.values().collect(); + // Unwrap safety: We validated pkgs has at least one value above let largest_timestamp = timestamps.iter().last().unwrap(); let version = pkgs.keys().fold("".to_string(), |mut s, n| { if !s.is_empty() { diff --git a/src/filetree.rs b/src/filetree.rs index c3f92d67b..07945e6b8 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -73,13 +73,6 @@ impl FileMetadata { sha512: digest, }) } - - // pub(crate) fn extend_hash(&self, hasher: &mut Hasher) { - // let mut lenbuf = [0; 8]; - // byteorder::BigEndian::write_u64(&mut lenbuf, self.size); - // hasher.update(&lenbuf).unwrap(); - // hasher.update(&self.sha512.digest_bytes()).unwrap(); - // } } #[allow(dead_code)] // Used for testing @@ -122,16 +115,6 @@ impl FileTree { Ok(ret) } - // pub(crate) fn digest(&self) -> SHA512String { - // let mut hasher = - // Hasher::new(MessageDigest::sha512()).expect("openssl sha512 hasher creation failed"); - // for (k, v) in self.children.iter() { - // hasher.update(k.as_bytes()).unwrap(); - // v.extend_hash(&mut hasher); - // } - // SHA512String::from_hasher(&mut hasher) - // } - /// Create a FileTree from the target directory. pub(crate) fn new_from_dir(dir: &openat::Dir) -> Result { let mut children = BTreeMap::new(); @@ -243,8 +226,8 @@ fn copy_file_at, DP: AsRef>( use openat_ext::FileExt as OpenatFileExt; let srcp = srcp.as_ref(); let srcf = srcdir.open_file(srcp)?; - let mut destf = destdir.write_file(destp.as_ref(), srcf.metadata()?.st_mode())?; - srcf.copy_to(&mut destf)?; + let destf = destdir.write_file(destp.as_ref(), srcf.metadata()?.st_mode())?; + srcf.copy_to(&destf)?; Ok(()) } diff --git a/src/sha512string.rs b/src/sha512string.rs index c086fa3a0..578b170c9 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -24,14 +24,4 @@ impl SHA512String { bs58::encode(hasher.finish().expect("completing hash")).into_string() )) } - - // pub(crate) fn digest_bs58(&self) -> &str { - // self.0.splitn(2, ':').next().unwrap() - // } - - // pub(crate) fn digest_bytes(&self) -> Vec { - // bs58::decode(self.digest_bs58()) - // .into_vec() - // .expect("decoding bs58 hash") - // } } diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index d67e690c7..acbce4a2d 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,17 +19,16 @@ function cleanup () { fi } -efibasedir=/boot/efi/ +bootefidir=/boot/efi/EFI bootupdir=/usr/lib/bootupd/updates efiupdir=${bootupdir}/EFI -ostbaseefi=/usr/lib/ostree-boot/efi/ -efisubdir=EFI/fedora +ostbaseefi=/usr/lib/ostree-boot/efi/EFI +efisubdir=fedora efidir=${efiupdir}/${efisubdir} ostefi=${ostbaseefi}/${efisubdir} shim=shimx64.efi -test -f "${efidir}"/${shim} -test -f "${ostefi}"/${shim} +test -f "${efidir}/${shim}" bootupd() { runv /usr/libexec/bootupd "$@" @@ -37,7 +36,8 @@ bootupd() { prepare_efi_update() { test -w /usr - cp -a ${efiupdir}.orig ${ostbaseefi} + mkdir -p ${ostbaseefi} + cp -a ${efiupdir}.orig/* ${ostbaseefi}/ rm -rf ${efiupdir} ${bootupdir}/EFI.json } @@ -47,14 +47,55 @@ bootupd status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' +ok status # From here we'll fake updates -rpm-ostree usroverlay +test -w /usr || rpm-ostree usroverlay # Save a backup copy of the update dir -cp -a ${efiupdir}{,.orig} +cp -a ${efiupdir} ${efiupdir}.orig prepare_efi_update +# FIXME need to synthesize an RPM for this +# echo somenewfile > ${ostefi}/somenew.efi +rm -v ${ostefi}/shim.efi +echo bootupd-test-changes >> ${ostefi}/grubx64.efi +bootupd generate-update-metadata / +ver=$(jq -r .version < ${bootupdir}/EFI.json) +cat >ver.json << EOF +{ "version": "${ver},test" } +EOF +jq -s add ${bootupdir}/EFI.json ver.json > new.json +mv new.json ${bootupdir}/EFI.json -# FIXME need to generate RPMs to sanely test updates +bootupd status | tee out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' +assert_not_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' +assert_file_has_content_literal out.txt 'Update: Available:' +ok update avail + +bootupd update | tee out.txt +assert_file_has_content out.txt 'Updated EFI: grub2-efi-x64.*,test' + +bootupd status > out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' +assert_file_has_content_literal out.txt 'Update: At latest version' +ok status after update + +# FIXME see above +# assert_file_has_content ${bootefidir}/${efisubdir}/somenew.efi 'somenewfile' +if test -f ${bootefidir}/${efisubdir}/shim.efi; then + fatal "failed to remove file" +fi +if ! grep -q 'bootupd-test-changes' ${bootefidir}/${efisubdir}/grubx64.efi; then + fatal "failed to update modified file" +fi +cmp ${bootefidir}/${efisubdir}/shimx64.efi ${efiupdir}/${efisubdir}/shimx64.efi +ok filesystem changes + +bootupd update | tee out.txt +assert_file_has_content_literal out.txt 'No update available for EFI' +assert_not_file_has_content_literal out.txt 'Updated EFI' tap_finish From c8b0ba1dfc6e746f9764539597834503e4be1f3e Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Tue, 8 Sep 2020 09:28:39 -0400 Subject: [PATCH 039/641] README.md: Fix missing word --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95db16dcc..de5a8687d 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ perform any updates to the `shimx64.efi` binary ### fwupd bootupd could be compared to [fwupd](https://github.com/fwupd/fwupd/) which is -project that exists today to update hardware device firmware - things not managed +a project that exists today to update hardware device firmware - things not managed by e.g. `apt/zypper/yum/rpm-ostree update` today. fwupd comes as a UEFI binary today, so bootupd *could* take care of updating `fwupd` From d3ccaba5c69f920b83440d186e6380ce155a244f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Sep 2020 21:37:45 +0000 Subject: [PATCH 040/641] Clean up used crates First, sort alphabetically. Then drop some unused crates, some needed looser versions. For now drop bs58 since it's a minor optimization for UX for the (currently not really used sha512string). This gets us to just needing openat-ext packaged for Fedora. --- Cargo.toml | 28 +++++++++++----------------- src/sha512string.rs | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 44a49a592..417b66e73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,28 +14,22 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" -serde = "1.0.112" -serde_derive = "1.0.112" -serde_json = "1.0" -serde_yaml = "0.8" -libc = "0.2" +bincode = "1.3.1" +chrono = { version = "0.4.11", features = ["serde"] } +clap = "~2.33" fs2 = "0.4.3" +hex = "0.4.2" +libc = "^0.2" +libsystemd = "^0.2" nix = "0.17.0" -tempfile = "3.0.3" -clap = "~2.33" -structopt = "0.3" openat = "0.1.19" openat-ext = "0.1.0" openssl = "^0.10" -libsystemd = "^0.2" -hex = "0.4.2" -bincode = "1.3.1" -bs58 = "0.3.1" -byteorder = "1" -c_utf8 = "0.1.0" -lazy_static = "1.1.0" -serde_plain = "0.3.0" -chrono = { version = "0.4.11", features = ["serde"] } +serde = "^1.0" +serde_derive = "^1.0" +serde_json = "^1.0" +structopt = "0.3" +tempfile = "^3.1" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo diff --git a/src/sha512string.rs b/src/sha512string.rs index 578b170c9..89f8f7443 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -21,7 +21,7 @@ impl SHA512String { pub(crate) fn from_hasher(hasher: &mut Hasher) -> Self { Self(format!( "sha512:{}", - bs58::encode(hasher.finish().expect("completing hash")).into_string() + hex::encode(hasher.finish().expect("completing hash")) )) } } From 0dfa15d5798eab0628a5a5ea411d449448c6750a Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Thu, 10 Sep 2020 13:56:32 +0000 Subject: [PATCH 041/641] cargo: directly use serde derive feature This tweaks serde usage in order to directly consume its derive feature. --- Cargo.toml | 3 +-- src/bootupd.rs | 2 +- src/efi.rs | 2 +- src/filetree.rs | 2 +- src/ipc.rs | 2 +- src/model.rs | 2 +- src/sha512string.rs | 2 +- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 417b66e73..e25cd1fa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,7 @@ nix = "0.17.0" openat = "0.1.19" openat-ext = "0.1.0" openssl = "^0.10" -serde = "^1.0" -serde_derive = "^1.0" +serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" structopt = "0.3" tempfile = "^3.1" diff --git a/src/bootupd.rs b/src/bootupd.rs index 02647e25e..d3455813e 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -10,7 +10,7 @@ use anyhow::{bail, Context, Result}; use fs2::FileExt; use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::fmt::Write as WriteFmt; use std::io::prelude::*; use std::path::Path; diff --git a/src/efi.rs b/src/efi.rs index 973285317..48ca08127 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -10,7 +10,7 @@ use std::path::Path; use std::process::Command; use anyhow::{bail, Result}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use chrono::NaiveDateTime; diff --git a/src/filetree.rs b/src/filetree.rs index 07945e6b8..3caee2c1d 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -8,7 +8,7 @@ use anyhow::{bail, Context, Result}; use chrono::prelude::*; use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet}; use std::os::linux::fs::MetadataExt; use std::os::unix::io::AsRawFd; diff --git a/src/ipc.rs b/src/ipc.rs index 46d04a82d..a6da73060 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -6,7 +6,7 @@ use anyhow::{bail, Context, Result}; use nix::sys::socket as nixsocket; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::os::unix::io::RawFd; pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; diff --git a/src/model.rs b/src/model.rs index eaf55e506..73ca99353 100644 --- a/src/model.rs +++ b/src/model.rs @@ -5,7 +5,7 @@ */ use chrono::prelude::*; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; /// The directory where updates are stored diff --git a/src/sha512string.rs b/src/sha512string.rs index 89f8f7443..fbc1c9adb 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -5,7 +5,7 @@ */ use openssl::hash::Hasher; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] From 3e0bfc5ac6e032ad5ed22a6a082a5d63f6735aae Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Sep 2020 21:06:52 +0000 Subject: [PATCH 042/641] Add functional RPM packaging Roughly derived from `rust-afterburn.spec`. --- packaging/bootupd.spec | 56 ------------------------------- packaging/rust-bootupd.spec | 67 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 56 deletions(-) delete mode 100644 packaging/bootupd.spec create mode 100644 packaging/rust-bootupd.spec diff --git a/packaging/bootupd.spec b/packaging/bootupd.spec deleted file mode 100644 index a74726796..000000000 --- a/packaging/bootupd.spec +++ /dev/null @@ -1,56 +0,0 @@ -%bcond_without check -%global __cargo_skip_build 0 - -%global crate bootupd - -Name: %{crate} -Version: 0.1.0 -Release: 1%{?dist} -Summary: Bootloader updater - -License: ASL 2.0 -URL: https://crates.io/crates/bootupd -Source0: https://crates.io/api/v1/crates/%{crate}/%{version}/download#/%{crate}-%{version}.crate -Source1: https://github.com/coreos/bootupd/releases/download/v%{version}/%{crate}-%{version}-vendor.tar.gz - -# For now, see upstream -ExclusiveArch: x86_64 -BuildRequires: openssl-devel -%if 0%{?rhel} && !0%{?eln} -BuildRequires: rust-toolset -%else -BuildRequires: cargo -BuildRequires: rust -%endif -BuildRequires: systemd - -%description -%{summary} - -%files -%license LICENSE -%doc README.md -%{_libexecdir}/bootupd -%{_unitdir}/* - -%prep -# FIXME shouldn't both source0/source be extracted with this? -%autosetup -n %{crate}-%{version} -p1 -%autosetup -n %{crate}-%{version} -p1 -a 1 -# https://github.com/rust-lang-nursery/error-chain/pull/289 -find -name '*.rs' -executable -exec chmod a-x {} \; -mkdir -p .cargo -cat >.cargo/config << 'EOF' -[source.crates-io] -registry = 'https://github.com/rust-lang/crates.io-index' -replace-with = 'vendored-sources' - -[source.vendored-sources] -directory = './vendor' -EOF - -%build -%cargo_build - -%install -%make_install INSTALL="install -p -c" diff --git a/packaging/rust-bootupd.spec b/packaging/rust-bootupd.spec new file mode 100644 index 000000000..d3e884949 --- /dev/null +++ b/packaging/rust-bootupd.spec @@ -0,0 +1,67 @@ +%bcond_without check +%global __cargo_skip_build 0 + +%global crate bootupd + +Name: rust-%{crate} +Version: 0.1.0 +Release: 3%{?dist} +Summary: Bootloader updater + +License: ASL 2.0 +URL: https://crates.io/crates/bootupd +Source: %{crates_source} + +# For now, see upstream +ExclusiveArch: x86_64 +BuildRequires: openssl-devel +%if 0%{?rhel} && !0%{?eln} +BuildRequires: rust-toolset +%else +BuildRequires: rust-packaging +%endif +BuildRequires: systemd + +%global _description %{expand: +Bootloader updater} +%description %{_description} + +%package -n %{crate} +Summary: %{summary} +License: ASL 2.0 +%{?systemd_requires} + +%description -n %{crate} %{_description} + +%files -n %{crate} +%license LICENSE +%doc README.md +%{_libexecdir}/bootupd +%{_unitdir}/* + +%prep +%autosetup -n %{crate}-%{version_no_tilde} -p1 +%cargo_prep + +%generate_buildrequires +%cargo_generate_buildrequires + +%build +%cargo_build + +%install +%make_install INSTALL="install -p -c" + +%post -n %{crate} +%systemd_post bootupd.service bootupd.socket + +%preun -n %{crate} +%systemd_preun bootupd.service bootupd.socket + +%postun -n %{crate} +%systemd_postun bootupd.service bootupd.socket + +%changelog +* Fri Sep 11 2020 Colin Walters - 0.1.0-3 +- Initial package + From e7cadf188094799ba9f817b87a63fce6741e326c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 11 Sep 2020 17:29:07 +0000 Subject: [PATCH 043/641] Add some CI infrastructure Prep for adding this to OpenShift Prow and CoreOS CI. --- .cci.jenkinsfile | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ OWNERS | 17 +++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 .cci.jenkinsfile create mode 100644 OWNERS diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile new file mode 100644 index 000000000..40ed37276 --- /dev/null +++ b/.cci.jenkinsfile @@ -0,0 +1,56 @@ +// Documentation: https://github.com/coreos/coreos-ci/blob/master/README-upstream-ci.md + +stage("Build") { +parallel build: { + def n = 5 + cosaPod(buildroot: true, runAsUser: 0, memory: "2Gi", cpu: "${n}") { + checkout scm + stage("Core build") { + shwrap(""" + make -j ${n} + """) + } + stage("Unit tests") { + shwrap(""" + cargo test + """) + } + shwrap(""" + make install DESTDIR=\$(pwd)/insttree/ + tar -c -C insttree/ -zvf insttree.tar.gz . + """) + stash includes: 'insttree.tar.gz', name: 'build' + } +}, +codestyle: { + cosaPod { + checkout scm + shwrap("cargo fmt -- --check") + } +} +} + +// Build FCOS and do a kola basic run +// stage("FCOS") { +// cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { +// stage("Build FCOS") { +// checkout scm +// unstash 'build' +// shwrap(""" +// mkdir insttree +// tar -C insttree -xzvf insttree.tar.gz +// rsync -rlv insttree/ / +// coreos-assembler init --force https://github.com/coreos/fedora-coreos-config +// mkdir -p overrides/rootfs +// mv insttree/* overrides/rootfs/ +// rmdir insttree +// coreos-assembler fetch +// coreos-assembler build +// """) +// } +// stage("Test") { +// fcosKola(cosaDir: "${env.WORKSPACE}") +// } +// } +// } + diff --git a/OWNERS b/OWNERS new file mode 100644 index 000000000..97350e99a --- /dev/null +++ b/OWNERS @@ -0,0 +1,17 @@ +# This list is outdated, but it's copied from coreos-assembler +# Once we figure out a better way to maintain it please ensure +# that coreos-assembler is fixed first. +approvers: + - arithx + - ashcrow + - bgilbert + - cgwalters + - darkmuggle + - dustymabe + - jlebon + - LorbusChris + - lucab + - miabbott + - mike-nguyen + - yuqi-zhddang + - zonggen From 5c8abf5fb38ec5ede7b64db063de42c9b152978a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Sep 2020 19:49:48 +0000 Subject: [PATCH 044/641] bootupd.service: Add ProtectHome=yes One of the benefits of running as a systemd service is getting simple declarative access to sandboxing/containerization. Since bootupd should never touch `/home`, let's flip on that flag. Also add `MountFlags=slave` in preparation for support for handling read-only default mounts for `/boot/efi` for example, like what ostree does for `/sysroot`. --- systemd/bootupd.service | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 45491e7d2..91464e97d 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -1,6 +1,11 @@ [Unit] Description=bootloader update daemon +Documentation=https://github.com/coreos/bootupd [Service] Type=notify ExecStart=/usr/libexec/bootupd daemon +# On general principle +ProtectHome=yes +# So we can remount /boot writable +MountFlags=slave From 39fbe630cb98c514bd93294796f6070d07340bd7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 15 Sep 2020 20:03:32 +0000 Subject: [PATCH 045/641] sha512string: Add a test Just on general principle. --- src/sha512string.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sha512string.rs b/src/sha512string.rs index fbc1c9adb..4c473b1ad 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -25,3 +25,17 @@ impl SHA512String { )) } } + +#[cfg(test)] +mod test { + use super::*; + use anyhow::Result; + + #[test] + fn test_empty() -> Result<()> { + let mut h = Hasher::new(openssl::hash::MessageDigest::sha512())?; + let s = SHA512String::from_hasher(&mut h); + assert_eq!("sha512:cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", format!("{}", s)); + Ok(()) + } +} From 756ce84c0c77c1610f8a303febdb3d2c219bb3dc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 15 Sep 2020 20:29:50 +0000 Subject: [PATCH 046/641] Cargo.toml: Add description/license --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index e25cd1fa2..2e1f6f310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [package] name = "bootupd" +description = "Bootloader updater" +license = "Apache-2.0" version = "0.1.0" authors = ["Colin Walters "] edition = "2018" From 721b887e20db69c61284c5f9318a824ceb72abdf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 15 Sep 2020 19:45:10 +0000 Subject: [PATCH 047/641] Move binary to /usr/bin/bootupctl A good way to look at what we need is something much like systemd's `bootctl` except for shim/grub2. It's not as nice for admins to explicitly type `/usr/libexec/bootupd`, plus it intermixes options with things they shouldn't use. Move the "backend" options to a hidden `backend` verb for now. --- Cargo.toml | 2 +- Makefile | 2 +- packaging/rust-bootupd.spec | 2 +- src/bootupd.rs | 70 +++++++++++++++++++++++-------------- systemd/bootupd.service | 2 +- tests/kola/test-bootupd | 16 ++++----- 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e1f6f310..c24b0e16b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ name = "bootupd" path = "src/bootupd.rs" [[bin]] -name = "bootupd" +name = "bootupctl" path = "src/main.rs" [dependencies] diff --git a/Makefile b/Makefile index 9ce2719f6..0ce73e0e6 100644 --- a/Makefile +++ b/Makefile @@ -37,4 +37,4 @@ install-units: $(units) .PHONY: install install: install-units - install -D -t ${DESTDIR}$(PREFIX)/libexec target/${PROFILE}/bootupd + install -D -t ${DESTDIR}$(PREFIX)/bin target/${PROFILE}/bootupctl diff --git a/packaging/rust-bootupd.spec b/packaging/rust-bootupd.spec index d3e884949..7f7a6b4dd 100644 --- a/packaging/rust-bootupd.spec +++ b/packaging/rust-bootupd.spec @@ -36,7 +36,7 @@ License: ASL 2.0 %files -n %{crate} %license LICENSE %doc README.md -%{_libexecdir}/bootupd +%{_bindir}/bootupctl %{_unitdir}/* %prep diff --git a/src/bootupd.rs b/src/bootupd.rs index d3455813e..30b478f9e 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -58,10 +58,11 @@ struct StatusOptions { json: bool, } +// Options exposed by `bootupctl backend` #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(name = "boot-update")] #[structopt(rename_all = "kebab-case")] -enum Opt { +enum BackendOpt { /// Install data from available components into a disk image Install { /// Source root @@ -75,6 +76,13 @@ enum Opt { /// Physical root mountpoint sysroot: String, }, +} + +// "end user" options, i.e. what people should run on client systems +#[derive(Debug, Serialize, Deserialize, StructOpt)] +#[structopt(name = "boot-update")] +#[structopt(rename_all = "kebab-case")] +enum Opt { /// Update available components Update(UpdateOptions), /// Print the current state @@ -293,7 +301,6 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { println!("Processing status"); status(opts) } - _ => Err(anyhow::anyhow!("Invalid option")), }; let r = match r { Ok(s) => ipc::DaemonToClientReply::Success(s), @@ -336,36 +343,47 @@ fn daemon() -> Result<()> { } } -/// Main entrypoint -pub fn boot_update_main(args: &[String]) -> Result<()> { - if let Some(arg1) = args.get(1) { - if arg1 == "daemon" { - return daemon(); - } - } - let opt = Opt::from_iter(args.iter()); +pub fn backend_main(args: &[&str]) -> Result<()> { + let opt = BackendOpt::from_iter(args.iter()); match opt { - Opt::Install { + BackendOpt::Install { src_root, dest_root, } => install(&src_root, &dest_root).context("boot data installation failed")?, - Opt::GenerateUpdateMetadata { sysroot } => { + BackendOpt::GenerateUpdateMetadata { sysroot } => { generate_update_metadata(&sysroot).context("generating metadata failed")? } - o @ Opt::Update(_) | o @ Opt::Status(_) => { - let mut c = ipc::ClientToDaemonConnection::new(); - c.connect()?; - let r = c.send(&o)?; - match r { - ipc::DaemonToClientReply::Success(buf) => { - print!("{}", buf); - } - ipc::DaemonToClientReply::Failure(buf) => { - bail!("{}", buf); - } - } - c.shutdown()?; - } }; Ok(()) } + +pub fn frontend_main(args: &[&str]) -> Result<()> { + let opt = Opt::from_iter(args.iter()); + let mut c = ipc::ClientToDaemonConnection::new(); + c.connect()?; + let r = c.send(&opt)?; + match r { + ipc::DaemonToClientReply::Success(buf) => { + print!("{}", buf); + } + ipc::DaemonToClientReply::Failure(buf) => { + bail!("{}", buf); + } + } + c.shutdown()?; + Ok(()) +} + +/// Main entrypoint +pub fn boot_update_main(args: &[String]) -> Result<()> { + let mut args: Vec<&str> = args.iter().map(|s| s.as_str()).collect(); + if let Some(&argv1) = args.get(1) { + if argv1 == "backend" { + args.remove(1); + return backend_main(&args); + } else if argv1 == "daemon" { + return daemon(); + } + } + return frontend_main(&args); +} diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 91464e97d..7f412e99f 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -4,7 +4,7 @@ Documentation=https://github.com/coreos/bootupd [Service] Type=notify -ExecStart=/usr/libexec/bootupd daemon +ExecStart=/usr/bin/bootupctl daemon # On general principle ProtectHome=yes # So we can remount /boot writable diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index acbce4a2d..ab392ae50 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -30,10 +30,6 @@ shim=shimx64.efi test -f "${efidir}/${shim}" -bootupd() { - runv /usr/libexec/bootupd "$@" -} - prepare_efi_update() { test -w /usr mkdir -p ${ostbaseefi} @@ -43,7 +39,7 @@ prepare_efi_update() { systemctl start bootupd.socket -bootupd status > out.txt +bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' @@ -59,7 +55,7 @@ prepare_efi_update # echo somenewfile > ${ostefi}/somenew.efi rm -v ${ostefi}/shim.efi echo bootupd-test-changes >> ${ostefi}/grubx64.efi -bootupd generate-update-metadata / +bootupctl backend generate-update-metadata / ver=$(jq -r .version < ${bootupdir}/EFI.json) cat >ver.json << EOF { "version": "${ver},test" } @@ -67,17 +63,17 @@ EOF jq -s add ${bootupdir}/EFI.json ver.json > new.json mv new.json ${bootupdir}/EFI.json -bootupd status | tee out.txt +bootupctl status | tee out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_not_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' assert_file_has_content_literal out.txt 'Update: Available:' ok update avail -bootupd update | tee out.txt +bootupctl update | tee out.txt assert_file_has_content out.txt 'Updated EFI: grub2-efi-x64.*,test' -bootupd status > out.txt +bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' assert_file_has_content_literal out.txt 'Update: At latest version' @@ -94,7 +90,7 @@ fi cmp ${bootefidir}/${efisubdir}/shimx64.efi ${efiupdir}/${efisubdir}/shimx64.efi ok filesystem changes -bootupd update | tee out.txt +bootupctl update | tee out.txt assert_file_has_content_literal out.txt 'No update available for EFI' assert_not_file_has_content_literal out.txt 'Updated EFI' From 3e41539b3332d278f1431d7c52ceb42d88b0b664 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Sep 2020 18:53:47 +0000 Subject: [PATCH 048/641] main: Fix a clippy warning Will try to add this to CI at some point. --- src/bootupd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 30b478f9e..3c4084e36 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -385,5 +385,5 @@ pub fn boot_update_main(args: &[String]) -> Result<()> { return daemon(); } } - return frontend_main(&args); + frontend_main(&args) } From dcf786ae20229b7386531f01c72d8bd21811d314 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Sep 2020 13:44:12 +0000 Subject: [PATCH 049/641] ci: Fix test script The test naming convention changed in cosa, let's grab all the bootupd tests anyways in case we add more. --- ci/build-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/build-test.sh b/ci/build-test.sh index af3465337..77b5e2430 100755 --- a/ci/build-test.sh +++ b/ci/build-test.sh @@ -3,4 +3,4 @@ set -xeuo pipefail test -n "${COSA_DIR:-}" make cosa build-fast -kola run -E $(pwd) --qemu-image fastbuild-*-qemu.qcow2 --qemu-firmware uefi ext.bootupd +kola run -E $(pwd) --qemu-image fastbuild-*-qemu.qcow2 --qemu-firmware uefi ext.bootupd.'*' From 19e37dd9026291c4fd673658396680811d9f33e6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Sep 2020 15:14:56 -0400 Subject: [PATCH 050/641] Add Rust GH action So we have some CI while we wait for Prow to get fixed. --- .github/workflows/rust.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 000000000..3c13d1be2 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,22 @@ +name: Rust + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose From dc4f0e4064c70137d749069b7a489cceb7714a48 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Sep 2020 13:32:36 +0000 Subject: [PATCH 051/641] Track when an update is interrupted and print it We could handle this better, but let's at least start tracking when an update was interrupted so we can print it. --- src/bootupd.rs | 43 +++++++++++++++++++++++++++++++++++-------- src/model.rs | 3 +++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 3c4084e36..8a41c9806 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -104,6 +104,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { } let mut state = SavedState { installed: Default::default(), + pending: Default::default(), }; for component in components { let meta = component.install(source_root, dest_root)?; @@ -161,15 +162,23 @@ fn update(_opts: &UpdateOptions) -> Result { writeln!(r, "Component {} is not installed", component.name())?; continue; }; - let pending = component.query_update()?; - let update = match pending.as_ref() { + let update = component.query_update()?; + let update = match update.as_ref() { Some(p) if !p.compare(&installed.meta) => Some(p), _ => None, }; if let Some(update) = update { - // FIXME make this more transactional by recording the fact that - // we're starting an update at least so we can detect if we - // were interrupted. + let mut pending_container = state.pending.take().unwrap_or_default(); + if let Some(pending) = pending_container.get(component.name()) { + writeln!( + r, + "warning: Previous update {} was interrupted, continuing", + format_version(&pending) + )?; + } + + pending_container.insert(component.name().into(), update.clone()); + update_state(&sysroot, &state)?; let newinst = component .run_update(&installed) .with_context(|| format!("Failed to update {}", component.name()))?; @@ -180,6 +189,7 @@ fn update(_opts: &UpdateOptions) -> Result { format_version(&update) )?; state.installed.insert(component.name().into(), newinst); + pending_container.remove(component.name()); update_state(&sysroot, &state)?; } else { writeln!( @@ -244,16 +254,24 @@ fn format_version(meta: &ContentMetadata) -> String { fn print_component( component: &dyn Component, installed: &ContentMetadata, + pending: Option<&ContentMetadata>, r: &mut String, ) -> Result<()> { let name = component.name(); writeln!(r, "Component {}", name)?; writeln!(r, " Installed: {}", format_version(installed))?; - let pending = component.query_update()?; - let update = match pending.as_ref() { + let update = component.query_update()?; + let update = match update.as_ref() { Some(p) if !p.compare(installed) => Some(p), _ => None, }; + if let Some(pending) = pending { + writeln!( + r, + " WARNING: Update to {} was interrupted", + format_version(&pending) + )?; + } if let Some(update) = update { writeln!(r, " Update: Available: {}", format_version(&update))?; } else { @@ -273,7 +291,16 @@ fn status(opts: &StatusOptions) -> Result { for (name, ic) in state.installed.iter() { let component = component::new_from_name(&name)?; let component = component.as_ref(); - print_component(component, &ic.meta, &mut r)?; + print_component( + component, + &ic.meta, + state + .pending + .as_ref() + .map(|p| p.get(name.as_str())) + .flatten(), + &mut r, + )?; } Ok(r) } else { diff --git a/src/model.rs b/src/model.rs index 73ca99353..78eab361e 100644 --- a/src/model.rs +++ b/src/model.rs @@ -40,7 +40,10 @@ pub(crate) struct InstalledContent { #[derive(Serialize, Deserialize, Default, Debug)] #[serde(rename_all = "kebab-case")] pub(crate) struct SavedState { + /// Maps a component name to its currently installed version pub(crate) installed: BTreeMap, + /// Maps a component name to an in progress update + pub(crate) pending: Option>, } // Should be stored in /usr/lib/bootupd/edges.json From adf974c529e8091a933966303974312287934edb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Sep 2020 15:27:23 +0000 Subject: [PATCH 052/641] Release 0.1.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c24b0e16b..e099758a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.1.0" +version = "0.1.1" authors = ["Colin Walters "] edition = "2018" From 230e64c97f41a70640463ad765cec5e883abf824 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 19 Sep 2020 14:35:26 +0000 Subject: [PATCH 053/641] Rework IPC to use generics Prep for moving things like printing output to the client. --- src/bootupd.rs | 11 ++--------- src/ipc.rs | 16 +++++++++++----- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 8a41c9806..fd97fb0d5 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -388,15 +388,8 @@ pub fn frontend_main(args: &[&str]) -> Result<()> { let opt = Opt::from_iter(args.iter()); let mut c = ipc::ClientToDaemonConnection::new(); c.connect()?; - let r = c.send(&opt)?; - match r { - ipc::DaemonToClientReply::Success(buf) => { - print!("{}", buf); - } - ipc::DaemonToClientReply::Failure(buf) => { - bail!("{}", buf); - } - } + let r: String = c.send(&opt)?; + print!("{}", r); c.shutdown()?; Ok(()) } diff --git a/src/ipc.rs b/src/ipc.rs index a6da73060..7a1befb5a 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -15,8 +15,8 @@ pub(crate) const MSGSIZE: usize = 1_048_576; pub(crate) const BOOTUPD_HELLO_MSG: &str = "bootupd-hello\n"; #[derive(Debug, Serialize, Deserialize)] -pub(crate) enum DaemonToClientReply { - Success(String), +pub(crate) enum DaemonToClientReply { + Success(T), Failure(String), } @@ -65,13 +65,13 @@ impl ClientToDaemonConnection { Ok(()) } - pub(crate) fn send(&mut self, opt: &crate::Opt) -> Result { + pub(crate) fn send(&mut self, opt: &crate::Opt) -> Result { { let serialized = bincode::serialize(opt)?; let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) .context("client sending request")?; } - let reply: DaemonToClientReply = { + let reply: DaemonToClientReply = { let mut buf = [0u8; MSGSIZE]; let n = nixsocket::recv(self.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) .context("client recv")?; @@ -81,7 +81,13 @@ impl ClientToDaemonConnection { } bincode::deserialize(&buf).context("client parsing reply")? }; - Ok(reply) + match reply { + DaemonToClientReply::Success::(r) => Ok(r), + DaemonToClientReply::Failure(buf) => { + // For now we just prefix server + anyhow::bail!("internal error: {}", buf); + } + } } pub(crate) fn shutdown(&mut self) -> Result<()> { From dbe4b01783d836e7cb29f771cc86890ace8286ca Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Sep 2020 21:49:20 +0000 Subject: [PATCH 054/641] Move formatting of status to client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way we were just serializing a `String` from daemon → client was rather...crude. Instead have the daemon return a serialized status object which we print on the client end. --- src/bootupd.rs | 128 +++++++++++++++++++++------------------- src/model.rs | 23 ++++++++ tests/kola/test-bootupd | 4 ++ 3 files changed, 93 insertions(+), 62 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index fd97fb0d5..edeabf14d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -51,8 +51,6 @@ struct UpdateOptions { #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct StatusOptions { - components: Vec, - // Output JSON #[structopt(long)] json: bool, @@ -251,61 +249,29 @@ fn format_version(meta: &ContentMetadata) -> String { } } -fn print_component( - component: &dyn Component, - installed: &ContentMetadata, - pending: Option<&ContentMetadata>, - r: &mut String, -) -> Result<()> { - let name = component.name(); - writeln!(r, "Component {}", name)?; - writeln!(r, " Installed: {}", format_version(installed))?; - let update = component.query_update()?; - let update = match update.as_ref() { - Some(p) if !p.compare(installed) => Some(p), - _ => None, - }; - if let Some(pending) = pending { - writeln!( - r, - " WARNING: Update to {} was interrupted", - format_version(&pending) - )?; - } - if let Some(update) = update { - writeln!(r, " Update: Available: {}", format_version(&update))?; - } else { - writeln!(r, " Update: At latest version")?; - } - - Ok(()) -} - -fn status(opts: &StatusOptions) -> Result { - let state = get_saved_state("/")?; - if opts.json { - let r = serde_json::to_string(&state)?; - Ok(r) - } else if let Some(state) = state { - let mut r = String::new(); +fn status(_opts: &StatusOptions) -> Result { + let mut ret: Status = Default::default(); + if let Some(state) = get_saved_state("/")? { for (name, ic) in state.installed.iter() { let component = component::new_from_name(&name)?; let component = component.as_ref(); - print_component( - component, - &ic.meta, - state - .pending - .as_ref() - .map(|p| p.get(name.as_str())) - .flatten(), - &mut r, - )?; + let interrupted = state + .pending + .as_ref() + .map(|p| p.get(name.as_str())) + .flatten(); + let update = component.query_update()?; + ret.components.insert( + name.to_string(), + ComponentStatus { + installed: ic.meta.clone(), + interrupted: interrupted.cloned(), + update, + }, + ); } - Ok(r) - } else { - Ok("No components installed.".to_string()) - } + }; + Ok(ret) } fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { @@ -322,18 +288,19 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { let r = match opt { Opt::Update(ref opts) => { println!("Processing update"); - update(opts) + bincode::serialize(&match update(opts) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? } Opt::Status(ref opts) => { println!("Processing status"); - status(opts) + bincode::serialize(&match status(opts) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? } }; - let r = match r { - Ok(s) => ipc::DaemonToClientReply::Success(s), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - }; - let r = bincode::serialize(&r)?; let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; if written != r.len() { bail!("Wrote {} bytes to client, expected {}", written, r.len()); @@ -384,12 +351,49 @@ pub fn backend_main(args: &[&str]) -> Result<()> { Ok(()) } +fn print_status(status: &Status) { + for (name, component) in status.components.iter() { + println!("Component {}", name); + println!(" Installed: {}", format_version(&component.installed)); + + if let Some(i) = component.interrupted.as_ref() { + println!( + " WARNING: Previous update to {} was interrupted", + format_version(i) + ); + } + let update = match component.update.as_ref() { + Some(p) if !p.compare(&component.installed) => Some(p), + _ => None, + }; + if let Some(update) = update { + println!(" Update: Available: {}", format_version(&update)); + } else { + println!(" Update: At latest version"); + } + } +} + pub fn frontend_main(args: &[&str]) -> Result<()> { let opt = Opt::from_iter(args.iter()); let mut c = ipc::ClientToDaemonConnection::new(); c.connect()?; - let r: String = c.send(&opt)?; - print!("{}", r); + match &opt { + Opt::Status(statusopts) => { + let r: Status = c.send(&opt)?; + if statusopts.json { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + serde_json::to_writer_pretty(&mut stdout, &r)?; + } else { + print_status(&r); + } + } + Opt::Update(_) => { + let r: String = c.send(&opt)?; + print!("{}", r); + } + } c.shutdown()?; Ok(()) } diff --git a/src/model.rs b/src/model.rs index 78eab361e..5eb0b0882 100644 --- a/src/model.rs +++ b/src/model.rs @@ -46,6 +46,29 @@ pub(crate) struct SavedState { pub(crate) pending: Option>, } +/// The status of an individual component. +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ComponentStatus { + /// Currently installed version + pub(crate) installed: ContentMetadata, + /// In progress update that was interrupted + pub(crate) interrupted: Option, + /// Update in the deployed filesystem tree + pub(crate) update: Option, +} + +/// Representation of bootupd's worldview at a point in time. +/// This is intended to be a stable format that is output by `bootupctl status --json` +/// and parsed by higher level management tools. Transitively then +/// everything referenced from here should also be stable. +#[derive(Serialize, Deserialize, Default, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Status { + /// Maps a component name to status + pub(crate) components: BTreeMap, +} + // Should be stored in /usr/lib/bootupd/edges.json //#[derive(Serialize, Deserialize, Debug)] // #[serde(rename_all = "kebab-case")] diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ab392ae50..4d64cb4fa 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -70,6 +70,10 @@ assert_not_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' assert_file_has_content_literal out.txt 'Update: Available:' ok update avail +bootupctl status --json > status.json +jq -r '.components.EFI.installed.version' < status.json > installed.txt +assert_file_has_content installed.txt '^grub2-efi-x64' + bootupctl update | tee out.txt assert_file_has_content out.txt 'Updated EFI: grub2-efi-x64.*,test' From 0cb6012d8c71f3fb5281a8247b9bed25a86c959c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 20 Sep 2020 21:10:29 +0000 Subject: [PATCH 055/641] Move more update logic to client side Similar to the previous move of `status`, return a structure from the daemon and render it on the client. This actually moves more logic for updating to the client too; the IPC request updates just one component, and the client iterates over all installed components to update. This way we also better return "partial" status. --- src/bootupd.rs | 187 +++++++++++++++++++++++----------------- src/ipc.rs | 7 +- src/model.rs | 2 + tests/kola/test-bootupd | 2 +- 4 files changed, 118 insertions(+), 80 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index edeabf14d..2a7f11320 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -11,7 +11,6 @@ use fs2::FileExt; use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; -use std::fmt::Write as WriteFmt; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; @@ -36,18 +35,6 @@ pub(crate) const STATEFILE_DIR: &str = "boot"; pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; -#[derive(Debug, Serialize, Deserialize, StructOpt)] -#[structopt(rename_all = "kebab-case")] -struct UpdateOptions { - // Perform an update even if there is no state transition - #[structopt(long)] - force: bool, - - /// The destination ESP mount point - #[structopt(default_value = "/usr/share/bootd-transitions.json", long)] - state_transition_file: String, -} - #[derive(Debug, Serialize, Deserialize, StructOpt)] #[structopt(rename_all = "kebab-case")] struct StatusOptions { @@ -81,12 +68,21 @@ enum BackendOpt { #[structopt(name = "boot-update")] #[structopt(rename_all = "kebab-case")] enum Opt { - /// Update available components - Update(UpdateOptions), + /// Update all components + Update, /// Print the current state Status(StatusOptions), } +/// A message sent from client to server +#[derive(Debug, Serialize, Deserialize, StructOpt)] +enum ClientRequest { + /// Update a component + Update { component: String }, + /// Print the current state + Status, +} + pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { let statepath = Path::new(dest_root) .join(STATEFILE_DIR) @@ -146,59 +142,49 @@ fn acquire_write_lock>(sysroot: P) -> Result { Ok(lockf) } -fn update(_opts: &UpdateOptions) -> Result { +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +enum ComponentUpdateResult { + AtLatestVersion, + Updated { + previous: ContentMetadata, + interrupted: Option, + new: ContentMetadata, + }, +} + +fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; let _lock = acquire_write_lock("/")?; - let mut r = String::new(); let mut state = get_saved_state("/")?.unwrap_or_else(|| SavedState { ..Default::default() }); - for component in get_components() { - let installed = if let Some(i) = state.installed.get(component.name()) { - i - } else { - writeln!(r, "Component {} is not installed", component.name())?; - continue; - }; + let component = component::new_from_name(name)?; + if let Some(inst) = state.installed.get(name).cloned() { let update = component.query_update()?; let update = match update.as_ref() { - Some(p) if !p.compare(&installed.meta) => Some(p), - _ => None, + Some(p) if !p.compare(&inst.meta) => p, + _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; - if let Some(update) = update { - let mut pending_container = state.pending.take().unwrap_or_default(); - if let Some(pending) = pending_container.get(component.name()) { - writeln!( - r, - "warning: Previous update {} was interrupted, continuing", - format_version(&pending) - )?; - } - - pending_container.insert(component.name().into(), update.clone()); - update_state(&sysroot, &state)?; - let newinst = component - .run_update(&installed) - .with_context(|| format!("Failed to update {}", component.name()))?; - writeln!( - r, - "Updated {}: {}", - component.name(), - format_version(&update) - )?; - state.installed.insert(component.name().into(), newinst); - pending_container.remove(component.name()); - update_state(&sysroot, &state)?; - } else { - writeln!( - r, - "No update available for {}: {:?}", - component.name(), - installed - )?; - } + let mut pending_container = state.pending.take().unwrap_or_default(); + let interrupted = pending_container.get(component.name()).cloned(); + + pending_container.insert(component.name().into(), update.clone()); + update_state(&sysroot, &state)?; + let newinst = component + .run_update(&inst) + .with_context(|| format!("Failed to update {}", component.name()))?; + state.installed.insert(component.name().into(), newinst); + pending_container.remove(component.name()); + update_state(&sysroot, &state)?; + Ok(ComponentUpdateResult::Updated { + previous: inst.meta, + interrupted, + new: update.clone(), + }) + } else { + anyhow::bail!("Component {} is not installed", name); } - Ok(r) } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { @@ -249,7 +235,7 @@ fn format_version(meta: &ContentMetadata) -> String { } } -fn status(_opts: &StatusOptions) -> Result { +fn status() -> Result { let mut ret: Status = Default::default(); if let Some(state) = get_saved_state("/")? { for (name, ic) in state.installed.iter() { @@ -261,12 +247,17 @@ fn status(_opts: &StatusOptions) -> Result { .map(|p| p.get(name.as_str())) .flatten(); let update = component.query_update()?; + let updatable = match update.as_ref() { + Some(p) if !p.compare(&ic.meta) => true, + _ => false, + }; ret.components.insert( name.to_string(), ComponentStatus { installed: ic.meta.clone(), interrupted: interrupted.cloned(), update, + updatable, }, ); } @@ -284,18 +275,18 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { break; } - let opt = bincode::deserialize(&buf)?; - let r = match opt { - Opt::Update(ref opts) => { + let msg = bincode::deserialize(&buf)?; + let r = match msg { + ClientRequest::Update { component } => { println!("Processing update"); - bincode::serialize(&match update(opts) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), + bincode::serialize(&match update(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } - Opt::Status(ref opts) => { + ClientRequest::Status => { println!("Processing status"); - bincode::serialize(&match status(opts) { + bincode::serialize(&match status() { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? @@ -362,16 +353,59 @@ fn print_status(status: &Status) { format_version(i) ); } - let update = match component.update.as_ref() { - Some(p) if !p.compare(&component.installed) => Some(p), - _ => None, - }; - if let Some(update) = update { + if component.updatable { + let update = component.update.as_ref().expect("update"); println!(" Update: Available: {}", format_version(&update)); - } else { + } else if component.update.is_some() { println!(" Update: At latest version"); + } else { + println!(" Update: No update found"); + } + } +} + +fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { + let status: Status = c.send(&ClientRequest::Status)?; + if status.components.is_empty() { + println!("No components installed."); + return Ok(()); + } + let mut updated = false; + for (name, cstatus) in status.components.iter() { + if !cstatus.updatable { + continue; } + match c.send(&ClientRequest::Update { + component: name.to_string(), + })? { + ComponentUpdateResult::AtLatestVersion => { + // Shouldn't happen unless we raced with another client + eprintln!( + "warning: Expected update for {}, raced with a different client?", + name + ); + continue; + } + ComponentUpdateResult::Updated { + previous: _, + interrupted, + new, + } => { + if let Some(i) = interrupted { + eprintln!( + "warning: Continued from previous interrupted update: {}", + format_version(&i) + ); + } + println!("Updated {}: {}", name, format_version(&new)); + } + } + updated = true; } + if !updated { + println!("No update available for any component."); + } + Ok(()) } pub fn frontend_main(args: &[&str]) -> Result<()> { @@ -380,7 +414,7 @@ pub fn frontend_main(args: &[&str]) -> Result<()> { c.connect()?; match &opt { Opt::Status(statusopts) => { - let r: Status = c.send(&opt)?; + let r: Status = c.send(&ClientRequest::Status)?; if statusopts.json { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); @@ -389,9 +423,8 @@ pub fn frontend_main(args: &[&str]) -> Result<()> { print_status(&r); } } - Opt::Update(_) => { - let r: String = c.send(&opt)?; - print!("{}", r); + Opt::Update => { + client_run_update(&mut c)?; } } c.shutdown()?; diff --git a/src/ipc.rs b/src/ipc.rs index 7a1befb5a..5ba955261 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -65,9 +65,12 @@ impl ClientToDaemonConnection { Ok(()) } - pub(crate) fn send(&mut self, opt: &crate::Opt) -> Result { + pub(crate) fn send( + &mut self, + msg: &S, + ) -> Result { { - let serialized = bincode::serialize(opt)?; + let serialized = bincode::serialize(msg)?; let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) .context("client sending request")?; } diff --git a/src/model.rs b/src/model.rs index 5eb0b0882..b8eb16d97 100644 --- a/src/model.rs +++ b/src/model.rs @@ -56,6 +56,8 @@ pub(crate) struct ComponentStatus { pub(crate) interrupted: Option, /// Update in the deployed filesystem tree pub(crate) update: Option, + /// Is true if the version in `update` is different from `installed` + pub(crate) updatable: bool, } /// Representation of bootupd's worldview at a point in time. diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 4d64cb4fa..5cec4d403 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -95,7 +95,7 @@ cmp ${bootefidir}/${efisubdir}/shimx64.efi ${efiupdir}/${efisubdir}/shimx64.efi ok filesystem changes bootupctl update | tee out.txt -assert_file_has_content_literal out.txt 'No update available for EFI' +assert_file_has_content_literal out.txt 'No update available for any component' assert_not_file_has_content_literal out.txt 'Updated EFI' tap_finish From 246d0a7883a7f5be09ca411f90276b9c0f16633d Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 21 Sep 2020 09:02:47 +0000 Subject: [PATCH 056/641] docs: add machine-readable COPYRIGHT --- COPYRIGHT | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 COPYRIGHT diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 000000000..62c7d7b2c --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,7 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: bootupd +Source: https://www.github.com/coreos/bootupd + +Files: * +Copyright: 2020 Red Hat, Inc. +License: Apache-2.0 From 8543785c41bbbf51c66023731583befc262e8457 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 21 Sep 2020 08:45:30 +0000 Subject: [PATCH 057/641] cargo: add env_logger and log --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index e099758a7..491542a30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,12 @@ anyhow = "1.0" bincode = "1.3.1" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" +env_logger = "^0.7" fs2 = "0.4.3" hex = "0.4.2" libc = "^0.2" libsystemd = "^0.2" +log = "^0.4" nix = "0.17.0" openat = "0.1.19" openat-ext = "0.1.0" From 545f0e8503179ea9cd6a918af3485f68f81e5ae9 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 21 Sep 2020 09:43:13 +0000 Subject: [PATCH 058/641] main: setup logging This introduces and sets up a logging environment for all CLI logic. It also re-arranges docstrings so that they properly appear in rustdoc output. --- src/bootupd.rs | 17 ++++++++++++----- src/main.rs | 37 ++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 2a7f11320..4d951ee34 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,8 +1,15 @@ -/* - * Copyright (C) 2020 Red Hat, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ +/*! +**Boot**loader **upd**ater. + +This is an early prototype hidden/not-yet-standardized mechanism +which just updates EFI for now (x86_64/aarch64 only). + +But in the future will hopefully gain some independence from +ostree and also support e.g. updating the MBR etc. + +Refs: + * +!*/ #![deny(unused_must_use)] diff --git a/src/main.rs b/src/main.rs index 44d82d1a0..3b67410ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,33 @@ -/* - * Copyright (C) 2020 Red Hat, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ +//! Bootupd command-line application. -//! See: https://github.com/coreos/fedora-coreos-tracker/issues/510 -//! This is an early prototype hidden/not-yet-standardized mechanism -//! which just updates EFI for now (x86_64/aarch64 only). -//! -//! But in the future will hopefully gain some independence from -//! ostree and also support e.g. updating the MBR etc. - -// To run the unit tests for this code, use `make check TESTS=tests/check/test-ex-boot-update.sh` +use log::LevelFilter; +use structopt::clap::crate_name; +/// Binary entrypoint, for both daemon and client logic. fn main() { + let exit_code = run_cli(); + std::process::exit(exit_code); +} + +/// CLI logic. +fn run_cli() -> i32 { + // Gather command-line options. let args: Vec<_> = std::env::args().collect(); + + // Setup logging. + env_logger::Builder::from_default_env() + .format_timestamp(None) + .format_module_path(false) + .filter(Some(crate_name!()), LevelFilter::Warn) + .init(); + + // Dispatch CLI subcommand. match bootupd::boot_update_main(&args) { - Ok(_) => {} + Ok(_) => libc::EXIT_SUCCESS, Err(e) => { // Use the alternative formatter to get everything on a single line...it reads better. eprintln!("error: {:#}", e); - std::process::exit(1); + libc::EXIT_FAILURE } } } From 918d5efef751ac025efc850501b4b5e38048b409 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 21 Sep 2020 16:51:14 +0000 Subject: [PATCH 059/641] tests: Validate that we can't run bootupd as non-root Perhaps in the future we'll allow non-root status but that's a lot more code complexity, no immediate need for it. --- tests/kola/test-bootupd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 5cec4d403..4dc28f5e2 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -45,6 +45,11 @@ assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' ok status +if env LANG=C.UTF-8 runuser -u bin bootupctl status 2>err.txt; then + fatal "Was able to bootupctl status as non-root" +fi +assert_file_has_content err.txt 'error:.*: Permission denied' + # From here we'll fake updates test -w /usr || rpm-ostree usroverlay # Save a backup copy of the update dir From 359b4ffb1b44b5f54fbe8ed4795458d787dfad84 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 21 Sep 2020 21:12:26 +0000 Subject: [PATCH 060/641] Fix build on aarch64 I got confused and thought it was "arm" in rust but no it really is `aarch64`, matching the Fedora naming. Tested to work in a podman fedora:32 container image on a RHEL8 host `4.18.0-193.14.3.el8_2.aarch64`. --- src/bootupd.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 4d951ee34..6d17d92b4 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -25,7 +25,7 @@ use structopt::StructOpt; // #[cfg(any(target_arch = "x86_64"))] // mod bios; mod component; -#[cfg(any(target_arch = "x86_64", target_arch = "arm"))] +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; mod filetree; mod ipc; @@ -121,7 +121,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { pub(crate) fn get_components() -> Vec> { let mut components: Vec> = Vec::new(); - #[cfg(any(target_arch = "x86_64", target_arch = "arm"))] + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] components.push(Box::new(efi::EFI::new())); // #[cfg(target_arch = "x86_64")] From 1ed307e20c074db8cbf73b76fdcbd82623d0e51c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 12:32:36 +0000 Subject: [PATCH 061/641] ci: Use buildroot for codestyle Not sure how we had `cargo` in the main cosa before. --- .cci.jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 40ed37276..c8e3a9eb9 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -23,7 +23,7 @@ parallel build: { } }, codestyle: { - cosaPod { + cosaPod(buildroot: true) { checkout scm shwrap("cargo fmt -- --check") } From 8b5c974fed108c415bb627dd0f8389c27a47780c Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 22 Sep 2020 14:22:57 +0000 Subject: [PATCH 062/641] cli: split handlers and runners for sub-commands This moves CLI parsing logic and sub-commands handling to its own module, making full use of structopt for matching verbs to enum variant and for dispatching to the relevant entrypoint. --- src/bootupd.rs | 55 ++------------------------------ src/cli/mod.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 9 +++--- 3 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 src/cli/mod.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 6d17d92b4..2d861f0bb 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -24,6 +24,8 @@ use structopt::StructOpt; // #[cfg(any(target_arch = "x86_64"))] // mod bios; +mod cli; +pub use cli::CliOptions; mod component; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; @@ -82,7 +84,7 @@ enum Opt { } /// A message sent from client to server -#[derive(Debug, Serialize, Deserialize, StructOpt)] +#[derive(Debug, Serialize, Deserialize)] enum ClientRequest { /// Update a component Update { component: String }, @@ -335,20 +337,6 @@ fn daemon() -> Result<()> { } } -pub fn backend_main(args: &[&str]) -> Result<()> { - let opt = BackendOpt::from_iter(args.iter()); - match opt { - BackendOpt::Install { - src_root, - dest_root, - } => install(&src_root, &dest_root).context("boot data installation failed")?, - BackendOpt::GenerateUpdateMetadata { sysroot } => { - generate_update_metadata(&sysroot).context("generating metadata failed")? - } - }; - Ok(()) -} - fn print_status(status: &Status) { for (name, component) in status.components.iter() { println!("Component {}", name); @@ -414,40 +402,3 @@ fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { } Ok(()) } - -pub fn frontend_main(args: &[&str]) -> Result<()> { - let opt = Opt::from_iter(args.iter()); - let mut c = ipc::ClientToDaemonConnection::new(); - c.connect()?; - match &opt { - Opt::Status(statusopts) => { - let r: Status = c.send(&ClientRequest::Status)?; - if statusopts.json { - let stdout = std::io::stdout(); - let mut stdout = stdout.lock(); - serde_json::to_writer_pretty(&mut stdout, &r)?; - } else { - print_status(&r); - } - } - Opt::Update => { - client_run_update(&mut c)?; - } - } - c.shutdown()?; - Ok(()) -} - -/// Main entrypoint -pub fn boot_update_main(args: &[String]) -> Result<()> { - let mut args: Vec<&str> = args.iter().map(|s| s.as_str()).collect(); - if let Some(&argv1) = args.get(1) { - if argv1 == "backend" { - args.remove(1); - return backend_main(&args); - } else if argv1 == "daemon" { - return daemon(); - } - } - frontend_main(&args) -} diff --git a/src/cli/mod.rs b/src/cli/mod.rs new file mode 100644 index 000000000..294e472b8 --- /dev/null +++ b/src/cli/mod.rs @@ -0,0 +1,85 @@ +//! Command-line interface (CLI) logic. + +use crate::ipc::ClientToDaemonConnection; +use anyhow::{Context, Result}; +use structopt::StructOpt; + +/// Top-level CLI options. +#[derive(Debug, StructOpt)] +pub struct CliOptions { + /// CLI sub-commands. + #[structopt(subcommand)] + pub(crate) cmd: CliCommand, +} + +impl CliOptions { + /// Run CLI application. + pub fn run(self) -> Result<()> { + match self.cmd { + CliCommand::Backend(opts) => run_backend(opts), + CliCommand::Daemon => crate::daemon(), + CliCommand::Status(opts) => run_status(opts), + CliCommand::Update => run_update(), + } + } +} + +/// CLI sub-commands. +#[derive(Debug, StructOpt)] +pub(crate) enum CliCommand { + #[structopt(name = "backend")] + Backend(crate::BackendOpt), + #[structopt(name = "daemon")] + Daemon, + #[structopt(name = "status")] + Status(crate::StatusOptions), + #[structopt(name = "update")] + Update, +} + +/// Runner for `backend` verb. +fn run_backend(opts: crate::BackendOpt) -> Result<()> { + use crate::BackendOpt; + + match opts { + BackendOpt::Install { + src_root, + dest_root, + } => crate::install(&src_root, &dest_root).context("boot data installation failed")?, + BackendOpt::GenerateUpdateMetadata { sysroot } => { + crate::generate_update_metadata(&sysroot).context("generating metadata failed")? + } + }; + + Ok(()) +} + +/// Runner for `status` verb. +fn run_status(opts: crate::StatusOptions) -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + + let r: crate::Status = client.send(&crate::ClientRequest::Status)?; + if opts.json { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + serde_json::to_writer_pretty(&mut stdout, &r)?; + } else { + crate::print_status(&r); + } + + client.shutdown()?; + + Ok(()) +} + +/// Runner for `update` verb. +fn run_update() -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + + crate::client_run_update(&mut client)?; + + client.shutdown()?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 3b67410ad..beabe808c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use log::LevelFilter; use structopt::clap::crate_name; +use structopt::StructOpt; /// Binary entrypoint, for both daemon and client logic. fn main() { @@ -11,8 +12,8 @@ fn main() { /// CLI logic. fn run_cli() -> i32 { - // Gather command-line options. - let args: Vec<_> = std::env::args().collect(); + // Parse command-line options. + let cli_opts = bootupd::CliOptions::from_args(); // Setup logging. env_logger::Builder::from_default_env() @@ -22,10 +23,10 @@ fn run_cli() -> i32 { .init(); // Dispatch CLI subcommand. - match bootupd::boot_update_main(&args) { + match cli_opts.run() { Ok(_) => libc::EXIT_SUCCESS, Err(e) => { - // Use the alternative formatter to get everything on a single line...it reads better. + // Use the alternative formatter to get everything on a single line... it reads better. eprintln!("error: {:#}", e); libc::EXIT_FAILURE } From 534bb60cf37bd4f00ab044e04a7f4f8cbff3edbf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 15:41:12 +0000 Subject: [PATCH 063/641] generate-update-metadata: Print the result Might as well output information at build time. --- src/bootupd.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 2d861f0bb..67614f8df 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -134,7 +134,12 @@ pub(crate) fn get_components() -> Vec> { pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { for component in get_components() { - let _ = component.generate_update_metadata(sysroot_path)?; + let v = component.generate_update_metadata(sysroot_path)?; + println!( + "Generated update layout for {}: {}", + component.name(), + format_version(&v) + ); } Ok(()) From cd1e6416156e7ed0e2c649039375cd0f802e43ec Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 15:44:23 +0000 Subject: [PATCH 064/641] ci: Enable fcos build + kola This currently should just run only our test, we can't really break anything else. --- .cci.jenkinsfile | 50 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index c8e3a9eb9..d8ce44de4 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -31,26 +31,32 @@ codestyle: { } // Build FCOS and do a kola basic run -// stage("FCOS") { -// cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { -// stage("Build FCOS") { -// checkout scm -// unstash 'build' -// shwrap(""" -// mkdir insttree -// tar -C insttree -xzvf insttree.tar.gz -// rsync -rlv insttree/ / -// coreos-assembler init --force https://github.com/coreos/fedora-coreos-config -// mkdir -p overrides/rootfs -// mv insttree/* overrides/rootfs/ -// rmdir insttree -// coreos-assembler fetch -// coreos-assembler build -// """) -// } -// stage("Test") { -// fcosKola(cosaDir: "${env.WORKSPACE}") -// } -// } -// } +// FIXME update to main branch once https://github.com/coreos/fedora-coreos-config/pull/595 merges +stage("FCOS") { + cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { + stage("Build FCOS") { + checkout scm + unstash 'build' + // Note that like {rpm-,}ostree we want to install to both / and overrides/rootfs + // because bootupd is used both during the `rpm-ostree compose tree` as well as + // inside the target operating system. + shwrap(""" + mkdir insttree + tar -C insttree -xzvf insttree.tar.gz + rsync -rlv insttree/ / + # https://github.com/coreos/fedora-coreos-config/pull/595 + coreos-assembler init --force https://github.com/cgwalters/fedora-coreos-config + (cd src/config && git checkout use-bootupd) + mkdir -p overrides/rootfs + mv insttree/* overrides/rootfs/ + rmdir insttree + coreos-assembler fetch + coreos-assembler build + """) + } + stage("Test") { + fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*") + } + } +} From 80664ca246e4006798aa5e4de99fd46761aa899a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 17:08:01 +0000 Subject: [PATCH 065/641] update: Require BOOTUPD_ACCEPT_PREVIEW in environment Further ensure admins don't accidentally try this until we've tested it very heavily. --- src/bootupd.rs | 13 +++++++++++++ tests/kola/test-bootupd | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index 67614f8df..c54b8b361 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -364,7 +364,20 @@ fn print_status(status: &Status) { } } +fn validate_preview_env() -> Result<()> { + let v = "BOOTUPD_ACCEPT_PREVIEW"; + if std::env::var_os(v).is_none() { + Err(anyhow::anyhow!( + "bootupd is currently alpha; set {}=1 in environment to continue", + v + )) + } else { + Ok(()) + } +} + fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { + validate_preview_env()?; let status: Status = c.send(&ClientRequest::Status)?; if status.components.is_empty() { println!("No components installed."); diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 4dc28f5e2..95d52f21a 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,6 +19,9 @@ function cleanup () { fi } +# For now +export BOOTUPD_ACCEPT_PREVIEW=1 + bootefidir=/boot/efi/EFI bootupdir=/usr/lib/bootupd/updates efiupdir=${bootupdir}/EFI @@ -79,6 +82,11 @@ bootupctl status --json > status.json jq -r '.components.EFI.installed.version' < status.json > installed.txt assert_file_has_content installed.txt '^grub2-efi-x64' +if env -u BOOTUPD_ACCEPT_PREVIEW bootupctl update; then + fatal "Ran without BOOTUPD_ACCEPT_PREVIEW" +fi +ok required env + bootupctl update | tee out.txt assert_file_has_content out.txt 'Updated EFI: grub2-efi-x64.*,test' From d1c459f32a750330020629f1d55b4d38d798fa9d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 18:41:08 +0000 Subject: [PATCH 066/641] De-indent status & update code Use the "return early" pattern to avoid excess indentation. --- src/bootupd.rs | 98 ++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index c54b8b361..23f0dbe1c 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -174,31 +174,32 @@ fn update(name: &str) -> Result { ..Default::default() }); let component = component::new_from_name(name)?; - if let Some(inst) = state.installed.get(name).cloned() { - let update = component.query_update()?; - let update = match update.as_ref() { - Some(p) if !p.compare(&inst.meta) => p, - _ => return Ok(ComponentUpdateResult::AtLatestVersion), - }; - let mut pending_container = state.pending.take().unwrap_or_default(); - let interrupted = pending_container.get(component.name()).cloned(); - - pending_container.insert(component.name().into(), update.clone()); - update_state(&sysroot, &state)?; - let newinst = component - .run_update(&inst) - .with_context(|| format!("Failed to update {}", component.name()))?; - state.installed.insert(component.name().into(), newinst); - pending_container.remove(component.name()); - update_state(&sysroot, &state)?; - Ok(ComponentUpdateResult::Updated { - previous: inst.meta, - interrupted, - new: update.clone(), - }) + let inst = if let Some(inst) = state.installed.get(name) { + inst.clone() } else { anyhow::bail!("Component {} is not installed", name); - } + }; + let update = component.query_update()?; + let update = match update.as_ref() { + Some(p) if !p.compare(&inst.meta) => p, + _ => return Ok(ComponentUpdateResult::AtLatestVersion), + }; + let mut pending_container = state.pending.take().unwrap_or_default(); + let interrupted = pending_container.get(component.name()).cloned(); + + pending_container.insert(component.name().into(), update.clone()); + update_state(&sysroot, &state)?; + let newinst = component + .run_update(&inst) + .with_context(|| format!("Failed to update {}", component.name()))?; + state.installed.insert(component.name().into(), newinst); + pending_container.remove(component.name()); + update_state(&sysroot, &state)?; + Ok(ComponentUpdateResult::Updated { + previous: inst.meta, + interrupted, + new: update.clone(), + }) } fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { @@ -251,31 +252,34 @@ fn format_version(meta: &ContentMetadata) -> String { fn status() -> Result { let mut ret: Status = Default::default(); - if let Some(state) = get_saved_state("/")? { - for (name, ic) in state.installed.iter() { - let component = component::new_from_name(&name)?; - let component = component.as_ref(); - let interrupted = state - .pending - .as_ref() - .map(|p| p.get(name.as_str())) - .flatten(); - let update = component.query_update()?; - let updatable = match update.as_ref() { - Some(p) if !p.compare(&ic.meta) => true, - _ => false, - }; - ret.components.insert( - name.to_string(), - ComponentStatus { - installed: ic.meta.clone(), - interrupted: interrupted.cloned(), - update, - updatable, - }, - ); - } + let state = if let Some(state) = get_saved_state("/")? { + state + } else { + return Ok(ret); }; + for (name, ic) in state.installed.iter() { + let component = component::new_from_name(&name)?; + let component = component.as_ref(); + let interrupted = state + .pending + .as_ref() + .map(|p| p.get(name.as_str())) + .flatten(); + let update = component.query_update()?; + let updatable = match update.as_ref() { + Some(p) if !p.compare(&ic.meta) => true, + _ => false, + }; + ret.components.insert( + name.to_string(), + ComponentStatus { + installed: ic.meta.clone(), + interrupted: interrupted.cloned(), + update, + updatable, + }, + ); + } Ok(ret) } From 97496ba556aa5f46e6f2a67a6de75db8112a6a4a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 18:44:41 +0000 Subject: [PATCH 067/641] Add some docstrings Just trying to increase doc coverage. --- src/bootupd.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index 23f0dbe1c..0af80db43 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -145,6 +145,9 @@ pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { Ok(()) } +/// Hold a lock on the system root; while ordinarily we run +/// as a systemd unit which implicitly ensures a "singleton" +/// instance this is a double check. fn acquire_write_lock>(sysroot: P) -> Result { let sysroot = sysroot.as_ref(); let lockf = std::fs::OpenOptions::new() @@ -156,6 +159,7 @@ fn acquire_write_lock>(sysroot: P) -> Result { Ok(lockf) } +/// Return value from daemon → client for component update #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] enum ComponentUpdateResult { @@ -167,6 +171,7 @@ enum ComponentUpdateResult { }, } +/// daemon implementation of component update fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; let _lock = acquire_write_lock("/")?; @@ -202,6 +207,7 @@ fn update(name: &str) -> Result { }) } +/// Atomically replace the on-disk state with a new version fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { let subdir = sysroot_dir.sub_dir(STATEFILE_DIR)?; let f = { @@ -227,6 +233,7 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { Ok(()) } +/// Load the JSON file containing on-disk state fn get_saved_state(sysroot_path: &str) -> Result> { let sysroot_dir = openat::Dir::open(sysroot_path) .with_context(|| format!("opening sysroot {}", sysroot_path))?; @@ -242,6 +249,7 @@ fn get_saved_state(sysroot_path: &str) -> Result> { Ok(saved_state) } +/// Print a version if available, or fall back to timestamp fn format_version(meta: &ContentMetadata) -> String { if let Some(version) = meta.version.as_ref() { version.into() @@ -368,6 +376,8 @@ fn print_status(status: &Status) { } } +/// Checks that the user has provided an environment variable to signal +/// acceptance of our alpha state - use this when performing write operations. fn validate_preview_env() -> Result<()> { let v = "BOOTUPD_ACCEPT_PREVIEW"; if std::env::var_os(v).is_none() { From b46e703a7fffe864283db1e54f69bbc89a585896 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 19:12:01 +0000 Subject: [PATCH 068/641] model: Remove some dead code We aren't implementing transitions right now, updates are manually initiated. --- src/model.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/model.rs b/src/model.rs index b8eb16d97..0ee6226fb 100644 --- a/src/model.rs +++ b/src/model.rs @@ -70,14 +70,3 @@ pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, } - -// Should be stored in /usr/lib/bootupd/edges.json -//#[derive(Serialize, Deserialize, Debug)] -// #[serde(rename_all = "kebab-case")] -// pub(crate) struct UpgradeEdge { -// /// Set to true if we should upgrade from an unknown state -// #[serde(default)] -// pub(crate) from_unknown: bool, -// /// Upgrade from content past this timestamp -// pub(crate) from_timestamp: Option, -// } From a725a35c57d7ecc5e0d271912a4ff63ced6c013c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 22:04:51 +0000 Subject: [PATCH 069/641] filetree: Remove timestamp UEFI doesn't care about timestamps on binaries, there's no reason for us to do so either. Nothing was using this value. --- src/filetree.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 3caee2c1d..7f8a44827 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -5,7 +5,6 @@ */ use anyhow::{bail, Context, Result}; -use chrono::prelude::*; use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; use serde::{Deserialize, Serialize}; @@ -38,7 +37,6 @@ pub(crate) struct FileMetadata { #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] #[serde(rename_all = "kebab-case")] pub(crate) struct FileTree { - pub(crate) timestamp: NaiveDateTime, pub(crate) children: BTreeMap, } @@ -122,13 +120,7 @@ impl FileTree { children.insert(k, v); } - let meta = dir.metadata(".")?; - let stat = meta.stat(); - - Ok(Self { - timestamp: chrono::NaiveDateTime::from_timestamp(stat.st_mtime, 0), - children, - }) + Ok(Self { children }) } /// Determine the changes *from* self to the updated tree From 72e6120ce88d520f450a9cae574bf0bcc0fe7d52 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2020 12:53:36 +0000 Subject: [PATCH 070/641] README.md: Explain more about relationship with rpm-ostree Help explain the rationale for this project's existence and future. --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index de5a8687d..c63f233f7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ in an inconsistent and ad-hoc way. For example, on Fedora and Debian, a package manager update will update UEFI binaries in `/boot/efi`, but not the BIOS MBR data. -Many transactional update systems like [OSTree](https://github.com/ostreedev/ostree/) +Transactional/"image" update systems like [OSTree](https://github.com/ostreedev/ostree/) and dual-partition systems like the Container Linux update system are more consistent: they normally cover kernel/userspace but not anything related to bootloaders. @@ -63,3 +63,22 @@ this project would probably just proxy that if we detect systemd-boot is in use. One idea is that bootupd could help support [redundant bootable disks](https://github.com/coreos/fedora-coreos-tracker/issues/581). For various reasons it doesn't really work to try to use RAID1 for an entire disk; the ESP must be handled specially. `bootupd` could learn how to synchronize multiple EFI system partitions from a primary. + +## More details on rationale and integration + +A notable problem today for [rpm-ostree](https://github.com/coreos/rpm-ostree/) based +systems is that `rpm -q shim-x64` is misleading because it's not actually +updated in place. + +Particularly [this commit][1] makes things clear - the data +from the RPM goes into `/usr` (part of the OSTree), so it doesn't touch `/boot/efi`. +But that commit didn't change how the RPM database works (and more generally it +would be technically complex for rpm-ostree to change how the RPM database works today). + +What we ultimately want is that `rpm -q shim-x64` returns "not installed" - because +it's not managed by RPM or by ostree. Instead one would purely use `bootupctl` to manage it. +However, it might still be *built* as an RPM, just not installed that way. The RPM version numbers would be used +for the bootupd version associated with the payload, and ultimately we'd teach `rpm-ostree compose tree` +how to separately download bootloaders and pass them to `bootupctl backend`. + +[1]: https://github.com/coreos/rpm-ostree/pull/969/commits/dc0e8db5bd92e1f478a0763d1a02b48e57022b59 From 16467eb4a7e237072020995d91e666fb98cbf33b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 22:00:07 +0000 Subject: [PATCH 071/641] Use UTC for serialized timestamp Using local timestamps is obviously broken; while our build process will probably use UTC, relying on that is wrong, and clients may not use UTC. Noticed this while going to do some other work around comparing `ContentMetadata`. I did verify that RPM's `%{buildtime}` is UTC - the source invokes `time(NULL)` and the value isn't interpreted when printed. --- src/efi.rs | 12 +++++++----- src/model.rs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 48ca08127..40f377b7f 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -9,10 +9,10 @@ use std::io::prelude::*; use std::path::Path; use std::process::Command; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use serde::{Deserialize, Serialize}; -use chrono::NaiveDateTime; +use chrono::prelude::*; use crate::component::*; use crate::filetree; @@ -130,16 +130,18 @@ impl Component for EFI { let parts: Vec<_> = s.splitn(2, ',').collect(); let name = parts[0]; if let Some(ts) = parts.get(1) { - Ok((name, NaiveDateTime::parse_from_str(ts, "%s")?)) + let nt = NaiveDateTime::parse_from_str(ts, "%s") + .context("Failed to parse rpm buildtime")?; + Ok((name, DateTime::::from_utc(nt, Utc))) } else { bail!("Failed to parse: {}", s); } }) - .collect::>>()?; + .collect::>>>()?; if pkgs.is_empty() { bail!("Failed to find any RPM packages matching files in source efidir"); } - let timestamps: BTreeSet<&NaiveDateTime> = pkgs.values().collect(); + let timestamps: BTreeSet<&DateTime> = pkgs.values().collect(); // Unwrap safety: We validated pkgs has at least one value above let largest_timestamp = timestamps.iter().last().unwrap(); let version = pkgs.keys().fold("".to_string(), |mut s, n| { diff --git a/src/model.rs b/src/model.rs index 0ee6226fb..c8aa83b6e 100644 --- a/src/model.rs +++ b/src/model.rs @@ -14,7 +14,7 @@ pub(crate) const BOOTUPD_UPDATES_DIR: &str = "usr/lib/bootupd/updates"; #[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq)] pub(crate) struct ContentMetadata { /// The timestamp, which is used to determine update availability - pub(crate) timestamp: NaiveDateTime, + pub(crate) timestamp: DateTime, /// Human readable version number, like ostree it is not ever parsed, just displayed pub(crate) version: Option, } From ce2ce0ae4d1a43fabcd2525aff53891376db8792 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Sep 2020 22:48:39 +0000 Subject: [PATCH 072/641] Make version number not optional There's no good reason to have version numbers be optional. They're essential for human understanding of things. We still use a timestamp around for total ordering. Rework the model to more precisely keep track of "upgradable". --- src/bootupd.rs | 52 +++++++++++++++-------------------- src/efi.rs | 2 +- src/model.rs | 61 +++++++++++++++++++++++++++++++++++++---- tests/kola/test-bootupd | 2 +- 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0af80db43..b9571243b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -18,6 +18,7 @@ use fs2::FileExt; use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; use std::io::prelude::*; use std::path::Path; use structopt::StructOpt; @@ -138,7 +139,7 @@ pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { println!( "Generated update layout for {}: {}", component.name(), - format_version(&v) + v.version, ); } @@ -186,7 +187,7 @@ fn update(name: &str) -> Result { }; let update = component.query_update()?; let update = match update.as_ref() { - Some(p) if !p.compare(&inst.meta) => p, + Some(p) if inst.meta.can_upgrade_to(&p) => p, _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; let mut pending_container = state.pending.take().unwrap_or_default(); @@ -249,15 +250,6 @@ fn get_saved_state(sysroot_path: &str) -> Result> { Ok(saved_state) } -/// Print a version if available, or fall back to timestamp -fn format_version(meta: &ContentMetadata) -> String { - if let Some(version) = meta.version.as_ref() { - version.into() - } else { - meta.timestamp.format("%Y-%m-%dT%H:%M:%S+00:00").to_string() - } -} - fn status() -> Result { let mut ret: Status = Default::default(); let state = if let Some(state) = get_saved_state("/")? { @@ -274,10 +266,7 @@ fn status() -> Result { .map(|p| p.get(name.as_str())) .flatten(); let update = component.query_update()?; - let updatable = match update.as_ref() { - Some(p) if !p.compare(&ic.meta) => true, - _ => false, - }; + let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); ret.components.insert( name.to_string(), ComponentStatus { @@ -357,22 +346,24 @@ fn daemon() -> Result<()> { fn print_status(status: &Status) { for (name, component) in status.components.iter() { println!("Component {}", name); - println!(" Installed: {}", format_version(&component.installed)); + println!(" Installed: {}", component.installed.version); if let Some(i) = component.interrupted.as_ref() { println!( " WARNING: Previous update to {} was interrupted", - format_version(i) + i.version ); } - if component.updatable { - let update = component.update.as_ref().expect("update"); - println!(" Update: Available: {}", format_version(&update)); - } else if component.update.is_some() { - println!(" Update: At latest version"); - } else { - println!(" Update: No update found"); - } + let msg = match component.updatable { + ComponentUpdatable::NoUpdateAvailable => Cow::Borrowed("No update found"), + ComponentUpdatable::AtLatestVersion => Cow::Borrowed("At latest version"), + ComponentUpdatable::WouldDowngrade => Cow::Borrowed("Ignoring downgrade"), + ComponentUpdatable::Upgradable => Cow::Owned(format!( + "Available: {}", + component.update.as_ref().expect("update").version + )), + }; + println!(" Update: {}", msg); } } @@ -399,9 +390,10 @@ fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { } let mut updated = false; for (name, cstatus) in status.components.iter() { - if !cstatus.updatable { - continue; - } + match cstatus.updatable { + ComponentUpdatable::Upgradable => {} + _ => continue, + }; match c.send(&ClientRequest::Update { component: name.to_string(), })? { @@ -421,10 +413,10 @@ fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { if let Some(i) = interrupted { eprintln!( "warning: Continued from previous interrupted update: {}", - format_version(&i) + i.version, ); } - println!("Updated {}: {}", name, format_version(&new)); + println!("Updated {}: {}", name, new.version); } } updated = true; diff --git a/src/efi.rs b/src/efi.rs index 40f377b7f..b6e3bad83 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -154,7 +154,7 @@ impl Component for EFI { let meta = ContentMetadata { timestamp: **largest_timestamp, - version: Some(version), + version: version, }; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) diff --git a/src/model.rs b/src/model.rs index c8aa83b6e..889429cd1 100644 --- a/src/model.rs +++ b/src/model.rs @@ -16,15 +16,16 @@ pub(crate) struct ContentMetadata { /// The timestamp, which is used to determine update availability pub(crate) timestamp: DateTime, /// Human readable version number, like ostree it is not ever parsed, just displayed - pub(crate) version: Option, + pub(crate) version: String, } impl ContentMetadata { - pub(crate) fn compare(&self, other: &Self) -> bool { - match (self.version.as_ref(), other.version.as_ref()) { - (Some(a), Some(b)) => a.as_str() == b.as_str(), - _ => self.timestamp == other.timestamp, + /// Returns `true` if `target` is different and chronologically newer + pub(crate) fn can_upgrade_to(&self, target: &Self) -> bool { + if self.version == target.version { + return false; } + return target.timestamp > self.timestamp; } } @@ -46,6 +47,33 @@ pub(crate) struct SavedState { pub(crate) pending: Option>, } +/// The status of an individual component. +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum ComponentUpdatable { + NoUpdateAvailable, + AtLatestVersion, + Upgradable, + WouldDowngrade, +} + +impl ComponentUpdatable { + pub(crate) fn from_metadata(from: &ContentMetadata, to: Option<&ContentMetadata>) -> Self { + match to { + Some(to) => { + if from.version == to.version { + ComponentUpdatable::AtLatestVersion + } else if from.can_upgrade_to(to) { + ComponentUpdatable::Upgradable + } else { + ComponentUpdatable::WouldDowngrade + } + } + None => ComponentUpdatable::NoUpdateAvailable, + } + } +} + /// The status of an individual component. #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] @@ -57,7 +85,7 @@ pub(crate) struct ComponentStatus { /// Update in the deployed filesystem tree pub(crate) update: Option, /// Is true if the version in `update` is different from `installed` - pub(crate) updatable: bool, + pub(crate) updatable: ComponentUpdatable, } /// Representation of bootupd's worldview at a point in time. @@ -70,3 +98,24 @@ pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, } + +#[cfg(test)] +mod test { + use super::*; + use chrono::Duration; + + #[test] + fn test_meta_compare() { + let t = Utc::now(); + let a = ContentMetadata { + timestamp: t, + version: "v1".into(), + }; + let b = ContentMetadata { + timestamp: t + Duration::seconds(1), + version: "v2".into(), + }; + assert!(a.can_upgrade_to(&b)); + assert!(!b.can_upgrade_to(&a)); + } +} diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 95d52f21a..d683654f2 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -66,7 +66,7 @@ echo bootupd-test-changes >> ${ostefi}/grubx64.efi bootupctl backend generate-update-metadata / ver=$(jq -r .version < ${bootupdir}/EFI.json) cat >ver.json << EOF -{ "version": "${ver},test" } +{ "version": "${ver},test", "timestamp": "$(date -u --iso-8601=seconds)" } EOF jq -s add ${bootupdir}/EFI.json ver.json > new.json mv new.json ${bootupdir}/EFI.json From 185dadac299bd9102901dff7c6b2fe6afdb5dd05 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2020 21:24:09 +0000 Subject: [PATCH 073/641] efi: Do check ESP is FAT After refactoring this method was lying around as `#[allow(dead_code)]`. Previously we were trying to use Rust unit tests more but now we favor the real kola tests. Let's use it again to double-check we're operating on the right thing. --- src/efi.rs | 20 ++++++++------------ src/util.rs | 4 ---- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index b6e3bad83..f1093bbce 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -48,6 +48,10 @@ impl Component for EFI { let srcd = openat::Dir::open(&srcdir)?; let ft = crate::filetree::FileTree::new_from_dir(&srcd)?; let destdir = Path::new(dest_root).join(MOUNT_PATH); + { + let destd = openat::Dir::open(&destdir)?; + validate_esp(&destd)?; + } let r = std::process::Command::new("cp") .args(&["-rp", "--reflink=auto"]) .arg(&srcdir) @@ -72,6 +76,7 @@ impl Component for EFI { let updatef = filetree::FileTree::new_from_dir(&updated)?; let diff = currentf.diff(&updatef)?; let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI"))?; + validate_esp(&destdir)?; filetree::apply_diff(&updated, &destdir, &diff, None)?; Ok(InstalledContent { meta: updatemeta, @@ -165,20 +170,11 @@ impl Component for EFI { } } -#[allow(dead_code)] -pub(crate) fn validate_esp>(mnt: P) -> Result<()> { - if crate::util::running_in_test_suite() { - return Ok(()); - } - let mnt = mnt.as_ref(); - let stat = nix::sys::statfs::statfs(mnt)?; +fn validate_esp(dir: &openat::Dir) -> Result<()> { + let stat = nix::sys::statfs::fstatfs(dir)?; let fstype = stat.filesystem_type(); if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { - bail!( - "Mount {} is not a msdos filesystem, but is {:?}", - mnt.display(), - fstype - ); + bail!("EFI mount is not a msdos filesystem, but is {:?}", fstype); }; Ok(()) } diff --git a/src/util.rs b/src/util.rs index d02b45375..5af899fa8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -33,10 +33,6 @@ pub(crate) fn getenv_utf8(n: &str) -> Result> { } } -pub(crate) fn running_in_test_suite() -> bool { - !nix::unistd::getuid().is_root() -} - pub(crate) fn filenames(dir: &openat::Dir) -> Result> { let mut ret = HashSet::new(); for entry in dir.list_dir(".")? { From c512950068e8d4e0d095c213e0dbeb59c21d1210 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2020 18:04:38 +0000 Subject: [PATCH 074/641] status: Also print the boot method I forsee people pasting the output of `bootupctl status` into issues and bugs, so let's gather this one by default. --- src/bootupd.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index b9571243b..a45fc7c03 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -365,6 +365,16 @@ fn print_status(status: &Status) { }; println!(" Update: {}", msg); } + + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] + { + let boot_method = if Path::new("/sys/firmware/efi").exists() { + "EFI" + } else { + "BIOS" + }; + println!("Boot method: {}", boot_method); + } } /// Checks that the user has provided an environment variable to signal From baebc9f2f6545c67dde51ff0f55e0a422e1a3fb5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2020 21:05:15 +0000 Subject: [PATCH 075/641] efi: Some minor cleanup - Don't need to serialize anymore - Use `Default` since it's nicer --- src/bootupd.rs | 2 +- src/component.rs | 2 +- src/efi.rs | 9 +-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index a45fc7c03..048233c20 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -125,7 +125,7 @@ pub(crate) fn get_components() -> Vec> { let mut components: Vec> = Vec::new(); #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] - components.push(Box::new(efi::EFI::new())); + components.push(Box::new(efi::EFI::default())); // #[cfg(target_arch = "x86_64")] // components.push(Box::new(bios::BIOS::new())); diff --git a/src/component.rs b/src/component.rs index 788be54ac..7a05bf457 100644 --- a/src/component.rs +++ b/src/component.rs @@ -26,7 +26,7 @@ pub(crate) trait Component { pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { - "EFI" => Box::new(crate::efi::EFI::new()), + "EFI" => Box::new(crate::efi::EFI::default()), _ => anyhow::bail!("No component {}", name), }; Ok(r) diff --git a/src/efi.rs b/src/efi.rs index f1093bbce..3e2b15921 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -10,7 +10,6 @@ use std::path::Path; use std::process::Command; use anyhow::{bail, Context, Result}; -use serde::{Deserialize, Serialize}; use chrono::prelude::*; @@ -24,15 +23,9 @@ use crate::util::CommandRunExt; /// The path to the ESP mount pub(crate) const MOUNT_PATH: &str = "boot/efi"; -#[derive(Serialize, Deserialize)] +#[derive(Default)] pub(crate) struct EFI {} -impl EFI { - pub(crate) fn new() -> Self { - Self {} - } -} - impl Component for EFI { fn name(&self) -> &'static str { "EFI" From 444459116592ce7bbac1c04ca1f4c0cdd121db46 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2020 18:27:51 +0000 Subject: [PATCH 076/641] Add a `validate` command Let's add support for checking the on-disk state. This helps cross-check our implementation and is also useful for administrators (ref `ostree fsck`, `rpm -V` etc). --- src/bootupd.rs | 51 +++++++++++++++++++++++++++++++++++++++++ src/cli/mod.rs | 12 ++++++++++ src/component.rs | 10 ++++++++ src/efi.rs | 22 ++++++++++++++++++ src/filetree.rs | 39 +++++++++++++++++++++++++++++++ tests/kola/test-bootupd | 14 +++++++++++ 6 files changed, 148 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index 048233c20..07436c151 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -89,6 +89,8 @@ enum Opt { enum ClientRequest { /// Update a component Update { component: String }, + /// Validate a component + Validate { component: String }, /// Print the current state Status, } @@ -208,6 +210,20 @@ fn update(name: &str) -> Result { }) } +/// daemon implementation of component validate +fn validate(name: &str) -> Result { + let state = get_saved_state("/")?.unwrap_or_else(|| SavedState { + ..Default::default() + }); + let component = component::new_from_name(name)?; + let inst = if let Some(inst) = state.installed.get(name) { + inst.clone() + } else { + anyhow::bail!("Component {} is not installed", name); + }; + component.validate(&inst) +} + /// Atomically replace the on-disk state with a new version fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { let subdir = sysroot_dir.sub_dir(STATEFILE_DIR)?; @@ -299,6 +315,13 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } + ClientRequest::Validate { component } => { + println!("Processing validate"); + bincode::serialize(&match validate(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? + } ClientRequest::Status => { println!("Processing status"); bincode::serialize(&match status() { @@ -436,3 +459,31 @@ fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { } Ok(()) } + +fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { + let status: Status = c.send(&ClientRequest::Status)?; + if status.components.is_empty() { + println!("No components installed."); + return Ok(()); + } + let mut caught_validation_error = false; + for (name, _) in status.components.iter() { + match c.send(&ClientRequest::Validate { + component: name.to_string(), + })? { + ValidationResult::Valid => { + println!("Validated: {}", name); + } + ValidationResult::Errors(errs) => { + for err in errs { + eprintln!("{}", err); + } + caught_validation_error = true; + } + } + } + if caught_validation_error { + anyhow::bail!("Caught validation errors"); + } + Ok(()) +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 294e472b8..d34530a91 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -20,6 +20,7 @@ impl CliOptions { CliCommand::Daemon => crate::daemon(), CliCommand::Status(opts) => run_status(opts), CliCommand::Update => run_update(), + CliCommand::Validate => run_validate(), } } } @@ -35,6 +36,8 @@ pub(crate) enum CliCommand { Status(crate::StatusOptions), #[structopt(name = "update")] Update, + #[structopt(name = "validate")] + Validate, } /// Runner for `backend` verb. @@ -83,3 +86,12 @@ fn run_update() -> Result<()> { client.shutdown()?; Ok(()) } + +/// Runner for `validate` verb. +fn run_validate() -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + crate::client_run_validate(&mut client)?; + client.shutdown()?; + Ok(()) +} diff --git a/src/component.rs b/src/component.rs index 7a05bf457..0467cb2e7 100644 --- a/src/component.rs +++ b/src/component.rs @@ -5,12 +5,20 @@ */ use anyhow::Result; +use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::Write as IoWrite; use std::path::{Path, PathBuf}; use crate::model::*; +#[serde(rename_all = "kebab-case")] +#[derive(Serialize, Deserialize, Debug)] +pub(crate) enum ValidationResult { + Valid, + Errors(Vec), +} + /// A component along with a possible update pub(crate) trait Component { fn name(&self) -> &'static str; @@ -22,6 +30,8 @@ pub(crate) trait Component { fn query_update(&self) -> Result>; fn run_update(&self, current: &InstalledContent) -> Result; + + fn validate(&self, current: &InstalledContent) -> Result; } pub(crate) fn new_from_name(name: &str) -> Result> { diff --git a/src/efi.rs b/src/efi.rs index 3e2b15921..95822ffb4 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -161,6 +161,28 @@ impl Component for EFI { fn query_update(&self) -> Result> { get_component_update("/", self) } + + fn validate(&self, current: &InstalledContent) -> Result { + let currentf = current + .filetree + .as_ref() + .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; + let efidir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI"))?; + let diff = currentf.relative_diff_to(&efidir)?; + let mut errs = Vec::new(); + for f in diff.changes.iter() { + errs.push(format!("Changed: {}", f)); + } + for f in diff.removals.iter() { + errs.push(format!("Removed: {}", f)); + } + assert_eq!(diff.additions.len(), 0); + if !errs.is_empty() { + Ok(ValidationResult::Errors(errs)) + } else { + Ok(ValidationResult::Valid) + } + } } fn validate_esp(dir: &openat::Dir) -> Result<()> { diff --git a/src/filetree.rs b/src/filetree.rs index 7f8a44827..541c0ea48 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -171,6 +171,39 @@ impl FileTree { changes, }) } + + /// Create a diff from a target directory. This will ignore + /// any files or directories that are not part of the original tree. + pub(crate) fn relative_diff_to(&self, dir: &openat::Dir) -> Result { + let mut removals = HashSet::new(); + let mut changes = HashSet::new(); + + for (path, info) in self.children.iter() { + assert!(!path.starts_with("/")); + + if let Some(meta) = dir.metadata_optional(path)? { + match meta.simple_type() { + openat::SimpleType::File => { + let target_info = FileMetadata::new_from_path(dir, path)?; + if info != &target_info { + changes.insert(path.clone()); + } + } + _ => { + // If a file became a directory + changes.insert(path.clone()); + } + } + } else { + removals.insert(path.clone()); + } + } + Ok(FileTreeDiff { + additions: HashSet::new(), + removals, + changes, + }) + } } // Recursively remove all files in the directory that start with our TMP_PREFIX @@ -405,6 +438,8 @@ mod tests { let udiff = ta.updates(&tb)?; assert_eq!(udiff.count(), 0); test_apply(&pa, &pb).context("testing apply 1")?; + let rdiff = ta.relative_diff_to(&b)?; + assert_eq!(rdiff.removals.len(), cdiff.removals.len()); b.create_dir("foo", 0o755)?; { @@ -421,6 +456,10 @@ mod tests { let diff = run_diff(&a, &b)?; assert_eq!(diff.count(), 1); assert_eq!(diff.changes.len(), 1); + let ta = FileTree::new_from_dir(&a)?; + let rdiff = ta.relative_diff_to(&b)?; + assert_eq!(rdiff.count(), diff.count()); + assert_eq!(rdiff.changes.len(), diff.changes.len()); test_apply(&pa, &pb).context("testing apply 3")?; Ok(()) } diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index d683654f2..ee0894320 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -48,6 +48,9 @@ assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' ok status +bootupctl validate | tee out.txt +ok validate + if env LANG=C.UTF-8 runuser -u bin bootupctl status 2>err.txt; then fatal "Was able to bootupctl status as non-root" fi @@ -96,6 +99,9 @@ assert_file_has_content out.txt ' Installed: grub2-efi-x64.*,test' assert_file_has_content_literal out.txt 'Update: At latest version' ok status after update +bootupctl validate | tee out.txt +ok validate after update + # FIXME see above # assert_file_has_content ${bootefidir}/${efisubdir}/somenew.efi 'somenewfile' if test -f ${bootefidir}/${efisubdir}/shim.efi; then @@ -111,4 +117,12 @@ bootupctl update | tee out.txt assert_file_has_content_literal out.txt 'No update available for any component' assert_not_file_has_content_literal out.txt 'Updated EFI' +echo "some additions" >> ${bootefidir}/${efisubdir}/shimx64.efi +if bootupctl validate 2>err.txt; then + fatal "unexpectedly passed validation" +fi +assert_file_has_content err.txt "Changed: ${efisubdir}/shimx64.efi" +test "$(grep -cEe '^Changed:' err.txt)" = "1" +ok validate detected changes + tap_finish From 189334de9652c376bba1b2237e031dd35a16b386 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Fri, 25 Sep 2020 06:59:07 +0000 Subject: [PATCH 077/641] filetree: properly scope test-only import rust-analyzer is complaining about a too-broad import which is only used by tests. This moves it to the proper scope and drops the previous silence. --- src/filetree.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 541c0ea48..ea6dc67a2 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -13,9 +13,6 @@ use std::os::linux::fs::MetadataExt; use std::os::unix::io::AsRawFd; use std::os::unix::process::CommandExt; use std::path::Path; -// Seems like a rust-analyzer bug? -#[allow(unused_imports)] -use std::io::Write; /// The prefix we apply to our temporary files. #[allow(dead_code)] // Used for testing @@ -342,6 +339,7 @@ pub(crate) fn apply_diff( #[cfg(test)] mod tests { use super::*; + use std::io::Write; fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { let ta = FileTree::new_from_dir(&a)?; From 375dd1eadcade96f3b7c53981f6fe19e782e639c Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Fri, 25 Sep 2020 06:56:59 +0000 Subject: [PATCH 078/641] cargo: bump open-ext A fresh version of openat-ext is required in order to use `metadata_optional`. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 491542a30..35c965075 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.17.0" openat = "0.1.19" -openat-ext = "0.1.0" +openat-ext = "^0.1.5" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 0f29095acd870b9bda7e4a412175963e7263318b Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Fri, 25 Sep 2020 07:01:04 +0000 Subject: [PATCH 079/641] cargo: keep track of lockfile It is recommended that all binaries check in their Cargo.lock, see https://doc.rust-lang.org/cargo/faq.html#why-do-binaries-have-cargolock-in-version-control-but-not-libraries --- .gitignore | 1 - Cargo.lock | 804 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 804 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index d02d3a0e8..693b85c69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /target -Cargo.lock fastbuild*.qcow2 _kola_temp diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..9696a45de --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,804 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bincode" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +dependencies = [ + "byteorder", + "serde", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bootupd" +version = "0.1.1" +dependencies = [ + "anyhow", + "bincode", + "chrono", + "clap", + "env_logger", + "fs2", + "hex", + "libc", + "libsystemd", + "log", + "nix", + "openat", + "openat-ext", + "openssl", + "serde", + "serde_json", + "structopt", + "tempfile", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cc" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "chrono" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" +dependencies = [ + "num-integer", + "num-traits", + "serde", + "time", +] + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" + +[[package]] +name = "libsystemd" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a64961e79726a5b05e0db592097ca895831d755484203578fe75b580847262" +dependencies = [ + "error-chain", + "hmac", + "libc", + "nix", + "serde", + "sha2", + "uuid", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "nix" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "openat" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eff876e3964841fd6067ecf1d040e0315879c1a1cce2a0f162828e82f04d1ce" +dependencies = [ + "libc", +] + +[[package]] +name = "openat-ext" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2862a15ef65cac3c516de37ce6f026e0d77ad03d229f471e8294a29a962da1d6" +dependencies = [ + "libc", + "nix", + "openat", +] + +[[package]] +name = "openssl" +version = "0.10.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "lazy_static", + "libc", + "openssl-sys", +] + +[[package]] +name = "openssl-sys" +version = "0.9.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pkg-config" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" + +[[package]] +name = "ppv-lite86" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33f6461027d7f08a13715659b2948e1602c31a3756aeae9378bfe7518c72e82" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92e775028122a4b3dd55d58f14fc5120289c69bee99df1d117ae30f84b225c9" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "syn" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tempfile" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +dependencies = [ + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "uuid" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +dependencies = [ + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" From 3658f5aafeca4e8cc75c2b4a778369d7f4ac0bff Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 23 Sep 2020 10:14:36 +0000 Subject: [PATCH 080/641] cli: rework into a multicall binary This reworks the CLI options parser to branch the inner logic to accommodate two entrypoints, `bootupd` and `bootupctl`, into a single multicall binary. --- Cargo.toml | 2 +- Makefile | 6 +- packaging/rust-bootupd.spec | 1 + src/bootupd.rs | 42 +------------- src/cli/bootupctl.rs | 71 +++++++++++++++++++++++ src/cli/bootupd.rs | 52 +++++++++++++++++ src/cli/mod.rs | 110 +++++++++--------------------------- src/main.rs | 3 +- systemd/bootupd.service | 2 +- tests/kola/test-bootupd | 2 +- 10 files changed, 160 insertions(+), 131 deletions(-) create mode 100644 src/cli/bootupctl.rs create mode 100644 src/cli/bootupd.rs diff --git a/Cargo.toml b/Cargo.toml index 35c965075..646e73e1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ name = "bootupd" path = "src/bootupd.rs" [[bin]] -name = "bootupctl" +name = "bootupd" path = "src/main.rs" [dependencies] diff --git a/Makefile b/Makefile index 0ce73e0e6..68ed075ca 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ DESTDIR ?= PREFIX ?= /usr +LIBEXECDIR ?= ${PREFIX}/libexec RELEASE ?= 1 CONTAINER_RUNTIME ?= podman IMAGE_PREFIX ?= @@ -22,6 +23,7 @@ units = $(addprefix systemd/, bootupd.service bootupd.socket) .PHONY: all all: $(units) cargo build ${CARGO_ARGS} + ln -f target/${PROFILE}/bootupd target/${PROFILE}/bootupctl .PHONY: create-build-container create-build-container: @@ -37,4 +39,6 @@ install-units: $(units) .PHONY: install install: install-units - install -D -t ${DESTDIR}$(PREFIX)/bin target/${PROFILE}/bootupctl + mkdir -p "${DESTDIR}$(PREFIX)/bin" "${DESTDIR}$(LIBEXECDIR)" + install -D -t "${DESTDIR}$(LIBEXECDIR)" target/${PROFILE}/bootupd + ln -f ${DESTDIR}$(LIBEXECDIR)/bootupd ${DESTDIR}$(PREFIX)/bin/bootupctl diff --git a/packaging/rust-bootupd.spec b/packaging/rust-bootupd.spec index 7f7a6b4dd..164d15c9a 100644 --- a/packaging/rust-bootupd.spec +++ b/packaging/rust-bootupd.spec @@ -37,6 +37,7 @@ License: ASL 2.0 %license LICENSE %doc README.md %{_bindir}/bootupctl +%{_libexecdir}/bootupd %{_unitdir}/* %prep diff --git a/src/bootupd.rs b/src/bootupd.rs index 07436c151..24c22e934 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -21,12 +21,11 @@ use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::io::prelude::*; use std::path::Path; -use structopt::StructOpt; // #[cfg(any(target_arch = "x86_64"))] // mod bios; mod cli; -pub use cli::CliOptions; +pub use cli::MultiCall; mod component; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; @@ -45,45 +44,6 @@ pub(crate) const STATEFILE_DIR: &str = "boot"; pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; -#[derive(Debug, Serialize, Deserialize, StructOpt)] -#[structopt(rename_all = "kebab-case")] -struct StatusOptions { - // Output JSON - #[structopt(long)] - json: bool, -} - -// Options exposed by `bootupctl backend` -#[derive(Debug, Serialize, Deserialize, StructOpt)] -#[structopt(name = "boot-update")] -#[structopt(rename_all = "kebab-case")] -enum BackendOpt { - /// Install data from available components into a disk image - Install { - /// Source root - #[structopt(long, default_value = "/")] - src_root: String, - /// Target root - dest_root: String, - }, - /// Install data from available components into a filesystem tree - GenerateUpdateMetadata { - /// Physical root mountpoint - sysroot: String, - }, -} - -// "end user" options, i.e. what people should run on client systems -#[derive(Debug, Serialize, Deserialize, StructOpt)] -#[structopt(name = "boot-update")] -#[structopt(rename_all = "kebab-case")] -enum Opt { - /// Update all components - Update, - /// Print the current state - Status(StatusOptions), -} - /// A message sent from client to server #[derive(Debug, Serialize, Deserialize)] enum ClientRequest { diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs new file mode 100644 index 000000000..5d1c3f066 --- /dev/null +++ b/src/cli/bootupctl.rs @@ -0,0 +1,71 @@ +use crate::ipc::ClientToDaemonConnection; +use anyhow::Result; +use structopt::StructOpt; + +/// `bootupctl` sub-commands. +#[derive(Debug, StructOpt)] +#[structopt(name = "bootupctl", about = "Bootupd client application")] +pub enum CtlCommand { + #[structopt(name = "status", about = "Show components status")] + Status(StatusOpts), + #[structopt(name = "update", about = "Update all components")] + Update, + #[structopt(name = "validate", about = "Validate system state")] + Validate, +} + +#[derive(Debug, StructOpt)] +pub struct StatusOpts { + // Output JSON + #[structopt(long)] + json: bool, +} + +impl CtlCommand { + /// Run CLI application. + pub fn run(self) -> Result<()> { + match self { + CtlCommand::Status(opts) => Self::run_status(opts), + CtlCommand::Update => Self::run_update(), + CtlCommand::Validate => Self::run_validate(), + } + } + + /// Runner for `status` verb. + fn run_status(opts: StatusOpts) -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + + let r: crate::Status = client.send(&crate::ClientRequest::Status)?; + if opts.json { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + serde_json::to_writer_pretty(&mut stdout, &r)?; + } else { + crate::print_status(&r); + } + + client.shutdown()?; + Ok(()) + } + + /// Runner for `update` verb. + fn run_update() -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + + crate::client_run_update(&mut client)?; + + client.shutdown()?; + Ok(()) + } + + /// Runner for `validate` verb. + fn run_validate() -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + crate::client_run_validate(&mut client)?; + client.shutdown()?; + Ok(()) + } +} diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs new file mode 100644 index 000000000..644e1c825 --- /dev/null +++ b/src/cli/bootupd.rs @@ -0,0 +1,52 @@ +use anyhow::{Context, Result}; +use structopt::StructOpt; + +/// `bootupd` sub-commands. +#[derive(Debug, StructOpt)] +#[structopt(name = "bootupd", about = "Bootupd backend commands")] +pub enum DCommand { + #[structopt(name = "daemon", about = "Run service logic")] + Daemon, + #[structopt(name = "generate-update-metadata", about = "Generate metadata")] + GenerateUpdateMetadata(GenerateOpts), + #[structopt(name = "install", about = "Install components")] + Install(InstallOpts), +} + +#[derive(Debug, StructOpt)] +pub struct InstallOpts { + /// Source root + #[structopt(long, default_value = "/")] + src_root: String, + /// Target root + dest_root: String, +} + +#[derive(Debug, StructOpt)] +pub struct GenerateOpts { + /// Physical root mountpoint + sysroot: String, +} + +impl DCommand { + /// Run CLI application. + pub fn run(self) -> Result<()> { + match self { + DCommand::Daemon => crate::daemon(), + DCommand::Install(opts) => Self::run_install(opts), + DCommand::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), + } + } + + /// Runner for `generate-install-metadata` verb. + fn run_generate_meta(opts: GenerateOpts) -> Result<()> { + crate::generate_update_metadata(&opts.sysroot).context("generating metadata failed")?; + Ok(()) + } + + /// Runner for `install` verb. + fn run_install(opts: InstallOpts) -> Result<()> { + crate::install(&opts.src_root, &opts.dest_root).context("boot data installation failed")?; + Ok(()) + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index d34530a91..01f246d73 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,97 +1,39 @@ //! Command-line interface (CLI) logic. -use crate::ipc::ClientToDaemonConnection; -use anyhow::{Context, Result}; +use anyhow::Result; use structopt::StructOpt; -/// Top-level CLI options. +mod bootupctl; +mod bootupd; + +/// Top-level multicall CLI. #[derive(Debug, StructOpt)] -pub struct CliOptions { - /// CLI sub-commands. - #[structopt(subcommand)] - pub(crate) cmd: CliCommand, +pub enum MultiCall { + Ctl(bootupctl::CtlCommand), + D(bootupd::DCommand), } -impl CliOptions { - /// Run CLI application. - pub fn run(self) -> Result<()> { - match self.cmd { - CliCommand::Backend(opts) => run_backend(opts), - CliCommand::Daemon => crate::daemon(), - CliCommand::Status(opts) => run_status(opts), - CliCommand::Update => run_update(), - CliCommand::Validate => run_validate(), +impl MultiCall { + pub fn from_args() -> Self { + use std::os::unix::ffi::OsStrExt; + + // This is a multicall binary, dispatched based on the introspected + // filename found in argv[0]. + let exe_name = { + let arg0 = std::env::args().nth(0).unwrap_or_default(); + let exe_path = std::path::PathBuf::from(arg0); + exe_path.file_name().unwrap_or_default().to_os_string() + }; + match exe_name.as_bytes() { + b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::from_args()), + b"bootupd" | _ => MultiCall::D(bootupd::DCommand::from_args()), } } -} - -/// CLI sub-commands. -#[derive(Debug, StructOpt)] -pub(crate) enum CliCommand { - #[structopt(name = "backend")] - Backend(crate::BackendOpt), - #[structopt(name = "daemon")] - Daemon, - #[structopt(name = "status")] - Status(crate::StatusOptions), - #[structopt(name = "update")] - Update, - #[structopt(name = "validate")] - Validate, -} - -/// Runner for `backend` verb. -fn run_backend(opts: crate::BackendOpt) -> Result<()> { - use crate::BackendOpt; - match opts { - BackendOpt::Install { - src_root, - dest_root, - } => crate::install(&src_root, &dest_root).context("boot data installation failed")?, - BackendOpt::GenerateUpdateMetadata { sysroot } => { - crate::generate_update_metadata(&sysroot).context("generating metadata failed")? + pub fn run(self) -> Result<()> { + match self { + MultiCall::Ctl(ctl_cmd) => ctl_cmd.run(), + MultiCall::D(d_cmd) => d_cmd.run(), } - }; - - Ok(()) -} - -/// Runner for `status` verb. -fn run_status(opts: crate::StatusOptions) -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - - let r: crate::Status = client.send(&crate::ClientRequest::Status)?; - if opts.json { - let stdout = std::io::stdout(); - let mut stdout = stdout.lock(); - serde_json::to_writer_pretty(&mut stdout, &r)?; - } else { - crate::print_status(&r); } - - client.shutdown()?; - - Ok(()) -} - -/// Runner for `update` verb. -fn run_update() -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - - crate::client_run_update(&mut client)?; - - client.shutdown()?; - Ok(()) -} - -/// Runner for `validate` verb. -fn run_validate() -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - crate::client_run_validate(&mut client)?; - client.shutdown()?; - Ok(()) } diff --git a/src/main.rs b/src/main.rs index beabe808c..c860c8ebe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ use log::LevelFilter; use structopt::clap::crate_name; -use structopt::StructOpt; /// Binary entrypoint, for both daemon and client logic. fn main() { @@ -13,7 +12,7 @@ fn main() { /// CLI logic. fn run_cli() -> i32 { // Parse command-line options. - let cli_opts = bootupd::CliOptions::from_args(); + let cli_opts = bootupd::MultiCall::from_args(); // Setup logging. env_logger::Builder::from_default_env() diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 7f412e99f..91464e97d 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -4,7 +4,7 @@ Documentation=https://github.com/coreos/bootupd [Service] Type=notify -ExecStart=/usr/bin/bootupctl daemon +ExecStart=/usr/libexec/bootupd daemon # On general principle ProtectHome=yes # So we can remount /boot writable diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ee0894320..964f2438a 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -66,7 +66,7 @@ prepare_efi_update # echo somenewfile > ${ostefi}/somenew.efi rm -v ${ostefi}/shim.efi echo bootupd-test-changes >> ${ostefi}/grubx64.efi -bootupctl backend generate-update-metadata / +/usr/libexec/bootupd generate-update-metadata / ver=$(jq -r .version < ${bootupdir}/EFI.json) cat >ver.json << EOF { "version": "${ver},test", "timestamp": "$(date -u --iso-8601=seconds)" } From 6fad76e096d880ae56e08894f770f591a78689ae Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Thu, 24 Sep 2020 14:40:49 +0000 Subject: [PATCH 081/641] cli/bootupctl: temporary backend verbs This is a temporary compat patch to bridge backend verbs via bootupctl, for existing consumers. It is meant to be reverted as a whole later on once all consumers have been migrated. --- src/cli/bootupctl.rs | 19 +++++++++++++++++++ src/cli/bootupd.rs | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 5d1c3f066..338e22d79 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -1,11 +1,16 @@ use crate::ipc::ClientToDaemonConnection; use anyhow::Result; +use structopt::clap::AppSettings; use structopt::StructOpt; /// `bootupctl` sub-commands. #[derive(Debug, StructOpt)] #[structopt(name = "bootupctl", about = "Bootupd client application")] pub enum CtlCommand { + // FIXME(lucab): drop this after refreshing + // https://github.com/coreos/fedora-coreos-config/pull/595 + #[structopt(name = "backend", setting = AppSettings::Hidden)] + Backend(CtlBackend), #[structopt(name = "status", about = "Show components status")] Status(StatusOpts), #[structopt(name = "update", about = "Update all components")] @@ -14,6 +19,14 @@ pub enum CtlCommand { Validate, } +#[derive(Debug, StructOpt)] +pub enum CtlBackend { + #[structopt(name = "generate-update-metadata", setting = AppSettings::Hidden)] + Generate(super::bootupd::GenerateOpts), + #[structopt(name = "install", setting = AppSettings::Hidden)] + Install(super::bootupd::InstallOpts), +} + #[derive(Debug, StructOpt)] pub struct StatusOpts { // Output JSON @@ -28,6 +41,12 @@ impl CtlCommand { CtlCommand::Status(opts) => Self::run_status(opts), CtlCommand::Update => Self::run_update(), CtlCommand::Validate => Self::run_validate(), + CtlCommand::Backend(CtlBackend::Generate(opts)) => { + super::bootupd::DCommand::run_generate_meta(opts) + } + CtlCommand::Backend(CtlBackend::Install(opts)) => { + super::bootupd::DCommand::run_install(opts) + } } } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 644e1c825..9793ab38d 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -39,13 +39,13 @@ impl DCommand { } /// Runner for `generate-install-metadata` verb. - fn run_generate_meta(opts: GenerateOpts) -> Result<()> { + pub(crate) fn run_generate_meta(opts: GenerateOpts) -> Result<()> { crate::generate_update_metadata(&opts.sysroot).context("generating metadata failed")?; Ok(()) } /// Runner for `install` verb. - fn run_install(opts: InstallOpts) -> Result<()> { + pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { crate::install(&opts.src_root, &opts.dest_root).context("boot data installation failed")?; Ok(()) } From 33974f9f87bcaa105fd6c237cf507acc975770fe Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 28 Sep 2020 10:19:31 +0000 Subject: [PATCH 082/641] daemon: split daemon core-loop logic --- src/bootupd.rs | 72 +----------------------------------------- src/cli/bootupd.rs | 2 +- src/daemon/mod.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 72 deletions(-) create mode 100644 src/daemon/mod.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 24c22e934..dbe728c99 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -15,7 +15,6 @@ Refs: use anyhow::{bail, Context, Result}; use fs2::FileExt; -use nix::sys::socket as nixsocket; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -27,6 +26,7 @@ use std::path::Path; mod cli; pub use cli::MultiCall; mod component; +mod daemon; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; mod filetree; @@ -256,76 +256,6 @@ fn status() -> Result { Ok(ret) } -fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { - let mut buf = [0u8; ipc::MSGSIZE]; - loop { - let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; - let buf = &buf[0..n]; - if buf.is_empty() { - println!("Client disconnected"); - break; - } - - let msg = bincode::deserialize(&buf)?; - let r = match msg { - ClientRequest::Update { component } => { - println!("Processing update"); - bincode::serialize(&match update(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - ClientRequest::Validate { component } => { - println!("Processing validate"); - bincode::serialize(&match validate(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - ClientRequest::Status => { - println!("Processing status"); - bincode::serialize(&match status() { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - }; - let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; - if written != r.len() { - bail!("Wrote {} bytes to client, expected {}", written, r.len()); - } - } - Ok(()) -} - -fn daemon() -> Result<()> { - use libsystemd::daemon::{self, NotifyState}; - use std::os::unix::io::IntoRawFd; - if !daemon::booted() { - bail!("Not running systemd") - } - let mut fds = libsystemd::activation::receive_descriptors(true) - .map_err(|e| anyhow::anyhow!("Failed to receieve systemd descriptors: {}", e))?; - let srvsock_fd = if let Some(fd) = fds.pop() { - fd - } else { - bail!("No fd passed from systemd"); - }; - let srvsock_fd = srvsock_fd.into_raw_fd(); - let sent = daemon::notify(true, &[NotifyState::Ready]).expect("notify failed"); - if !sent { - bail!("Failed to notify systemd"); - } - loop { - let client = ipc::UnauthenticatedClient::new(nixsocket::accept4( - srvsock_fd, - nixsocket::SockFlag::SOCK_CLOEXEC, - )?); - let mut client = client.authenticate()?; - daemon_process_one(&mut client)?; - } -} - fn print_status(status: &Status) { for (name, component) in status.components.iter() { println!("Component {}", name); diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 9793ab38d..79af7e3e5 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -32,7 +32,7 @@ impl DCommand { /// Run CLI application. pub fn run(self) -> Result<()> { match self { - DCommand::Daemon => crate::daemon(), + DCommand::Daemon => crate::daemon::daemon(), DCommand::Install(opts) => Self::run_install(opts), DCommand::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs new file mode 100644 index 000000000..75f3ebd88 --- /dev/null +++ b/src/daemon/mod.rs @@ -0,0 +1,78 @@ +//! Daemon logic. + +use crate::ipc; +use anyhow::{bail, Result}; +use nix::sys::socket as nixsocket; + +pub fn daemon() -> Result<()> { + use libsystemd::daemon::{self, NotifyState}; + use std::os::unix::io::IntoRawFd; + + if !daemon::booted() { + bail!("Not running systemd") + } + let mut fds = libsystemd::activation::receive_descriptors(true) + .map_err(|e| anyhow::anyhow!("Failed to receieve systemd descriptors: {}", e))?; + let srvsock_fd = if let Some(fd) = fds.pop() { + fd + } else { + bail!("No fd passed from systemd"); + }; + let srvsock_fd = srvsock_fd.into_raw_fd(); + let sent = daemon::notify(true, &[NotifyState::Ready]).expect("notify failed"); + if !sent { + bail!("Failed to notify systemd"); + } + loop { + let client = ipc::UnauthenticatedClient::new(nixsocket::accept4( + srvsock_fd, + nixsocket::SockFlag::SOCK_CLOEXEC, + )?); + let mut client = client.authenticate()?; + daemon_process_one(&mut client)?; + } +} + +fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { + use crate::ClientRequest; + + let mut buf = [0u8; ipc::MSGSIZE]; + loop { + let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + let buf = &buf[0..n]; + if buf.is_empty() { + println!("Client disconnected"); + break; + } + + let msg = bincode::deserialize(&buf)?; + let r = match msg { + ClientRequest::Update { component } => { + println!("Processing update"); + bincode::serialize(&match crate::update(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? + } + ClientRequest::Validate { component } => { + println!("Processing validate"); + bincode::serialize(&match crate::validate(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? + } + ClientRequest::Status => { + println!("Processing status"); + bincode::serialize(&match crate::status() { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? + } + }; + let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; + if written != r.len() { + bail!("Wrote {} bytes to client, expected {}", written, r.len()); + } + } + Ok(()) +} From bc0904eeae77e16b1f00d53fe78f6b8e295ff2ce Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 28 Sep 2020 11:14:36 +0000 Subject: [PATCH 083/641] daemon: log and keep going on client errors This tweaks daemon core-logic to keep going on client-induced errors, logging them at "error" level. It also introduces docstring to ease casual code navigation. --- src/cli/bootupd.rs | 2 +- src/daemon/mod.rs | 84 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 79af7e3e5..64a01e9c5 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -32,7 +32,7 @@ impl DCommand { /// Run CLI application. pub fn run(self) -> Result<()> { match self { - DCommand::Daemon => crate::daemon::daemon(), + DCommand::Daemon => crate::daemon::run_coreloop(), DCommand::Install(opts) => Self::run_install(opts), DCommand::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 75f3ebd88..ca77f08df 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -1,39 +1,79 @@ //! Daemon logic. use crate::ipc; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use nix::sys::socket as nixsocket; +use std::os::unix::io::RawFd; -pub fn daemon() -> Result<()> { +/// Run daemon core-logic loop, endlessly. +pub fn run_coreloop() -> Result<()> { + let srvsock_fd = systemd_activation().context("systemd service activation error")?; + + loop { + // Accept an incoming client. + let client = match accept_authenticate_client(srvsock_fd) { + Ok(auth_client) => auth_client, + Err(e) => { + log::error!("failed to authenticate client: {}", e); + continue; + } + }; + + // Process all requests from this client. + if let Err(e) = process_client_requests(client) { + log::error!("failed to process request from client: {}", e); + continue; + } + } +} + +/// Perform initialization steps required by systemd service activation. +/// +/// This ensures that the system is running under systemd, then receives the +/// socket-FD for main IPC logic, and notifies systemd about ready-state. +fn systemd_activation() -> Result { use libsystemd::daemon::{self, NotifyState}; use std::os::unix::io::IntoRawFd; if !daemon::booted() { - bail!("Not running systemd") + bail!("daemon is not running as a systemd service"); } - let mut fds = libsystemd::activation::receive_descriptors(true) - .map_err(|e| anyhow::anyhow!("Failed to receieve systemd descriptors: {}", e))?; - let srvsock_fd = if let Some(fd) = fds.pop() { - fd - } else { - bail!("No fd passed from systemd"); + + let srvsock_fd = { + let mut fds = libsystemd::activation::receive_descriptors(true) + .map_err(|e| anyhow::anyhow!("failed to receive file-descriptors: {}", e))?; + let srvsock_fd = if let Some(fd) = fds.pop() { + fd + } else { + bail!("no socket-fd received on service activation"); + }; + srvsock_fd.into_raw_fd() }; - let srvsock_fd = srvsock_fd.into_raw_fd(); - let sent = daemon::notify(true, &[NotifyState::Ready]).expect("notify failed"); + + let sent = daemon::notify(true, &[NotifyState::Ready]) + .map_err(|e| anyhow::anyhow!("failed to notify ready-state: {}", e))?; if !sent { - bail!("Failed to notify systemd"); - } - loop { - let client = ipc::UnauthenticatedClient::new(nixsocket::accept4( - srvsock_fd, - nixsocket::SockFlag::SOCK_CLOEXEC, - )?); - let mut client = client.authenticate()?; - daemon_process_one(&mut client)?; + eprintln!("notifications not supported for this service"); } + + Ok(srvsock_fd) +} + +/// Accept an incoming connection, then authenticate the client. +fn accept_authenticate_client(srvsock_fd: RawFd) -> Result { + let accepted = nixsocket::accept4(srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC)?; + let client = ipc::UnauthenticatedClient::new(accepted); + + let authed = client.authenticate()?; + + Ok(authed) } -fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { +/// Process all requests from a given client. +/// +/// This sequentially processes all requests from a client, until it +/// disconnects or a connection error is encountered. +fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { use crate::ClientRequest; let mut buf = [0u8; ipc::MSGSIZE]; @@ -71,7 +111,7 @@ fn daemon_process_one(client: &mut ipc::AuthenticatedClient) -> Result<()> { }; let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; if written != r.len() { - bail!("Wrote {} bytes to client, expected {}", written, r.len()); + bail!("wrote {} bytes to client, expected {}", written, r.len()); } } Ok(()) From b20cd821ff472eb7d95547e512820ec97f62b866 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 29 Sep 2020 11:24:45 -0400 Subject: [PATCH 084/641] ci: Use main fedora-coreos-config repo Now that the PR is merged. --- .cci.jenkinsfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index d8ce44de4..88933ece5 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -44,9 +44,7 @@ stage("FCOS") { mkdir insttree tar -C insttree -xzvf insttree.tar.gz rsync -rlv insttree/ / - # https://github.com/coreos/fedora-coreos-config/pull/595 - coreos-assembler init --force https://github.com/cgwalters/fedora-coreos-config - (cd src/config && git checkout use-bootupd) + coreos-assembler init --force https://github.com/coreos/fedora-coreos-config mkdir -p overrides/rootfs mv insttree/* overrides/rootfs/ rmdir insttree From 3ae7fecc69d734d06349777c5826657f958ab624 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 29 Sep 2020 15:23:45 -0400 Subject: [PATCH 085/641] efi: Add more error context I hit an error here and wanted to know which specific phase was failing. --- src/efi.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 95822ffb4..004d6b78e 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -65,12 +65,15 @@ impl Component for EFI { .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; let updatemeta = self.query_update()?.expect("update available"); - let updated = openat::Dir::open(&component_updatedir("/", self))?; - let updatef = filetree::FileTree::new_from_dir(&updated)?; + let updated = + openat::Dir::open(&component_updatedir("/", self)).context("opening update dir")?; + let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; let diff = currentf.diff(&updatef)?; - let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI"))?; + let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI")) + .context("opening EFI dir")?; validate_esp(&destdir)?; - filetree::apply_diff(&updated, &destdir, &diff, None)?; + filetree::apply_diff(&updated, &destdir, &diff, None) + .context("applying filesystem changes")?; Ok(InstalledContent { meta: updatemeta, filetree: Some(updatef), From 6f1ff70fd05f018e2c563e1984ff22416b2cb7ae Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 30 Sep 2020 12:17:53 +0000 Subject: [PATCH 086/641] daemon: avoid direct printing, log instead This converts all daemon logic to stop directly printing to stdout/stderr, and instead perform logging at the appropriate level. --- src/daemon/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index ca77f08df..f1ed85dfd 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -53,7 +53,7 @@ fn systemd_activation() -> Result { let sent = daemon::notify(true, &[NotifyState::Ready]) .map_err(|e| anyhow::anyhow!("failed to notify ready-state: {}", e))?; if !sent { - eprintln!("notifications not supported for this service"); + log::warn!("failed to notify ready-state: service notifications not supported"); } Ok(srvsock_fd) @@ -81,28 +81,28 @@ fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; let buf = &buf[0..n]; if buf.is_empty() { - println!("Client disconnected"); + log::trace!("client disconnected"); break; } let msg = bincode::deserialize(&buf)?; let r = match msg { ClientRequest::Update { component } => { - println!("Processing update"); + log::trace!("processing 'update' request"); bincode::serialize(&match crate::update(component.as_str()) { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } ClientRequest::Validate { component } => { - println!("Processing validate"); + log::trace!("processing 'validate' request"); bincode::serialize(&match crate::validate(component.as_str()) { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } ClientRequest::Status => { - println!("Processing status"); + log::trace!("processing 'status' request"); bincode::serialize(&match crate::status() { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), From 830fa380fbfd660919e3b3fb5cb1fc968f82e5c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 29 Sep 2020 20:30:03 -0400 Subject: [PATCH 087/641] filetree: Fix creation of parent directories An embarrassing bug where I accidentally intermixed absolute path handling with fd-relative, and wasn't caught by either the unit tests or integration tests because the current directory was writable. But it was caught by a new test suite which doesn't use `rpm-ostree usroverlay`. --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/filetree.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9696a45de..bf9cdd279 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -385,9 +385,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2862a15ef65cac3c516de37ce6f026e0d77ad03d229f471e8294a29a962da1d6" +checksum = "af1be1e54fbd54bae8b4497ddcc30f97ae57f18fa37fa2f35d48db7b0a8f0b59" dependencies = [ "libc", "nix", diff --git a/Cargo.toml b/Cargo.toml index 646e73e1b..bad5206b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.17.0" openat = "0.1.19" -openat-ext = "^0.1.5" +openat-ext = "^0.1.6" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" diff --git a/src/filetree.rs b/src/filetree.rs index ea6dc67a2..8041e8fe1 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -303,7 +303,7 @@ pub(crate) fn apply_diff( let path = Path::new(pathstr); if let Some(parent) = path.parent() { // TODO: care about directory modes? We don't for FAT. - std::fs::create_dir_all(parent)?; + destdir.ensure_dir_all(parent, 0o755)?; } let destp = tmpname_for_path(path); copy_file_at(srcdir, destdir, path, destp.as_path()) @@ -339,6 +339,7 @@ pub(crate) fn apply_diff( #[cfg(test)] mod tests { use super::*; + use std::fs; use std::io::Write; fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { @@ -461,4 +462,47 @@ mod tests { test_apply(&pa, &pb).context("testing apply 3")?; Ok(()) } + + #[test] + fn test_filetree2() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let tmpdp = tmpd.path(); + let relp = "EFI/fedora"; + let a = tmpdp.join("a"); + let b = tmpdp.join("b"); + for d in &[&a, &b] { + let efidir = d.join(relp); + fs::create_dir_all(&efidir)?; + let shimdata = "shim data"; + fs::write(efidir.join("shim.x64"), shimdata)?; + let grubdata = "grub data"; + fs::write(efidir.join("grub.x64"), grubdata)?; + } + fs::write(b.join(relp).join("grub.x64"), "grub data 2")?; + let newsubp = Path::new(relp).join("subdir"); + fs::create_dir_all(b.join(&newsubp))?; + fs::write(b.join(&newsubp).join("newgrub.x64"), "newgrub data")?; + fs::remove_file(b.join(&relp).join("shim.x64"))?; + { + let a = openat::Dir::open(&a)?; + let b = openat::Dir::open(&b)?; + let ta = FileTree::new_from_dir(&a)?; + let tb = FileTree::new_from_dir(&b)?; + let diff = ta.diff(&tb)?; + assert_eq!(diff.changes.len(), 1); + assert_eq!(diff.additions.len(), 1); + assert_eq!(diff.count(), 3); + super::apply_diff(&b, &a, &diff, None)?; + } + assert_eq!( + String::from_utf8(std::fs::read(a.join(relp).join("grub.x64"))?)?, + "grub data 2" + ); + assert_eq!( + String::from_utf8(std::fs::read(a.join(&newsubp).join("newgrub.x64"))?)?, + "newgrub data" + ); + assert!(!a.join(&relp).join("shim.x64").exists()); + Ok(()) + } } From bfd47c93dbff810722ef333151ed17a4fb267cdd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 30 Sep 2020 13:06:11 -0400 Subject: [PATCH 088/641] filetree: Remove lots of #[allow(dead_code)] For a while the filetree code wasn't used by EFI, now it is again, so remove most of the `allow(dead_code)` and only use `cfg(test)` for a few of them that are only used by tests. Came up in PR review. --- src/filetree.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 8041e8fe1..9792dfcdc 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -15,7 +15,6 @@ use std::os::unix::process::CommandExt; use std::path::Path; /// The prefix we apply to our temporary files. -#[allow(dead_code)] // Used for testing pub(crate) const TMP_PREFIX: &str = ".btmp."; use crate::sha512string::SHA512String; @@ -44,14 +43,13 @@ pub(crate) struct FileTreeDiff { pub(crate) changes: HashSet, } +#[cfg(test)] impl FileTreeDiff { - #[allow(dead_code)] // Used for testing pub(crate) fn count(&self) -> usize { self.additions.len() + self.removals.len() + self.changes.len() } } -#[allow(dead_code)] // Used for testing impl FileMetadata { pub(crate) fn new_from_path( dir: &openat::Dir, @@ -70,7 +68,6 @@ impl FileMetadata { } } -#[allow(dead_code)] // Used for testing impl FileTree { // Internal helper to generate a sub-tree fn unsorted_from_dir(dir: &openat::Dir) -> Result> { @@ -121,7 +118,6 @@ impl FileTree { } /// Determine the changes *from* self to the updated tree - #[allow(dead_code)] // Used in tests and kept for completeness pub(crate) fn diff(&self, updated: &Self) -> Result { self.diff_impl(updated, true) } @@ -129,13 +125,14 @@ impl FileTree { /// Determine any changes only using the files tracked in self as /// a reference. In other words, this will ignore any unknown /// files and not count them as additions. + #[cfg(test)] pub(crate) fn changes(&self, current: &Self) -> Result { self.diff_impl(current, false) } /// The inverse of `changes` - determine if there are any files /// changed or added in `current` compared to self. - #[allow(dead_code)] + #[cfg(test)] pub(crate) fn updates(&self, current: &Self) -> Result { current.diff_impl(self, false) } @@ -231,14 +228,12 @@ fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { } #[derive(Default, Clone)] -#[allow(dead_code)] // Used for testing pub(crate) struct ApplyUpdateOptions { pub(crate) skip_removals: bool, pub(crate) skip_sync: bool, } /// A bit like std::fs::copy but operates dirfd-relative -#[allow(dead_code)] // Used for testing fn copy_file_at, DP: AsRef>( srcdir: &openat::Dir, destdir: &openat::Dir, @@ -258,7 +253,6 @@ fn copy_file_at, DP: AsRef>( // to be bound in nix today. I found https://github.com/XuShaohua/nc // but that's a nontrivial dependency with not a lot of code review. // Let's just fork off a helper process for now. -#[allow(dead_code)] // Used for testing pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { let d = d.sub_dir(".").expect("subdir"); let mut c = std::process::Command::new("sync"); @@ -276,7 +270,6 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { Ok(()) } -#[allow(dead_code)] // Used for testing fn tmpname_for_path>(path: P) -> std::path::PathBuf { let path = path.as_ref(); let mut buf = path.file_name().expect("filename").to_os_string(); @@ -285,7 +278,6 @@ fn tmpname_for_path>(path: P) -> std::path::PathBuf { } /// Given two directories, apply a diff generated from srcdir to destdir -#[allow(dead_code)] // Used for testing pub(crate) fn apply_diff( srcdir: &openat::Dir, destdir: &openat::Dir, From 51f4f898312018c893b08078d68a10df8587b65c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 28 Sep 2020 10:21:15 -0400 Subject: [PATCH 089/641] Add a more realistic e2e upgrade test The way we generate updates uses the timestamp and version numbers from the set of RPMs. --- .cci.jenkinsfile | 12 +++- tests/e2e/e2e-in-vm.sh | 72 +++++++++++++++++++ tests/e2e/e2e.sh | 99 ++++++++++++++++++++++++++ tests/e2e/testrpmbuild.sh | 142 +++++++++++++++++++++++++++++++++++++ tests/kola/data/libtest.sh | 5 ++ 5 files changed, 327 insertions(+), 3 deletions(-) create mode 100755 tests/e2e/e2e-in-vm.sh create mode 100755 tests/e2e/e2e.sh create mode 100644 tests/e2e/testrpmbuild.sh diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 88933ece5..49a9689de 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -49,11 +49,17 @@ stage("FCOS") { mv insttree/* overrides/rootfs/ rmdir insttree coreos-assembler fetch - coreos-assembler build """) } - stage("Test") { - fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*") + // The e2e test does a build, so we just end at fetch above + stage("e2e upgrade test") { + shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e/e2e.sh") + } + stage("Kola testing") { + // The previous e2e leaves things only having built an ostree update + shwrap("cosa build") + // bootupd really can't break upgrades for the OS + fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) } } } diff --git a/tests/e2e/e2e-in-vm.sh b/tests/e2e/e2e-in-vm.sh new file mode 100755 index 000000000..9df6e3110 --- /dev/null +++ b/tests/e2e/e2e-in-vm.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# Run inside the vm spawned from e2e.sh +set -euo pipefail + +dn=$(cd $(dirname $0) && pwd) +bn=$(basename $0) +. ${dn}/../kola/data/libtest.sh + +cd $(mktemp -d) + +echo "Starting $0" + +current_commit=$(rpm-ostree status --json | jq -r .deployments[0].checksum) + +stampfile=/etc/${bn}.upgraded +if ! test -f ${stampfile}; then + if test "${current_commit}" = ${TARGET_COMMIT}; then + fatal "already at ${TARGET_COMMIT}" + fi + + current_grub=$(rpm -q --queryformat='%{nevra}\n' ${TARGET_GRUB_NAME}) + if test "${current_grub}" == "${TARGET_GRUB_PKG}"; then + fatal "Current grub ${current_grub} is same as target ${TARGET_GRUB_PKG}" + fi + + # FIXME + # https://github.com/coreos/rpm-ostree/issues/2210 + runv setenforce 0 + runv rpm-ostree rebase /run/cosadir/tmp/repo:${TARGET_COMMIT} + runv touch ${stampfile} + runv systemd-run -- systemctl reboot + touch /run/rebooting + sleep infinity +else + if test "${current_commit}" != ${TARGET_COMMIT}; then + fatal "not at ${TARGET_COMMIT}" + fi +fi + +# We did setenforce 0 above for https://github.com/coreos/rpm-ostree/issues/2210 +# Validate that on reboot we're still enforcing. +semode=$(getenforce) +if test "$semode" != Enforcing; then + fatal "SELinux mode is ${semode}" +fi + +if ! test -n "${TARGET_GRUB_PKG}"; then + fatal "Missing TARGET_GRUB_PKG" +fi + +systemctl start bootupd.socket +# For now +export BOOTUPD_ACCEPT_PREVIEW=1 + +bootupctl validate +ok validate + +bootupctl status | tee out.txt +assert_file_has_content_literal out.txt 'Component EFI' +assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' +assert_not_file_has_content out.txt ' Installed:.*'"${TARGET_GRUB_PKG}" +assert_file_has_content out.txt 'Update: Available:.*'"${TARGET_GRUB_PKG}" +ok update avail + +bootupctl update | tee out.txt +assert_file_has_content_literal out.txt 'Updated EFI: '"${TARGET_GRUB_PKG}" + +tap_finish +touch /run/testtmp/success +sync +# TODO maybe try to make this use more of the exttest infrastructure? +exec poweroff -ff diff --git a/tests/e2e/e2e.sh b/tests/e2e/e2e.sh new file mode 100755 index 000000000..ab83b586c --- /dev/null +++ b/tests/e2e/e2e.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# Given a coreos-assembler dir (COSA_DIR) and assuming +# the current dir is a git repository for bootupd, +# synthesize a test update and upgrade to it. This +# assumes that the latest cosa build is using the +# code we want to test (as happens in CI). +set -euo pipefail + +dn=$(cd $(dirname $0) && pwd) +. ${dn}/../kola/data/libtest.sh +. ${dn}/testrpmbuild.sh + +if test -z "${COSA_DIR:-}"; then + fatal "COSA_DIR must be set" +fi +# Validate source directory +bootupd_git=$(cd ${dn} && git rev-parse --show-toplevel) +test -f ${bootupd_git}/systemd/bootupd.service + +# Start in cosa dir +cd ${COSA_DIR} +test -d builds + +overrides=${COSA_DIR}/overrides +test -d "${overrides}" +mkdir -p ${overrides}/rpm +add_override() { + override=$1 + shift + # This relies on "gold" grub not being pruned, and different from what's + # in the latest fcos + (cd ${overrides}/rpm && runv koji download-build --arch=noarch --arch=$(arch) ${override}) +} +if test -z "${e2e_skip_build:-}"; then + echo "Building starting image" + rm -f ${overrides}/rpm/*.rpm + add_override grub2-2.04-22.fc32 + (cd ${bootupd_git} && runv make && runv make install DESTDIR=${overrides}/rootfs) + runv cosa build + prev_image=$(runv cosa meta --image-path qemu) + rm -f ${overrides}/rpm/*.rpm + echo "Building update ostree" + add_override grub2-2.04-23.fc32 + # Only build ostree update + runv cosa build ostree +fi +echo "Preparing test" +grubarch= +case $(arch) in + x86_64) grubarch=x64;; + aarch64) grubarch=aa64;; + *) fatal "Unhandled arch $(arch)";; +esac +target_grub_name=grub2-efi-${grubarch} +target_grub_pkg=$(rpm -qp --queryformat='%{nevra}\n' ${overrides}/rpm/${target_grub_name}-2*.rpm) +target_commit=$(cosa meta --get-value ostree-commit) +echo "Target commit: ${target_commit}" +# For some reason 9p can't write to tmpfs +testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) +cat >${testtmp}/test.fcct << EOF +variant: fcos +version: 1.0.0 +systemd: + units: + - name: bootupd-test.service + enabled: true + contents: | + [Unit] + RequiresMountsFor=/run/testtmp + [Service] + Type=oneshot + RemainAfterExit=yes + Environment=TARGET_COMMIT=${target_commit} + Environment=TARGET_GRUB_NAME=${target_grub_name} + Environment=TARGET_GRUB_PKG=${target_grub_pkg} + Environment=SRCDIR=/run/bootupd-source + # Run via shell because selinux denies systemd writing to 9p apparently + ExecStart=/bin/sh -c '/run/bootupd-source/tests/e2e/e2e-in-vm.sh &>>/run/testtmp/out.txt; test -f /run/rebooting || poweroff -ff' + [Install] + WantedBy=multi-user.target +EOF +runv fcct -o ${testtmp}/test.ign ${testtmp}/test.fcct +cd ${testtmp} +qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${prev_image}" --qemu-firmware uefi \ + -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw .,/run/testtmp) +if test -n "${e2e_debug:-}"; then + runv ${qemuexec_args[@]} --devshell +else + runv timeout 5m "${qemuexec_args[@]}" -- -chardev file,id=log,path=console.txt -serial chardev:log +fi +if ! test -f ${testtmp}/success; then + if test -s ${testtmp}/out.txt; then + sed -e 's,^,# ,' < ${testtmp}/out.txt + else + echo "No out.txt created, systemd unit failed to start" + fi + fatal "test failed" +fi +echo "ok bootupd e2e" diff --git a/tests/e2e/testrpmbuild.sh b/tests/e2e/testrpmbuild.sh new file mode 100644 index 000000000..5a6f3c22f --- /dev/null +++ b/tests/e2e/testrpmbuild.sh @@ -0,0 +1,142 @@ +# Copied from rpm-ostree + +# builds a new RPM and adds it to the testdir's repo +# $1 - name +# $2+ - optional, treated as directive/value pairs +build_rpm() { + local name=$1; shift + # Unset, not zero https://github.com/projectatomic/rpm-ostree/issues/349 + local epoch="" + local version=1.0 + local release=1 + local arch=x86_64 + + mkdir -p $test_tmpdir/yumrepo/{specs,packages} + local spec=$test_tmpdir/yumrepo/specs/$name.spec + + # write out the header + cat > $spec << EOF +Name: $name +Summary: %{name} +License: GPLv2+ +EOF + + local build= install= files= pretrans= pre= post= posttrans= post_args= + local verifyscript= uinfo= + local transfiletriggerin= transfiletriggerin_patterns= + local transfiletriggerin2= transfiletriggerin2_patterns= + local transfiletriggerun= transfiletriggerun_patterns= + while [ $# -ne 0 ]; do + local section=$1; shift + local arg=$1; shift + case $section in + requires) + echo "Requires: $arg" >> $spec;; + recommends) + echo "Recommends: $arg" >> $spec;; + provides) + echo "Provides: $arg" >> $spec;; + conflicts) + echo "Conflicts: $arg" >> $spec;; + post_args) + post_args="$arg";; + version|release|epoch|arch|build|install|files|pretrans|pre|post|posttrans|verifyscript|uinfo) + declare $section="$arg";; + transfiletriggerin) + transfiletriggerin_patterns="$arg"; + declare $section="$1"; shift;; + transfiletriggerin2) + transfiletriggerin2_patterns="$arg"; + declare $section="$1"; shift;; + transfiletriggerun) + transfiletriggerun_patterns="$arg"; + declare $section="$1"; shift;; + *) + assert_not_reached "unhandled section $section";; + esac + done + + cat >> $spec << EOF +Version: $version +Release: $release +${epoch:+Epoch: $epoch} +BuildArch: $arch + +%description +%{summary} + +# by default, we create a /usr/bin/$name script which just outputs $name +%build +echo -e "#!/bin/sh\necho $name-$version-$release.$arch" > $name +chmod a+x $name +$build + +${pretrans:+%pretrans} +$pretrans + +${pre:+%pre} +$pre + +${post:+%post} ${post_args} +$post + +${posttrans:+%posttrans} +$posttrans + +${transfiletriggerin:+%transfiletriggerin -- ${transfiletriggerin_patterns}} +$transfiletriggerin + +${transfiletriggerin2:+%transfiletriggerin -- ${transfiletriggerin2_patterns}} +$transfiletriggerin2 + +${transfiletriggerun:+%transfiletriggerun -- ${transfiletriggerun_patterns}} +$transfiletriggerun + +${verifyscript:+%verifyscript} +$verifyscript + +%install +mkdir -p %{buildroot}/usr/bin +install $name %{buildroot}/usr/bin +$install + +%clean +rm -rf %{buildroot} + +%files +/usr/bin/$name +$files +EOF + + # because it'd be overkill to set up mock for this, let's just fool + # rpmbuild using setarch + local buildarch=$arch + if [ "$arch" == "noarch" ]; then + buildarch=$(uname -m) + fi + + (cd $test_tmpdir/yumrepo/specs && + setarch $buildarch rpmbuild --target $arch -ba $name.spec \ + --define "_topdir $PWD" \ + --define "_sourcedir $PWD" \ + --define "_specdir $PWD" \ + --define "_builddir $PWD/.build" \ + --define "_srcrpmdir $PWD" \ + --define "_rpmdir $test_tmpdir/yumrepo/packages" \ + --define "_buildrootdir $PWD") + # use --keep-all-metadata to retain previous updateinfo + (cd $test_tmpdir/yumrepo && + createrepo_c --no-database --update --keep-all-metadata .) + # convenience function to avoid follow-up add-pkg + if [ -n "$uinfo" ]; then + uinfo_cmd add-pkg $uinfo $name 0 $version $release $arch + fi + if test '!' -f $test_tmpdir/yumrepo.repo; then + cat > $test_tmpdir/yumrepo.repo.tmp << EOF +[test-repo] +name=test-repo +baseurl=file:///$PWD/yumrepo +EOF + mv $test_tmpdir/yumrepo.repo{.tmp,} + fi +} diff --git a/tests/kola/data/libtest.sh b/tests/kola/data/libtest.sh index 80844bf9e..f21a89496 100644 --- a/tests/kola/data/libtest.sh +++ b/tests/kola/data/libtest.sh @@ -21,6 +21,11 @@ fatal() { echo error: $@ 1>&2; exit 1 } +runv() { + set -x + "$@" +} + # Dump ls -al + file contents to stderr, then fatal() _fatal_print_file() { file="$1" From 9d638b327aa014561c86d791ec7534a7eefc412e Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 29 Sep 2020 14:49:50 +0000 Subject: [PATCH 090/641] cli: add flag to control logging level This introduces a new `-v(vv)` flag on both `bootupd` and `bootupctl` to control log verbosity. The default level only shows warnings and higher priorities. The service unit sets up the daemon to log info messages too, and can be overridden via a drop-in. This also introduces some basic unit-tests on CLI parsing. --- src/cli/bootupctl.rs | 39 ++++++++++++++++++++----- src/cli/bootupd.rs | 35 +++++++++++++++++++---- src/cli/mod.rs | 63 ++++++++++++++++++++++++++++++++++++++--- src/main.rs | 6 ++-- systemd/bootupd.service | 3 +- 5 files changed, 126 insertions(+), 20 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 338e22d79..33bed26b9 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -1,12 +1,37 @@ use crate::ipc::ClientToDaemonConnection; use anyhow::Result; +use log::LevelFilter; use structopt::clap::AppSettings; use structopt::StructOpt; /// `bootupctl` sub-commands. #[derive(Debug, StructOpt)] #[structopt(name = "bootupctl", about = "Bootupd client application")] -pub enum CtlCommand { +pub struct CtlCommand { + /// Verbosity level (higher is more verbose). + #[structopt(short = "v", parse(from_occurrences), global = true)] + verbosity: u8, + + /// CLI sub-command. + #[structopt(subcommand)] + pub cmd: CtlVerb, +} + +impl CtlCommand { + /// Return the log-level set via command-line flags. + pub(crate) fn loglevel(&self) -> LevelFilter { + match self.verbosity { + 0 => LevelFilter::Warn, + 1 => LevelFilter::Info, + 2 => LevelFilter::Debug, + _ => LevelFilter::Trace, + } + } +} + +/// CLI sub-commands. +#[derive(Debug, StructOpt)] +pub enum CtlVerb { // FIXME(lucab): drop this after refreshing // https://github.com/coreos/fedora-coreos-config/pull/595 #[structopt(name = "backend", setting = AppSettings::Hidden)] @@ -37,14 +62,14 @@ pub struct StatusOpts { impl CtlCommand { /// Run CLI application. pub fn run(self) -> Result<()> { - match self { - CtlCommand::Status(opts) => Self::run_status(opts), - CtlCommand::Update => Self::run_update(), - CtlCommand::Validate => Self::run_validate(), - CtlCommand::Backend(CtlBackend::Generate(opts)) => { + match self.cmd { + CtlVerb::Status(opts) => Self::run_status(opts), + CtlVerb::Update => Self::run_update(), + CtlVerb::Validate => Self::run_validate(), + CtlVerb::Backend(CtlBackend::Generate(opts)) => { super::bootupd::DCommand::run_generate_meta(opts) } - CtlCommand::Backend(CtlBackend::Install(opts)) => { + CtlVerb::Backend(CtlBackend::Install(opts)) => { super::bootupd::DCommand::run_install(opts) } } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 64a01e9c5..377bf65e5 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -1,10 +1,35 @@ use anyhow::{Context, Result}; +use log::LevelFilter; use structopt::StructOpt; /// `bootupd` sub-commands. #[derive(Debug, StructOpt)] #[structopt(name = "bootupd", about = "Bootupd backend commands")] -pub enum DCommand { +pub struct DCommand { + /// Verbosity level (higher is more verbose). + #[structopt(short = "v", parse(from_occurrences), global = true)] + verbosity: u8, + + /// CLI sub-command. + #[structopt(subcommand)] + pub cmd: DVerb, +} + +impl DCommand { + /// Return the log-level set via command-line flags. + pub(crate) fn loglevel(&self) -> LevelFilter { + match self.verbosity { + 0 => LevelFilter::Warn, + 1 => LevelFilter::Info, + 2 => LevelFilter::Debug, + _ => LevelFilter::Trace, + } + } +} + +/// CLI sub-commands. +#[derive(Debug, StructOpt)] +pub enum DVerb { #[structopt(name = "daemon", about = "Run service logic")] Daemon, #[structopt(name = "generate-update-metadata", about = "Generate metadata")] @@ -31,10 +56,10 @@ pub struct GenerateOpts { impl DCommand { /// Run CLI application. pub fn run(self) -> Result<()> { - match self { - DCommand::Daemon => crate::daemon::run_coreloop(), - DCommand::Install(opts) => Self::run_install(opts), - DCommand::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), + match self.cmd { + DVerb::Daemon => crate::daemon::run_coreloop(), + DVerb::Install(opts) => Self::run_install(opts), + DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 01f246d73..5ea94e76b 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,6 +1,7 @@ //! Command-line interface (CLI) logic. use anyhow::Result; +use log::LevelFilter; use structopt::StructOpt; mod bootupctl; @@ -14,19 +15,19 @@ pub enum MultiCall { } impl MultiCall { - pub fn from_args() -> Self { + pub fn from_args(args: Vec) -> Self { use std::os::unix::ffi::OsStrExt; // This is a multicall binary, dispatched based on the introspected // filename found in argv[0]. let exe_name = { - let arg0 = std::env::args().nth(0).unwrap_or_default(); + let arg0 = args.get(0).cloned().unwrap_or_default(); let exe_path = std::path::PathBuf::from(arg0); exe_path.file_name().unwrap_or_default().to_os_string() }; match exe_name.as_bytes() { - b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::from_args()), - b"bootupd" | _ => MultiCall::D(bootupd::DCommand::from_args()), + b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::from_iter(args)), + b"bootupd" | _ => MultiCall::D(bootupd::DCommand::from_iter(args)), } } @@ -36,4 +37,58 @@ impl MultiCall { MultiCall::D(d_cmd) => d_cmd.run(), } } + + /// Return the log-level set via command-line flags. + pub fn loglevel(&self) -> LevelFilter { + match self { + MultiCall::Ctl(cmd) => cmd.loglevel(), + MultiCall::D(cmd) => cmd.loglevel(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_multicall_dispatch() { + { + let d_argv = vec!["/usr/bin/bootupd".to_string(), "daemon".to_string()]; + let cli = MultiCall::from_args(d_argv); + match cli { + MultiCall::Ctl(cmd) => panic!(cmd), + MultiCall::D(_) => {} + }; + } + { + let ctl_argv = vec!["/usr/bin/bootupctl".to_string(), "validate".to_string()]; + let cli = MultiCall::from_args(ctl_argv); + match cli { + MultiCall::Ctl(_) => {} + MultiCall::D(cmd) => panic!(cmd), + }; + } + { + let ctl_argv = vec!["/bin-mount/bootupctl".to_string(), "validate".to_string()]; + let cli = MultiCall::from_args(ctl_argv); + match cli { + MultiCall::Ctl(_) => {} + MultiCall::D(cmd) => panic!(cmd), + }; + } + } + + #[test] + fn test_verbosity() { + let default = MultiCall::from_args(vec!["bootupd".to_string(), "daemon".to_string()]); + assert_eq!(default.loglevel(), LevelFilter::Warn); + + let info = MultiCall::from_args(vec![ + "bootupd".to_string(), + "daemon".to_string(), + "-v".to_string(), + ]); + assert_eq!(info.loglevel(), LevelFilter::Info); + } } diff --git a/src/main.rs b/src/main.rs index c860c8ebe..20236b1fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ //! Bootupd command-line application. -use log::LevelFilter; use structopt::clap::crate_name; /// Binary entrypoint, for both daemon and client logic. @@ -12,13 +11,14 @@ fn main() { /// CLI logic. fn run_cli() -> i32 { // Parse command-line options. - let cli_opts = bootupd::MultiCall::from_args(); + let args: Vec<_> = std::env::args().collect(); + let cli_opts = bootupd::MultiCall::from_args(args); // Setup logging. env_logger::Builder::from_default_env() .format_timestamp(None) .format_module_path(false) - .filter(Some(crate_name!()), LevelFilter::Warn) + .filter(Some(crate_name!()), cli_opts.loglevel()) .init(); // Dispatch CLI subcommand. diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 91464e97d..3266eedfb 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -4,7 +4,8 @@ Documentation=https://github.com/coreos/bootupd [Service] Type=notify -ExecStart=/usr/libexec/bootupd daemon +Environment=BOOTUPD_VERBOSITY="-v" +ExecStart=/usr/libexec/bootupd daemon $BOOTUPD_VERBOSITY # On general principle ProtectHome=yes # So we can remount /boot writable From ac3cd8d6f4e5c93f6e748c9536154673fd9225ba Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 1 Oct 2020 15:23:02 -0400 Subject: [PATCH 091/641] daemon: Exit when done processing requests There's no reason to sit there taking up RAM just because someone did `bootupctl status`. Properly implementing exit-on-idle really requires an event loop (e.g. `tokio`) but that'd be a large change. For now let's just exit when a client disconnects. However, this quickly broke the test suite which does a lot of commands in a row. Tweak the systemd unit to allow more restarts, and also add a few strategic sleeps. Closes: https://github.com/coreos/bootupd/issues/43 --- src/cli/bootupd.rs | 2 +- src/daemon/mod.rs | 40 ++++++++++++++++++++++++---------------- systemd/bootupd.service | 5 +++++ tests/kola/test-bootupd | 5 +++++ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 377bf65e5..4a3834d3f 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -57,7 +57,7 @@ impl DCommand { /// Run CLI application. pub fn run(self) -> Result<()> { match self.cmd { - DVerb::Daemon => crate::daemon::run_coreloop(), + DVerb::Daemon => crate::daemon::run(), DVerb::Install(opts) => Self::run_install(opts), DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index f1ed85dfd..5a583b30c 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -5,26 +5,34 @@ use anyhow::{bail, Context, Result}; use nix::sys::socket as nixsocket; use std::os::unix::io::RawFd; -/// Run daemon core-logic loop, endlessly. -pub fn run_coreloop() -> Result<()> { +/// Accept a single client and then exit; we don't want to +/// persistently run as a daemon. The systemd unit is mostly +/// and implementation detail - it lets us use things like +/// systemd's built in sandboxing (ProtectHome=yes) etc. and also +/// ensures that only a single bootupd instance is running at +/// a time (i.e. don't support concurrent updates). +pub fn run() -> Result<()> { let srvsock_fd = systemd_activation().context("systemd service activation error")?; - loop { - // Accept an incoming client. - let client = match accept_authenticate_client(srvsock_fd) { - Ok(auth_client) => auth_client, - Err(e) => { - log::error!("failed to authenticate client: {}", e); - continue; - } - }; - - // Process all requests from this client. - if let Err(e) = process_client_requests(client) { - log::error!("failed to process request from client: {}", e); - continue; + // Accept an incoming client. + let client = match accept_authenticate_client(srvsock_fd) { + Ok(auth_client) => auth_client, + Err(e) => { + log::error!("failed to authenticate client: {}", e); + return Ok(()); } + }; + + // Process all requests from this client. + if let Err(e) = process_client_requests(client) { + log::error!("failed to process request from client: {}", e); } + + // Sleep for a half second to avoid triggering systemd service + // restart limits. + std::thread::sleep(std::time::Duration::from_secs_f32(0.5)); + + Ok(()) } /// Perform initialization steps required by systemd service activation. diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 3266eedfb..7a7bcdc99 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -1,6 +1,11 @@ [Unit] Description=bootloader update daemon Documentation=https://github.com/coreos/bootupd +# Because the daemon currently agressively auto-exits +# and our test suite runs many requests, let's allow +# a lot of restarts before failing. +StartLimitIntervalSec=2s +StartLimitBurst=10 [Service] Type=notify diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 964f2438a..ce7b4df2a 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -48,6 +48,11 @@ assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' ok status +# Validate we auto-exited +sleep 2 +systemctl show -p ActiveState bootupd > out.txt +assert_file_has_content_literal out.txt 'ActiveState=inactive' + bootupctl validate | tee out.txt ok validate From 784189cb641ef8d82d2b09bd14ea3a1ce819ed12 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 1 Oct 2020 19:41:30 -0400 Subject: [PATCH 092/641] tests/e2e: Validate adding a new RPM With new content. This helps test things more. --- tests/e2e/e2e-in-vm.sh | 8 +++++- tests/e2e/e2e.sh | 51 ++++++++++++++++++++++++++++++++++++-- tests/kola/data/libtest.sh | 8 ++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/tests/e2e/e2e-in-vm.sh b/tests/e2e/e2e-in-vm.sh index 9df6e3110..4d41d4466 100755 --- a/tests/e2e/e2e-in-vm.sh +++ b/tests/e2e/e2e-in-vm.sh @@ -58,12 +58,18 @@ ok validate bootupctl status | tee out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' +assert_not_file_has_content out.txt ' Installed:.*test-bootupd-payload' assert_not_file_has_content out.txt ' Installed:.*'"${TARGET_GRUB_PKG}" assert_file_has_content out.txt 'Update: Available:.*'"${TARGET_GRUB_PKG}" +assert_file_has_content out.txt 'Update: Available:.*test-bootupd-payload-1.0' ok update avail +assert_not_has_file /boot/efi/EFI/fedora/test-bootupd.efi + bootupctl update | tee out.txt -assert_file_has_content_literal out.txt 'Updated EFI: '"${TARGET_GRUB_PKG}" +assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd-payload-1.0" + +assert_file_has_content /boot/efi/EFI/fedora/test-bootupd.efi test-payload tap_finish touch /run/testtmp/success diff --git a/tests/e2e/e2e.sh b/tests/e2e/e2e.sh index ab83b586c..921f3a53f 100755 --- a/tests/e2e/e2e.sh +++ b/tests/e2e/e2e.sh @@ -17,6 +17,16 @@ fi bootupd_git=$(cd ${dn} && git rev-parse --show-toplevel) test -f ${bootupd_git}/systemd/bootupd.service +testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) +export test_tmpdir=${testtmp} + +# This is new content for our update +test_bootupd_payload_file=/boot/efi/EFI/fedora/test-bootupd.efi +build_rpm test-bootupd-payload \ + files ${test_bootupd_payload_file} \ + install "mkdir -p %{buildroot}/$(dirname ${test_bootupd_payload_file}) + echo test-payload > %{buildroot}/${test_bootupd_payload_file}" + # Start in cosa dir cd ${COSA_DIR} test -d builds @@ -31,6 +41,40 @@ add_override() { # in the latest fcos (cd ${overrides}/rpm && runv koji download-build --arch=noarch --arch=$(arch) ${override}) } + +create_manifest_fork() { + if test ! -f src/config/bootupd-fork; then + echo "NOTICE: overriding src/config in ${COSA_DIR}" + sleep 2 + runv rm -rf src/config.bootupd-testing-old + runv mv src/config src/config.orig + runv git clone src/config.orig src/config + touch src/config/bootupd-fork + # This will fall over if the upstream manifest gains `packages:` + cat >> src/config/manifest.yaml << EOF +packages: + - test-bootupd-payload +EOF + echo "forked src/config" + else + fatal "already forked manifest" + fi +} + +undo_manifest_fork() { + test -d src/config.orig + assert_file_has_content src/config/manifest.yaml test-bootupd-payload + if test -f src/config/bootupd-fork; then + runv rm src/config -rf + else + # Keep this around just in case + runv mv src/config{,.bootupd-testing-old} + fi + runv mv src/config.orig src/config + test ! -f src/config/bootupd-fork + echo "undo src/config fork OK" +} + if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm @@ -38,11 +82,14 @@ if test -z "${e2e_skip_build:-}"; then (cd ${bootupd_git} && runv make && runv make install DESTDIR=${overrides}/rootfs) runv cosa build prev_image=$(runv cosa meta --image-path qemu) + create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" add_override grub2-2.04-23.fc32 + mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree + undo_manifest_fork fi echo "Preparing test" grubarch= @@ -56,7 +103,7 @@ target_grub_pkg=$(rpm -qp --queryformat='%{nevra}\n' ${overrides}/rpm/${target_g target_commit=$(cosa meta --get-value ostree-commit) echo "Target commit: ${target_commit}" # For some reason 9p can't write to tmpfs -testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) + cat >${testtmp}/test.fcct << EOF variant: fcos version: 1.0.0 @@ -86,7 +133,7 @@ qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${prev_ if test -n "${e2e_debug:-}"; then runv ${qemuexec_args[@]} --devshell else - runv timeout 5m "${qemuexec_args[@]}" -- -chardev file,id=log,path=console.txt -serial chardev:log + runv timeout 5m "${qemuexec_args[@]}" --console-to-file $(pwd)/console.txt fi if ! test -f ${testtmp}/success; then if test -s ${testtmp}/out.txt; then diff --git a/tests/kola/data/libtest.sh b/tests/kola/data/libtest.sh index f21a89496..91e61f35d 100644 --- a/tests/kola/data/libtest.sh +++ b/tests/kola/data/libtest.sh @@ -35,6 +35,14 @@ _fatal_print_file() { fatal "$@" } +assert_not_has_file () { + fpath=$1 + shift + if test -e "$fpath"; then + fatal "Path exists: ${fpath}" + fi +} + assert_file_has_content () { fpath=$1 shift From 644db684e19b1ae4a4b8eca547c1277433313514 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 2 Oct 2020 17:40:06 -0400 Subject: [PATCH 093/641] component: Add a lot of docstrings On general principle but also prep for adding a new method. --- src/component.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/component.rs b/src/component.rs index 0467cb2e7..b770da402 100644 --- a/src/component.rs +++ b/src/component.rs @@ -21,19 +21,37 @@ pub(crate) enum ValidationResult { /// A component along with a possible update pub(crate) trait Component { + /// Returns the name of the component; this will be used for serialization + /// and should remain stable. fn name(&self) -> &'static str; + /// Implementation of `bootupd install` for a given component. This should + /// gather data (or run binaries) from the source root, and install them + /// into the target root. It is expected that sub-partitions (e.g. the ESP) + /// are mounted at the expected place. For operations that require a block device instead + /// of a filesystem root, the component should query the mount point to + /// determine the block device. + /// This will be run during a disk image build process. fn install(&self, src_root: &str, dest_root: &str) -> Result; + /// Implementation of `bootupd generate-update-metadata` for a given component. + /// This expects to be run during an "image update build" process. For CoreOS + /// this is an `rpm-ostree compose tree` for example. For a dual-partition + /// style updater, this would be run as part of a postprocessing step + /// while the filesystem for the partition is mounted. fn generate_update_metadata(&self, sysroot: &str) -> Result; + /// Used on the client to query for an update cached in the current booted OS. fn query_update(&self) -> Result>; + /// Used on the client to run an update. fn run_update(&self, current: &InstalledContent) -> Result; + /// Used on the client to validate an installed version. fn validate(&self, current: &InstalledContent) -> Result; } +/// Given a component name, create an implementation. pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { "EFI" => Box::new(crate::efi::EFI::default()), @@ -42,12 +60,16 @@ pub(crate) fn new_from_name(name: &str) -> Result> { Ok(r) } +/// Returns the path to the JSON file containing a component's available update metadata installed +/// into the booted operating system root. pub(crate) fn component_update_metapath(sysroot: &str, component: &dyn Component) -> PathBuf { Path::new(sysroot) .join(BOOTUPD_UPDATES_DIR) .join(format!("{}.json", component.name())) } +/// Returns the path to the payload directory for an available update for +/// a component. pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { Path::new(sysroot) .join(BOOTUPD_UPDATES_DIR) @@ -67,6 +89,7 @@ pub(crate) fn write_update_metadata( Ok(()) } +/// Given a component, return metadata on the available update (if any) pub(crate) fn get_component_update( sysroot: &str, component: &dyn Component, From 065a496d52dc1a31c14a17bc34d99badccb96f3c Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 5 Oct 2020 14:10:56 +0000 Subject: [PATCH 094/641] cargo: drop library crate, for now This removes the current library/binary crate split, leaving only the application in place. The original idea was to add the logic as a vendored library into rpm-ostree for an emergency fix. However the urgency dropped and this now lives as a self-standing application. We may or may not consider re-adding it later on, but only for the interop parts (paths, JSON, etc). --- Cargo.toml | 4 ---- src/bootupd.rs | 54 +++++++++++--------------------------------- src/cli/bootupctl.rs | 10 ++++---- src/cli/bootupd.rs | 6 +++-- src/daemon/mod.rs | 18 ++++++++------- src/main.rs | 30 ++++++++++++++++++++++-- 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bad5206b8..6e1e75720 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,6 @@ version = "0.1.1" authors = ["Colin Walters "] edition = "2018" -[lib] -name = "bootupd" -path = "src/bootupd.rs" - [[bin]] name = "bootupd" path = "src/main.rs" diff --git a/src/bootupd.rs b/src/bootupd.rs index dbe728c99..744a65897 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,18 +1,7 @@ -/*! -**Boot**loader **upd**ater. - -This is an early prototype hidden/not-yet-standardized mechanism -which just updates EFI for now (x86_64/aarch64 only). - -But in the future will hopefully gain some independence from -ostree and also support e.g. updating the MBR etc. - -Refs: - * -!*/ - -#![deny(unused_must_use)] - +use crate::component::{Component, ValidationResult}; +use crate::efi; +use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; +use crate::{component, ipc}; use anyhow::{bail, Context, Result}; use fs2::FileExt; use openat_ext::OpenatDirExt; @@ -21,23 +10,6 @@ use std::borrow::Cow; use std::io::prelude::*; use std::path::Path; -// #[cfg(any(target_arch = "x86_64"))] -// mod bios; -mod cli; -pub use cli::MultiCall; -mod component; -mod daemon; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -mod efi; -mod filetree; -mod ipc; -use component::*; -mod model; -use model::*; -mod ostreeutil; -mod sha512string; -mod util; - /// Stored in /boot to describe our state; think of it like /// a tiny rpm/dpkg database. It's stored in /boot pub(crate) const STATEFILE_DIR: &str = "boot"; @@ -46,7 +18,7 @@ pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; /// A message sent from client to server #[derive(Debug, Serialize, Deserialize)] -enum ClientRequest { +pub(crate) enum ClientRequest { /// Update a component Update { component: String }, /// Validate a component @@ -125,7 +97,7 @@ fn acquire_write_lock>(sysroot: P) -> Result { /// Return value from daemon → client for component update #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] -enum ComponentUpdateResult { +pub(crate) enum ComponentUpdateResult { AtLatestVersion, Updated { previous: ContentMetadata, @@ -135,7 +107,7 @@ enum ComponentUpdateResult { } /// daemon implementation of component update -fn update(name: &str) -> Result { +pub(crate) fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; let _lock = acquire_write_lock("/")?; let mut state = get_saved_state("/")?.unwrap_or_else(|| SavedState { @@ -171,7 +143,7 @@ fn update(name: &str) -> Result { } /// daemon implementation of component validate -fn validate(name: &str) -> Result { +pub(crate) fn validate(name: &str) -> Result { let state = get_saved_state("/")?.unwrap_or_else(|| SavedState { ..Default::default() }); @@ -226,7 +198,7 @@ fn get_saved_state(sysroot_path: &str) -> Result> { Ok(saved_state) } -fn status() -> Result { +pub(crate) fn status() -> Result { let mut ret: Status = Default::default(); let state = if let Some(state) = get_saved_state("/")? { state @@ -234,7 +206,7 @@ fn status() -> Result { return Ok(ret); }; for (name, ic) in state.installed.iter() { - let component = component::new_from_name(&name)?; + let component = crate::component::new_from_name(&name)?; let component = component.as_ref(); let interrupted = state .pending @@ -256,7 +228,7 @@ fn status() -> Result { Ok(ret) } -fn print_status(status: &Status) { +pub(crate) fn print_status(status: &Status) { for (name, component) in status.components.iter() { println!("Component {}", name); println!(" Installed: {}", component.installed.version); @@ -304,7 +276,7 @@ fn validate_preview_env() -> Result<()> { } } -fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { +pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { validate_preview_env()?; let status: Status = c.send(&ClientRequest::Status)?; if status.components.is_empty() { @@ -350,7 +322,7 @@ fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { Ok(()) } -fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { +pub(crate) fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { let status: Status = c.send(&ClientRequest::Status)?; if status.components.is_empty() { println!("No components installed."); diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 33bed26b9..f55935b73 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -1,4 +1,6 @@ +use crate::bootupd; use crate::ipc::ClientToDaemonConnection; +use crate::model::Status; use anyhow::Result; use log::LevelFilter; use structopt::clap::AppSettings; @@ -80,13 +82,13 @@ impl CtlCommand { let mut client = ClientToDaemonConnection::new(); client.connect()?; - let r: crate::Status = client.send(&crate::ClientRequest::Status)?; + let r: Status = client.send(&bootupd::ClientRequest::Status)?; if opts.json { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); serde_json::to_writer_pretty(&mut stdout, &r)?; } else { - crate::print_status(&r); + bootupd::print_status(&r); } client.shutdown()?; @@ -98,7 +100,7 @@ impl CtlCommand { let mut client = ClientToDaemonConnection::new(); client.connect()?; - crate::client_run_update(&mut client)?; + bootupd::client_run_update(&mut client)?; client.shutdown()?; Ok(()) @@ -108,7 +110,7 @@ impl CtlCommand { fn run_validate() -> Result<()> { let mut client = ClientToDaemonConnection::new(); client.connect()?; - crate::client_run_validate(&mut client)?; + bootupd::client_run_validate(&mut client)?; client.shutdown()?; Ok(()) } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 4a3834d3f..efd58ddea 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -1,3 +1,4 @@ +use crate::bootupd; use anyhow::{Context, Result}; use log::LevelFilter; use structopt::StructOpt; @@ -65,13 +66,14 @@ impl DCommand { /// Runner for `generate-install-metadata` verb. pub(crate) fn run_generate_meta(opts: GenerateOpts) -> Result<()> { - crate::generate_update_metadata(&opts.sysroot).context("generating metadata failed")?; + bootupd::generate_update_metadata(&opts.sysroot).context("generating metadata failed")?; Ok(()) } /// Runner for `install` verb. pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { - crate::install(&opts.src_root, &opts.dest_root).context("boot data installation failed")?; + bootupd::install(&opts.src_root, &opts.dest_root) + .context("boot data installation failed")?; Ok(()) } } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 5a583b30c..c7f7479c5 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -1,6 +1,8 @@ //! Daemon logic. -use crate::ipc; +use crate::component::ValidationResult; +use crate::model::Status; +use crate::{bootupd, ipc}; use anyhow::{bail, Context, Result}; use nix::sys::socket as nixsocket; use std::os::unix::io::RawFd; @@ -82,7 +84,7 @@ fn accept_authenticate_client(srvsock_fd: RawFd) -> Result Result<()> { - use crate::ClientRequest; + use crate::bootupd::ClientRequest; let mut buf = [0u8; ipc::MSGSIZE]; loop { @@ -97,22 +99,22 @@ fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { let r = match msg { ClientRequest::Update { component } => { log::trace!("processing 'update' request"); - bincode::serialize(&match crate::update(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), + bincode::serialize(&match bootupd::update(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } ClientRequest::Validate { component } => { log::trace!("processing 'validate' request"); - bincode::serialize(&match crate::validate(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), + bincode::serialize(&match bootupd::validate(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } ClientRequest::Status => { log::trace!("processing 'status' request"); - bincode::serialize(&match crate::status() { - Ok(v) => ipc::DaemonToClientReply::Success::(v), + bincode::serialize(&match bootupd::status() { + Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } diff --git a/src/main.rs b/src/main.rs index 20236b1fd..762792de7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,30 @@ -//! Bootupd command-line application. +/*! +**Boot**loader **upd**ater. + +This is an early prototype hidden/not-yet-standardized mechanism +which just updates EFI for now (x86_64/aarch64 only). + +But in the future will hopefully gain some independence from +ostree and also support e.g. updating the MBR etc. + +Refs: + * +!*/ + +#![deny(unused_must_use)] + +mod bootupd; +mod cli; +mod component; +mod daemon; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +mod efi; +mod filetree; +mod ipc; +mod model; +mod ostreeutil; +mod sha512string; +mod util; use structopt::clap::crate_name; @@ -12,7 +38,7 @@ fn main() { fn run_cli() -> i32 { // Parse command-line options. let args: Vec<_> = std::env::args().collect(); - let cli_opts = bootupd::MultiCall::from_args(args); + let cli_opts = cli::MultiCall::from_args(args); // Setup logging. env_logger::Builder::from_default_env() From 3993ea051920f79348333e0ee9d80370772ef4da Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 5 Oct 2020 14:45:51 +0000 Subject: [PATCH 095/641] lockfile: refresh after cargo manifest changes --- Cargo.lock | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf9cdd279..50c44abd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,14 +128,16 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" -version = "0.4.15" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ + "libc", "num-integer", "num-traits", "serde", "time", + "winapi", ] [[package]] @@ -302,9 +304,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" [[package]] name = "libsystemd" @@ -459,9 +461,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.21" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] @@ -583,9 +585,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" dependencies = [ "itoa", "ryu", @@ -642,9 +644,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "syn" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" dependencies = [ "proc-macro2", "quote", From d37debe7a8ac6f4399ebb882e01654aa99621eeb Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 5 Oct 2020 11:34:39 -0400 Subject: [PATCH 096/641] OWNERS: Update to match current CoreOS updates & remoting team This list is that current team. --- OWNERS | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/OWNERS b/OWNERS index 97350e99a..3ada13fdb 100644 --- a/OWNERS +++ b/OWNERS @@ -1,17 +1,6 @@ -# This list is outdated, but it's copied from coreos-assembler -# Once we figure out a better way to maintain it please ensure -# that coreos-assembler is fixed first. +# This list is the CoreOS updates&remoting team approvers: - - arithx - - ashcrow - - bgilbert - cgwalters - - darkmuggle - - dustymabe - - jlebon - - LorbusChris + - kelvinfan001 - lucab - - miabbott - - mike-nguyen - - yuqi-zhddang - - zonggen + - travier From 7ae4edf1937ed962e7cbbc7a64d6677aa30d1dd2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 1 Oct 2020 15:31:23 -0400 Subject: [PATCH 097/641] filetree: Remove TODO and link to fcos umask PR Nothing to fix here. --- src/filetree.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 9792dfcdc..4ef2aad64 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -16,6 +16,12 @@ use std::path::Path; /// The prefix we apply to our temporary files. pub(crate) const TMP_PREFIX: &str = ".btmp."; +// This module doesn't handle modes right now, because +// we're only targeting FAT filesystems for UEFI. +// In FAT there are no unix permission bits, usually +// they're set by mount options. +// See also https://github.com/coreos/fedora-coreos-config/commit/8863c2b34095a2ae5eae6fbbd121768a5f592091 +const DEFAULT_FILE_MODE: u32 = 0o700; use crate::sha512string::SHA512String; @@ -294,8 +300,7 @@ pub(crate) fn apply_diff( for pathstr in diff.additions.iter().chain(diff.changes.iter()) { let path = Path::new(pathstr); if let Some(parent) = path.parent() { - // TODO: care about directory modes? We don't for FAT. - destdir.ensure_dir_all(parent, 0o755)?; + destdir.ensure_dir_all(parent, DEFAULT_FILE_MODE)?; } let destp = tmpname_for_path(path); copy_file_at(srcdir, destdir, path, destp.as_path()) From 8dea81707dda6ad37fde2110b2f33feee8cfe7cb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 2 Oct 2020 15:20:41 -0400 Subject: [PATCH 098/641] state: Consistently kebab-case and validate a previous saved format I noticed we were missing `kebab-case` on a few structs (but it doesn't matter since none of them have a name that would change). To ensure we don't regress on parsing old file formats, add a JSON file from a current system and test loading it. --- src/model.rs | 16 ++++++++++ tests/fixtures/example-state-v0.json | 47 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/fixtures/example-state-v0.json diff --git a/src/model.rs b/src/model.rs index 889429cd1..81dce5d4e 100644 --- a/src/model.rs +++ b/src/model.rs @@ -12,6 +12,7 @@ use std::collections::BTreeMap; pub(crate) const BOOTUPD_UPDATES_DIR: &str = "usr/lib/bootupd/updates"; #[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] pub(crate) struct ContentMetadata { /// The timestamp, which is used to determine update availability pub(crate) timestamp: DateTime, @@ -30,6 +31,7 @@ impl ContentMetadata { } #[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "kebab-case")] pub(crate) struct InstalledContent { /// Associated metadata pub(crate) meta: ContentMetadata, @@ -102,6 +104,7 @@ pub(crate) struct Status { #[cfg(test)] mod test { use super::*; + use anyhow::Result; use chrono::Duration; #[test] @@ -118,4 +121,17 @@ mod test { assert!(a.can_upgrade_to(&b)); assert!(!b.can_upgrade_to(&a)); } + + /// Validate we're not breaking the serialized format. + #[test] + fn test_deserialize() -> Result<()> { + let data = include_str!("../tests/fixtures/example-state-v0.json"); + let state: SavedState = serde_json::from_str(data)?; + let efi = state.installed.get("EFI").expect("EFI"); + assert_eq!( + efi.meta.version, + "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + ); + Ok(()) + } } diff --git a/tests/fixtures/example-state-v0.json b/tests/fixtures/example-state-v0.json new file mode 100644 index 000000000..467e4b058 --- /dev/null +++ b/tests/fixtures/example-state-v0.json @@ -0,0 +1,47 @@ +{ + "installed": { + "EFI": { + "meta": { + "timestamp": "2020-09-15T13:01:21Z", + "version": "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + }, + "filetree": { + "children": { + "BOOT/BOOTX64.EFI": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + }, + "BOOT/fbx64.efi": { + "size": 357248, + "sha512": "sha512:81fed5039bdd2bc53a203a1eaf56c6a6c9a95aa7ac88f037718a342205d83550f409741c8ef86b481f55ea7188ce0d661742548596f92ef97ba2a1695bc4caae" + }, + "fedora/BOOTX64.CSV": { + "size": 110, + "sha512": "sha512:0c29b8ae73171ef683ba690069c1bae711e130a084a81169af33a83dfbae4e07d909c2482dbe89a96ab26e171f17c53f1de8cb13d558bc1535412ff8accf253f" + }, + "fedora/grubx64.efi": { + "size": 2528520, + "sha512": "sha512:b35a6317658d07844d6bf0f96c35f2df90342b8b13a329b4429ac892351ff74fc794a97bc3d3e2d79bef4c234b49a8dd5147b71a3376f24bc956130994e9961c" + }, + "fedora/mmx64.efi": { + "size": 1159560, + "sha512": "sha512:f83ea67756cfcc3ec4eb1c83104c719ba08e66abfadb94b4bd75891e237c448bbec0fdb5bd42826e291ccc3dee559af424900b3d642a7d11c5bc9f117718837a" + }, + "fedora/shim.efi": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + }, + "fedora/shimx64-fedora.efi": { + "size": 1204496, + "sha512": "sha512:dc3656b90c0d1767365bea462cc94a2a3044899f510bd61a9a7ae1a9ca586e3d6189592b1ba1ee859f45614421297fa2f5353328caa615f51da5aed9ecfbf29c" + }, + "fedora/shimx64.efi": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + } + } + } + } + }, + "pending": null +} From 536aca6b15eb575b303acbe76472ab47e01520c6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 2 Oct 2020 14:17:14 -0400 Subject: [PATCH 099/641] Parse and print CoreOS aleph version This is prep for work on "adoption": https://github.com/coreos/bootupd/issues/38 In order to (as safely as possible) take over management of a system *not installed via bootupd* we want to gather as much information as we can. For example, we can use the imgid as the "version" of the current bootloader data. --- src/bootupd.rs | 18 ++++++++++++- src/coreos.rs | 59 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/model.rs | 8 ++++++ tests/kola/test-bootupd | 1 + 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/coreos.rs diff --git a/src/bootupd.rs b/src/bootupd.rs index 744a65897..cf76bd2ad 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,6 +1,9 @@ use crate::component::{Component, ValidationResult}; +use crate::coreos; use crate::efi; -use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; +use crate::model::{ + ComponentStatus, ComponentUpdatable, ContentMetadata, OperatingSystem, SavedState, Status, +}; use crate::{component, ipc}; use anyhow::{bail, Context, Result}; use fs2::FileExt; @@ -225,6 +228,11 @@ pub(crate) fn status() -> Result { }, ); } + if let Some(coreos_aleph) = coreos::get_aleph_version()? { + ret.os = Some(OperatingSystem::CoreOS { + aleph_imgid: coreos_aleph.imgid, + }) + } Ok(ret) } @@ -251,6 +259,14 @@ pub(crate) fn print_status(status: &Status) { println!(" Update: {}", msg); } + if let Some(ref os) = status.os { + match os { + OperatingSystem::CoreOS { aleph_imgid } => { + println!(" CoreOS aleph image ID: {}", aleph_imgid); + } + } + } + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] { let boot_method = if Path::new("/sys/firmware/efi").exists() { diff --git a/src/coreos.rs b/src/coreos.rs new file mode 100644 index 000000000..8ee905071 --- /dev/null +++ b/src/coreos.rs @@ -0,0 +1,59 @@ +//! Bits specific to Fedora CoreOS (and derivatives). + +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +use anyhow::Result; +use openat_ext::OpenatDirExt; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +/// See https://github.com/coreos/fedora-coreos-tracker/blob/66d7d00bedd9d5eabc7287b9577f443dcefb7c04/internals/README-internals.md#aleph-version +pub(crate) struct Aleph { + pub(crate) build: String, + #[serde(rename = "ref")] + pub(crate) ostree_ref: String, + pub(crate) ostree_commit: String, + pub(crate) imgid: String, +} + +/// Path to the file, see above +const ALEPH_PATH: &str = "/sysroot/.coreos-aleph-version.json"; + +pub(crate) fn get_aleph_version() -> Result> { + let sysroot = openat::Dir::open("/")?; + if let Some(statusf) = sysroot.open_file_optional(ALEPH_PATH)? { + let bufr = std::io::BufReader::new(statusf); + let aleph: Aleph = serde_json::from_reader(bufr)?; + Ok(Some(aleph)) + } else { + Ok(None) + } +} + +#[cfg(test)] +mod test { + use super::*; + use anyhow::Result; + + #[test] + fn test_parse_aleph() -> Result<()> { + let alephdata = r##" +{ + "build": "32.20201002.dev.2", + "ref": "fedora/x86_64/coreos/testing-devel", + "ostree-commit": "b2ea6159d6274e1bbbb49aa0ef093eda5d53a75c8a793dbe184f760ed64dc862", + "imgid": "fedora-coreos-32.20201002.dev.2-qemu.x86_64.qcow2" +}"##; + let aleph: Aleph = serde_json::from_str(alephdata)?; + assert_eq!( + aleph.imgid, + "fedora-coreos-32.20201002.dev.2-qemu.x86_64.qcow2" + ); + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 762792de7..ed93b0373 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ Refs: mod bootupd; mod cli; mod component; +mod coreos; mod daemon; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; diff --git a/src/model.rs b/src/model.rs index 81dce5d4e..b1cdda96a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -90,6 +90,12 @@ pub(crate) struct ComponentStatus { pub(crate) updatable: ComponentUpdatable, } +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) enum OperatingSystem { + CoreOS { aleph_imgid: String }, +} + /// Representation of bootupd's worldview at a point in time. /// This is intended to be a stable format that is output by `bootupctl status --json` /// and parsed by higher level management tools. Transitively then @@ -99,6 +105,8 @@ pub(crate) struct ComponentStatus { pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, + /// The detected operating system + pub(crate) os: Option, } #[cfg(test)] diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ce7b4df2a..b099ebcc3 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -46,6 +46,7 @@ bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' +assert_file_has_content out.txt 'CoreOS aleph image ID: .*-qemu.'$(arch)'.qcow2' ok status # Validate we auto-exited From ad52f02935b7c12cd6f4a91d0134a845db1b652b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 6 Oct 2020 09:22:56 -0400 Subject: [PATCH 100/641] main: Add more error context I was debugging a failure to write the statefile which turned out to be me having https://github.com/coreos/fedora-coreos-config/pull/659 locally. Anyways let's add some error context to aid future debugging. --- src/bootupd.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index cf76bd2ad..8f72f008d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -53,7 +53,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { } let sysroot = openat::Dir::open(dest_root)?; - update_state(&sysroot, &state)?; + update_state(&sysroot, &state).context("Failed to update state")?; Ok(()) } @@ -112,7 +112,7 @@ pub(crate) enum ComponentUpdateResult { /// daemon implementation of component update pub(crate) fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; - let _lock = acquire_write_lock("/")?; + let _lock = acquire_write_lock("/").context("Failed to acquire write lock")?; let mut state = get_saved_state("/")?.unwrap_or_else(|| SavedState { ..Default::default() }); @@ -131,7 +131,7 @@ pub(crate) fn update(name: &str) -> Result { let interrupted = pending_container.get(component.name()).cloned(); pending_container.insert(component.name().into(), update.clone()); - update_state(&sysroot, &state)?; + update_state(&sysroot, &state).context("Failed to update state")?; let newinst = component .run_update(&inst) .with_context(|| format!("Failed to update {}", component.name()))?; @@ -163,7 +163,9 @@ pub(crate) fn validate(name: &str) -> Result { fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { let subdir = sysroot_dir.sub_dir(STATEFILE_DIR)?; let f = { - let f = subdir.new_unnamed_file(0o644)?; + let f = subdir + .new_unnamed_file(0o644) + .context("creating temp file")?; let mut buff = std::io::BufWriter::new(f); serde_json::to_writer(&mut buff, state)?; buff.flush()?; @@ -177,11 +179,17 @@ fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { }; let dest_tmp_name = Path::new(&dest_tmp_name); if subdir.exists(dest_tmp_name)? { - subdir.remove_file(dest_tmp_name)?; + subdir + .remove_file(dest_tmp_name) + .context("Removing temp file")?; } - subdir.link_file_at(&f, dest_tmp_name)?; - f.sync_all()?; - subdir.local_rename(dest_tmp_name, STATEFILE_NAME)?; + subdir + .link_file_at(&f, dest_tmp_name) + .context("Linking temp file")?; + f.sync_all().context("syncing")?; + subdir + .local_rename(dest_tmp_name, STATEFILE_NAME) + .context("Renaming temp file")?; Ok(()) } From b232b93ea052fd40420423b2150865f7cfa82e72 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 6 Oct 2020 09:20:22 -0400 Subject: [PATCH 101/641] Use a lot more systemd hardening features Just on general principle. In particular the combination of a readonly `/usr` and `WorkingDirectory=/usr` will give us a consistent clean error if we somehow accidentally write to the current working directory. --- systemd/bootupd.service | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 7a7bcdc99..5a4d08aed 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -11,7 +11,17 @@ StartLimitBurst=10 Type=notify Environment=BOOTUPD_VERBOSITY="-v" ExecStart=/usr/libexec/bootupd daemon $BOOTUPD_VERBOSITY -# On general principle +# This way our working directory isn't writable by default. +WorkingDirectory=/usr +# Various hardening flags just on general principle. We need +# to run as root, but let's avoid accidental damage. ProtectHome=yes +ReadOnlyPaths=/usr +PrivateTmp=yes +PrivateNetwork=yes +ProtectClock=yes +ProtectHostname=yes +ProtectControlGroups=yes +RestrictSUIDSGID=yes # So we can remount /boot writable MountFlags=slave From 97753fd84dd34aa7b728b6e5d42d364c13a983f1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 6 Oct 2020 13:19:17 -0400 Subject: [PATCH 102/641] =?UTF-8?q?Rename=20tests/e2e=20=E2=86=92=20tests/?= =?UTF-8?q?e2e-update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I plan to add another test `e2e-adopt` for the case of going from a known disk image not using bootupd initially. --- .cci.jenkinsfile | 4 ++-- tests/{e2e/e2e-in-vm.sh => e2e-update/e2e-update-in-vm.sh} | 0 tests/{e2e/e2e.sh => e2e-update/e2e-update.sh} | 3 ++- tests/{e2e => e2e-update}/testrpmbuild.sh | 0 4 files changed, 4 insertions(+), 3 deletions(-) rename tests/{e2e/e2e-in-vm.sh => e2e-update/e2e-update-in-vm.sh} (100%) rename tests/{e2e/e2e.sh => e2e-update/e2e-update.sh} (95%) rename tests/{e2e => e2e-update}/testrpmbuild.sh (100%) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 49a9689de..4bfc694ed 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -51,9 +51,9 @@ stage("FCOS") { coreos-assembler fetch """) } - // The e2e test does a build, so we just end at fetch above + // The e2e-update test does a build, so we just end at fetch above stage("e2e upgrade test") { - shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e/e2e.sh") + shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") } stage("Kola testing") { // The previous e2e leaves things only having built an ostree update diff --git a/tests/e2e/e2e-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh similarity index 100% rename from tests/e2e/e2e-in-vm.sh rename to tests/e2e-update/e2e-update-in-vm.sh diff --git a/tests/e2e/e2e.sh b/tests/e2e-update/e2e-update.sh similarity index 95% rename from tests/e2e/e2e.sh rename to tests/e2e-update/e2e-update.sh index 921f3a53f..e72acad0a 100755 --- a/tests/e2e/e2e.sh +++ b/tests/e2e-update/e2e-update.sh @@ -7,6 +7,7 @@ set -euo pipefail dn=$(cd $(dirname $0) && pwd) +testprefix=$(cd ${dn} && git rev-parse --show-prefix) . ${dn}/../kola/data/libtest.sh . ${dn}/testrpmbuild.sh @@ -122,7 +123,7 @@ systemd: Environment=TARGET_GRUB_PKG=${target_grub_pkg} Environment=SRCDIR=/run/bootupd-source # Run via shell because selinux denies systemd writing to 9p apparently - ExecStart=/bin/sh -c '/run/bootupd-source/tests/e2e/e2e-in-vm.sh &>>/run/testtmp/out.txt; test -f /run/rebooting || poweroff -ff' + ExecStart=/bin/sh -c '/run/bootupd-source/${testprefix}/e2e-update-in-vm.sh &>>/run/testtmp/out.txt; test -f /run/rebooting || poweroff -ff' [Install] WantedBy=multi-user.target EOF diff --git a/tests/e2e/testrpmbuild.sh b/tests/e2e-update/testrpmbuild.sh similarity index 100% rename from tests/e2e/testrpmbuild.sh rename to tests/e2e-update/testrpmbuild.sh From 20d4aaa6ff751a9a4a150696205496ad4222c8f6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 6 Oct 2020 16:19:56 -0400 Subject: [PATCH 103/641] status: Fix indentation of CoreOS aleph image ID If it's indented it looks like it's part of the EFI component. --- src/bootupd.rs | 2 +- tests/kola/test-bootupd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 8f72f008d..fb1919595 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -270,7 +270,7 @@ pub(crate) fn print_status(status: &Status) { if let Some(ref os) = status.os { match os { OperatingSystem::CoreOS { aleph_imgid } => { - println!(" CoreOS aleph image ID: {}", aleph_imgid); + println!("CoreOS aleph image ID: {}", aleph_imgid); } } } diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index b099ebcc3..8e6a6691b 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -46,7 +46,7 @@ bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' -assert_file_has_content out.txt 'CoreOS aleph image ID: .*-qemu.'$(arch)'.qcow2' +assert_file_has_content out.txt '^CoreOS aleph image ID: .*-qemu.'$(arch)'.qcow2' ok status # Validate we auto-exited From 46f1be0e0edf36db14e958d6ac6bb664667a88cf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 6 Oct 2020 15:14:05 -0400 Subject: [PATCH 104/641] status: Print message if nothing is installed No tests yet, this will be covered in future "adoption" work. --- src/bootupd.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index fb1919595..6534ad1ad 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -245,6 +245,9 @@ pub(crate) fn status() -> Result { } pub(crate) fn print_status(status: &Status) { + if status.components.is_empty() { + println!("No components installed."); + } for (name, component) in status.components.iter() { println!("Component {}", name); println!(" Installed: {}", component.installed.version); From ff70480ab36836715e18d943cbbd71926bad6085 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 09:21:30 -0400 Subject: [PATCH 105/641] daemon: Log all requests at debug level The requests aren't large, let's log the whole thing consistently rather than having a copy/paste version for each request. This way we include the component too. --- src/daemon/mod.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index c7f7479c5..1f22fb3ed 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -96,28 +96,24 @@ fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { } let msg = bincode::deserialize(&buf)?; + log::trace!("processing request: {:?}", &msg); let r = match msg { ClientRequest::Update { component } => { - log::trace!("processing 'update' request"); bincode::serialize(&match bootupd::update(component.as_str()) { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } ClientRequest::Validate { component } => { - log::trace!("processing 'validate' request"); bincode::serialize(&match bootupd::validate(component.as_str()) { Ok(v) => ipc::DaemonToClientReply::Success::(v), Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } - ClientRequest::Status => { - log::trace!("processing 'status' request"); - bincode::serialize(&match bootupd::status() { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } + ClientRequest::Status => bincode::serialize(&match bootupd::status() { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })?, }; let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; if written != r.len() { From 1d7d55d3f30634db58e7ea4f6438b0b8522145b3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 15:40:00 -0400 Subject: [PATCH 106/641] main: Gather status even if no components are installed Prep for adoption work. Previously we just bailed out if nothing was installed, but we want to return a status even if there are no components installed. Rework the component list to be a map so we can conveniently look up things by name. --- src/bootupd.rs | 71 +++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 6534ad1ad..8d7fa23df 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -5,11 +5,12 @@ use crate::model::{ ComponentStatus, ComponentUpdatable, ContentMetadata, OperatingSystem, SavedState, Status, }; use crate::{component, ipc}; -use anyhow::{bail, Context, Result}; +use anyhow::{anyhow, bail, Context, Result}; use fs2::FileExt; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; use std::borrow::Cow; +use std::collections::BTreeMap; use std::io::prelude::*; use std::path::Path; @@ -47,7 +48,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { installed: Default::default(), pending: Default::default(), }; - for component in components { + for component in components.values() { let meta = component.install(source_root, dest_root)?; state.installed.insert(component.name().into(), meta); } @@ -58,11 +59,17 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { Ok(()) } -pub(crate) fn get_components() -> Vec> { - let mut components: Vec> = Vec::new(); +type Components = BTreeMap<&'static str, Box>; + +pub(crate) fn get_components() -> Components { + let mut components = BTreeMap::new(); + + fn insert_component(components: &mut Components, component: Box) { + components.insert(component.name(), component); + } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] - components.push(Box::new(efi::EFI::default())); + insert_component(&mut components, Box::new(efi::EFI::default())); // #[cfg(target_arch = "x86_64")] // components.push(Box::new(bios::BIOS::new())); @@ -71,7 +78,7 @@ pub(crate) fn get_components() -> Vec> { } pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { - for component in get_components() { + for component in get_components().values() { let v = component.generate_update_metadata(sysroot_path)?; println!( "Generated update layout for {}: {}", @@ -211,31 +218,37 @@ fn get_saved_state(sysroot_path: &str) -> Result> { pub(crate) fn status() -> Result { let mut ret: Status = Default::default(); - let state = if let Some(state) = get_saved_state("/")? { - state + let mut known_components = get_components(); + let state = get_saved_state("/")?; + if let Some(state) = state { + for (name, ic) in state.installed.iter() { + log::trace!("Gathering status for installed component: {}", name); + let component = known_components + .remove(name.as_str()) + .ok_or_else(|| anyhow!("Unknown component installed: {}", name))?; + let component = component.as_ref(); + let interrupted = state + .pending + .as_ref() + .map(|p| p.get(name.as_str())) + .flatten(); + let update = component.query_update()?; + let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); + ret.components.insert( + name.to_string(), + ComponentStatus { + installed: ic.meta.clone(), + interrupted: interrupted.cloned(), + update, + updatable, + }, + ); + } } else { - return Ok(ret); - }; - for (name, ic) in state.installed.iter() { - let component = crate::component::new_from_name(&name)?; - let component = component.as_ref(); - let interrupted = state - .pending - .as_ref() - .map(|p| p.get(name.as_str())) - .flatten(); - let update = component.query_update()?; - let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); - ret.components.insert( - name.to_string(), - ComponentStatus { - installed: ic.meta.clone(), - interrupted: interrupted.cloned(), - update, - updatable, - }, - ); + log::trace!("No saved state"); } + log::trace!("Remaining known components: {}", known_components.len()); + if let Some(coreos_aleph) = coreos::get_aleph_version()? { ret.os = Some(OperatingSystem::CoreOS { aleph_imgid: coreos_aleph.imgid, From 02d5c554c4c500657ef649f16518b2173b33504d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 09:14:41 -0400 Subject: [PATCH 107/641] ci: Remove unnecessary outer stage{} Jenkins doesn't seem to render nested stages, so drop the outer one. This makes CI look nicer and more useful as we add more testing runs. --- .cci.jenkinsfile | 57 +++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 4bfc694ed..6f35a808b 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -32,35 +32,32 @@ codestyle: { // Build FCOS and do a kola basic run // FIXME update to main branch once https://github.com/coreos/fedora-coreos-config/pull/595 merges -stage("FCOS") { - cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { - stage("Build FCOS") { - checkout scm - unstash 'build' - // Note that like {rpm-,}ostree we want to install to both / and overrides/rootfs - // because bootupd is used both during the `rpm-ostree compose tree` as well as - // inside the target operating system. - shwrap(""" - mkdir insttree - tar -C insttree -xzvf insttree.tar.gz - rsync -rlv insttree/ / - coreos-assembler init --force https://github.com/coreos/fedora-coreos-config - mkdir -p overrides/rootfs - mv insttree/* overrides/rootfs/ - rmdir insttree - coreos-assembler fetch - """) - } - // The e2e-update test does a build, so we just end at fetch above - stage("e2e upgrade test") { - shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") - } - stage("Kola testing") { - // The previous e2e leaves things only having built an ostree update - shwrap("cosa build") - // bootupd really can't break upgrades for the OS - fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) - } +cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { + stage("Build FCOS") { + checkout scm + unstash 'build' + // Note that like {rpm-,}ostree we want to install to both / and overrides/rootfs + // because bootupd is used both during the `rpm-ostree compose tree` as well as + // inside the target operating system. + shwrap(""" + mkdir insttree + tar -C insttree -xzvf insttree.tar.gz + rsync -rlv insttree/ / + coreos-assembler init --force https://github.com/coreos/fedora-coreos-config + mkdir -p overrides/rootfs + mv insttree/* overrides/rootfs/ + rmdir insttree + coreos-assembler fetch + """) + } + // The e2e-update test does a build, so we just end at fetch above + stage("e2e upgrade test") { + shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") + } + stage("Kola testing") { + // The previous e2e leaves things only having built an ostree update + shwrap("cosa build") + // bootupd really can't break upgrades for the OS + fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) } } - From 9811210c47f4420904e1e0f425dd0c5e24b0a8d3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 09:28:38 -0400 Subject: [PATCH 108/641] coreos: Add timestamp to aleph version Prep for adoption; we use the aleph as a `ContentMetadata` which wants both a timestamp and a version string. --- src/bootupd.rs | 2 +- src/coreos.rs | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 8d7fa23df..ebb27f636 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -251,7 +251,7 @@ pub(crate) fn status() -> Result { if let Some(coreos_aleph) = coreos::get_aleph_version()? { ret.os = Some(OperatingSystem::CoreOS { - aleph_imgid: coreos_aleph.imgid, + aleph_imgid: coreos_aleph.aleph.imgid, }) } Ok(ret) diff --git a/src/coreos.rs b/src/coreos.rs index 8ee905071..e8b91cdc9 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -7,6 +7,7 @@ */ use anyhow::Result; +use chrono::prelude::*; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; @@ -21,15 +22,25 @@ pub(crate) struct Aleph { pub(crate) imgid: String, } +pub(crate) struct AlephWithTimestamp { + pub(crate) aleph: Aleph, + #[allow(dead_code)] + pub(crate) ts: chrono::DateTime, +} + /// Path to the file, see above const ALEPH_PATH: &str = "/sysroot/.coreos-aleph-version.json"; -pub(crate) fn get_aleph_version() -> Result> { +pub(crate) fn get_aleph_version() -> Result> { let sysroot = openat::Dir::open("/")?; if let Some(statusf) = sysroot.open_file_optional(ALEPH_PATH)? { + let meta = statusf.metadata()?; let bufr = std::io::BufReader::new(statusf); let aleph: Aleph = serde_json::from_reader(bufr)?; - Ok(Some(aleph)) + Ok(Some(AlephWithTimestamp { + aleph, + ts: meta.created()?.into(), + })) } else { Ok(None) } From 4a07ead918f8bea3dad049bd9428d1c3e6e6662b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 17:03:51 -0400 Subject: [PATCH 109/641] model: Deny unknown fields, add test for status json There's no reason for us to ever parse unknown fields in status JSON, so let's deny it. Related, we do want tooling to parse `bootupctl status --json`, so let's add a test to validate we're not unexpectedly breaking it. --- src/model.rs | 18 ++++++++++++++++-- tests/fixtures/example-status-v0.json | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/example-status-v0.json diff --git a/src/model.rs b/src/model.rs index b1cdda96a..e22b97532 100644 --- a/src/model.rs +++ b/src/model.rs @@ -102,6 +102,7 @@ pub(crate) enum OperatingSystem { /// everything referenced from here should also be stable. #[derive(Serialize, Deserialize, Default, Debug)] #[serde(rename_all = "kebab-case")] +#[serde(deny_unknown_fields)] pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, @@ -130,9 +131,9 @@ mod test { assert!(!b.can_upgrade_to(&a)); } - /// Validate we're not breaking the serialized format. + /// Validate we're not breaking the serialized format of /boot/bootupd-state.json #[test] - fn test_deserialize() -> Result<()> { + fn test_deserialize_state() -> Result<()> { let data = include_str!("../tests/fixtures/example-state-v0.json"); let state: SavedState = serde_json::from_str(data)?; let efi = state.installed.get("EFI").expect("EFI"); @@ -142,4 +143,17 @@ mod test { ); Ok(()) } + + /// Validate we're not breaking the serialized format of `bootupctl status --json` + #[test] + fn test_deserialize_status() -> Result<()> { + let data = include_str!("../tests/fixtures/example-status-v0.json"); + let status: Status = serde_json::from_str(data)?; + let efi = status.components.get("EFI").expect("EFI"); + assert_eq!( + efi.installed.version, + "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + ); + Ok(()) + } } diff --git a/tests/fixtures/example-status-v0.json b/tests/fixtures/example-status-v0.json new file mode 100644 index 000000000..8d7e93337 --- /dev/null +++ b/tests/fixtures/example-status-v0.json @@ -0,0 +1,22 @@ +{ + "components": { + "EFI": { + "installed": { + "timestamp": "2020-09-15T13:01:21Z", + "version": "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + }, + "interrupted": null, + "update": { + "timestamp": "2020-09-15T13:01:21Z", + "version": "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + }, + "updatable": "at-latest-version", + "adopted-from": null + } + }, + "os": { + "core-o-s": { + "aleph_imgid": "fedora-coreos-32.20201007.dev.0-qemu.x86_64.qcow2" + } + } +} From 549316b271deb34cfad514b89d2fe90007b0c3c7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 8 Oct 2020 19:28:35 +0000 Subject: [PATCH 110/641] model: Deny unknown saved state fields This is a big hammer and eventually what we'll really need to do is introduce versioning or compatibility flags. That said, for now it's better to ensure we're not reading anything unexpected. And in a scenario where bootupd is downgraded, it's not a really big deal because it just means you can't update the bootloader - which you probably don't want to do if you're downgrading the operating system anyways. --- src/model.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/model.rs b/src/model.rs index e22b97532..e005213ee 100644 --- a/src/model.rs +++ b/src/model.rs @@ -42,6 +42,7 @@ pub(crate) struct InstalledContent { /// Will be serialized into /boot/bootupd-state.json #[derive(Serialize, Deserialize, Default, Debug)] #[serde(rename_all = "kebab-case")] +#[serde(deny_unknown_fields)] pub(crate) struct SavedState { /// Maps a component name to its currently installed version pub(crate) installed: BTreeMap, From 9fb441876426016565b67513a85a56fd8f22bb6a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Oct 2020 17:05:49 -0400 Subject: [PATCH 111/641] Drop operating system from status, print client side For now let's address concerns over how we represent the operating system by dropping them from the status JSON. Instead detect CoreOS specifically client side too and print the aleph there. --- src/bootupd.rs | 22 +++++++--------------- src/cli/bootupctl.rs | 2 +- src/model.rs | 8 -------- tests/fixtures/example-status-v0.json | 5 ----- 4 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index ebb27f636..9fdecb155 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,9 +1,7 @@ use crate::component::{Component, ValidationResult}; use crate::coreos; use crate::efi; -use crate::model::{ - ComponentStatus, ComponentUpdatable, ContentMetadata, OperatingSystem, SavedState, Status, -}; +use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; use crate::{component, ipc}; use anyhow::{anyhow, bail, Context, Result}; use fs2::FileExt; @@ -247,17 +245,13 @@ pub(crate) fn status() -> Result { } else { log::trace!("No saved state"); } + log::trace!("Remaining known components: {}", known_components.len()); - if let Some(coreos_aleph) = coreos::get_aleph_version()? { - ret.os = Some(OperatingSystem::CoreOS { - aleph_imgid: coreos_aleph.aleph.imgid, - }) - } Ok(ret) } -pub(crate) fn print_status(status: &Status) { +pub(crate) fn print_status(status: &Status) -> Result<()> { if status.components.is_empty() { println!("No components installed."); } @@ -283,12 +277,8 @@ pub(crate) fn print_status(status: &Status) { println!(" Update: {}", msg); } - if let Some(ref os) = status.os { - match os { - OperatingSystem::CoreOS { aleph_imgid } => { - println!("CoreOS aleph image ID: {}", aleph_imgid); - } - } + if let Some(coreos_aleph) = coreos::get_aleph_version()? { + println!("CoreOS aleph image ID: {}", coreos_aleph.aleph.imgid); } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] @@ -300,6 +290,8 @@ pub(crate) fn print_status(status: &Status) { }; println!("Boot method: {}", boot_method); } + + Ok(()) } /// Checks that the user has provided an environment variable to signal diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index f55935b73..3fb368600 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -88,7 +88,7 @@ impl CtlCommand { let mut stdout = stdout.lock(); serde_json::to_writer_pretty(&mut stdout, &r)?; } else { - bootupd::print_status(&r); + bootupd::print_status(&r)?; } client.shutdown()?; diff --git a/src/model.rs b/src/model.rs index e005213ee..34910c3ed 100644 --- a/src/model.rs +++ b/src/model.rs @@ -91,12 +91,6 @@ pub(crate) struct ComponentStatus { pub(crate) updatable: ComponentUpdatable, } -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "kebab-case")] -pub(crate) enum OperatingSystem { - CoreOS { aleph_imgid: String }, -} - /// Representation of bootupd's worldview at a point in time. /// This is intended to be a stable format that is output by `bootupctl status --json` /// and parsed by higher level management tools. Transitively then @@ -107,8 +101,6 @@ pub(crate) enum OperatingSystem { pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, - /// The detected operating system - pub(crate) os: Option, } #[cfg(test)] diff --git a/tests/fixtures/example-status-v0.json b/tests/fixtures/example-status-v0.json index 8d7e93337..6c657db88 100644 --- a/tests/fixtures/example-status-v0.json +++ b/tests/fixtures/example-status-v0.json @@ -13,10 +13,5 @@ "updatable": "at-latest-version", "adopted-from": null } - }, - "os": { - "core-o-s": { - "aleph_imgid": "fedora-coreos-32.20201007.dev.0-qemu.x86_64.qcow2" - } } } From c38feb3d5f8735480918d32bd0e872d0c7f12e0e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Oct 2020 09:49:57 -0400 Subject: [PATCH 112/641] Fix clippy lints Nothing really important, may try to add clippy to CI at some point. --- src/cli/mod.rs | 1 + src/efi.rs | 2 +- src/filetree.rs | 2 +- src/model.rs | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5ea94e76b..04a3fe9b5 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -25,6 +25,7 @@ impl MultiCall { let exe_path = std::path::PathBuf::from(arg0); exe_path.file_name().unwrap_or_default().to_os_string() }; + #[allow(clippy::wildcard_in_or_patterns)] match exe_name.as_bytes() { b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::from_iter(args)), b"bootupd" | _ => MultiCall::D(bootupd::DCommand::from_iter(args)), diff --git a/src/efi.rs b/src/efi.rs index 004d6b78e..c16864606 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -155,7 +155,7 @@ impl Component for EFI { let meta = ContentMetadata { timestamp: **largest_timestamp, - version: version, + version, }; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) diff --git a/src/filetree.rs b/src/filetree.rs index 4ef2aad64..a1d84d835 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -179,7 +179,7 @@ impl FileTree { let mut changes = HashSet::new(); for (path, info) in self.children.iter() { - assert!(!path.starts_with("/")); + assert!(!path.starts_with('/')); if let Some(meta) = dir.metadata_optional(path)? { match meta.simple_type() { diff --git a/src/model.rs b/src/model.rs index 34910c3ed..d3ff4b5f0 100644 --- a/src/model.rs +++ b/src/model.rs @@ -26,7 +26,7 @@ impl ContentMetadata { if self.version == target.version { return false; } - return target.timestamp > self.timestamp; + target.timestamp > self.timestamp } } From e3c36fb4cb9968d09ef73872dbf366d486fb9fbf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Oct 2020 10:25:42 -0400 Subject: [PATCH 113/641] main: Use unwrap_or_default() Noticed in code review in another case. --- src/bootupd.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 9fdecb155..559baa9f1 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -118,9 +118,7 @@ pub(crate) enum ComponentUpdateResult { pub(crate) fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; let _lock = acquire_write_lock("/").context("Failed to acquire write lock")?; - let mut state = get_saved_state("/")?.unwrap_or_else(|| SavedState { - ..Default::default() - }); + let mut state = get_saved_state("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; let inst = if let Some(inst) = state.installed.get(name) { inst.clone() @@ -152,9 +150,7 @@ pub(crate) fn update(name: &str) -> Result { /// daemon implementation of component validate pub(crate) fn validate(name: &str) -> Result { - let state = get_saved_state("/")?.unwrap_or_else(|| SavedState { - ..Default::default() - }); + let state = get_saved_state("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; let inst = if let Some(inst) = state.installed.get(name) { inst.clone() From 6d9d2e36a4e7aae518f8264bce682f8012d90c38 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 2 Oct 2020 17:32:18 -0400 Subject: [PATCH 114/641] Implementation of adoption So far we've supported updating systems that we installed, but we also need to handle updating at least older CoreOS systems. This shares a lot of similarity with `update`; the biggest difference is that we aren't sure which files we should be managing. So given a pending update, we only replace files that exist in that update. Closes: https://github.com/coreos/bootupd/issues/38 --- .cci.jenkinsfile | 10 +- src/bootupd.rs | 57 +++++++++++ src/cli/bootupctl.rs | 14 +++ src/component.rs | 8 ++ src/coreos.rs | 1 - src/daemon/mod.rs | 6 ++ src/efi.rs | 69 ++++++++++++- src/filetree.rs | 13 +++ src/model.rs | 6 ++ tests/e2e-adopt/e2e-adopt-in-vm.sh | 133 ++++++++++++++++++++++++++ tests/e2e-adopt/e2e-adopt.sh | 92 ++++++++++++++++++ tests/fixtures/example-status-v0.json | 3 +- 12 files changed, 407 insertions(+), 5 deletions(-) create mode 100755 tests/e2e-adopt/e2e-adopt-in-vm.sh create mode 100755 tests/e2e-adopt/e2e-adopt.sh diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 6f35a808b..19596ff7a 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -47,10 +47,16 @@ cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { mkdir -p overrides/rootfs mv insttree/* overrides/rootfs/ rmdir insttree - coreos-assembler fetch + cosa fetch + cosa build """) } - // The e2e-update test does a build, so we just end at fetch above + // The e2e-adopt test will use the ostree commit we just generated above + // but a static qemu base image. + stage("e2e adopt test") { + shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-adopt/e2e-adopt.sh") + } + // Now a test that upgrades using bootupd stage("e2e upgrade test") { shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") } diff --git a/src/bootupd.rs b/src/bootupd.rs index 559baa9f1..587ce5363 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -23,6 +23,8 @@ pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; pub(crate) enum ClientRequest { /// Update a component Update { component: String }, + /// Update a component via adoption + AdoptAndUpdate { component: String }, /// Validate a component Validate { component: String }, /// Print the current state @@ -148,6 +150,28 @@ pub(crate) fn update(name: &str) -> Result { }) } +/// daemon implementation of component adoption +pub(crate) fn adopt_and_update(name: &str) -> Result { + let sysroot = openat::Dir::open("/")?; + let _lock = acquire_write_lock("/").context("Failed to acquire write lock")?; + let mut state = get_saved_state("/")?.unwrap_or_default(); + let component = component::new_from_name(name)?; + if state.installed.get(name).is_some() { + anyhow::bail!("Component {} is already installed", name); + }; + let update = if let Some(update) = component.query_update()? { + update + } else { + anyhow::bail!("Component {} has no available update", name); + }; + let inst = component + .adopt_update(&update) + .context("Failed adopt and update")?; + state.installed.insert(component.name().into(), inst); + update_state(&sysroot, &state)?; + Ok(update) +} + /// daemon implementation of component validate pub(crate) fn validate(name: &str) -> Result { let state = get_saved_state("/")?.unwrap_or_default(); @@ -228,6 +252,7 @@ pub(crate) fn status() -> Result { .flatten(); let update = component.query_update()?; let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); + let adopted_from = ic.adopted_from.clone(); ret.components.insert( name.to_string(), ComponentStatus { @@ -235,6 +260,7 @@ pub(crate) fn status() -> Result { interrupted: interrupted.cloned(), update, updatable, + adopted_from, }, ); } @@ -242,7 +268,15 @@ pub(crate) fn status() -> Result { log::trace!("No saved state"); } + // Process the remaining components not installed log::trace!("Remaining known components: {}", known_components.len()); + for (name, component) in known_components { + if let Some(adopt_ver) = component.query_adopt()? { + ret.adoptable.insert(name.to_string(), adopt_ver); + } else { + log::trace!("Not adoptable: {}", name); + } + } Ok(ret) } @@ -273,6 +307,13 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { println!(" Update: {}", msg); } + if status.adoptable.is_empty() { + println!("No components are adoptable."); + } + for (name, version) in status.adoptable.iter() { + println!("Adoptable: {}: {}", name, version.version); + } + if let Some(coreos_aleph) = coreos::get_aleph_version()? { println!("CoreOS aleph image ID: {}", coreos_aleph.aleph.imgid); } @@ -350,6 +391,22 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result Ok(()) } +pub(crate) fn client_run_adopt_and_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { + validate_preview_env()?; + let status: Status = c.send(&ClientRequest::Status)?; + if status.adoptable.is_empty() { + println!("No components are adoptable."); + } else { + for (name, _) in status.adoptable.iter() { + let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate { + component: name.to_string(), + })?; + println!("Adopted and updated: {}: {}", name, r.version); + } + } + Ok(()) +} + pub(crate) fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { let status: Status = c.send(&ClientRequest::Status)?; if status.components.is_empty() { diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 3fb368600..fd05dfcff 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -42,6 +42,8 @@ pub enum CtlVerb { Status(StatusOpts), #[structopt(name = "update", about = "Update all components")] Update, + #[structopt(name = "adopt-and-update", about = "Update all adoptable components")] + AdoptAndUpdate, #[structopt(name = "validate", about = "Validate system state")] Validate, } @@ -67,6 +69,7 @@ impl CtlCommand { match self.cmd { CtlVerb::Status(opts) => Self::run_status(opts), CtlVerb::Update => Self::run_update(), + CtlVerb::AdoptAndUpdate => Self::run_adopt_and_update(), CtlVerb::Validate => Self::run_validate(), CtlVerb::Backend(CtlBackend::Generate(opts)) => { super::bootupd::DCommand::run_generate_meta(opts) @@ -106,6 +109,17 @@ impl CtlCommand { Ok(()) } + /// Runner for `update` verb. + fn run_adopt_and_update() -> Result<()> { + let mut client = ClientToDaemonConnection::new(); + client.connect()?; + + bootupd::client_run_adopt_and_update(&mut client)?; + + client.shutdown()?; + Ok(()) + } + /// Runner for `validate` verb. fn run_validate() -> Result<()> { let mut client = ClientToDaemonConnection::new(); diff --git a/src/component.rs b/src/component.rs index b770da402..ec6fcb4df 100644 --- a/src/component.rs +++ b/src/component.rs @@ -25,6 +25,14 @@ pub(crate) trait Component { /// and should remain stable. fn name(&self) -> &'static str; + /// In an operating system whose initially booted disk image is not + /// using bootupd, detect whether it looks like the component exists + /// and "synthesize" content metadata from it. + fn query_adopt(&self) -> Result>; + + /// Given an adoptable system and an update, perform the update. + fn adopt_update(&self, update: &ContentMetadata) -> Result; + /// Implementation of `bootupd install` for a given component. This should /// gather data (or run binaries) from the source root, and install them /// into the target root. It is expected that sub-partitions (e.g. the ESP) diff --git a/src/coreos.rs b/src/coreos.rs index e8b91cdc9..5e9fee79c 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -24,7 +24,6 @@ pub(crate) struct Aleph { pub(crate) struct AlephWithTimestamp { pub(crate) aleph: Aleph, - #[allow(dead_code)] pub(crate) ts: chrono::DateTime, } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 1f22fb3ed..bcc317739 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -104,6 +104,12 @@ fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), })? } + ClientRequest::AdoptAndUpdate { component } => { + bincode::serialize(&match bootupd::adopt_and_update(component.as_str()) { + Ok(v) => ipc::DaemonToClientReply::Success::(v), + Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), + })? + } ClientRequest::Validate { component } => { bincode::serialize(&match bootupd::validate(component.as_str()) { Ok(v) => ipc::DaemonToClientReply::Success::(v), diff --git a/src/efi.rs b/src/efi.rs index c16864606..08da57bfa 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -6,10 +6,11 @@ use std::collections::{BTreeMap, BTreeSet}; use std::io::prelude::*; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::{bail, Context, Result}; +use openat_ext::OpenatDirExt; use chrono::prelude::*; @@ -26,11 +27,73 @@ pub(crate) const MOUNT_PATH: &str = "boot/efi"; #[derive(Default)] pub(crate) struct EFI {} +impl EFI { + fn esp_path(&self) -> PathBuf { + Path::new(MOUNT_PATH).join("EFI") + } + + fn open_esp_optional(&self) -> Result> { + let sysroot = openat::Dir::open("/")?; + let esp = sysroot.sub_dir_optional(&self.esp_path())?; + Ok(esp) + } + fn open_esp(&self) -> Result { + let sysroot = openat::Dir::open("/")?; + let esp = sysroot.sub_dir(&self.esp_path())?; + Ok(esp) + } +} + impl Component for EFI { fn name(&self) -> &'static str { "EFI" } + fn query_adopt(&self) -> Result> { + let esp = self.open_esp_optional()?; + if esp.is_none() { + log::trace!("No ESP detected"); + return Ok(None); + }; + // This would be extended with support for other operating systems later + let coreos_aleph = if let Some(a) = crate::coreos::get_aleph_version()? { + a + } else { + log::trace!("No CoreOS aleph detected"); + return Ok(None); + }; + let meta = ContentMetadata { + timestamp: coreos_aleph.ts, + version: coreos_aleph.aleph.imgid, + }; + log::trace!("EFI adoptable: {:?}", &meta); + Ok(Some(meta)) + } + + /// Given an adoptable system and an update, perform the update. + fn adopt_update(&self, updatemeta: &ContentMetadata) -> Result { + let meta = if let Some(meta) = self.query_adopt()? { + meta + } else { + anyhow::bail!("Failed to find adoptable system"); + }; + + let esp = self.open_esp()?; + validate_esp(&esp)?; + let updated = + openat::Dir::open(&component_updatedir("/", self)).context("opening update dir")?; + let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; + // For adoption, we should only touch files that we know about. + let diff = updatef.relative_diff_to(&esp)?; + log::trace!("applying adoption diff: {}", &diff); + filetree::apply_diff(&updated, &esp, &diff, None).context("applying filesystem changes")?; + Ok(InstalledContent { + meta: updatemeta.clone(), + filetree: Some(updatef), + adopted_from: Some(meta), + }) + } + fn install(&self, src_root: &str, dest_root: &str) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta @@ -56,6 +119,7 @@ impl Component for EFI { Ok(InstalledContent { meta, filetree: Some(ft), + adopted_from: None, }) } @@ -72,11 +136,14 @@ impl Component for EFI { let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI")) .context("opening EFI dir")?; validate_esp(&destdir)?; + log::trace!("applying diff: {}", &diff); filetree::apply_diff(&updated, &destdir, &diff, None) .context("applying filesystem changes")?; + let adopted_from = None; Ok(InstalledContent { meta: updatemeta, filetree: Some(updatef), + adopted_from: adopted_from, }) } diff --git a/src/filetree.rs b/src/filetree.rs index a1d84d835..886953209 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -9,6 +9,7 @@ use openat_ext::OpenatDirExt; use openssl::hash::{Hasher, MessageDigest}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet}; +use std::fmt::Display; use std::os::linux::fs::MetadataExt; use std::os::unix::io::AsRawFd; use std::os::unix::process::CommandExt; @@ -49,6 +50,18 @@ pub(crate) struct FileTreeDiff { pub(crate) changes: HashSet, } +impl Display for FileTreeDiff { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + write!( + f, + "additions: {} removals: {} changes: {}", + self.additions.len(), + self.removals.len(), + self.changes.len() + ) + } +} + #[cfg(test)] impl FileTreeDiff { pub(crate) fn count(&self) -> usize { diff --git a/src/model.rs b/src/model.rs index d3ff4b5f0..eee23a7e6 100644 --- a/src/model.rs +++ b/src/model.rs @@ -37,6 +37,8 @@ pub(crate) struct InstalledContent { pub(crate) meta: ContentMetadata, /// Human readable version number, like ostree it is not ever parsed, just displayed pub(crate) filetree: Option, + /// The version this was originally adopted from + pub(crate) adopted_from: Option, } /// Will be serialized into /boot/bootupd-state.json @@ -89,6 +91,8 @@ pub(crate) struct ComponentStatus { pub(crate) update: Option, /// Is true if the version in `update` is different from `installed` pub(crate) updatable: ComponentUpdatable, + /// Originally adopted version + pub(crate) adopted_from: Option, } /// Representation of bootupd's worldview at a point in time. @@ -101,6 +105,8 @@ pub(crate) struct ComponentStatus { pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, + /// Components that appear to be installed, not via bootupd + pub(crate) adoptable: BTreeMap, } #[cfg(test)] diff --git a/tests/e2e-adopt/e2e-adopt-in-vm.sh b/tests/e2e-adopt/e2e-adopt-in-vm.sh new file mode 100755 index 000000000..5f34b42df --- /dev/null +++ b/tests/e2e-adopt/e2e-adopt-in-vm.sh @@ -0,0 +1,133 @@ +#!/bin/bash +# Run inside the vm spawned from e2e.sh +set -euo pipefail + +dn=$(cd $(dirname $0) && pwd) +bn=$(basename $0) +. ${dn}/../kola/data/libtest.sh + +cd $(mktemp -d) + +echo "Starting $0" + +enable_bootupd() { + systemctl start bootupd.socket + # For now + export BOOTUPD_ACCEPT_PREVIEW=1 +} + +current_commit=$(rpm-ostree status --json | jq -r .deployments[0].checksum) + +reboot_with_mark() { + mark=$1; shift + runv echo ${mark} > ${reboot_mark_path} + sync ${reboot_mark_path} + runv systemd-run -- systemctl reboot + touch /run/rebooting + sleep infinity +} + +status_ok_no_update() { + bootupctl status | tee out.txt + assert_file_has_content_literal out.txt 'Component EFI' + assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' + assert_file_has_content_literal out.txt 'Update: At latest version' + assert_file_has_content out.txt 'CoreOS aleph image ID: .*coreos.*-qemu' + bootupctl validate + ok status and validate +} + +reboot_mark_path=/etc/${bn}.rebootstamp +reboot_mark= +if test -f "${reboot_mark_path}"; then + reboot_mark=$(cat ${reboot_mark_path}) +fi +case "${reboot_mark}" in + "") + if test "${current_commit}" = ${TARGET_COMMIT}; then + fatal "already at ${TARGET_COMMIT}" + fi + + # This system wasn't built via bootupd + assert_not_has_file /boot/bootupd-state.json + + # FIXME + # https://github.com/coreos/rpm-ostree/issues/2210 + runv setenforce 0 + runv rpm-ostree rebase /run/cosadir/tmp/repo:${TARGET_COMMIT} + reboot_with_mark first + ;; + first) + if test "${current_commit}" != ${TARGET_COMMIT}; then + fatal "not at ${TARGET_COMMIT}" + fi + # NOTE Fall through NOTE + ;; + second) + enable_bootupd + status_ok_no_update + touch /run/testtmp/success + sync + # TODO maybe try to make this use more of the exttest infrastructure? + exec poweroff -ff + ;; +esac + +enable_bootupd + +# We did setenforce 0 above for https://github.com/coreos/rpm-ostree/issues/2210 +# Validate that on reboot we're still enforcing. +semode=$(getenforce) +if test "$semode" != Enforcing; then + fatal "SELinux mode is ${semode}" +fi + +source_grub_cfg=$(find /boot/efi/EFI -name grub.cfg) +test -f "${source_grub_cfg}" + +source_grub=$(find /boot/efi/EFI -name grubx64.efi) +test -f ${source_grub} +source_grub_sha256=$(sha256sum ${source_grub} | cut -f 1 -d ' ') + +update_grub=$(find /usr/lib/bootupd/updates/EFI/ -name grubx64.efi) +test -f ${update_grub} +update_grub_sha256=$(sha256sum ${update_grub} | cut -f 1 -d ' ') +if test "${source_grub_sha256}" = "${update_grub_sha256}"; then + fatal "Already have target grubx64.efi" +fi + +bootupctl status | tee out.txt +assert_file_has_content_literal out.txt 'No components installed.' +assert_file_has_content out.txt 'Adoptable: EFI: .*coreos.*-qemu.*' + +bootupctl validate | tee out.txt +assert_file_has_content_literal out.txt 'No components installed.' +assert_not_file_has_content_literal out.txt "Validated" +# Shouldn't write state just starting and validating +assert_not_has_file /boot/bootupd-state.json +ok validate + +bootupctl adopt-and-update | tee out.txt +assert_file_has_content out.txt 'Adopted and updated: EFI: grub2-efi-x64' +ok adoption + +status_ok_no_update + +bootupctl validate | tee out.txt +assert_not_file_has_content_literal out.txt "Validated EFI" + +new_grub_sha256=$(sha256sum ${source_grub} | cut -f 1 -d ' ') +if test "${new_grub_sha256}" != "${update_grub_sha256}"; then + fatal "Failed to update grub" +fi +ok updated grub + +# We shouldn't have deleted the config file which was unmanaged +test -f "${source_grub_cfg}" +ok still have grub.cfg + +tap_finish + +# And now do another reboot to validate that things are good +reboot_with_mark second + diff --git a/tests/e2e-adopt/e2e-adopt.sh b/tests/e2e-adopt/e2e-adopt.sh new file mode 100755 index 000000000..9f3c2116a --- /dev/null +++ b/tests/e2e-adopt/e2e-adopt.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# Given an old FCOS build (pre-bootupd), upgrade +# to the latest build in ${COSA_DIR} and run through +# the adoption procedure to update the ESP. +set -euo pipefail + +# There was a grub2-efi-x64 change after this +PRE_BOOTUPD_FCOS=https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200907.3.0/x86_64/meta.json + +dn=$(cd $(dirname $0) && pwd) +testprefix=$(cd ${dn} && git rev-parse --show-prefix) +. ${dn}/../kola/data/libtest.sh + +if test -z "${COSA_DIR:-}"; then + fatal "COSA_DIR must be set" +fi +# Validate source directory +bootupd_git=$(cd ${dn} && git rev-parse --show-toplevel) +test -f ${bootupd_git}/systemd/bootupd.service + +testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) +export test_tmpdir=${testtmp} +cd ${test_tmpdir} +runv curl -sSL -o meta.json ${PRE_BOOTUPD_FCOS} +jq .images.qemu < meta.json > qemu.json +qemu_image_xz=$(jq -r .path < qemu.json) +qemu_image=${qemu_image_xz%%.xz} +if test -f "${COSA_DIR}/tmp/${qemu_image}"; then + qemu_image="${COSA_DIR}/tmp/${qemu_image}" +else + runv curl -sSL $(dirname ${PRE_BOOTUPD_FCOS})/${qemu_image_xz} | xz -d > ${COSA_DIR}/tmp/${qemu_image}.tmp + mv ${COSA_DIR}/tmp/${qemu_image}{.tmp,} + qemu_image=${COSA_DIR}/tmp/${qemu_image} +fi + +# Start in cosa dir +cd ${COSA_DIR} +test -d builds + +echo "Preparing test" +target_commit=$(cosa meta --get-value ostree-commit) +echo "Target commit: ${target_commit}" + +execstop='test -f /run/rebooting || poweroff -ff' +if test -n "${e2e_debug:-}"; then + execstop= +fi +cat >${testtmp}/test.fcct << EOF +variant: fcos +version: 1.0.0 +systemd: + units: + - name: zincati.service + dropins: + - name: disabled.conf + contents: | + [Unit] + # Disable zincati, we're going to do our own updates + ConditionPathExists=/nosuchfile + - name: bootupd-test.service + enabled: true + contents: | + [Unit] + RequiresMountsFor=/run/testtmp + [Service] + Type=oneshot + RemainAfterExit=yes + Environment=TARGET_COMMIT=${target_commit} + Environment=SRCDIR=/run/bootupd-source + # Run via shell because selinux denies systemd writing to 9p apparently + ExecStart=/bin/sh -c '/run/bootupd-source/${testprefix}/e2e-adopt-in-vm.sh &>>/run/testtmp/out.txt; ${execstop}' + [Install] + WantedBy=multi-user.target +EOF +runv fcct -o ${testtmp}/test.ign ${testtmp}/test.fcct +cd ${testtmp} +qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${qemu_image}" --qemu-firmware uefi \ + -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw .,/run/testtmp) +if test -n "${e2e_debug:-}"; then + runv ${qemuexec_args[@]} --devshell +else + runv timeout 5m "${qemuexec_args[@]}" --console-to-file $(pwd)/console.txt +fi +if ! test -f ${testtmp}/success; then + if test -s ${testtmp}/out.txt; then + sed -e 's,^,# ,' < ${testtmp}/out.txt + else + echo "No out.txt created, systemd unit failed to start" + fi + fatal "test failed" +fi +echo "ok bootupd e2e" diff --git a/tests/fixtures/example-status-v0.json b/tests/fixtures/example-status-v0.json index 6c657db88..11af285e5 100644 --- a/tests/fixtures/example-status-v0.json +++ b/tests/fixtures/example-status-v0.json @@ -13,5 +13,6 @@ "updatable": "at-latest-version", "adopted-from": null } - } + }, + "adoptable": {} } From b08092b52f32924409fe735b66a3e53ca30ff36c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Oct 2020 13:53:39 -0400 Subject: [PATCH 115/641] Release 0.1.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6e1e75720..3a79e1abc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.1.1" +version = "0.1.3" authors = ["Colin Walters "] edition = "2018" From 7161a34a538ca1cb874ae695fbc9bc708d20eaa1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Oct 2020 15:38:37 -0400 Subject: [PATCH 116/641] Drop requirement for BOOTUPD_ACCEPT_PREVIEW=1 I'm increasingly confident in our testing, so let's drop the requirement to set the environment variable. --- src/bootupd.rs | 16 ---------------- tests/e2e-adopt/e2e-adopt-in-vm.sh | 2 -- tests/e2e-update/e2e-update-in-vm.sh | 2 -- tests/kola/test-bootupd | 8 -------- 4 files changed, 28 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 587ce5363..40c0fb22b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -331,22 +331,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { Ok(()) } -/// Checks that the user has provided an environment variable to signal -/// acceptance of our alpha state - use this when performing write operations. -fn validate_preview_env() -> Result<()> { - let v = "BOOTUPD_ACCEPT_PREVIEW"; - if std::env::var_os(v).is_none() { - Err(anyhow::anyhow!( - "bootupd is currently alpha; set {}=1 in environment to continue", - v - )) - } else { - Ok(()) - } -} - pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { - validate_preview_env()?; let status: Status = c.send(&ClientRequest::Status)?; if status.components.is_empty() { println!("No components installed."); @@ -392,7 +377,6 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result } pub(crate) fn client_run_adopt_and_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { - validate_preview_env()?; let status: Status = c.send(&ClientRequest::Status)?; if status.adoptable.is_empty() { println!("No components are adoptable."); diff --git a/tests/e2e-adopt/e2e-adopt-in-vm.sh b/tests/e2e-adopt/e2e-adopt-in-vm.sh index 5f34b42df..f7f6c4dcf 100755 --- a/tests/e2e-adopt/e2e-adopt-in-vm.sh +++ b/tests/e2e-adopt/e2e-adopt-in-vm.sh @@ -12,8 +12,6 @@ echo "Starting $0" enable_bootupd() { systemctl start bootupd.socket - # For now - export BOOTUPD_ACCEPT_PREVIEW=1 } current_commit=$(rpm-ostree status --json | jq -r .deployments[0].checksum) diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index 4d41d4466..b0cd38764 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -49,8 +49,6 @@ if ! test -n "${TARGET_GRUB_PKG}"; then fi systemctl start bootupd.socket -# For now -export BOOTUPD_ACCEPT_PREVIEW=1 bootupctl validate ok validate diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 8e6a6691b..ab8207876 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,9 +19,6 @@ function cleanup () { fi } -# For now -export BOOTUPD_ACCEPT_PREVIEW=1 - bootefidir=/boot/efi/EFI bootupdir=/usr/lib/bootupd/updates efiupdir=${bootupdir}/EFI @@ -91,11 +88,6 @@ bootupctl status --json > status.json jq -r '.components.EFI.installed.version' < status.json > installed.txt assert_file_has_content installed.txt '^grub2-efi-x64' -if env -u BOOTUPD_ACCEPT_PREVIEW bootupctl update; then - fatal "Ran without BOOTUPD_ACCEPT_PREVIEW" -fi -ok required env - bootupctl update | tee out.txt assert_file_has_content out.txt 'Updated EFI: grub2-efi-x64.*,test' From 721b521c41896eaf46d890bf0c88c8d73281b6e0 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 14 Oct 2020 12:23:17 +0000 Subject: [PATCH 117/641] github: add dependabot config This adds initial configuration for dependabot. --- .github/dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..582dadd78 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: +- package-ecosystem: cargo + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + labels: + - area/dependencies From a205704892c989e6dfbe9f735d44eaa7e3b5cff8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Oct 2020 08:46:52 -0400 Subject: [PATCH 118/641] Release 0.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50c44abd7..614ea2e90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.1.1" +version = "0.2.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 3a79e1abc..51de547b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.1.3" +version = "0.2.0" authors = ["Colin Walters "] edition = "2018" From e64b10d899943660a9ec9c73b8018393ba3a023c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:37:26 +0000 Subject: [PATCH 119/641] build(deps): bump serde_json from 1.0.58 to 1.0.59 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.58 to 1.0.59. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.58...v1.0.59) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 614ea2e90..c98ddfc36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,9 +585,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", From 018866d244924396852693c53360b1cd1fe458bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:37:27 +0000 Subject: [PATCH 120/641] build(deps): bump structopt from 0.3.18 to 0.3.20 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.18 to 0.3.20. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.18...v0.3.20) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c98ddfc36..9cee56e7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -614,9 +614,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33f6461027d7f08a13715659b2948e1602c31a3756aeae9378bfe7518c72e82" +checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" dependencies = [ "clap", "lazy_static", @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92e775028122a4b3dd55d58f14fc5120289c69bee99df1d117ae30f84b225c9" +checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" dependencies = [ "heck", "proc-macro-error", From b07c2ef251710298577206921dd114543db2f587 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:37:30 +0000 Subject: [PATCH 121/641] build(deps): bump anyhow from 1.0.32 to 1.0.33 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.32 to 1.0.33. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.32...1.0.33) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cee56e7a..35d257bf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" [[package]] name = "atty" From 3ab61bdcf9567e9dccfe9b6e2fe28721b50d724d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:37:30 +0000 Subject: [PATCH 122/641] build(deps): bump nix from 0.17.0 to 0.19.0 Bumps [nix](https://github.com/nix-rust/nix) from 0.17.0 to 0.19.0. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.17.0...v0.19.0) Signed-off-by: dependabot[bot] --- Cargo.lock | 18 +++++++++++++++--- Cargo.toml | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35d257bf6..ab8323135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,7 +92,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix", + "nix 0.19.0", "openat", "openat-ext", "openssl", @@ -317,7 +317,7 @@ dependencies = [ "error-chain", "hmac", "libc", - "nix", + "nix 0.17.0", "serde", "sha2", "uuid", @@ -351,6 +351,18 @@ dependencies = [ "void", ] +[[package]] +name = "nix" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", +] + [[package]] name = "num-integer" version = "0.1.43" @@ -392,7 +404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1be1e54fbd54bae8b4497ddcc30f97ae57f18fa37fa2f35d48db7b0a8f0b59" dependencies = [ "libc", - "nix", + "nix 0.17.0", "openat", ] diff --git a/Cargo.toml b/Cargo.toml index 51de547b1..ed7737ed9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ hex = "0.4.2" libc = "^0.2" libsystemd = "^0.2" log = "^0.4" -nix = "0.17.0" +nix = "0.19.0" openat = "0.1.19" openat-ext = "^0.1.6" openssl = "^0.10" From 9a8ba50ec24f306de8a8e3855e204b4aa3474894 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 19 Oct 2020 09:29:48 +0000 Subject: [PATCH 123/641] backend/statefile: add a write-lock guard for statefile updates This introduces a write-lock guard in order to to ensure that all update operations attempted on the on-disk statefile have properly acquired the system-wide lock first. --- src/backend/mod.rs | 3 + src/backend/statefile.rs | 108 +++++++++++++++++++++++++++++++++ src/bootupd.rs | 128 +++++++++------------------------------ src/main.rs | 1 + 4 files changed, 142 insertions(+), 98 deletions(-) create mode 100644 src/backend/mod.rs create mode 100644 src/backend/statefile.rs diff --git a/src/backend/mod.rs b/src/backend/mod.rs new file mode 100644 index 000000000..df7c63705 --- /dev/null +++ b/src/backend/mod.rs @@ -0,0 +1,3 @@ +//! Internal logic for bootloader and system state manipulation. + +mod statefile; diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs new file mode 100644 index 000000000..01df4d9b1 --- /dev/null +++ b/src/backend/statefile.rs @@ -0,0 +1,108 @@ +//! On-disk saved state. + +use crate::model::SavedState; +use anyhow::{bail, Context, Result}; +use fs2::FileExt; +use openat_ext::OpenatDirExt; +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; + +impl SavedState { + /// System-wide bootupd write lock (relative to sysroot). + const WRITE_LOCK_PATH: &'static str = "run/bootupd-lock"; + /// Top-level directory for statefile (relative to sysroot). + pub(crate) const STATEFILE_DIR: &'static str = "boot"; + /// On-disk bootloader statefile, akin to a tiny rpm/dpkg database, stored in `/boot`. + pub(crate) const STATEFILE_NAME: &'static str = "bootupd-state.json"; + + /// Try to acquire a system-wide lock to ensure non-conflicting state updates. + /// + /// While ordinarily the daemon runs as a systemd unit (which implicitly + /// ensures a single instance) this is a double check against other + /// execution paths. + pub(crate) fn acquire_write_lock(root_path: impl AsRef) -> Result { + let root_path = root_path.as_ref(); + let lockfile = std::fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(root_path.join(Self::WRITE_LOCK_PATH))?; + lockfile.lock_exclusive()?; + let guard = StateLockGuard { lockfile }; + Ok(guard) + } + + /// Load the JSON file containing on-disk state. + pub(crate) fn load_from_disk(root_path: impl AsRef) -> Result> { + let root_path = root_path.as_ref(); + let sysroot = openat::Dir::open(root_path) + .with_context(|| format!("opening sysroot '{}'", root_path.display()))?; + + let statefile_path = Path::new(Self::STATEFILE_DIR).join(Self::STATEFILE_NAME); + let saved_state = if let Some(statusf) = sysroot.open_file_optional(&statefile_path)? { + let bufr = std::io::BufReader::new(statusf); + let saved_state: SavedState = serde_json::from_reader(bufr)?; + Some(saved_state) + } else { + None + }; + Ok(saved_state) + } + + /// Check whether statefile exists. + pub(crate) fn ensure_not_present(root_path: impl AsRef) -> Result<()> { + let statepath = Path::new(root_path.as_ref()) + .join(Self::STATEFILE_DIR) + .join(Self::STATEFILE_NAME); + if statepath.exists() { + bail!("{} already exists", statepath.display()); + } + Ok(()) + } +} + +/// Write-lock guard for statefile, protecting against concurrent state updates. +#[derive(Debug)] +pub(crate) struct StateLockGuard { + lockfile: File, +} + +impl StateLockGuard { + /// Atomically replace the on-disk state with a new version. + pub(crate) fn update_state( + &mut self, + sysroot: &mut openat::Dir, + state: &SavedState, + ) -> Result<()> { + let subdir = sysroot.sub_dir(SavedState::STATEFILE_DIR)?; + let f = { + let f = subdir + .new_unnamed_file(0o644) + .context("creating temp file")?; + let mut buff = std::io::BufWriter::new(f); + serde_json::to_writer(&mut buff, state)?; + buff.flush()?; + buff.into_inner()? + }; + let dest_tmp_name = { + let mut buf = std::ffi::OsString::from(SavedState::STATEFILE_NAME); + buf.push(".tmp"); + buf + }; + let dest_tmp_name = Path::new(&dest_tmp_name); + if subdir.exists(dest_tmp_name)? { + subdir + .remove_file(dest_tmp_name) + .context("Removing temp file")?; + } + subdir + .link_file_at(&f, dest_tmp_name) + .context("Linking temp file")?; + f.sync_all().context("syncing")?; + subdir + .local_rename(dest_tmp_name, SavedState::STATEFILE_NAME) + .context("Renaming temp file")?; + Ok(()) + } +} diff --git a/src/bootupd.rs b/src/bootupd.rs index 40c0fb22b..0d61874b8 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -3,21 +3,12 @@ use crate::coreos; use crate::efi; use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; use crate::{component, ipc}; -use anyhow::{anyhow, bail, Context, Result}; -use fs2::FileExt; -use openat_ext::OpenatDirExt; +use anyhow::{anyhow, Context, Result}; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::collections::BTreeMap; -use std::io::prelude::*; use std::path::Path; -/// Stored in /boot to describe our state; think of it like -/// a tiny rpm/dpkg database. It's stored in /boot -pub(crate) const STATEFILE_DIR: &str = "boot"; -pub(crate) const STATEFILE_NAME: &str = "bootupd-state.json"; -pub(crate) const WRITE_LOCK_PATH: &str = "run/bootupd-lock"; - /// A message sent from client to server #[derive(Debug, Serialize, Deserialize)] pub(crate) enum ClientRequest { @@ -32,29 +23,27 @@ pub(crate) enum ClientRequest { } pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { - let statepath = Path::new(dest_root) - .join(STATEFILE_DIR) - .join(STATEFILE_NAME); - if statepath.exists() { - bail!("{:?} already exists, cannot re-install", statepath); - } + SavedState::ensure_not_present(dest_root) + .context("failed to install, invalid re-install attempted")?; let components = get_components(); if components.is_empty() { println!("No components available for this platform."); return Ok(()); } - let mut state = SavedState { - installed: Default::default(), - pending: Default::default(), - }; + + let mut state = SavedState::default(); for component in components.values() { let meta = component.install(source_root, dest_root)?; state.installed.insert(component.name().into(), meta); } - let sysroot = openat::Dir::open(dest_root)?; - update_state(&sysroot, &state).context("Failed to update state")?; + let mut state_guard = + SavedState::acquire_write_lock(source_root).context("failed to acquire write lock")?; + let mut sysroot = openat::Dir::open(dest_root)?; + state_guard + .update_state(&mut sysroot, &state) + .context("failed to update state")?; Ok(()) } @@ -90,20 +79,6 @@ pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { Ok(()) } -/// Hold a lock on the system root; while ordinarily we run -/// as a systemd unit which implicitly ensures a "singleton" -/// instance this is a double check. -fn acquire_write_lock>(sysroot: P) -> Result { - let sysroot = sysroot.as_ref(); - let lockf = std::fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(sysroot.join(WRITE_LOCK_PATH))?; - lockf.lock_exclusive()?; - Ok(lockf) -} - /// Return value from daemon → client for component update #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "kebab-case")] @@ -118,9 +93,7 @@ pub(crate) enum ComponentUpdateResult { /// daemon implementation of component update pub(crate) fn update(name: &str) -> Result { - let sysroot = openat::Dir::open("/")?; - let _lock = acquire_write_lock("/").context("Failed to acquire write lock")?; - let mut state = get_saved_state("/")?.unwrap_or_default(); + let mut state = SavedState::load_from_disk("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; let inst = if let Some(inst) = state.installed.get(name) { inst.clone() @@ -132,17 +105,24 @@ pub(crate) fn update(name: &str) -> Result { Some(p) if inst.meta.can_upgrade_to(&p) => p, _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; + + let mut sysroot = openat::Dir::open("/")?; let mut pending_container = state.pending.take().unwrap_or_default(); let interrupted = pending_container.get(component.name()).cloned(); - pending_container.insert(component.name().into(), update.clone()); - update_state(&sysroot, &state).context("Failed to update state")?; + let mut state_guard = + SavedState::acquire_write_lock("/").context("Failed to acquire write lock")?; + state_guard + .update_state(&mut sysroot, &state) + .context("Failed to update state")?; + let newinst = component .run_update(&inst) .with_context(|| format!("Failed to update {}", component.name()))?; state.installed.insert(component.name().into(), newinst); pending_container.remove(component.name()); - update_state(&sysroot, &state)?; + state_guard.update_state(&mut sysroot, &state)?; + Ok(ComponentUpdateResult::Updated { previous: inst.meta, interrupted, @@ -152,9 +132,7 @@ pub(crate) fn update(name: &str) -> Result { /// daemon implementation of component adoption pub(crate) fn adopt_and_update(name: &str) -> Result { - let sysroot = openat::Dir::open("/")?; - let _lock = acquire_write_lock("/").context("Failed to acquire write lock")?; - let mut state = get_saved_state("/")?.unwrap_or_default(); + let mut state = SavedState::load_from_disk("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; if state.installed.get(name).is_some() { anyhow::bail!("Component {} is already installed", name); @@ -168,13 +146,17 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { .adopt_update(&update) .context("Failed adopt and update")?; state.installed.insert(component.name().into(), inst); - update_state(&sysroot, &state)?; + + let mut sysroot = openat::Dir::open("/")?; + let mut state_guard = + SavedState::acquire_write_lock("/").context("Failed to acquire write lock")?; + state_guard.update_state(&mut sysroot, &state)?; Ok(update) } /// daemon implementation of component validate pub(crate) fn validate(name: &str) -> Result { - let state = get_saved_state("/")?.unwrap_or_default(); + let state = SavedState::load_from_disk("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; let inst = if let Some(inst) = state.installed.get(name) { inst.clone() @@ -184,60 +166,10 @@ pub(crate) fn validate(name: &str) -> Result { component.validate(&inst) } -/// Atomically replace the on-disk state with a new version -fn update_state(sysroot_dir: &openat::Dir, state: &SavedState) -> Result<()> { - let subdir = sysroot_dir.sub_dir(STATEFILE_DIR)?; - let f = { - let f = subdir - .new_unnamed_file(0o644) - .context("creating temp file")?; - let mut buff = std::io::BufWriter::new(f); - serde_json::to_writer(&mut buff, state)?; - buff.flush()?; - buff.into_inner()? - }; - let dest_tmp_name = { - // expect OK because we just created the filename above from a constant - let mut buf = std::ffi::OsString::from(STATEFILE_NAME); - buf.push(".tmp"); - buf - }; - let dest_tmp_name = Path::new(&dest_tmp_name); - if subdir.exists(dest_tmp_name)? { - subdir - .remove_file(dest_tmp_name) - .context("Removing temp file")?; - } - subdir - .link_file_at(&f, dest_tmp_name) - .context("Linking temp file")?; - f.sync_all().context("syncing")?; - subdir - .local_rename(dest_tmp_name, STATEFILE_NAME) - .context("Renaming temp file")?; - Ok(()) -} - -/// Load the JSON file containing on-disk state -fn get_saved_state(sysroot_path: &str) -> Result> { - let sysroot_dir = openat::Dir::open(sysroot_path) - .with_context(|| format!("opening sysroot {}", sysroot_path))?; - - let statefile_path = Path::new(STATEFILE_DIR).join(STATEFILE_NAME); - let saved_state = if let Some(statusf) = sysroot_dir.open_file_optional(&statefile_path)? { - let bufr = std::io::BufReader::new(statusf); - let saved_state: SavedState = serde_json::from_reader(bufr)?; - Some(saved_state) - } else { - None - }; - Ok(saved_state) -} - pub(crate) fn status() -> Result { let mut ret: Status = Default::default(); let mut known_components = get_components(); - let state = get_saved_state("/")?; + let state = SavedState::load_from_disk("/")?; if let Some(state) = state { for (name, ic) in state.installed.iter() { log::trace!("Gathering status for installed component: {}", name); diff --git a/src/main.rs b/src/main.rs index ed93b0373..1bd24e9a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ Refs: #![deny(unused_must_use)] +mod backend; mod bootupd; mod cli; mod component; From 028041fa3e8b2bd3bc5a26919e099e636f7dfd36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2020 06:41:49 +0000 Subject: [PATCH 124/641] build(deps): bump serde from 1.0.116 to 1.0.117 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab8323135..42cce6169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -577,18 +577,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ "proc-macro2", "quote", From ce67a6850d002f0cf35e4a8e6b3c3630feeeb0e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2020 07:30:35 +0000 Subject: [PATCH 125/641] build(deps): bump libc from 0.2.79 to 0.2.80 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.79 to 0.2.80. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.79...0.2.80) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42cce6169..42583f63d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -304,9 +304,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "libsystemd" From 18aa7f281a3c9a31b4388d1cecaa50cded4ebb73 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Mon, 26 Oct 2020 15:58:27 -0400 Subject: [PATCH 126/641] Add some more error-prefixing I think we're hitting issues in CI in this path right now. See: https://github.com/coreos/fedora-coreos-config/pull/711. --- src/bootupd.rs | 4 +++- src/efi.rs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0d61874b8..3d4a30fad 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -34,7 +34,9 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { let mut state = SavedState::default(); for component in components.values() { - let meta = component.install(source_root, dest_root)?; + let meta = component + .install(source_root, dest_root) + .with_context(|| format!("installing component {}", component.name()))?; state.installed.insert(component.name().into(), meta); } diff --git a/src/efi.rs b/src/efi.rs index 08da57bfa..44d9341bd 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -101,11 +101,13 @@ impl Component for EFI { anyhow::bail!("No update metadata for component {} found", self.name()); }; let srcdir = component_updatedir(src_root, self); - let srcd = openat::Dir::open(&srcdir)?; + let srcd = openat::Dir::open(&srcdir) + .with_context(|| format!("opening src dir {}", srcdir.display()))?; let ft = crate::filetree::FileTree::new_from_dir(&srcd)?; let destdir = Path::new(dest_root).join(MOUNT_PATH); { - let destd = openat::Dir::open(&destdir)?; + let destd = openat::Dir::open(&destdir) + .with_context(|| format!("opening dest dir {}", destdir.display()))?; validate_esp(&destd)?; } let r = std::process::Command::new("cp") From 80469cbf66bceca2efb89159a2489584a2b6b58a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 23 Oct 2020 17:02:52 +0000 Subject: [PATCH 127/641] Rework sysroot/statefile locking Have the guard actually own the sysroot - matching how in Rust the `Mutex` type wraps what it guards. Also add an `unlocked()` method to deal with the install case, since there's no `/run` in the target root. xref https://github.com/coreos/bootupd/pull/86#issuecomment-715351465 xref https://github.com/coreos/bootupd/pull/84#issuecomment-709414840 --- src/backend/statefile.rs | 34 +++++++++++++++++++--------------- src/bootupd.rs | 21 ++++++++++----------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 01df4d9b1..57cc05030 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -21,18 +21,25 @@ impl SavedState { /// While ordinarily the daemon runs as a systemd unit (which implicitly /// ensures a single instance) this is a double check against other /// execution paths. - pub(crate) fn acquire_write_lock(root_path: impl AsRef) -> Result { - let root_path = root_path.as_ref(); - let lockfile = std::fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(root_path.join(Self::WRITE_LOCK_PATH))?; + pub(crate) fn acquire_write_lock(sysroot: openat::Dir) -> Result { + let lockfile = sysroot.write_file(Self::WRITE_LOCK_PATH, 0o644)?; lockfile.lock_exclusive()?; - let guard = StateLockGuard { lockfile }; + let guard = StateLockGuard { + sysroot, + lockfile: Some(lockfile), + }; Ok(guard) } + /// Use this for cases when the target root isn't booted, which is + /// offline installs. + pub(crate) fn unlocked(sysroot: openat::Dir) -> Result { + Ok(StateLockGuard { + sysroot, + lockfile: None, + }) + } + /// Load the JSON file containing on-disk state. pub(crate) fn load_from_disk(root_path: impl AsRef) -> Result> { let root_path = root_path.as_ref(); @@ -65,17 +72,14 @@ impl SavedState { /// Write-lock guard for statefile, protecting against concurrent state updates. #[derive(Debug)] pub(crate) struct StateLockGuard { - lockfile: File, + sysroot: openat::Dir, + lockfile: Option, } impl StateLockGuard { /// Atomically replace the on-disk state with a new version. - pub(crate) fn update_state( - &mut self, - sysroot: &mut openat::Dir, - state: &SavedState, - ) -> Result<()> { - let subdir = sysroot.sub_dir(SavedState::STATEFILE_DIR)?; + pub(crate) fn update_state(&mut self, state: &SavedState) -> Result<()> { + let subdir = self.sysroot.sub_dir(SavedState::STATEFILE_DIR)?; let f = { let f = subdir .new_unnamed_file(0o644) diff --git a/src/bootupd.rs b/src/bootupd.rs index 3d4a30fad..13a044245 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -40,11 +40,10 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { state.installed.insert(component.name().into(), meta); } - let mut state_guard = - SavedState::acquire_write_lock(source_root).context("failed to acquire write lock")?; - let mut sysroot = openat::Dir::open(dest_root)?; + let sysroot = openat::Dir::open(dest_root)?; + let mut state_guard = SavedState::unlocked(sysroot).context("failed to acquire write lock")?; state_guard - .update_state(&mut sysroot, &state) + .update_state(&state) .context("failed to update state")?; Ok(()) @@ -108,14 +107,14 @@ pub(crate) fn update(name: &str) -> Result { _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; - let mut sysroot = openat::Dir::open("/")?; let mut pending_container = state.pending.take().unwrap_or_default(); let interrupted = pending_container.get(component.name()).cloned(); pending_container.insert(component.name().into(), update.clone()); + let sysroot = openat::Dir::open("/")?; let mut state_guard = - SavedState::acquire_write_lock("/").context("Failed to acquire write lock")?; + SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; state_guard - .update_state(&mut sysroot, &state) + .update_state(&state) .context("Failed to update state")?; let newinst = component @@ -123,7 +122,7 @@ pub(crate) fn update(name: &str) -> Result { .with_context(|| format!("Failed to update {}", component.name()))?; state.installed.insert(component.name().into(), newinst); pending_container.remove(component.name()); - state_guard.update_state(&mut sysroot, &state)?; + state_guard.update_state(&state)?; Ok(ComponentUpdateResult::Updated { previous: inst.meta, @@ -149,10 +148,10 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { .context("Failed adopt and update")?; state.installed.insert(component.name().into(), inst); - let mut sysroot = openat::Dir::open("/")?; + let sysroot = openat::Dir::open("/")?; let mut state_guard = - SavedState::acquire_write_lock("/").context("Failed to acquire write lock")?; - state_guard.update_state(&mut sysroot, &state)?; + SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; + state_guard.update_state(&state)?; Ok(update) } From 66c044cc0cb56a285488650e8aa20b2bd621af89 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 26 Oct 2020 19:53:17 +0000 Subject: [PATCH 128/641] component: Add error prefixing I think this is the error we're seeing in https://github.com/coreos/fedora-coreos-config/pull/711#issuecomment-716780537 But let's add some error prefixing to be sure for the future. --- src/component.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/component.rs b/src/component.rs index ec6fcb4df..7c6a98329 100644 --- a/src/component.rs +++ b/src/component.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -use anyhow::Result; +use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::Write as IoWrite; @@ -107,6 +107,7 @@ pub(crate) fn get_component_update( return Ok(None); } let mut f = std::io::BufReader::new(File::open(&metap)?); - let u = serde_json::from_reader(&mut f)?; + let u = + serde_json::from_reader(&mut f).with_context(|| format!("failed to parse {:?}", metap))?; Ok(Some(u)) } From 91a989527a0a1ae23134ff60a2b4fa7c9e5cf198 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 26 Oct 2020 19:34:51 +0000 Subject: [PATCH 129/641] Use new openat-ext APIs for writing files Less code, not as error prone (e.g. forgetting to `flush()` a `BufWriter`) and technically better using `O_TMPFILE`. --- Cargo.lock | 26 +++++++++++++++++++++++--- Cargo.toml | 2 +- src/backend/statefile.rs | 32 ++++---------------------------- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42583f63d..ae484b6c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "drop_bomb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" + [[package]] name = "env_logger" version = "0.7.1" @@ -351,6 +357,18 @@ dependencies = [ "void", ] +[[package]] +name = "nix" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", +] + [[package]] name = "nix" version = "0.19.0" @@ -399,13 +417,15 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be1e54fbd54bae8b4497ddcc30f97ae57f18fa37fa2f35d48db7b0a8f0b59" +checksum = "ea8f6f2601742142683130af7d1b387f10e1c3d73121f069203d4139bbb27c4c" dependencies = [ + "drop_bomb", "libc", - "nix 0.17.0", + "nix 0.18.0", "openat", + "rand", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ed7737ed9..246da126d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.0" openat = "0.1.19" -openat-ext = "^0.1.6" +openat-ext = "^0.1.7" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 57cc05030..0dba743fe 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -5,7 +5,6 @@ use anyhow::{bail, Context, Result}; use fs2::FileExt; use openat_ext::OpenatDirExt; use std::fs::File; -use std::io::prelude::*; use std::path::Path; impl SavedState { @@ -80,33 +79,10 @@ impl StateLockGuard { /// Atomically replace the on-disk state with a new version. pub(crate) fn update_state(&mut self, state: &SavedState) -> Result<()> { let subdir = self.sysroot.sub_dir(SavedState::STATEFILE_DIR)?; - let f = { - let f = subdir - .new_unnamed_file(0o644) - .context("creating temp file")?; - let mut buff = std::io::BufWriter::new(f); - serde_json::to_writer(&mut buff, state)?; - buff.flush()?; - buff.into_inner()? - }; - let dest_tmp_name = { - let mut buf = std::ffi::OsString::from(SavedState::STATEFILE_NAME); - buf.push(".tmp"); - buf - }; - let dest_tmp_name = Path::new(&dest_tmp_name); - if subdir.exists(dest_tmp_name)? { - subdir - .remove_file(dest_tmp_name) - .context("Removing temp file")?; - } - subdir - .link_file_at(&f, dest_tmp_name) - .context("Linking temp file")?; - f.sync_all().context("syncing")?; - subdir - .local_rename(dest_tmp_name, SavedState::STATEFILE_NAME) - .context("Renaming temp file")?; + subdir.write_file_with_sync(SavedState::STATEFILE_NAME, 0o644, |w| -> Result<()> { + serde_json::to_writer(w, state)?; + Ok(()) + })?; Ok(()) } } From ffb028430458278aa4da3fbc0e4733683b591de0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 27 Oct 2020 16:50:51 +0000 Subject: [PATCH 130/641] component: More porting to openat Clean up this code to use the openat helpers too, just on general principle of using fd-relative in more places. For this we also need to bump openat-ext to get the fallback, since `rofiles-fuse` doesn't handle `O_TMPFILE` either. --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/component.rs | 44 +++++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae484b6c5..61a9a96bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8f6f2601742142683130af7d1b387f10e1c3d73121f069203d4139bbb27c4c" +checksum = "73e85ee792caf10bf54dc2a844b9f5cbc4a05095360fdeba67ffe687912d2b8b" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index 246da126d..70f0bd4d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.0" openat = "0.1.19" -openat-ext = "^0.1.7" +openat-ext = "^0.1.8" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" diff --git a/src/component.rs b/src/component.rs index 7c6a98329..141a5cde4 100644 --- a/src/component.rs +++ b/src/component.rs @@ -5,9 +5,8 @@ */ use anyhow::{Context, Result}; +use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; -use std::fs::File; -use std::io::Write as IoWrite; use std::path::{Path, PathBuf}; use crate::model::*; @@ -68,14 +67,6 @@ pub(crate) fn new_from_name(name: &str) -> Result> { Ok(r) } -/// Returns the path to the JSON file containing a component's available update metadata installed -/// into the booted operating system root. -pub(crate) fn component_update_metapath(sysroot: &str, component: &dyn Component) -> PathBuf { - Path::new(sysroot) - .join(BOOTUPD_UPDATES_DIR) - .join(format!("{}.json", component.name())) -} - /// Returns the path to the payload directory for an available update for /// a component. pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { @@ -84,16 +75,24 @@ pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> P .join(component.name()) } +/// Returns the name of the JSON file containing a component's available update metadata installed +/// into the booted operating system root. +fn component_update_data_name(component: &dyn Component) -> PathBuf { + Path::new(&format!("{}.json", component.name())).into() +} + /// Helper method for writing an update file pub(crate) fn write_update_metadata( sysroot: &str, component: &dyn Component, meta: &ContentMetadata, ) -> Result<()> { - let metap = component_update_metapath(sysroot, component); - let mut f = std::io::BufWriter::new(std::fs::File::create(&metap)?); - serde_json::to_writer(&mut f, &meta)?; - f.flush()?; + let sysroot = openat::Dir::open(sysroot)?; + let dir = sysroot.sub_dir(BOOTUPD_UPDATES_DIR)?; + let name = component_update_data_name(component); + dir.write_file_with(&name, 0o644, |w| -> Result<_> { + Ok(serde_json::to_writer(w, &meta)?) + })?; Ok(()) } @@ -102,12 +101,15 @@ pub(crate) fn get_component_update( sysroot: &str, component: &dyn Component, ) -> Result> { - let metap = component_update_metapath(sysroot, component); - if !metap.exists() { - return Ok(None); + let sysroot = openat::Dir::open(sysroot)?; + let name = component_update_data_name(component); + let path = Path::new(BOOTUPD_UPDATES_DIR).join(name); + if let Some(f) = sysroot.open_file_optional(&path)? { + let mut f = std::io::BufReader::new(f); + let u = serde_json::from_reader(&mut f) + .with_context(|| format!("failed to parse {:?}", &path))?; + Ok(Some(u)) + } else { + Ok(None) } - let mut f = std::io::BufReader::new(File::open(&metap)?); - let u = - serde_json::from_reader(&mut f).with_context(|| format!("failed to parse {:?}", metap))?; - Ok(Some(u)) } From bfb2ce6aafcfda43c1f97f19fe2816f34c95a67f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 28 Oct 2020 18:41:40 +0000 Subject: [PATCH 131/641] Parse old "0.1" format installed state format Since bootupd 0.1.1 shipped in FCOS stable we need to support updating it, as well as "pre-bootupd" systems and bootupd 0.2 systems. I tested this manually; not yet adding an e2e yet for this because our test suite is already really expensive and the unit test covers most of it. Closes: https://github.com/coreos/bootupd/issues/91 --- src/backend/statefile.rs | 22 ++++- src/main.rs | 1 + src/model_legacy.rs | 101 ++++++++++++++++++++ tests/fixtures/example-state-v0-legacy.json | 48 ++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 src/model_legacy.rs create mode 100644 tests/fixtures/example-state-v0-legacy.json diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 0dba743fe..3be708e9b 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -5,6 +5,7 @@ use anyhow::{bail, Context, Result}; use fs2::FileExt; use openat_ext::OpenatDirExt; use std::fs::File; +use std::io::prelude::*; use std::path::Path; impl SavedState { @@ -47,9 +48,24 @@ impl SavedState { let statefile_path = Path::new(Self::STATEFILE_DIR).join(Self::STATEFILE_NAME); let saved_state = if let Some(statusf) = sysroot.open_file_optional(&statefile_path)? { - let bufr = std::io::BufReader::new(statusf); - let saved_state: SavedState = serde_json::from_reader(bufr)?; - Some(saved_state) + let mut bufr = std::io::BufReader::new(statusf); + let mut s = String::new(); + bufr.read_to_string(&mut s)?; + let state: serde_json::Result = serde_json::from_str(s.as_str()); + let r = match state { + Ok(s) => s, + Err(orig_err) => { + let state: serde_json::Result = + serde_json::from_str(s.as_str()); + match state { + Ok(s) => s.upconvert(), + Err(_) => { + return Err(orig_err)?; + } + } + } + }; + Some(r) } else { None }; diff --git a/src/main.rs b/src/main.rs index 1bd24e9a9..740c0db55 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ mod efi; mod filetree; mod ipc; mod model; +mod model_legacy; mod ostreeutil; mod sha512string; mod util; diff --git a/src/model_legacy.rs b/src/model_legacy.rs new file mode 100644 index 000000000..a584025ea --- /dev/null +++ b/src/model_legacy.rs @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 Red Hat, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +//! Implementation of the original bootupd data format, which is the same +//! as the current one except that the date is defined to be in UTC. + +use crate::model::ContentMetadata as NewContentMetadata; +use crate::model::InstalledContent as NewInstalledContent; +use crate::model::SavedState as NewSavedState; +use chrono::prelude::*; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[derive(Serialize, Deserialize, Clone, Debug, Hash, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct ContentMetadata01 { + /// The timestamp, which is used to determine update availability + pub(crate) timestamp: NaiveDateTime, + /// Human readable version number, like ostree it is not ever parsed, just displayed + pub(crate) version: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct InstalledContent01 { + /// Associated metadata + pub(crate) meta: ContentMetadata01, + /// File tree + pub(crate) filetree: Option, +} + +/// Will be serialized into /boot/bootupd-state.json +#[derive(Serialize, Deserialize, Default, Debug)] +#[serde(rename_all = "kebab-case")] +#[serde(deny_unknown_fields)] +pub(crate) struct SavedState01 { + /// Maps a component name to its currently installed version + pub(crate) installed: BTreeMap, + /// Maps a component name to an in progress update + pub(crate) pending: Option>, +} + +impl ContentMetadata01 { + pub(crate) fn upconvert(self) -> NewContentMetadata { + let timestamp = DateTime::::from_utc(self.timestamp, Utc); + NewContentMetadata { + timestamp, + version: self.version, + } + } +} + +impl InstalledContent01 { + pub(crate) fn upconvert(self) -> NewInstalledContent { + NewInstalledContent { + meta: self.meta.upconvert(), + filetree: self.filetree, + adopted_from: None, + } + } +} + +impl SavedState01 { + pub(crate) fn upconvert(self) -> NewSavedState { + let mut r: NewSavedState = Default::default(); + for (k, v) in self.installed { + r.installed.insert(k, v.upconvert()); + } + r + } +} + +#[cfg(test)] +mod test { + use super::*; + use anyhow::Result; + + /// Validate we're not breaking the serialized format of `bootupctl status --json` + #[test] + fn test_deserialize_status() -> Result<()> { + let data = include_str!("../tests/fixtures/example-state-v0-legacy.json"); + let state: SavedState01 = serde_json::from_str(data)?; + let efi = state.installed.get("EFI").expect("EFI"); + assert_eq!( + efi.meta.version, + "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + ); + let state: NewSavedState = state.upconvert(); + let efi = state.installed.get("EFI").expect("EFI"); + let t = chrono::DateTime::parse_from_rfc3339("2020-09-15T13:01:21Z")?; + assert_eq!(t, efi.meta.timestamp); + assert_eq!( + efi.meta.version, + "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + ); + Ok(()) + } +} diff --git a/tests/fixtures/example-state-v0-legacy.json b/tests/fixtures/example-state-v0-legacy.json new file mode 100644 index 000000000..85a0ae647 --- /dev/null +++ b/tests/fixtures/example-state-v0-legacy.json @@ -0,0 +1,48 @@ +{ + "installed": { + "EFI": { + "meta": { + "timestamp": "2020-09-15T13:01:21", + "version": "grub2-efi-x64-1:2.04-23.fc32.x86_64,shim-x64-15-8.x86_64" + }, + "filetree": { + "timestamp": "1970-01-01T00:00:00", + "children": { + "BOOT/BOOTX64.EFI": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + }, + "BOOT/fbx64.efi": { + "size": 357248, + "sha512": "sha512:81fed5039bdd2bc53a203a1eaf56c6a6c9a95aa7ac88f037718a342205d83550f409741c8ef86b481f55ea7188ce0d661742548596f92ef97ba2a1695bc4caae" + }, + "fedora/BOOTX64.CSV": { + "size": 110, + "sha512": "sha512:0c29b8ae73171ef683ba690069c1bae711e130a084a81169af33a83dfbae4e07d909c2482dbe89a96ab26e171f17c53f1de8cb13d558bc1535412ff8accf253f" + }, + "fedora/grubx64.efi": { + "size": 2528520, + "sha512": "sha512:b35a6317658d07844d6bf0f96c35f2df90342b8b13a329b4429ac892351ff74fc794a97bc3d3e2d79bef4c234b49a8dd5147b71a3376f24bc956130994e9961c" + }, + "fedora/mmx64.efi": { + "size": 1159560, + "sha512": "sha512:f83ea67756cfcc3ec4eb1c83104c719ba08e66abfadb94b4bd75891e237c448bbec0fdb5bd42826e291ccc3dee559af424900b3d642a7d11c5bc9f117718837a" + }, + "fedora/shim.efi": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + }, + "fedora/shimx64-fedora.efi": { + "size": 1204496, + "sha512": "sha512:dc3656b90c0d1767365bea462cc94a2a3044899f510bd61a9a7ae1a9ca586e3d6189592b1ba1ee859f45614421297fa2f5353328caa615f51da5aed9ecfbf29c" + }, + "fedora/shimx64.efi": { + "size": 1210776, + "sha512": "sha512:52e08b6e1686b19fea9e8f8d8ca51d22bba252467ceaf6db6ead8dd2dca4a0b0b02e547e50ddf1cdee225b8785f8514f6baa846bdf1ea0bf994e772daf70f2c3" + } + } + } + } + }, + "pending": null +} From aa0777238b9f0dd15c347016957a65c408c15fc9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 30 Oct 2020 00:07:45 +0000 Subject: [PATCH 132/641] Fix two minor clippy bits No particular reason. --- src/backend/statefile.rs | 2 +- src/efi.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 3be708e9b..513d4d160 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -60,7 +60,7 @@ impl SavedState { match state { Ok(s) => s.upconvert(), Err(_) => { - return Err(orig_err)?; + return Err(orig_err.into()); } } } diff --git a/src/efi.rs b/src/efi.rs index 44d9341bd..d0ce87963 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -145,7 +145,7 @@ impl Component for EFI { Ok(InstalledContent { meta: updatemeta, filetree: Some(updatef), - adopted_from: adopted_from, + adopted_from, }) } From 035f0bfc10a5568ee55ec8371b53eef3addeebfc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Nov 2020 21:22:14 +0000 Subject: [PATCH 133/641] Release 0.2.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61a9a96bb..6574a50c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 70f0bd4d7..96f0b3438 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.0" +version = "0.2.1" authors = ["Colin Walters "] edition = "2018" From 5e4ec993a84e6394a899314225d1f2d1fd1729ed Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 3 Nov 2020 10:14:14 +0000 Subject: [PATCH 134/641] gh/workflows: add jobs for linting, MSRV, release builds This adds more jobs to the existing GH actions workflow, in order to cover lintings (rustfmt and clippy), minimum toolchain (MSRV), beta/nightly channels, and building in release mode. --- .github/workflows/rust.yml | 94 ++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3c13d1be2..c28de7267 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,5 +1,5 @@ +--- name: Rust - on: push: branches: [ master ] @@ -8,15 +8,91 @@ on: env: CARGO_TERM_COLOR: always + # Minimum supported Rust version (MSRV) + ACTION_MSRV_TOOLCHAIN: 1.43.0 + # Pinned toolchain for linting + ACTION_LINTS_TOOLCHAIN: 1.47.0 jobs: - build: - + tests-stable: + name: "Tests, stable toolchain" runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: "stable" + default: true + - name: cargo build + run: cargo build + - name: cargo test + run: cargo test + tests-release-stable: + name: "Tests (release), stable toolchain" + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: "stable" + default: true + - name: cargo build (release) + run: cargo build --release + - name: cargo test (release) + run: cargo test --release + tests-release-msrv: + name: "Tests (release), minimum supported toolchain" + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env['ACTION_MSRV_TOOLCHAIN'] }} + default: true + - name: cargo build (release) + run: cargo build --release + - name: cargo test (release) + run: cargo test --release + linting: + name: "Lints, pinned toolchain" + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env['ACTION_LINTS_TOOLCHAIN'] }} + default: true + components: rustfmt, clippy + - name: cargo clippy (warnings) + run: cargo clippy -- -D warnings + - name: cargo fmt (check) + run: cargo fmt -- --check -l + tests-other-channels: + name: "Tests, unstable toolchain" + runs-on: ubuntu-latest + continue-on-error: true + strategy: + matrix: + channel: + - "beta" + - "nightly" + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.channel }} + default: true + - name: cargo build + run: cargo build + - name: cargo test + run: cargo test From 9192b46f2ff5e22ab2003ff19c1b315d229872d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2020 14:17:35 +0000 Subject: [PATCH 135/641] build(deps): bump anyhow from 1.0.33 to 1.0.34 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.33 to 1.0.34. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.33...1.0.34) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6574a50c4..27584a01f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" [[package]] name = "atty" From 3e62c9db9dc06bfb0acacdf1e862b28d84d7d8fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2020 14:20:42 +0000 Subject: [PATCH 136/641] build(deps): bump env_logger from 0.7.1 to 0.8.1 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.7.1 to 0.8.1. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/master/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.7.1...v0.8.1) Signed-off-by: dependabot[bot] --- Cargo.lock | 17 ++++------------- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27584a01f..6f0e22da4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] name = "env_logger" -version = "0.7.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" dependencies = [ "atty", "humantime", @@ -289,12 +289,9 @@ dependencies = [ [[package]] name = "humantime" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] +checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] name = "itoa" @@ -500,12 +497,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.7" diff --git a/Cargo.toml b/Cargo.toml index 96f0b3438..0c251cc43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ anyhow = "1.0" bincode = "1.3.1" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" -env_logger = "^0.7" +env_logger = "^0.8" fs2 = "0.4.3" hex = "0.4.2" libc = "^0.2" From a8e3bfd96fc1621585cc99d40a26de8b4fb5fdb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 06:43:33 +0000 Subject: [PATCH 137/641] build(deps): bump openat-ext from 0.1.8 to 0.1.9 Bumps [openat-ext](https://github.com/cgwalters/openat-ext) from 0.1.8 to 0.1.9. - [Release notes](https://github.com/cgwalters/openat-ext/releases) - [Commits](https://github.com/cgwalters/openat-ext/compare/v0.1.8...v0.1.9) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f0e22da4..b750d2343 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e85ee792caf10bf54dc2a844b9f5cbc4a05095360fdeba67ffe687912d2b8b" +checksum = "3dc1b204f9003fc6974231d2ed60e44206821e63c2cac1c8eccff0d2426e50f9" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index 0c251cc43..a1f9e6bd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.0" openat = "0.1.19" -openat-ext = "^0.1.8" +openat-ext = "^0.1.9" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From dd301364ba1011f0c375245cf2bf078ece8a5b24 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Nov 2020 16:42:21 +0000 Subject: [PATCH 138/641] Release 0.2.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b750d2343..08a04a4d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.1" +version = "0.2.2" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index a1f9e6bd1..70b8b85ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.1" +version = "0.2.2" authors = ["Colin Walters "] edition = "2018" From 481ae4836a1960bd7ee2aa312300370b7cd656f2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Nov 2020 21:13:36 +0000 Subject: [PATCH 139/641] Add a release-checklist + a script Taken from the one currently in coreos-installer: https://github.com/coreos/coreos-installer/blob/master/.github/ISSUE_TEMPLATE/release-checklist.md But tweaked in various ways: - I want to continue to use `git-evtag`, will try to teach `cargo-release` about that at some point. - Rework the vendoring stuff to be a script and run beforehand --- .github/ISSUE_TEMPLATE/release-checklist.md | 65 +++++++++++++++++++++ ci/prepare-release.sh | 20 +++++++ 2 files changed, 85 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/release-checklist.md create mode 100755 ci/prepare-release.sh diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md new file mode 100644 index 000000000..d36352427 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -0,0 +1,65 @@ +# Release process + +The release process follows the usual PR-and-review flow, allowing an external reviewer to have a final check before publishing. + +In order to ease downstream packaging of Rust binaries, an archive of vendored dependencies is also provided (only relevant for offline builds). + +## Requirements + +This guide requires: + + * a web browser (and network connectivity) + * `git` + * GPG setup and personal key for signing + * [git-evtag](https://github.com/cgwalters/git-evtag/) + * `cargo` (suggested: latest stable toolchain from [rustup][rustup]) + * A verified account on crates.io + * Write access to this GitHub project + * Upload access to this project on GitHub, crates.io + +## Release checklist + +- Prepare local branch+commit + - [ ] `git checkout -b release` + - [ ] Bump the version number in `Cargo.toml`. Usually you just want to bump the patch. + - [ ] Run `cargo build` to ensure `Cargo.lock` would be updated + - [ ] Commit changes `git commit -a -m 'Release x.y.z'`; include some useful brief changelog. + +- Prepare the release + - [ ] Run `./ci/prepare-release.sh` + +- Validate that `origin` points to the canonical upstream repository and not your fork: + `git remote show origin` should not be `github.com/$yourusername/$project` but should + be under the organization ownership. The remote `yourname` should be for your fork. + +- Push a PR to create the release: + - [ ] `git push --set-upstream origin release` + - [ ] open a web browser and create a PR for the branch above + - [ ] make sure the resulting PR contains the commit + - [ ] in the PR body, write a short changelog with relevant changes since last release + +- [ ] get the PR reviewed, approved and merged + +- publish the artifacts (tag and crate): + - [ ] `git fetch origin && git checkout ${RELEASE_COMMIT}` + - [ ] verify `Cargo.toml` has the expected version + - [ ] `git-evtag sign v${RELEASE_VER}` + - [ ] `git push --tags origin v${RELEASE_VER}` + - [ ] `cargo publish` + +- publish this release on GitHub: + - [ ] find the new tag in the [GitHub tag list](https://github.com/coreos/bootupd/tags) and click the triple dots menu, and create a release for it + - [ ] write a short changelog (i.e. re-use the PR content) + - [ ] upload `target/${PROJECT}-${RELEASE_VER}-vendor.tar.gz` + - [ ] record digests of local artifacts: + - `sha256sum target/package/${PROJECT}-${RELEASE_VER}.crate` + - `sha256sum target/${PROJECT}-${RELEASE_VER}-vendor.tar.gz` + - [ ] publish release + +- clean up: + - [ ] `git push origin :release` + - [ ] `cargo clean` + - [ ] `git checkout master` + +[rustup]: https://rustup.rs/ +[crates-io]: https://crates.io/ diff --git a/ci/prepare-release.sh b/ci/prepare-release.sh new file mode 100755 index 000000000..1a653cbc8 --- /dev/null +++ b/ci/prepare-release.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Prepare a release +set -euo pipefail +cargo publish --dry-run +name=$(cargo read-manifest | jq -r .name) +version=$(cargo read-manifest | jq -r .version) +commit=$(git rev-parse HEAD) + +# Generate a vendor tarball of sources to attach to a release +# in order to support offline builds. +vendor_dest=target/${name}-${version}-vendor.tar.gz +rm vendor ${vendor_dest} -rf +cargo vendor +# Trim off Windows pre-built libraries that make the vendor/ dir much larger +find vendor/ -name '*.a' -delete +tar czvf ${vendor_dest}.tmp vendor/ +rm vendor -rf +mv -Tf ${vendor_dest}{.tmp,} + +echo "Prepared ${version} at commit ${commit}" From e00de4a6b6bbd422b5328f486d856d9a44303088 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Nov 2020 20:47:27 +0000 Subject: [PATCH 140/641] Update all {F,RH}CoreOS systems that have an aleph version Came up in review in https://github.com/coreos/fedora-coreos-docs/pull/203 Basically it's confusing to users that they need to understand the difference between `update` and `adopt-and-update`. From bootupd's perspective these are quite different things; the first case is a completely known quantity, the second isn't. However...we can be pretty confident that we can update systems that have a CoreOS aleph version (i.e. they were generated by coreos-assembler), since we haven't changed how the bootloader is installed there really much at all. This means that for now RHCOS 4.{1,2} bootimages that were generated via Anaconda will still require `adopt-and-update`, but detecting and validating that can come as a second phase. The high level logic here is that the status gains a new `confident: bool` flag (which corresponds right now to "have CoreOS aleph"). The client side looks at this and automatically bridges the `update` CLI to `adopt-and-update`. Closes: https://github.com/coreos/bootupd/issues/103 --- src/bootupd.rs | 22 +++++++++++++++++++--- src/component.rs | 2 +- src/efi.rs | 9 ++++++--- src/model.rs | 12 +++++++++++- tests/e2e-adopt/e2e-adopt-in-vm.sh | 5 +++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 13a044245..f912d4397 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -243,8 +243,13 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { if status.adoptable.is_empty() { println!("No components are adoptable."); } - for (name, version) in status.adoptable.iter() { - println!("Adoptable: {}: {}", name, version.version); + for (name, adopt) in status.adoptable.iter() { + let ver = &adopt.version.version; + if adopt.confident { + println!("Detected: {}: {}", name, ver); + } else { + println!("Adoptable: {}: {}", name, ver); + } } if let Some(coreos_aleph) = coreos::get_aleph_version()? { @@ -266,7 +271,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { let status: Status = c.send(&ClientRequest::Status)?; - if status.components.is_empty() { + if status.components.is_empty() && status.adoptable.is_empty() { println!("No components installed."); return Ok(()); } @@ -303,6 +308,17 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result } updated = true; } + for (name, adoptable) in status.adoptable.iter() { + if adoptable.confident { + let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate { + component: name.to_string(), + })?; + println!("Adopted and updated: {}: {}", name, r.version); + updated = true; + } else { + println!("Component {} requires explicit adopt-and-update", name); + } + } if !updated { println!("No update available for any component."); } diff --git a/src/component.rs b/src/component.rs index 141a5cde4..089c9ad69 100644 --- a/src/component.rs +++ b/src/component.rs @@ -27,7 +27,7 @@ pub(crate) trait Component { /// In an operating system whose initially booted disk image is not /// using bootupd, detect whether it looks like the component exists /// and "synthesize" content metadata from it. - fn query_adopt(&self) -> Result>; + fn query_adopt(&self) -> Result>; /// Given an adoptable system and an update, perform the update. fn adopt_update(&self, update: &ContentMetadata) -> Result; diff --git a/src/efi.rs b/src/efi.rs index d0ce87963..007a4d55a 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -49,7 +49,7 @@ impl Component for EFI { "EFI" } - fn query_adopt(&self) -> Result> { + fn query_adopt(&self) -> Result> { let esp = self.open_esp_optional()?; if esp.is_none() { log::trace!("No ESP detected"); @@ -67,7 +67,10 @@ impl Component for EFI { version: coreos_aleph.aleph.imgid, }; log::trace!("EFI adoptable: {:?}", &meta); - Ok(Some(meta)) + Ok(Some(Adoptable { + version: meta, + confident: true, + })) } /// Given an adoptable system and an update, perform the update. @@ -90,7 +93,7 @@ impl Component for EFI { Ok(InstalledContent { meta: updatemeta.clone(), filetree: Some(updatef), - adopted_from: Some(meta), + adopted_from: Some(meta.version), }) } diff --git a/src/model.rs b/src/model.rs index eee23a7e6..89018d025 100644 --- a/src/model.rs +++ b/src/model.rs @@ -95,6 +95,16 @@ pub(crate) struct ComponentStatus { pub(crate) adopted_from: Option, } +/// Information on a component that can be adopted +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Adoptable { + /// A synthetic version + pub(crate) version: ContentMetadata, + /// True if we are likely to be able to reliably update this system + pub(crate) confident: bool, +} + /// Representation of bootupd's worldview at a point in time. /// This is intended to be a stable format that is output by `bootupctl status --json` /// and parsed by higher level management tools. Transitively then @@ -106,7 +116,7 @@ pub(crate) struct Status { /// Maps a component name to status pub(crate) components: BTreeMap, /// Components that appear to be installed, not via bootupd - pub(crate) adoptable: BTreeMap, + pub(crate) adoptable: BTreeMap, } #[cfg(test)] diff --git a/tests/e2e-adopt/e2e-adopt-in-vm.sh b/tests/e2e-adopt/e2e-adopt-in-vm.sh index f7f6c4dcf..9d90d4a93 100755 --- a/tests/e2e-adopt/e2e-adopt-in-vm.sh +++ b/tests/e2e-adopt/e2e-adopt-in-vm.sh @@ -96,7 +96,7 @@ fi bootupctl status | tee out.txt assert_file_has_content_literal out.txt 'No components installed.' -assert_file_has_content out.txt 'Adoptable: EFI: .*coreos.*-qemu.*' +assert_file_has_content out.txt 'Detected: EFI: .*coreos.*-qemu.*' bootupctl validate | tee out.txt assert_file_has_content_literal out.txt 'No components installed.' @@ -105,7 +105,8 @@ assert_not_file_has_content_literal out.txt "Validated" assert_not_has_file /boot/bootupd-state.json ok validate -bootupctl adopt-and-update | tee out.txt +# Explicitly testing https://github.com/coreos/bootupd/issues/103 +bootupctl update | tee out.txt assert_file_has_content out.txt 'Adopted and updated: EFI: grub2-efi-x64' ok adoption From 9873aaa8a0868b3a0efe3ea330cb3b7d8e9a25bb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 13 Nov 2020 18:26:23 +0000 Subject: [PATCH 141/641] tests: Add a serialization test for adoptable data Pointed out in code review in https://github.com/coreos/bootupd/pull/104 --- tests/fixtures/example-status-v0.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/fixtures/example-status-v0.json b/tests/fixtures/example-status-v0.json index 11af285e5..3df41595f 100644 --- a/tests/fixtures/example-status-v0.json +++ b/tests/fixtures/example-status-v0.json @@ -14,5 +14,13 @@ "adopted-from": null } }, - "adoptable": {} + "adoptable": { + "BIOS": { + "version": { + "version": "grub2-bios-42.x86_64", + "timestamp": "2020-09-15T13:01:21Z" + }, + "confident": true + } + } } From 7be8eb204c6c66f4e6688dc6827fe64710f19e71 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 13 Nov 2020 16:44:52 +0000 Subject: [PATCH 142/641] Add bootupctl status --print-if-available This is a middle ground between: 1) Parse arbitrary text output from `bootupctl status`; this could change at any time. 2) Parse JSON from `bootupctl status --json`; parsing this requires knowlege of bootupd and the JSON format still isn't 100% fixed in stone either. Projects like https://github.com/openshift/machine-config-operator/ will basically want a flow that just allows them to check for outstanding updates and apply them one node at a time. --- src/bootupd.rs | 18 ++++++++++++++++++ src/cli/bootupctl.rs | 8 ++++++++ tests/e2e-update/e2e-update-in-vm.sh | 8 ++++++++ 3 files changed, 34 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index f912d4397..cb690d392 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -214,6 +214,24 @@ pub(crate) fn status() -> Result { Ok(ret) } +pub(crate) fn print_status_avail(status: &Status) -> Result<()> { + let mut avail = Vec::new(); + for (name, component) in status.components.iter() { + if let ComponentUpdatable::Upgradable = component.updatable { + avail.push(name.as_str()); + } + } + for (name, adoptable) in status.adoptable.iter() { + if adoptable.confident { + avail.push(name.as_str()); + } + } + if !avail.is_empty() { + println!("Updates available: {}", avail.join(" ")); + } + Ok(()) +} + pub(crate) fn print_status(status: &Status) -> Result<()> { if status.components.is_empty() { println!("No components installed."); diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index fd05dfcff..66f4f747a 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -58,6 +58,12 @@ pub enum CtlBackend { #[derive(Debug, StructOpt)] pub struct StatusOpts { + // If there are updates available, output `Updates available: ` to standard output; + // otherwise output nothing. Avoid parsing this, just check whether or not + // the output is empty. + #[structopt(long)] + print_if_available: bool, + // Output JSON #[structopt(long)] json: bool, @@ -90,6 +96,8 @@ impl CtlCommand { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); serde_json::to_writer_pretty(&mut stdout, &r)?; + } else if opts.print_if_available { + bootupd::print_status_avail(&r)?; } else { bootupd::print_status(&r)?; } diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index b0cd38764..b2cb6b0cb 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -60,6 +60,8 @@ assert_not_file_has_content out.txt ' Installed:.*test-bootupd-payload' assert_not_file_has_content out.txt ' Installed:.*'"${TARGET_GRUB_PKG}" assert_file_has_content out.txt 'Update: Available:.*'"${TARGET_GRUB_PKG}" assert_file_has_content out.txt 'Update: Available:.*test-bootupd-payload-1.0' +bootupctl status --print-if-available > out.txt +assert_file_has_content_literal 'out.txt' 'Updates available: EFI' ok update avail assert_not_has_file /boot/efi/EFI/fedora/test-bootupd.efi @@ -69,6 +71,12 @@ assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd- assert_file_has_content /boot/efi/EFI/fedora/test-bootupd.efi test-payload +bootupctl status --print-if-available > out.txt +if test -s out.txt; then + fatal "Found available updates: $(cat out.txt)" +fi +ok update not avail + tap_finish touch /run/testtmp/success sync From 875a04a2fd34d5d9293c30ef1fabafa7f5798dbf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 16 Nov 2020 20:40:37 +0000 Subject: [PATCH 143/641] Release 0.2.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08a04a4d6..0752ba194 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.2" +version = "0.2.3" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 70b8b85ac..b2a884e4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.2" +version = "0.2.3" authors = ["Colin Walters "] edition = "2018" From 6e1c089ccfea1aa6b1651c5eced7bba4c4048811 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 17 Nov 2020 17:34:05 +0000 Subject: [PATCH 144/641] Pass sysroot through updates In order to fix https://github.com/coreos/bootupd/issues/108 we need to switch to not assuming `/` as the update source. We do provide the system root as a string in some cases but not all. Let's go fd-relative. --- src/backend/statefile.rs | 2 +- src/bootupd.rs | 7 +++---- src/component.rs | 16 ++++++++++++---- src/efi.rs | 11 ++++++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 513d4d160..68979c9e3 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -87,7 +87,7 @@ impl SavedState { /// Write-lock guard for statefile, protecting against concurrent state updates. #[derive(Debug)] pub(crate) struct StateLockGuard { - sysroot: openat::Dir, + pub(crate) sysroot: openat::Dir, lockfile: Option, } diff --git a/src/bootupd.rs b/src/bootupd.rs index cb690d392..324bd938d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -110,15 +110,14 @@ pub(crate) fn update(name: &str) -> Result { let mut pending_container = state.pending.take().unwrap_or_default(); let interrupted = pending_container.get(component.name()).cloned(); pending_container.insert(component.name().into(), update.clone()); - let sysroot = openat::Dir::open("/")?; - let mut state_guard = - SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; + let mut state_guard = SavedState::acquire_write_lock(openat::Dir::open("/")?) + .context("Failed to acquire write lock")?; state_guard .update_state(&state) .context("Failed to update state")?; let newinst = component - .run_update(&inst) + .run_update(&state_guard.sysroot, &inst) .with_context(|| format!("Failed to update {}", component.name()))?; state.installed.insert(component.name().into(), newinst); pending_container.remove(component.name()); diff --git a/src/component.rs b/src/component.rs index 089c9ad69..5fef488e1 100644 --- a/src/component.rs +++ b/src/component.rs @@ -52,7 +52,11 @@ pub(crate) trait Component { fn query_update(&self) -> Result>; /// Used on the client to run an update. - fn run_update(&self, current: &InstalledContent) -> Result; + fn run_update( + &self, + sysroot: &openat::Dir, + current: &InstalledContent, + ) -> Result; /// Used on the client to validate an installed version. fn validate(&self, current: &InstalledContent) -> Result; @@ -67,12 +71,16 @@ pub(crate) fn new_from_name(name: &str) -> Result> { Ok(r) } +/// Returns the path to the payload directory for an available update for +/// a component. +pub(crate) fn component_updatedirname(component: &dyn Component) -> PathBuf { + Path::new(BOOTUPD_UPDATES_DIR).join(component.name()) +} + /// Returns the path to the payload directory for an available update for /// a component. pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { - Path::new(sysroot) - .join(BOOTUPD_UPDATES_DIR) - .join(component.name()) + Path::new(sysroot).join(component_updatedirname(component)) } /// Returns the name of the JSON file containing a component's available update metadata installed diff --git a/src/efi.rs b/src/efi.rs index 007a4d55a..9ae31c8c6 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -128,14 +128,19 @@ impl Component for EFI { }) } - fn run_update(&self, current: &InstalledContent) -> Result { + fn run_update( + &self, + sysroot: &openat::Dir, + current: &InstalledContent, + ) -> Result { let currentf = current .filetree .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; let updatemeta = self.query_update()?.expect("update available"); - let updated = - openat::Dir::open(&component_updatedir("/", self)).context("opening update dir")?; + let updated = sysroot + .sub_dir(&component_updatedirname(self)) + .context("opening update dir")?; let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; let diff = currentf.diff(&updatef)?; let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI")) From 968b86c4854ee3e4fb1e8f54f0f63a1510c438f0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 17 Nov 2020 18:35:47 +0000 Subject: [PATCH 145/641] Thread sysroot through adopt+update flow More prep for https://github.com/coreos/bootupd/issues/108 Similar to the previous PR for updates. --- src/bootupd.rs | 8 ++++---- src/component.rs | 6 +++++- src/efi.rs | 11 ++++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 324bd938d..c9411c509 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -142,14 +142,14 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { } else { anyhow::bail!("Component {} has no available update", name); }; + let mut state_guard = SavedState::acquire_write_lock(openat::Dir::open("/")?) + .context("Failed to acquire write lock")?; + let inst = component - .adopt_update(&update) + .adopt_update(&state_guard.sysroot, &update) .context("Failed adopt and update")?; state.installed.insert(component.name().into(), inst); - let sysroot = openat::Dir::open("/")?; - let mut state_guard = - SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; state_guard.update_state(&state)?; Ok(update) } diff --git a/src/component.rs b/src/component.rs index 5fef488e1..2b056e9dd 100644 --- a/src/component.rs +++ b/src/component.rs @@ -30,7 +30,11 @@ pub(crate) trait Component { fn query_adopt(&self) -> Result>; /// Given an adoptable system and an update, perform the update. - fn adopt_update(&self, update: &ContentMetadata) -> Result; + fn adopt_update( + &self, + sysroot: &openat::Dir, + update: &ContentMetadata, + ) -> Result; /// Implementation of `bootupd install` for a given component. This should /// gather data (or run binaries) from the source root, and install them diff --git a/src/efi.rs b/src/efi.rs index 9ae31c8c6..9e0614b36 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -74,7 +74,11 @@ impl Component for EFI { } /// Given an adoptable system and an update, perform the update. - fn adopt_update(&self, updatemeta: &ContentMetadata) -> Result { + fn adopt_update( + &self, + sysroot: &openat::Dir, + updatemeta: &ContentMetadata, + ) -> Result { let meta = if let Some(meta) = self.query_adopt()? { meta } else { @@ -83,8 +87,9 @@ impl Component for EFI { let esp = self.open_esp()?; validate_esp(&esp)?; - let updated = - openat::Dir::open(&component_updatedir("/", self)).context("opening update dir")?; + let updated = sysroot + .sub_dir(&component_updatedirname(self)) + .context("opening update dir")?; let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; // For adoption, we should only touch files that we know about. let diff = updatef.relative_diff_to(&esp)?; From 9b407b452a3e0ae20d8169d8ae3c36c5bb0d7ad1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 18 Nov 2020 14:43:56 +0000 Subject: [PATCH 146/641] Thread sysroot through update query flow More incremental work on https://github.com/coreos/bootupd/issues/108 In some cases we're using both an absolute path and a dfd; fixing that gets involved because we need to use it for child processes too, which will require some more prep work. --- src/bootupd.rs | 17 ++++++++++------- src/component.rs | 5 ++--- src/efi.rs | 9 +++++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index c9411c509..fd7491551 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -101,7 +101,8 @@ pub(crate) fn update(name: &str) -> Result { } else { anyhow::bail!("Component {} is not installed", name); }; - let update = component.query_update()?; + let sysroot = openat::Dir::open("/")?; + let update = component.query_update(&sysroot)?; let update = match update.as_ref() { Some(p) if inst.meta.can_upgrade_to(&p) => p, _ => return Ok(ComponentUpdateResult::AtLatestVersion), @@ -110,8 +111,8 @@ pub(crate) fn update(name: &str) -> Result { let mut pending_container = state.pending.take().unwrap_or_default(); let interrupted = pending_container.get(component.name()).cloned(); pending_container.insert(component.name().into(), update.clone()); - let mut state_guard = SavedState::acquire_write_lock(openat::Dir::open("/")?) - .context("Failed to acquire write lock")?; + let mut state_guard = + SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; state_guard .update_state(&state) .context("Failed to update state")?; @@ -132,18 +133,19 @@ pub(crate) fn update(name: &str) -> Result { /// daemon implementation of component adoption pub(crate) fn adopt_and_update(name: &str) -> Result { + let sysroot = openat::Dir::open("/")?; let mut state = SavedState::load_from_disk("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; if state.installed.get(name).is_some() { anyhow::bail!("Component {} is already installed", name); }; - let update = if let Some(update) = component.query_update()? { + let update = if let Some(update) = component.query_update(&sysroot)? { update } else { anyhow::bail!("Component {} has no available update", name); }; - let mut state_guard = SavedState::acquire_write_lock(openat::Dir::open("/")?) - .context("Failed to acquire write lock")?; + let mut state_guard = + SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?; let inst = component .adopt_update(&state_guard.sysroot, &update) @@ -169,6 +171,7 @@ pub(crate) fn validate(name: &str) -> Result { pub(crate) fn status() -> Result { let mut ret: Status = Default::default(); let mut known_components = get_components(); + let sysroot = openat::Dir::open("/")?; let state = SavedState::load_from_disk("/")?; if let Some(state) = state { for (name, ic) in state.installed.iter() { @@ -182,7 +185,7 @@ pub(crate) fn status() -> Result { .as_ref() .map(|p| p.get(name.as_str())) .flatten(); - let update = component.query_update()?; + let update = component.query_update(&sysroot)?; let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); let adopted_from = ic.adopted_from.clone(); ret.components.insert( diff --git a/src/component.rs b/src/component.rs index 2b056e9dd..1e9c1f0e6 100644 --- a/src/component.rs +++ b/src/component.rs @@ -53,7 +53,7 @@ pub(crate) trait Component { fn generate_update_metadata(&self, sysroot: &str) -> Result; /// Used on the client to query for an update cached in the current booted OS. - fn query_update(&self) -> Result>; + fn query_update(&self, sysroot: &openat::Dir) -> Result>; /// Used on the client to run an update. fn run_update( @@ -110,10 +110,9 @@ pub(crate) fn write_update_metadata( /// Given a component, return metadata on the available update (if any) pub(crate) fn get_component_update( - sysroot: &str, + sysroot: &openat::Dir, component: &dyn Component, ) -> Result> { - let sysroot = openat::Dir::open(sysroot)?; let name = component_update_data_name(component); let path = Path::new(BOOTUPD_UPDATES_DIR).join(name); if let Some(f) = sysroot.open_file_optional(&path)? { diff --git a/src/efi.rs b/src/efi.rs index 9e0614b36..76be8f443 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -103,7 +103,8 @@ impl Component for EFI { } fn install(&self, src_root: &str, dest_root: &str) -> Result { - let meta = if let Some(meta) = get_component_update(src_root, self)? { + let src_rootd = openat::Dir::open(src_root)?; + let meta = if let Some(meta) = get_component_update(&src_rootd, self)? { meta } else { anyhow::bail!("No update metadata for component {} found", self.name()); @@ -142,7 +143,7 @@ impl Component for EFI { .filetree .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; - let updatemeta = self.query_update()?.expect("update available"); + let updatemeta = self.query_update(sysroot)?.expect("update available"); let updated = sysroot .sub_dir(&component_updatedirname(self)) .context("opening update dir")?; @@ -243,8 +244,8 @@ impl Component for EFI { Ok(meta) } - fn query_update(&self) -> Result> { - get_component_update("/", self) + fn query_update(&self, sysroot: &openat::Dir) -> Result> { + get_component_update(sysroot, self) } fn validate(&self, current: &InstalledContent) -> Result { From 605be598839620f168e21c0be8d01c0d4f0b6725 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 18 Nov 2020 19:46:17 +0000 Subject: [PATCH 147/641] status: Fix docstrings We need triple `///` to show in `bootupctl status --help`. --- src/cli/bootupctl.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 66f4f747a..fb67a377b 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -58,13 +58,13 @@ pub enum CtlBackend { #[derive(Debug, StructOpt)] pub struct StatusOpts { - // If there are updates available, output `Updates available: ` to standard output; - // otherwise output nothing. Avoid parsing this, just check whether or not - // the output is empty. + /// If there are updates available, output `Updates available: ` to standard output; + /// otherwise output nothing. Avoid parsing this, just check whether or not + /// the output is empty. #[structopt(long)] print_if_available: bool, - // Output JSON + /// Output JSON #[structopt(long)] json: bool, } From a4927ef92df05a06ae1dbc9aeccc2275fe1ee102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Nov 2020 06:47:06 +0000 Subject: [PATCH 148/641] build(deps): bump env_logger from 0.8.1 to 0.8.2 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.8.1 to 0.8.2. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/master/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.1...v0.8.2) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0752ba194..8240edd27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] name = "env_logger" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" +checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" dependencies = [ "atty", "humantime", From 0be1b276a99a3496135020562149109d7a710b31 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 18 Nov 2020 18:46:01 +0000 Subject: [PATCH 149/641] Thread sysroot through install flow More incremental work on https://github.com/coreos/bootupd/issues/108 --- src/bootupd.rs | 3 ++- src/component.rs | 2 +- src/efi.rs | 17 +++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index fd7491551..10432f09b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -23,6 +23,7 @@ pub(crate) enum ClientRequest { } pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { + let source_root = openat::Dir::open(source_root)?; SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; @@ -35,7 +36,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { let mut state = SavedState::default(); for component in components.values() { let meta = component - .install(source_root, dest_root) + .install(&source_root, dest_root) .with_context(|| format!("installing component {}", component.name()))?; state.installed.insert(component.name().into(), meta); } diff --git a/src/component.rs b/src/component.rs index 1e9c1f0e6..87ea0d5e5 100644 --- a/src/component.rs +++ b/src/component.rs @@ -43,7 +43,7 @@ pub(crate) trait Component { /// of a filesystem root, the component should query the mount point to /// determine the block device. /// This will be run during a disk image build process. - fn install(&self, src_root: &str, dest_root: &str) -> Result; + fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result; /// Implementation of `bootupd generate-update-metadata` for a given component. /// This expects to be run during an "image update build" process. For CoreOS diff --git a/src/efi.rs b/src/efi.rs index 76be8f443..77aabb05a 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -6,6 +6,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::io::prelude::*; +use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; use std::process::Command; @@ -102,27 +103,27 @@ impl Component for EFI { }) } - fn install(&self, src_root: &str, dest_root: &str) -> Result { - let src_rootd = openat::Dir::open(src_root)?; - let meta = if let Some(meta) = get_component_update(&src_rootd, self)? { + fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { + let meta = if let Some(meta) = get_component_update(&src_root, self)? { meta } else { anyhow::bail!("No update metadata for component {} found", self.name()); }; - let srcdir = component_updatedir(src_root, self); - let srcd = openat::Dir::open(&srcdir) - .with_context(|| format!("opening src dir {}", srcdir.display()))?; - let ft = crate::filetree::FileTree::new_from_dir(&srcd)?; + let srcdir_name = component_updatedirname(self); + let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; let destdir = Path::new(dest_root).join(MOUNT_PATH); { let destd = openat::Dir::open(&destdir) .with_context(|| format!("opening dest dir {}", destdir.display()))?; validate_esp(&destd)?; } + // TODO - add some sort of API that allows directly setting the working + // directory to a file descriptor. let r = std::process::Command::new("cp") .args(&["-rp", "--reflink=auto"]) - .arg(&srcdir) + .arg(&srcdir_name) .arg(&destdir) + .current_dir(format!("/proc/self/fd/{}", src_root.as_raw_fd())) .status()?; if !r.success() { anyhow::bail!("Failed to copy"); From b43cbae40b0857208ea81030ff8a0cbbb1d0b5cf Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Tue, 1 Dec 2020 14:38:32 -0500 Subject: [PATCH 150/641] Ensure mount points writable before updating The /boot and /boot/efi mount points may be read-only, so remount them as read-write if necessary when writing. --- src/bootupd.rs | 10 ++++++++++ src/efi.rs | 6 ++++++ src/util.rs | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index 10432f09b..24cca7df5 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -2,6 +2,7 @@ use crate::component::{Component, ValidationResult}; use crate::coreos; use crate::efi; use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; +use crate::util; use crate::{component, ipc}; use anyhow::{anyhow, Context, Result}; use serde::{Deserialize, Serialize}; @@ -93,6 +94,10 @@ pub(crate) enum ComponentUpdateResult { }, } +fn ensure_writable_boot() -> Result<()> { + util::ensure_writable_mount("/boot") +} + /// daemon implementation of component update pub(crate) fn update(name: &str) -> Result { let mut state = SavedState::load_from_disk("/")?.unwrap_or_default(); @@ -109,6 +114,8 @@ pub(crate) fn update(name: &str) -> Result { _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; + ensure_writable_boot()?; + let mut pending_container = state.pending.take().unwrap_or_default(); let interrupted = pending_container.get(component.name()).cloned(); pending_container.insert(component.name().into(), update.clone()); @@ -140,6 +147,9 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { if state.installed.get(name).is_some() { anyhow::bail!("Component {} is already installed", name); }; + + ensure_writable_boot()?; + let update = if let Some(update) = component.query_update(&sysroot)? { update } else { diff --git a/src/efi.rs b/src/efi.rs index 77aabb05a..423eac617 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -94,6 +94,7 @@ impl Component for EFI { let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; // For adoption, we should only touch files that we know about. let diff = updatef.relative_diff_to(&esp)?; + ensure_writable_efi()?; log::trace!("applying adoption diff: {}", &diff); filetree::apply_diff(&updated, &esp, &diff, None).context("applying filesystem changes")?; Ok(InstalledContent { @@ -153,6 +154,7 @@ impl Component for EFI { let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI")) .context("opening EFI dir")?; validate_esp(&destdir)?; + ensure_writable_efi()?; log::trace!("applying diff: {}", &diff); filetree::apply_diff(&updated, &destdir, &diff, None) .context("applying filesystem changes")?; @@ -280,3 +282,7 @@ fn validate_esp(dir: &openat::Dir) -> Result<()> { }; Ok(()) } + +fn ensure_writable_efi() -> Result<()> { + util::ensure_writable_mount(&Path::new("/").join(MOUNT_PATH)) +} diff --git a/src/util.rs b/src/util.rs index 5af899fa8..1b8a64e9a 100644 --- a/src/util.rs +++ b/src/util.rs @@ -3,6 +3,7 @@ use std::collections::HashSet; use anyhow::{bail, Result}; use openat_ext::OpenatDirExt; +use std::path::Path; use std::process::Command; pub(crate) trait CommandRunExt { @@ -65,3 +66,20 @@ pub(crate) fn filenames(dir: &openat::Dir) -> Result> { } Ok(ret) } + +pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { + use nix::sys::statvfs; + let p = p.as_ref(); + let stat = statvfs::statvfs(p)?; + if !stat.flags().contains(statvfs::FsFlags::ST_RDONLY) { + return Ok(()); + } + let status = std::process::Command::new("mount") + .args(&["-o", "remount,rw"]) + .arg(p) + .status()?; + if !status.success() { + anyhow::bail!("Failed to remount {:?} writable", p); + } + Ok(()) +} From b0b6cb607eaf6f106195a75b0f03ebfac20a31aa Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Tue, 1 Dec 2020 14:43:48 -0500 Subject: [PATCH 151/641] tests: Remount /boot and /boot/efi as rw In the future, FCOS' /boot and /boot/efi may be read-only. Remount them as read-write before attempting to write to those locations. --- tests/kola/test-bootupd | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ab8207876..ee0a65433 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,7 +19,9 @@ function cleanup () { fi } -bootefidir=/boot/efi/EFI +bootmount=/boot +bootefimount=${bootmount}/efi +bootefidir=${bootefimount}/EFI bootupdir=/usr/lib/bootupd/updates efiupdir=${bootupdir}/EFI ostbaseefi=/usr/lib/ostree-boot/efi/EFI @@ -115,6 +117,9 @@ bootupctl update | tee out.txt assert_file_has_content_literal out.txt 'No update available for any component' assert_not_file_has_content_literal out.txt 'Updated EFI' +# Ensure /boot and /boot/efi can be written to +mount -o remount,rw ${bootmount} +mount -o remount,rw ${bootefimount} echo "some additions" >> ${bootefidir}/${efisubdir}/shimx64.efi if bootupctl validate 2>err.txt; then fatal "unexpectedly passed validation" From ad4b90ed4c49c5dedec7cf9b09c6bbd752d28f10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Dec 2020 06:37:10 +0000 Subject: [PATCH 152/641] build(deps): bump serde_json from 1.0.59 to 1.0.60 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.59 to 1.0.60. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.59...v1.0.60) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8240edd27..ea431ef1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -608,9 +608,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" dependencies = [ "itoa", "ryu", From 8fa2832fc60910abf6c1d74529afe64eb12b3cb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Nov 2020 07:30:31 +0000 Subject: [PATCH 153/641] build(deps): bump nix from 0.19.0 to 0.19.1 Bumps [nix](https://github.com/nix-rust/nix) from 0.19.0 to 0.19.1. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.19.0...v0.19.1) Signed-off-by: dependabot[bot] --- Cargo.lock | 26 ++++++++++++++++---------- Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea431ef1b..cb86d9d5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,7 +92,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.19.0", + "nix 0.19.1", "openat", "openat-ext", "openssl", @@ -126,6 +126,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chrono" version = "0.4.19" @@ -248,7 +254,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -332,7 +338,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -349,7 +355,7 @@ checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 0.1.10", "libc", "void", ] @@ -362,19 +368,19 @@ checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 0.1.10", "libc", ] [[package]] name = "nix" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7" +checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", ] @@ -432,7 +438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 0.1.10", "foreign-types", "lazy_static", "libc", @@ -682,7 +688,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand", "redox_syscall", diff --git a/Cargo.toml b/Cargo.toml index b2a884e4e..ecbb6d7b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ hex = "0.4.2" libc = "^0.2" libsystemd = "^0.2" log = "^0.4" -nix = "0.19.0" +nix = "0.19.1" openat = "0.1.19" openat-ext = "^0.1.9" openssl = "^0.10" From 80aef46d81fec1ca5ba966857a7e1dd187daec92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Dec 2020 06:46:31 +0000 Subject: [PATCH 154/641] build(deps): bump structopt from 0.3.20 to 0.3.21 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.20 to 0.3.21. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.20...v0.3.21) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb86d9d5e..116643095 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -643,9 +643,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" +checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" dependencies = [ "clap", "lazy_static", @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" +checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" dependencies = [ "heck", "proc-macro-error", From cdef41b90a44ef6ed852a5f6a428550a9bafc1cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 07:46:12 +0000 Subject: [PATCH 155/641] build(deps): bump anyhow from 1.0.34 to 1.0.35 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.34 to 1.0.35. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.34...1.0.35) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 116643095..1b792b64a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" +checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" [[package]] name = "atty" From fe276cd1ad42429ee4f79a52c351b07d751abe45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 08:30:30 +0000 Subject: [PATCH 156/641] build(deps): bump libc from 0.2.80 to 0.2.81 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.80 to 0.2.81. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.80...0.2.81) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b792b64a..0add6f7a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -313,9 +313,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" [[package]] name = "libsystemd" From 1f2cba06991b69bc44361d4af60e9f8f11b5382e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 07:46:16 +0000 Subject: [PATCH 157/641] build(deps): bump serde from 1.0.117 to 1.0.118 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0add6f7a7..84dd1ac91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -594,18 +594,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" dependencies = [ "proc-macro2", "quote", From a9f134cf5103ca59b47cf9214751c4d7afbf3ef7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Dec 2020 06:36:23 +0000 Subject: [PATCH 158/641] build(deps): bump openssl from 0.10.30 to 0.10.31 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.30 to 0.10.31. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.30...openssl-v0.10.31) Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84dd1ac91..b00600db5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,12 +433,12 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.30" +version = "0.10.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" +checksum = "8d008f51b1acffa0d3450a68606e6a51c123012edaacb0f4e1426bd978869187" dependencies = [ "bitflags", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "foreign-types", "lazy_static", "libc", @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.58" +version = "0.9.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" +checksum = "de52d8eabd217311538a39bba130d7dea1f1e118010fee7a033d966845e7d5fe" dependencies = [ "autocfg", "cc", From 5a298e6550f06fd1bf82b1d727c84a8b5035569c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 15 Dec 2020 01:11:18 +0000 Subject: [PATCH 159/641] Release 0.2.4 Mainly internal cleanups, plus support for a read-only `/boot` and `/boot/efi`. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b00600db5..28d2516f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index ecbb6d7b0..0d6f619a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.3" +version = "0.2.4" authors = ["Colin Walters "] edition = "2018" From 6a20a238ea5521a4353ce7b8e5e5c5f8d011f0c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Dec 2020 07:32:12 +0000 Subject: [PATCH 160/641] build(deps): bump anyhow from 1.0.35 to 1.0.36 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.35 to 1.0.36. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.35...1.0.36) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28d2516f2..08318b6d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" +checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479" [[package]] name = "atty" From ff021b559879caee62075a35ddc285a1033acbd7 Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Mon, 21 Dec 2020 17:32:10 -0500 Subject: [PATCH 161/641] README-devel: Fix broken link and example command --- README-devel.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-devel.md b/README-devel.md index f197c290d..a885dd073 100644 --- a/README-devel.md +++ b/README-devel.md @@ -10,10 +10,10 @@ For real e2e testing, use e.g. ``` export COSA_DIR=/path/to/fcos cosa build-fast -kola run -E (pwd) --qemu-image fastbuild-fedora-coreos-bootupd-qemu.qcow2 --qemu-firmware uefi ext.bootupd +kola run -E $(pwd) --qemu-image fastbuild-fedora-coreos-bootupd-qemu.qcow2 --qemu-firmware uefi ext.bootupd.* ``` -See also [the coreos-assembler docs](https://github.com/coreos/coreos-assembler/blob/master/README-devel.md#using-overrides). +See also [the coreos-assembler docs](https://coreos.github.io/coreos-assembler/working/#using-overrides). ## Building With Containers From 7149cf3b5c89f4dcc34190ec123871baa30ed31a Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Thu, 24 Dec 2020 11:09:29 -0500 Subject: [PATCH 162/641] Ensure ESP is mounted Following https://github.com/coreos/fedora-coreos-config/pull/794, the ESP will no longer be mounted by default in FCOS. Mount the ESP at a directory with a random name in bootupd's sandboxed /tmp ourselves before reading from/writing to it. Note that ESPs on redundant disks is not yet supported, this commit simply mounts the device with part-label `EFI-SYSTEM` if one exists. `ProtectClock=yes` in `bootupd.service` is preventing the ESP from being mounted, remove that for now. --- Cargo.lock | 1 + Cargo.toml | 1 + src/efi.rs | 60 ++++++++++++++++++++++++++++++++--------- systemd/bootupd.service | 1 - 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08318b6d7..f64d725ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,7 @@ dependencies = [ "env_logger", "fs2", "hex", + "lazy_static", "libc", "libsystemd", "log", diff --git a/Cargo.toml b/Cargo.toml index 0d6f619a2..0ea90e31f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ clap = "~2.33" env_logger = "^0.8" fs2 = "0.4.3" hex = "0.4.2" +lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.2" log = "^0.4" diff --git a/src/efi.rs b/src/efi.rs index 423eac617..c37509c8c 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -14,6 +14,7 @@ use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; use chrono::prelude::*; +use lazy_static::lazy_static; use crate::component::*; use crate::filetree; @@ -22,27 +23,64 @@ use crate::ostreeutil; use crate::util; use crate::util::CommandRunExt; -/// The path to the ESP mount -pub(crate) const MOUNT_PATH: &str = "boot/efi"; +/// The ESP partition label +pub(crate) const ESP_PART_LABEL: &str = "EFI-SYSTEM"; + +#[macro_use] +lazy_static! { + /// The path to a temporary ESP mount + static ref MOUNT_PATH: PathBuf = { + // Create new directory in /tmp with randomly generated name at runtime for ESP mount path. + tempfile::tempdir_in("/tmp").expect("Failed to create temp dir for EFI mount").into_path() + }; +} #[derive(Default)] pub(crate) struct EFI {} impl EFI { fn esp_path(&self) -> PathBuf { - Path::new(MOUNT_PATH).join("EFI") + Path::new(&*MOUNT_PATH).join("EFI") + } + + fn esp_device(&self) -> PathBuf { + Path::new("/dev/disk/by-partlabel/").join(ESP_PART_LABEL) } fn open_esp_optional(&self) -> Result> { + self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; let esp = sysroot.sub_dir_optional(&self.esp_path())?; Ok(esp) } fn open_esp(&self) -> Result { + self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; let esp = sysroot.sub_dir(&self.esp_path())?; Ok(esp) } + + fn ensure_mounted_esp(&self) -> Result<()> { + let mount_point = &Path::new("/").join(&*MOUNT_PATH); + let output = std::process::Command::new("mountpoint") + .arg(mount_point) + .output()?; + if !output.status.success() { + let esp_device = &self.esp_device(); + if !esp_device.exists() { + log::error!("Single ESP device not found; ESP on multiple independent filesystems currently unsupported"); + anyhow::bail!("Could not find {:?}", esp_device); + } + let status = std::process::Command::new("mount") + .arg(&self.esp_device()) + .arg(mount_point) + .status()?; + if !status.success() { + anyhow::bail!("Failed to mount {:?}", esp_device); + } + }; + Ok(()) + } } impl Component for EFI { @@ -94,7 +132,6 @@ impl Component for EFI { let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; // For adoption, we should only touch files that we know about. let diff = updatef.relative_diff_to(&esp)?; - ensure_writable_efi()?; log::trace!("applying adoption diff: {}", &diff); filetree::apply_diff(&updated, &esp, &diff, None).context("applying filesystem changes")?; Ok(InstalledContent { @@ -112,7 +149,8 @@ impl Component for EFI { }; let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; - let destdir = Path::new(dest_root).join(MOUNT_PATH); + self.ensure_mounted_esp()?; + let destdir = Path::new(dest_root).join(&*MOUNT_PATH); { let destd = openat::Dir::open(&destdir) .with_context(|| format!("opening dest dir {}", destdir.display()))?; @@ -151,10 +189,9 @@ impl Component for EFI { .context("opening update dir")?; let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; let diff = currentf.diff(&updatef)?; - let destdir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI")) - .context("opening EFI dir")?; + self.ensure_mounted_esp()?; + let destdir = self.open_esp().context("opening EFI dir")?; validate_esp(&destdir)?; - ensure_writable_efi()?; log::trace!("applying diff: {}", &diff); filetree::apply_diff(&updated, &destdir, &diff, None) .context("applying filesystem changes")?; @@ -256,7 +293,8 @@ impl Component for EFI { .filetree .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; - let efidir = openat::Dir::open(&Path::new("/").join(MOUNT_PATH).join("EFI"))?; + self.ensure_mounted_esp()?; + let efidir = self.open_esp()?; let diff = currentf.relative_diff_to(&efidir)?; let mut errs = Vec::new(); for f in diff.changes.iter() { @@ -282,7 +320,3 @@ fn validate_esp(dir: &openat::Dir) -> Result<()> { }; Ok(()) } - -fn ensure_writable_efi() -> Result<()> { - util::ensure_writable_mount(&Path::new("/").join(MOUNT_PATH)) -} diff --git a/systemd/bootupd.service b/systemd/bootupd.service index 5a4d08aed..52735bfe0 100644 --- a/systemd/bootupd.service +++ b/systemd/bootupd.service @@ -19,7 +19,6 @@ ProtectHome=yes ReadOnlyPaths=/usr PrivateTmp=yes PrivateNetwork=yes -ProtectClock=yes ProtectHostname=yes ProtectControlGroups=yes RestrictSUIDSGID=yes From 402bc6ca6a84023a87c607e772861be52e168a5c Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Thu, 24 Dec 2020 11:16:16 -0500 Subject: [PATCH 163/641] tests: Mount ESP before operations Following https://github.com/coreos/fedora-coreos-config/pull/794, the ESP will no longer be mounted in /boot. Adjust tests to mount it before reading from it. --- tests/e2e-adopt/e2e-adopt-in-vm.sh | 7 +++++-- tests/e2e-update/e2e-update-in-vm.sh | 7 +++++-- tests/kola/data/libtest.sh | 8 ++++++++ tests/kola/test-bootupd | 18 ++++++++---------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/tests/e2e-adopt/e2e-adopt-in-vm.sh b/tests/e2e-adopt/e2e-adopt-in-vm.sh index 9d90d4a93..76cd800e1 100755 --- a/tests/e2e-adopt/e2e-adopt-in-vm.sh +++ b/tests/e2e-adopt/e2e-adopt-in-vm.sh @@ -80,10 +80,13 @@ if test "$semode" != Enforcing; then fatal "SELinux mode is ${semode}" fi -source_grub_cfg=$(find /boot/efi/EFI -name grub.cfg) +# Mount the EFI partition. +tmpefimount=$(mount_tmp_efi) + +source_grub_cfg=$(find ${tmpefimount}/EFI -name grub.cfg) test -f "${source_grub_cfg}" -source_grub=$(find /boot/efi/EFI -name grubx64.efi) +source_grub=$(find ${tmpefimount}/EFI -name grubx64.efi) test -f ${source_grub} source_grub_sha256=$(sha256sum ${source_grub} | cut -f 1 -d ' ') diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index b2cb6b0cb..ac3340a29 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -64,12 +64,15 @@ bootupctl status --print-if-available > out.txt assert_file_has_content_literal 'out.txt' 'Updates available: EFI' ok update avail -assert_not_has_file /boot/efi/EFI/fedora/test-bootupd.efi +# Mount the EFI partition. +tmpefimount=$(mount_tmp_efi) + +assert_not_has_file ${tmpefimount}/EFI/fedora/test-bootupd.efi bootupctl update | tee out.txt assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd-payload-1.0" -assert_file_has_content /boot/efi/EFI/fedora/test-bootupd.efi test-payload +assert_file_has_content ${tmpefimount}/EFI/fedora/test-bootupd.efi test-payload bootupctl status --print-if-available > out.txt if test -s out.txt; then diff --git a/tests/kola/data/libtest.sh b/tests/kola/data/libtest.sh index 91e61f35d..cc19f4613 100644 --- a/tests/kola/data/libtest.sh +++ b/tests/kola/data/libtest.sh @@ -81,3 +81,11 @@ assert_not_file_has_content_literal () { done } +# Mount the EFI partition at a temporary location. +efipart=/dev/disk/by-partlabel/EFI-SYSTEM +mount_tmp_efi () { + tmpmount=$(mktemp -d) + mkdir -p ${tmpmount} + mount ${efipart} ${tmpmount} + echo ${tmpmount} +} diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index ee0a65433..13fac40bc 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -19,9 +19,10 @@ function cleanup () { fi } +# Mount the EFI partition. +tmpefimount=$(mount_tmp_efi) bootmount=/boot -bootefimount=${bootmount}/efi -bootefidir=${bootefimount}/EFI +tmpefidir=${tmpefimount}/EFI bootupdir=/usr/lib/bootupd/updates efiupdir=${bootupdir}/EFI ostbaseefi=/usr/lib/ostree-boot/efi/EFI @@ -103,24 +104,21 @@ bootupctl validate | tee out.txt ok validate after update # FIXME see above -# assert_file_has_content ${bootefidir}/${efisubdir}/somenew.efi 'somenewfile' -if test -f ${bootefidir}/${efisubdir}/shim.efi; then +# assert_file_has_content ${tmpefidir}/${efisubdir}/somenew.efi 'somenewfile' +if test -f ${tmpefidir}/${efisubdir}/shim.efi; then fatal "failed to remove file" fi -if ! grep -q 'bootupd-test-changes' ${bootefidir}/${efisubdir}/grubx64.efi; then +if ! grep -q 'bootupd-test-changes' ${tmpefidir}/${efisubdir}/grubx64.efi; then fatal "failed to update modified file" fi -cmp ${bootefidir}/${efisubdir}/shimx64.efi ${efiupdir}/${efisubdir}/shimx64.efi +cmp ${tmpefidir}/${efisubdir}/shimx64.efi ${efiupdir}/${efisubdir}/shimx64.efi ok filesystem changes bootupctl update | tee out.txt assert_file_has_content_literal out.txt 'No update available for any component' assert_not_file_has_content_literal out.txt 'Updated EFI' -# Ensure /boot and /boot/efi can be written to -mount -o remount,rw ${bootmount} -mount -o remount,rw ${bootefimount} -echo "some additions" >> ${bootefidir}/${efisubdir}/shimx64.efi +echo "some additions" >> ${tmpefidir}/${efisubdir}/shimx64.efi if bootupctl validate 2>err.txt; then fatal "unexpectedly passed validation" fi From a970ad6f7a95bd8e25c07a2bfd0d0012e4c8e914 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 6 Jan 2021 01:25:22 +0000 Subject: [PATCH 164/641] Release 0.2.5 This adds support for having the ESP not be mounted by default, which we are going to do in Fedora CoreOS at least. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f64d725ba..4889af105 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.4" +version = "0.2.5" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 0ea90e31f..e64b89b5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.4" +version = "0.2.5" authors = ["Colin Walters "] edition = "2018" From 42cc0716641e33cf2f64e50779d99bc606e4eb10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 09:44:52 +0000 Subject: [PATCH 165/641] build(deps): bump openssl from 0.10.31 to 0.10.32 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.31 to 0.10.32. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.31...openssl-v0.10.32) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4889af105..3632b16b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,9 +434,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.31" +version = "0.10.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d008f51b1acffa0d3450a68606e6a51c123012edaacb0f4e1426bd978869187" +checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.59" +version = "0.9.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de52d8eabd217311538a39bba130d7dea1f1e118010fee7a033d966845e7d5fe" +checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" dependencies = [ "autocfg", "cc", From 51cc5d02125a8d430fa44b02b53b98fa8f208da8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 09:44:39 +0000 Subject: [PATCH 166/641] build(deps): bump serde_json from 1.0.60 to 1.0.61 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.60 to 1.0.61. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.60...v1.0.61) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3632b16b6..fcf3c6397 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -615,9 +615,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" dependencies = [ "itoa", "ryu", From 2ee1b9b3a31ed6109ced4355d55b147fb9d77d06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Jan 2021 06:25:24 +0000 Subject: [PATCH 167/641] build(deps): bump libc from 0.2.81 to 0.2.82 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.81 to 0.2.82. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.81...0.2.82) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcf3c6397..709cb052b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,9 +314,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.81" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" [[package]] name = "libsystemd" From 2ed206f46657eba3ace3d9448ec1eec5ef679f54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 09:34:27 +0000 Subject: [PATCH 168/641] build(deps): bump anyhow from 1.0.36 to 1.0.37 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.36 to 1.0.37. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.36...1.0.37) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 709cb052b..218872048 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479" +checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" [[package]] name = "atty" From f9b47eda945e0008344d0af856820b319e30d28c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 07:11:46 +0000 Subject: [PATCH 169/641] build(deps): bump anyhow from 1.0.37 to 1.0.38 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.37 to 1.0.38. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.37...1.0.38) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 218872048..f4deb0b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "atty" From 5daf5a2ac85122bf761d4686474ee45067bcce5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 06:28:32 +0000 Subject: [PATCH 170/641] build(deps): bump log from 0.4.11 to 0.4.13 Bumps [log](https://github.com/rust-lang/log) from 0.4.11 to 0.4.13. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.11...0.4.13) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4deb0b77..bff19b8ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,9 +335,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" dependencies = [ "cfg-if 0.1.10", ] From 5de4629965fb46babf06cd4ffd49ef040d7d7338 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 06:28:29 +0000 Subject: [PATCH 171/641] build(deps): bump serde from 1.0.118 to 1.0.119 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.118 to 1.0.119. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.118...v1.0.119) Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bff19b8ee..d9b9e7b14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,18 +595,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.118" +version = "1.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "552954ce79a059ddd5fd68c271592374bd15cab2274970380c000118aeffe1cd" dependencies = [ "proc-macro2", "quote", @@ -674,9 +674,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "syn" -version = "1.0.42" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" +checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" dependencies = [ "proc-macro2", "quote", From 7e8b6f952e628d39e98444796e74c75b1bf973af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 06:28:30 +0000 Subject: [PATCH 172/641] build(deps): bump tempfile from 3.1.0 to 3.2.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/Stebalien/tempfile/releases) - [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS) - [Commits](https://github.com/Stebalien/tempfile/commits) Signed-off-by: dependabot[bot] --- Cargo.lock | 82 ++++++++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 2 +- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9b9e7b14..3831e296a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,6 +260,17 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] +[[package]] +name = "getrandom" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", +] + [[package]] name = "heck" version = "0.3.1" @@ -429,7 +440,7 @@ dependencies = [ "libc", "nix 0.18.0", "openat", - "rand", + "rand 0.7.3", ] [[package]] @@ -519,11 +530,23 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.15", "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24fcd450d3fa2b592732565aa4f17a27a61c65ece4726353e000939b0edee34" +dependencies = [ + "libc", + "rand_chacha 0.3.0", + "rand_core 0.6.1", + "rand_hc 0.3.0", ] [[package]] @@ -533,7 +556,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.1", ] [[package]] @@ -542,7 +575,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.15", +] + +[[package]] +name = "rand_core" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" +dependencies = [ + "getrandom 0.2.1", ] [[package]] @@ -551,14 +593,26 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core 0.6.1", ] [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +dependencies = [ + "bitflags", +] [[package]] name = "regex" @@ -685,13 +739,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", - "rand", + "rand 0.8.1", "redox_syscall", "remove_dir_all", "winapi", diff --git a/Cargo.toml b/Cargo.toml index e64b89b5b..4e15fc03d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" structopt = "0.3" -tempfile = "^3.1" +tempfile = "^3.2" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo From fdc8f1d27f9211843adbbbe8906fa1e3eae193f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Jan 2021 07:38:33 +0000 Subject: [PATCH 173/641] build(deps): bump openat-ext from 0.1.9 to 0.1.10 Bumps [openat-ext](https://github.com/cgwalters/openat-ext) from 0.1.9 to 0.1.10. - [Release notes](https://github.com/cgwalters/openat-ext/releases) - [Commits](https://github.com/cgwalters/openat-ext/compare/v0.1.9...v0.1.10) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3831e296a..4ae22a628 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc1b204f9003fc6974231d2ed60e44206821e63c2cac1c8eccff0d2426e50f9" +checksum = "c7ac688336340b9ce22dd83e3b26d9d9063ceef5990679f75176b7e17f4e6a51" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index 4e15fc03d..eb8a36a95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.1" openat = "0.1.19" -openat-ext = "^0.1.9" +openat-ext = "^0.1.10" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From aa6d127c3a84a8bac08e14c665eed4772d667f73 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jan 2021 20:32:37 +0000 Subject: [PATCH 174/641] README.md: Add a question/answer section And discuss the relationship with ostree specifically around transactionality. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index c63f233f7..5e7940439 100644 --- a/README.md +++ b/README.md @@ -82,3 +82,33 @@ for the bootupd version associated with the payload, and ultimately we'd teach ` how to separately download bootloaders and pass them to `bootupctl backend`. [1]: https://github.com/coreos/rpm-ostree/pull/969/commits/dc0e8db5bd92e1f478a0763d1a02b48e57022b59 + + +## Questions and answers + +- Why is bootupd not part of ostree? + +This question is really covered at the top of this file already - hopefully +you read that already, but this answer will rephrase and try to go in more depth. + +A key advertised feature of ostree is that updates are truly transactional. +There's even a [a test case](https://blog.verbum.org/2020/12/01/committed-to-the-integrity-of-your-root-filesystem/) +that validates forcibly pulling the power during OS updates. A simple +way to look at this is that on an ostree-based system there is no need +to have a "please don't power off your computer" screen. This in turn +helps administrators to confidently enable automatic updates. + +Doing that for the bootloader (i.e. bootupd's domain) is an *entirely* separate problem. +There have been some ideas around how we could make the bootloaders +use an A/B type scheme (or at least be more resilient), and perhaps in the future bootupd will +use some of those. + +These updates hence carry different levels of risk. In many cases +actually it's OK if the bootloader lags behind; we don't need to update +every time. + +But out of conservatism currently today for e.g. Fedora CoreOS, bootupd is disabled +by default. On the other hand, if your OS update mechanism isn't transactional, +then you might as well enable bootupd by default too. + + From 4e371fce5a2ebb019c48ffa3355cc2538c2f9ed6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jan 2021 17:30:23 -0500 Subject: [PATCH 175/641] Update README.md Co-authored-by: Stephen Milner --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e7940439..c0b3d2bb5 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,5 @@ every time. But out of conservatism currently today for e.g. Fedora CoreOS, bootupd is disabled by default. On the other hand, if your OS update mechanism isn't transactional, -then you might as well enable bootupd by default too. - +then you may want to enable bootupd by default. From e8efb591e68fbb46aae20ab60eca84ba5cb8457a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Jan 2021 06:03:40 +0000 Subject: [PATCH 176/641] build(deps): bump serde from 1.0.119 to 1.0.120 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.119 to 1.0.120. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.119...v1.0.120) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ae22a628..2f578f9c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -649,18 +649,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.119" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3" +checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.119" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552954ce79a059ddd5fd68c271592374bd15cab2274970380c000118aeffe1cd" +checksum = "0ca2a8cb5805ce9e3b95435e3765b7b553cecc762d938d409434338386cb5775" dependencies = [ "proc-macro2", "quote", From 13f3dfab92768fb7edeaa19f17e01760efcfe863 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 07:16:47 +0000 Subject: [PATCH 177/641] build(deps): bump serde from 1.0.120 to 1.0.122 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.120 to 1.0.122. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.120...v1.0.122) Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f578f9c2..3b658a451 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -649,18 +649,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab" +checksum = "974ef1bd2ad8a507599b336595454081ff68a9599b4890af7643c0c0ed73a62c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca2a8cb5805ce9e3b95435e3765b7b553cecc762d938d409434338386cb5775" +checksum = "8dee1f300f838c8ac340ecb0112b3ac472464fa67e87292bdb3dfc9c49128e17" dependencies = [ "proc-macro2", "quote", @@ -728,9 +728,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "syn" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", From 2e8c88c0dc8ea232c4bc53e57eb333b9dd721db5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 07:16:52 +0000 Subject: [PATCH 178/641] build(deps): bump openat-ext from 0.1.10 to 0.1.11 Bumps [openat-ext](https://github.com/cgwalters/openat-ext) from 0.1.10 to 0.1.11. - [Release notes](https://github.com/cgwalters/openat-ext/releases) - [Commits](https://github.com/cgwalters/openat-ext/compare/v0.1.10...v0.1.11) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b658a451..fb13985b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ac688336340b9ce22dd83e3b26d9d9063ceef5990679f75176b7e17f4e6a51" +checksum = "5157ebc7a2da568f161a0d51d355b8520451fffb66c416617236f7c8dda733be" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index eb8a36a95..3aaa5c55c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.1" openat = "0.1.19" -openat-ext = "^0.1.10" +openat-ext = "^0.1.11" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 2c1d2f83de0cf90be1ccae53c3f43a92efc408b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Jan 2021 06:24:25 +0000 Subject: [PATCH 179/641] build(deps): bump serde from 1.0.122 to 1.0.123 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.122 to 1.0.123. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.122...v1.0.123) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb13985b3..a97b81d03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -649,18 +649,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.122" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974ef1bd2ad8a507599b336595454081ff68a9599b4890af7643c0c0ed73a62c" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.122" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dee1f300f838c8ac340ecb0112b3ac472464fa67e87292bdb3dfc9c49128e17" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ "proc-macro2", "quote", From 9d27443f642311c080a54fe38294ed613c5c104b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Jan 2021 06:25:03 +0000 Subject: [PATCH 180/641] build(deps): bump log from 0.4.13 to 0.4.14 Bumps [log](https://github.com/rust-lang/log) from 0.4.13 to 0.4.14. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.13...0.4.14) Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a97b81d03..98b3419ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -346,11 +346,11 @@ dependencies = [ [[package]] name = "log" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] From 6838b6e3263eabb90df6c54269f182fa37489d2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 06:23:29 +0000 Subject: [PATCH 181/641] build(deps): bump libc from 0.2.82 to 0.2.83 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.82 to 0.2.83. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.82...0.2.83) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98b3419ae..bdb87af61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "7eb0c4e9c72ee9d69b767adebc5f4788462a3b45624acd919475c92597bcaf4f" [[package]] name = "libsystemd" From aa6290a16750a7a25b69e1273dea3aeed88ba47f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Jan 2021 06:15:19 +0000 Subject: [PATCH 182/641] build(deps): bump libc from 0.2.83 to 0.2.84 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.83 to 0.2.84. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/commits) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdb87af61..8abaf1b7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0c4e9c72ee9d69b767adebc5f4788462a3b45624acd919475c92597bcaf4f" +checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" [[package]] name = "libsystemd" From 3c01ae135d6f50209b001541a3888bd43d261deb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 06:14:27 +0000 Subject: [PATCH 183/641] build(deps): bump libc from 0.2.84 to 0.2.85 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.84 to 0.2.85. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.84...0.2.85) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8abaf1b7f..c4a1931cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" +checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" [[package]] name = "libsystemd" From 3ab8339e11d781e75df3be8c54ad610ee9078a42 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 26 Jan 2021 10:17:53 +0000 Subject: [PATCH 184/641] filetree: minor cleanup, use copy_file_at This updates file copying to use the newer `copy_file_at` from openat-ext. --- src/filetree.rs | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 886953209..2ac89a8e8 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -10,7 +10,6 @@ use openssl::hash::{Hasher, MessageDigest}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Display; -use std::os::linux::fs::MetadataExt; use std::os::unix::io::AsRawFd; use std::os::unix::process::CommandExt; use std::path::Path; @@ -252,22 +251,6 @@ pub(crate) struct ApplyUpdateOptions { pub(crate) skip_sync: bool, } -/// A bit like std::fs::copy but operates dirfd-relative -fn copy_file_at, DP: AsRef>( - srcdir: &openat::Dir, - destdir: &openat::Dir, - srcp: SP, - destp: DP, -) -> Result<()> { - use openat_ext::FileExt as OpenatFileExt; - let srcp = srcp.as_ref(); - let srcf = srcdir.open_file(srcp)?; - let destf = destdir.write_file(destp.as_ref(), srcf.metadata()?.st_mode())?; - srcf.copy_to(&destf)?; - - Ok(()) -} - // syncfs() is a Linux-specific system call, which doesn't seem // to be bound in nix today. I found https://github.com/XuShaohua/nc // but that's a nontrivial dependency with not a lot of code review. @@ -316,7 +299,8 @@ pub(crate) fn apply_diff( destdir.ensure_dir_all(parent, DEFAULT_FILE_MODE)?; } let destp = tmpname_for_path(path); - copy_file_at(srcdir, destdir, path, destp.as_path()) + srcdir + .copy_file_at(path, destdir, destp.as_path()) .with_context(|| format!("writing {}", &pathstr))?; } // Ensure all of the new files are written persistently to disk From 16fdb335d4a052b1695cc8429f79d03dbb8360b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Feb 2021 06:09:56 +0000 Subject: [PATCH 185/641] build(deps): bump libc from 0.2.85 to 0.2.86 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.85 to 0.2.86. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.85...0.2.86) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4a1931cd..d71253bfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" [[package]] name = "libsystemd" From cb0bebfb0547fe97aac2249c706b88a10c2c7082 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Feb 2021 07:11:43 +0000 Subject: [PATCH 186/641] build(deps): bump openat-ext from 0.1.11 to 0.1.12 Bumps [openat-ext](https://github.com/cgwalters/openat-ext) from 0.1.11 to 0.1.12. - [Release notes](https://github.com/cgwalters/openat-ext/releases) - [Commits](https://github.com/cgwalters/openat-ext/compare/v0.1.11...v0.1.12) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d71253bfe..03c7e84a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5157ebc7a2da568f161a0d51d355b8520451fffb66c416617236f7c8dda733be" +checksum = "280cd85c8b57d226f3c3ed667b098d754e5afd3d2834a19b81198b8ba46c85c4" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index 3aaa5c55c..b39e51814 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.19.1" openat = "0.1.19" -openat-ext = "^0.1.11" +openat-ext = "^0.1.12" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 5651db871ffa3a76849a3559bd9b5bc8003f3b29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Feb 2021 09:03:38 +0000 Subject: [PATCH 187/641] build(deps): bump nix from 0.19.1 to 0.20.0 Bumps [nix](https://github.com/nix-rust/nix) from 0.19.1 to 0.20.0. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/commits) Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03c7e84a9..2d0ebe0f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,7 +93,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.19.1", + "nix 0.20.0", "openat", "openat-ext", "openssl", @@ -386,9 +386,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.19.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", diff --git a/Cargo.toml b/Cargo.toml index b39e51814..12e23e6aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.2" log = "^0.4" -nix = "0.19.1" +nix = "0.20.0" openat = "0.1.19" openat-ext = "^0.1.12" openssl = "^0.10" From 8df3a30dbf5067d2daedcc2d9a98d205bec58500 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Feb 2021 06:09:27 +0000 Subject: [PATCH 188/641] build(deps): bump bincode from 1.3.1 to 1.3.2 Bumps [bincode](https://github.com/servo/bincode) from 1.3.1 to 1.3.2. - [Release notes](https://github.com/servo/bincode/releases) - [Commits](https://github.com/servo/bincode/compare/v1.3.1...v1.3.2) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d0ebe0f4..65436e13b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bincode" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" dependencies = [ "byteorder", "serde", diff --git a/Cargo.toml b/Cargo.toml index 12e23e6aa..9383d16a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" -bincode = "1.3.1" +bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" env_logger = "^0.8" From 9d2345899100f8c7802e3257bd17c60a143f3f24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Mar 2021 07:43:43 +0000 Subject: [PATCH 189/641] build(deps): bump serde_json from 1.0.61 to 1.0.64 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.61 to 1.0.64. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.61...v1.0.64) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65436e13b..de3fbee8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -669,9 +669,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", From 8ba9a27f25c90b9ff9064c8c2d9900ad3515fc2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Feb 2021 08:25:57 +0000 Subject: [PATCH 190/641] build(deps): bump env_logger from 0.8.2 to 0.8.3 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.8.2 to 0.8.3. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/master/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.2...v0.8.3) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de3fbee8a..5efc1848c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,9 +189,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] name = "env_logger" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" +checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" dependencies = [ "atty", "humantime", From 55c9729ff11334e001be50d5f9e66d7c8e116c8c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 3 Feb 2021 19:33:11 +0000 Subject: [PATCH 191/641] doc: Add license_finder permitted licenses https://lists.fedoraproject.org/archives/list/rust@lists.fedoraproject.org/thread/UE4FU27OAHXQ2EOV5OFSXGHELUWZYSJM/ discusses license compliance as something a downstream distribution should be doing. Yes. But also, this is something that *upstreams* should be doing as part of their CI. Looking around I found https://github.com/pivotal/LicenseFinder which looks decent; it handles multiple languages, has a container image, is FOSS itself etc. I ran through it for bootupd and this lists the approvals. The next step here is to validate this in CI. --- doc/dependency_decisions.yml | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 doc/dependency_decisions.yml diff --git a/doc/dependency_decisions.yml b/doc/dependency_decisions.yml new file mode 100644 index 000000000..7da6010a2 --- /dev/null +++ b/doc/dependency_decisions.yml @@ -0,0 +1,37 @@ +--- +- - :permit + - MIT OR Apache-2.0 + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:31:28.263225624 Z +- - :permit + - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:31:42.436851761 Z +- - :permit + - MIT + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:31:54.278056841 Z +- - :permit + - Apache 2.0 + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:32:08.538863728 Z +- - :permit + - Apache-2.0 OR BSL-1.0 + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:32:17.034417362 Z +- - :permit + - New BSD + - :who: + :why: + :versions: [] + :when: 2021-02-03 19:33:02.120977990 Z From 4da736e70442ae60567d5818060d085dcdb67bbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Mar 2021 05:56:06 +0000 Subject: [PATCH 192/641] build(deps): bump libc from 0.2.86 to 0.2.87 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.86 to 0.2.87. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.86...0.2.87) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5efc1848c..0e9faf5d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" [[package]] name = "libsystemd" From e85114de2efb9a1728ebc55be493ae8088785d16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Mar 2021 06:06:20 +0000 Subject: [PATCH 193/641] build(deps): bump hex from 0.4.2 to 0.4.3 Bumps [hex](https://github.com/KokaKiwi/rust-hex) from 0.4.2 to 0.4.3. - [Release notes](https://github.com/KokaKiwi/rust-hex/releases) - [Commits](https://github.com/KokaKiwi/rust-hex/compare/v0.4.2...v0.4.3) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e9faf5d4..bfcc0d7ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "hex" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" diff --git a/Cargo.toml b/Cargo.toml index 9383d16a1..350784231 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" env_logger = "^0.8" fs2 = "0.4.3" -hex = "0.4.2" +hex = "0.4.3" lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.2" From 493f5155914fae63b1c69611d5e22d0c5146a853 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Mar 2021 07:17:09 +0000 Subject: [PATCH 194/641] build(deps): bump openat-ext from 0.1.12 to 0.1.13 Bumps [openat-ext](https://github.com/cgwalters/openat-ext) from 0.1.12 to 0.1.13. - [Release notes](https://github.com/cgwalters/openat-ext/releases) - [Commits](https://github.com/cgwalters/openat-ext/commits) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfcc0d7ba..8519eefd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280cd85c8b57d226f3c3ed667b098d754e5afd3d2834a19b81198b8ba46c85c4" +checksum = "b4c55e17c28995df7ff51cc9b2a9a4e548dde9ffa46efdd2750d22fe4ac64499" dependencies = [ "drop_bomb", "libc", diff --git a/Cargo.toml b/Cargo.toml index 350784231..b1420a9fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.20.0" openat = "0.1.19" -openat-ext = "^0.1.12" +openat-ext = "^0.1.13" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 70a0effa2d2bf5dc22f20984915c5d6426b9d652 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 9 Mar 2021 17:48:29 +0000 Subject: [PATCH 195/641] ci: Add Prow-oriented CI flow This is copied/adapted from rpm-ostree. I'm mainly doing this to prove out adding another GH repo using the nested virt support. As part of this, add the "standard" `tests/kolainst` directory that just copies in our un-installed tests. --- .gitignore | 1 + ci/prow/Dockerfile | 19 +++++++++++++++++++ ci/prow/fcos-e2e.sh | 11 +++++++++++ tests/kolainst/Makefile | 6 ++++++ 4 files changed, 37 insertions(+) create mode 100644 ci/prow/Dockerfile create mode 100755 ci/prow/fcos-e2e.sh create mode 100644 tests/kolainst/Makefile diff --git a/.gitignore b/.gitignore index 693b85c69..71c8efb41 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target fastbuild*.qcow2 _kola_temp +.cosa diff --git a/ci/prow/Dockerfile b/ci/prow/Dockerfile new file mode 100644 index 000000000..1c9baaa62 --- /dev/null +++ b/ci/prow/Dockerfile @@ -0,0 +1,19 @@ +FROM registry.ci.openshift.org/coreos/cosa-buildroot:latest as builder +WORKDIR /src +COPY . . +RUN make && make install DESTDIR=/cosa/component-install +RUN make -C tests/kolainst install DESTDIR=/cosa/component-tests +# Uncomment this to fake a build to test the code below +# RUN mkdir -p /cosa/component-install/usr/bin && echo foo > /cosa/component-install/usr/bin/foo + +FROM registry.ci.openshift.org/coreos/coreos-assembler:latest +WORKDIR /srv +USER root +# Install our built binaries as overrides for the target build +COPY --from=builder /cosa/component-install/ /srv/overrides/rootfs/ +# Copy and install tests too +COPY --from=builder /cosa/component-tests /srv/tmp/component-tests +# Install tests +RUN rsync -rlv /srv/tmp/component-tests/ / && rm -rf /srv/tmp/component-tests +COPY --from=builder /src/ci/prow/fcos-e2e.sh /usr/bin/fcos-e2e +USER builder diff --git a/ci/prow/fcos-e2e.sh b/ci/prow/fcos-e2e.sh new file mode 100755 index 000000000..258acf0f3 --- /dev/null +++ b/ci/prow/fcos-e2e.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -xeuo pipefail + +# Prow jobs don't support adding emptydir today +export COSA_SKIP_OVERLAY=1 +gitdir=$(pwd) +cd $(mktemp -d) +cosa init --force https://github.com/coreos/fedora-coreos-config/ +cosa fetch +cosa build +cosa kola run --qemu-firmware uefi 'ext.bootupd.*' diff --git a/tests/kolainst/Makefile b/tests/kolainst/Makefile new file mode 100644 index 000000000..1b74efc88 --- /dev/null +++ b/tests/kolainst/Makefile @@ -0,0 +1,6 @@ +all: + echo "No build step" + +install: + mkdir -p $(DESTDIR)/usr/lib/coreos-assembler/tests/kola/ + rsync -rlv ../kola $(DESTDIR)/usr/lib/coreos-assembler/tests/kola/bootupd From 9a728b3a67638747a3ae6b7f598bba0d1ec3a397 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 8 Mar 2021 18:50:02 +0000 Subject: [PATCH 196/641] Add and use fn-error-context for more reliable error traces Effectively what we're doing here is creating a human-readable subset of the stack trace. This is nicer than having the calling functions add `with_context()` because it's more verbose (gets duplicative at each call site), easy to forget, etc. --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 1 + src/backend/statefile.rs | 2 ++ src/component.rs | 2 ++ src/ipc.rs | 5 +++-- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8519eefd5..e76834299 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,7 @@ dependencies = [ "chrono", "clap", "env_logger", + "fn-error-context", "fs2", "hex", "lazy_static", @@ -215,6 +216,17 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fn-error-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0b92c51c8b8183a0c101a7b2ea5fac11d2f1e01057f91e390284c75d76ef44" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "foreign-types" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index b1420a9fc..942ca7832 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" env_logger = "^0.8" +fn-error-context = "0.1.1" fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index 68979c9e3..bc903eb63 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -2,6 +2,7 @@ use crate::model::SavedState; use anyhow::{bail, Context, Result}; +use fn_error_context::context; use fs2::FileExt; use openat_ext::OpenatDirExt; use std::fs::File; @@ -41,6 +42,7 @@ impl SavedState { } /// Load the JSON file containing on-disk state. + #[context("Loading saved state")] pub(crate) fn load_from_disk(root_path: impl AsRef) -> Result> { let root_path = root_path.as_ref(); let sysroot = openat::Dir::open(root_path) diff --git a/src/component.rs b/src/component.rs index 87ea0d5e5..99f302244 100644 --- a/src/component.rs +++ b/src/component.rs @@ -5,6 +5,7 @@ */ use anyhow::{Context, Result}; +use fn_error_context::context; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; @@ -109,6 +110,7 @@ pub(crate) fn write_update_metadata( } /// Given a component, return metadata on the available update (if any) +#[context("Loading update for component {}", component.name())] pub(crate) fn get_component_update( sysroot: &openat::Dir, component: &dyn Component, diff --git a/src/ipc.rs b/src/ipc.rs index 5ba955261..524d9039b 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -5,6 +5,7 @@ */ use anyhow::{bail, Context, Result}; +use fn_error_context::context; use nix::sys::socket as nixsocket; use serde::{Deserialize, Serialize}; use std::os::unix::io::RawFd; @@ -37,6 +38,7 @@ impl ClientToDaemonConnection { Self { fd: -1 } } + #[context("connecting to {}", BOOTUPD_SOCKET)] pub(crate) fn connect(&mut self) -> Result<()> { use nix::sys::uio::IoVec; self.fd = nixsocket::socket( @@ -46,8 +48,7 @@ impl ClientToDaemonConnection { None, )?; let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; - nixsocket::connect(self.fd, &addr) - .with_context(|| format!("connecting to {}", BOOTUPD_SOCKET))?; + nixsocket::connect(self.fd, &addr)?; let creds = libc::ucred { pid: nix::unistd::getpid().as_raw(), uid: nix::unistd::getuid().as_raw(), From a857ee6db1bb44356afc0286d084050fdd87c369 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Mar 2021 18:51:05 +0000 Subject: [PATCH 197/641] build(deps): bump serde from 1.0.123 to 1.0.124 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124) Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e76834299..5efe15122 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,18 +661,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.123" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" dependencies = [ "proc-macro2", "quote", From 5ee548c2fde7daec4ba186838a92952c72667199 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 9 Mar 2021 20:13:07 +0000 Subject: [PATCH 198/641] prow: Fix overrides Not actually testing what you think you are is the worst. --- .dockerignore | 2 ++ ci/prow/Dockerfile | 6 ++++-- ci/prow/fcos-e2e.sh | 2 -- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..a0dbd07ba --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +target +.cosa diff --git a/ci/prow/Dockerfile b/ci/prow/Dockerfile index 1c9baaa62..64c2036c0 100644 --- a/ci/prow/Dockerfile +++ b/ci/prow/Dockerfile @@ -8,12 +8,14 @@ RUN make -C tests/kolainst install DESTDIR=/cosa/component-tests FROM registry.ci.openshift.org/coreos/coreos-assembler:latest WORKDIR /srv -USER root # Install our built binaries as overrides for the target build COPY --from=builder /cosa/component-install/ /srv/overrides/rootfs/ # Copy and install tests too COPY --from=builder /cosa/component-tests /srv/tmp/component-tests +# And fix permissions +RUN sudo chown -R builder: /srv/* # Install tests +USER root RUN rsync -rlv /srv/tmp/component-tests/ / && rm -rf /srv/tmp/component-tests -COPY --from=builder /src/ci/prow/fcos-e2e.sh /usr/bin/fcos-e2e USER builder +COPY --from=builder /src/ci/prow/fcos-e2e.sh /usr/bin/fcos-e2e diff --git a/ci/prow/fcos-e2e.sh b/ci/prow/fcos-e2e.sh index 258acf0f3..83618464b 100755 --- a/ci/prow/fcos-e2e.sh +++ b/ci/prow/fcos-e2e.sh @@ -3,8 +3,6 @@ set -xeuo pipefail # Prow jobs don't support adding emptydir today export COSA_SKIP_OVERLAY=1 -gitdir=$(pwd) -cd $(mktemp -d) cosa init --force https://github.com/coreos/fedora-coreos-config/ cosa fetch cosa build From f7f15ee605f85bc444eb1c50925b63cbe28e9c9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Mar 2021 20:15:29 +0000 Subject: [PATCH 199/641] build(deps): bump libc from 0.2.87 to 0.2.88 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.87 to 0.2.88. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.87...0.2.88) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5efe15122..1257f07a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,9 +337,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" +checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" [[package]] name = "libsystemd" From 7a2c856879cffe1639857bac02e8730a51a259c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 07:27:59 +0000 Subject: [PATCH 200/641] build(deps): bump openssl from 0.10.32 to 0.10.33 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.32 to 0.10.33. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.32...openssl-v0.10.33) Signed-off-by: dependabot[bot] --- Cargo.lock | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1257f07a1..828365f5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,6 +427,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + [[package]] name = "opaque-debug" version = "0.2.3" @@ -457,23 +463,23 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.32" +version = "0.10.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" +checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577" dependencies = [ "bitflags", "cfg-if 1.0.0", "foreign-types", - "lazy_static", "libc", + "once_cell", "openssl-sys", ] [[package]] name = "openssl-sys" -version = "0.9.60" +version = "0.9.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" +checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" dependencies = [ "autocfg", "cc", From 8759ca901240648d98488121a7c8bcb21b496b25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Mar 2021 06:06:05 +0000 Subject: [PATCH 201/641] build(deps): bump libc from 0.2.88 to 0.2.89 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.88 to 0.2.89. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.88...0.2.89) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 828365f5d..e17247bae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,9 +337,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" [[package]] name = "libsystemd" From 8207e95e344afa3a97f34bbfcf5dc47274884c22 Mon Sep 17 00:00:00 2001 From: Kelvin Fan Date: Wed, 17 Mar 2021 13:15:05 -0400 Subject: [PATCH 202/641] github/release-checklist: misc updates Minor misc updates to make the checklist slightly easier to follow for first-timers. Note the requirement to be in the Fedora CoreOS Crates Owners group on Github. The changes here originated from https://github.com/coreos/zincati/pull/488; since the bootupd checklist is slightly tweaked, not all changes were carried over here, only the relevant parts of the diff were included. --- .github/ISSUE_TEMPLATE/release-checklist.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index d36352427..ce4577511 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -8,14 +8,15 @@ In order to ease downstream packaging of Rust binaries, an archive of vendored d This guide requires: - * a web browser (and network connectivity) + * A web browser (and network connectivity) * `git` - * GPG setup and personal key for signing + * [GPG setup][GPG setup] and personal key for signing * [git-evtag](https://github.com/cgwalters/git-evtag/) * `cargo` (suggested: latest stable toolchain from [rustup][rustup]) * A verified account on crates.io * Write access to this GitHub project * Upload access to this project on GitHub, crates.io + * Membership in the [Fedora CoreOS Crates Owners group](https://github.com/orgs/coreos/teams/fedora-coreos-crates-owners/members) ## Release checklist @@ -32,13 +33,12 @@ This guide requires: `git remote show origin` should not be `github.com/$yourusername/$project` but should be under the organization ownership. The remote `yourname` should be for your fork. -- Push a PR to create the release: +- open and merge a PR for this release: - [ ] `git push --set-upstream origin release` - [ ] open a web browser and create a PR for the branch above - [ ] make sure the resulting PR contains the commit - [ ] in the PR body, write a short changelog with relevant changes since last release - -- [ ] get the PR reviewed, approved and merged + - [ ] get the PR reviewed, approved and merged - publish the artifacts (tag and crate): - [ ] `git fetch origin && git checkout ${RELEASE_COMMIT}` @@ -48,7 +48,7 @@ This guide requires: - [ ] `cargo publish` - publish this release on GitHub: - - [ ] find the new tag in the [GitHub tag list](https://github.com/coreos/bootupd/tags) and click the triple dots menu, and create a release for it + - [ ] find the new tag in the [GitHub tag list](https://github.com/coreos/bootupd/tags), click the triple dots menu, and create a release for it - [ ] write a short changelog (i.e. re-use the PR content) - [ ] upload `target/${PROJECT}-${RELEASE_VER}-vendor.tar.gz` - [ ] record digests of local artifacts: @@ -63,3 +63,4 @@ This guide requires: [rustup]: https://rustup.rs/ [crates-io]: https://crates.io/ +[GPG setup]: https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification From 1630311f3ccfc4718a3ba6dc4cd1a37edce667c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Mar 2021 23:33:45 +0000 Subject: [PATCH 203/641] build(deps): bump openat from 0.1.19 to 0.1.20 Bumps [openat](https://github.com/tailhook/openat) from 0.1.19 to 0.1.20. - [Release notes](https://github.com/tailhook/openat/releases) - [Commits](https://github.com/tailhook/openat/compare/v0.1.19...v0.1.20) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e17247bae..174d96b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,9 +441,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openat" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eff876e3964841fd6067ecf1d040e0315879c1a1cce2a0f162828e82f04d1ce" +checksum = "97cdc0668b258e022a16a9c71a77f69b73e8d32b6f20bb3082b623f6396438b8" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 942ca7832..e1aaaafc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libc = "^0.2" libsystemd = "^0.2" log = "^0.4" nix = "0.20.0" -openat = "0.1.19" +openat = "0.1.20" openat-ext = "^0.1.13" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } From f9ad9c5176a2debb70c0707db4c3b49906ba5a89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:26:32 +0000 Subject: [PATCH 204/641] build(deps): bump anyhow from 1.0.38 to 1.0.39 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.38 to 1.0.39. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.38...1.0.39) Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e17247bae..5762e33bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" [[package]] name = "atty" From 63c6e65e5dc337ec0617eb817039eb0890f38320 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 26 Mar 2021 14:24:48 +0000 Subject: [PATCH 205/641] ci: Update to latest buildroot model Attempt to update both CCI and Prow. xref https://github.com/coreos/fedora-coreos-tracker/blob/master/docs/ci-and-builds.md --- .cci.jenkinsfile | 6 +++--- ci/prow/Dockerfile | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 19596ff7a..844e7d5ad 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -3,7 +3,7 @@ stage("Build") { parallel build: { def n = 5 - cosaPod(buildroot: true, runAsUser: 0, memory: "2Gi", cpu: "${n}") { + buildPod(runAsUser: 0, memory: "2Gi", cpu: "${n}") { checkout scm stage("Core build") { shwrap(""" @@ -23,7 +23,7 @@ parallel build: { } }, codestyle: { - cosaPod(buildroot: true) { + buildPod { checkout scm shwrap("cargo fmt -- --check") } @@ -32,7 +32,7 @@ codestyle: { // Build FCOS and do a kola basic run // FIXME update to main branch once https://github.com/coreos/fedora-coreos-config/pull/595 merges -cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") { +cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { stage("Build FCOS") { checkout scm unstash 'build' diff --git a/ci/prow/Dockerfile b/ci/prow/Dockerfile index 64c2036c0..717b5038a 100644 --- a/ci/prow/Dockerfile +++ b/ci/prow/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.ci.openshift.org/coreos/cosa-buildroot:latest as builder +FROM quay.io/coreos-assembler/fcos-buildroot:testing-devel as builder WORKDIR /src COPY . . RUN make && make install DESTDIR=/cosa/component-install @@ -6,7 +6,7 @@ RUN make -C tests/kolainst install DESTDIR=/cosa/component-tests # Uncomment this to fake a build to test the code below # RUN mkdir -p /cosa/component-install/usr/bin && echo foo > /cosa/component-install/usr/bin/foo -FROM registry.ci.openshift.org/coreos/coreos-assembler:latest +FROM quay.io/coreos-assembler/coreos-assembler:latest WORKDIR /srv # Install our built binaries as overrides for the target build COPY --from=builder /cosa/component-install/ /srv/overrides/rootfs/ From 9f6c0332ce2d8e5278e9219bca4821c3f9719bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Fri, 7 May 2021 15:03:20 +0200 Subject: [PATCH 206/641] *: rename master branch to main --- .cci.jenkinsfile | 2 +- .github/ISSUE_TEMPLATE/release-checklist.md | 2 +- .github/workflows/rust.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 844e7d5ad..7370ad18e 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -1,4 +1,4 @@ -// Documentation: https://github.com/coreos/coreos-ci/blob/master/README-upstream-ci.md +// Documentation: https://github.com/coreos/coreos-ci/blob/main/README-upstream-ci.md stage("Build") { parallel build: { diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index ce4577511..066ffc377 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -59,7 +59,7 @@ This guide requires: - clean up: - [ ] `git push origin :release` - [ ] `cargo clean` - - [ ] `git checkout master` + - [ ] `git checkout main` [rustup]: https://rustup.rs/ [crates-io]: https://crates.io/ diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index c28de7267..da60c2c97 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] + branches: [ main ] env: CARGO_TERM_COLOR: always From 4b8cdfe9ea60e333c72cada5696da93a05ae00d6 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 2 Jul 2021 17:48:48 -0400 Subject: [PATCH 207/641] OWNERS: remove Prow is not managing merges on this repo. --- OWNERS | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 OWNERS diff --git a/OWNERS b/OWNERS deleted file mode 100644 index 3ada13fdb..000000000 --- a/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -# This list is the CoreOS updates&remoting team -approvers: - - cgwalters - - kelvinfan001 - - lucab - - travier From 14f7b960cce6927c8bdf8ca318469d61b2f5ce22 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 28 Jul 2021 18:00:36 -0400 Subject: [PATCH 208/641] workflows: bump toolchains --- .github/workflows/rust.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index da60c2c97..b304865f8 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,9 +9,9 @@ on: env: CARGO_TERM_COLOR: always # Minimum supported Rust version (MSRV) - ACTION_MSRV_TOOLCHAIN: 1.43.0 + ACTION_MSRV_TOOLCHAIN: 1.49.0 # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.47.0 + ACTION_LINTS_TOOLCHAIN: 1.53.0 jobs: tests-stable: From 0cb7debe1818d6903e829b9235e4407a98d8bd50 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 28 Jul 2021 18:00:45 -0400 Subject: [PATCH 209/641] workflows: limit permissions to reading repo contents --- .github/workflows/rust.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b304865f8..7261b8c52 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,11 +1,15 @@ --- name: Rust + on: push: branches: [ main ] pull_request: branches: [ main ] +permissions: + contents: read + env: CARGO_TERM_COLOR: always # Minimum supported Rust version (MSRV) From c8bf3ef3bedd0c0e59f89ff60129496771c3bfd4 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 28 Jul 2021 18:07:00 -0400 Subject: [PATCH 210/641] Fix build warnings --- src/cli/mod.rs | 6 +++--- src/component.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 04a3fe9b5..bcd68cc3e 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -58,7 +58,7 @@ mod tests { let d_argv = vec!["/usr/bin/bootupd".to_string(), "daemon".to_string()]; let cli = MultiCall::from_args(d_argv); match cli { - MultiCall::Ctl(cmd) => panic!(cmd), + MultiCall::Ctl(cmd) => panic!("{:?}", cmd), MultiCall::D(_) => {} }; } @@ -67,7 +67,7 @@ mod tests { let cli = MultiCall::from_args(ctl_argv); match cli { MultiCall::Ctl(_) => {} - MultiCall::D(cmd) => panic!(cmd), + MultiCall::D(cmd) => panic!("{:?}", cmd), }; } { @@ -75,7 +75,7 @@ mod tests { let cli = MultiCall::from_args(ctl_argv); match cli { MultiCall::Ctl(_) => {} - MultiCall::D(cmd) => panic!(cmd), + MultiCall::D(cmd) => panic!("{:?}", cmd), }; } } diff --git a/src/component.rs b/src/component.rs index 99f302244..9fd8b0d47 100644 --- a/src/component.rs +++ b/src/component.rs @@ -12,8 +12,8 @@ use std::path::{Path, PathBuf}; use crate::model::*; -#[serde(rename_all = "kebab-case")] #[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] pub(crate) enum ValidationResult { Valid, Errors(Vec), From 777adf197a70febf534639c0e6448a9bd3968958 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 28 Jul 2021 18:09:03 -0400 Subject: [PATCH 211/641] Rename EFI struct for clippy It wants acronyms to be in title case. https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms --- src/bootupd.rs | 2 +- src/component.rs | 2 +- src/efi.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 24cca7df5..17e1429e0 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -61,7 +61,7 @@ pub(crate) fn get_components() -> Components { } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] - insert_component(&mut components, Box::new(efi::EFI::default())); + insert_component(&mut components, Box::new(efi::Efi::default())); // #[cfg(target_arch = "x86_64")] // components.push(Box::new(bios::BIOS::new())); diff --git a/src/component.rs b/src/component.rs index 9fd8b0d47..a0787838e 100644 --- a/src/component.rs +++ b/src/component.rs @@ -70,7 +70,7 @@ pub(crate) trait Component { /// Given a component name, create an implementation. pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { - "EFI" => Box::new(crate::efi::EFI::default()), + "EFI" => Box::new(crate::efi::Efi::default()), _ => anyhow::bail!("No component {}", name), }; Ok(r) diff --git a/src/efi.rs b/src/efi.rs index c37509c8c..51dc14ba8 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -36,9 +36,9 @@ lazy_static! { } #[derive(Default)] -pub(crate) struct EFI {} +pub(crate) struct Efi {} -impl EFI { +impl Efi { fn esp_path(&self) -> PathBuf { Path::new(&*MOUNT_PATH).join("EFI") } @@ -83,7 +83,7 @@ impl EFI { } } -impl Component for EFI { +impl Component for Efi { fn name(&self) -> &'static str { "EFI" } From 9c9c3eda5bb74836ff4f50cfd442b7033d8ca2f6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 21 Jul 2021 14:34:43 -0400 Subject: [PATCH 212/641] ci: Drop unnecessary rerun of make+make install Closes: https://github.com/coreos/bootupd/issues/193 When we switched to a split buildroot/cosa containers, this broke. We can just delete this line because the code-under-test is in `overrides/rootfs`, so doing `rm overrides/rpm/*` won't remove it. --- tests/e2e-update/e2e-update.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index e72acad0a..995a184ec 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -80,7 +80,6 @@ if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm add_override grub2-2.04-22.fc32 - (cd ${bootupd_git} && runv make && runv make install DESTDIR=${overrides}/rootfs) runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork From a2d715b32f302a01c88841e2511d037f7936e32c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 21 Jul 2021 17:23:02 -0400 Subject: [PATCH 213/641] ci: Archive console.txt So we can debug this. --- .cci.jenkinsfile | 26 +++++++++++++++----------- tests/e2e-update/e2e-update.sh | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 7370ad18e..4d84b080b 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -53,17 +53,21 @@ cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { } // The e2e-adopt test will use the ostree commit we just generated above // but a static qemu base image. - stage("e2e adopt test") { - shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-adopt/e2e-adopt.sh") - } - // Now a test that upgrades using bootupd - stage("e2e upgrade test") { + try { + stage("e2e adopt test") { + shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-adopt/e2e-adopt.sh") + } + // Now a test that upgrades using bootupd + stage("e2e upgrade test") { shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") - } - stage("Kola testing") { - // The previous e2e leaves things only having built an ostree update - shwrap("cosa build") - // bootupd really can't break upgrades for the OS - fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) + } + stage("Kola testing") { + // The previous e2e leaves things only having built an ostree update + shwrap("cosa build") + // bootupd really can't break upgrades for the OS + fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) + } + } finally { + archiveArtifacts allowEmptyArchive: true, artifacts: 'tmp/console.txt' } } diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 995a184ec..a678feb14 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -133,7 +133,7 @@ qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${prev_ if test -n "${e2e_debug:-}"; then runv ${qemuexec_args[@]} --devshell else - runv timeout 5m "${qemuexec_args[@]}" --console-to-file $(pwd)/console.txt + runv timeout 5m "${qemuexec_args[@]}" --console-to-file ${COSA_DIR}/tmp/console.txt fi if ! test -f ${testtmp}/success; then if test -s ${testtmp}/out.txt; then From 16312def35025842ff534690f896ea30a8e3ffa3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 16 Aug 2021 15:08:53 -0400 Subject: [PATCH 214/641] tests/e2e-update: Bump to f34 grub Need to tweak this to auto-detect gold versus updates, or probably better just synthesize an update. --- tests/e2e-update/e2e-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index a678feb14..d09ee053e 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -79,13 +79,13 @@ undo_manifest_fork() { if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm - add_override grub2-2.04-22.fc32 + add_override grub2-2.06-2.fc34 runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" - add_override grub2-2.04-23.fc32 + add_override grub2-2.06~rc1-3.fc34 mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree From cdb3da9f89d186437de40f09e79e753eac5dc26a Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 6 Jul 2021 15:30:39 +0000 Subject: [PATCH 215/641] lockfile: update all openssl crates This updates the openssl crate (and related ones) to latest version, in order to support the upcoming OpenSSL 3.0 release. --- Cargo.lock | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f48a222a..12f347ddb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.13" @@ -463,9 +465,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.33" +version = "0.10.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577" +checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -477,9 +479,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.61" +version = "0.9.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" +checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" dependencies = [ "autocfg", "cc", From 8083951ee4c884fb7c629200d995b189ebac48f1 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Tue, 6 Jul 2021 15:31:13 +0000 Subject: [PATCH 216/641] lockfile: refresh --- Cargo.lock | 214 +++++++++++++++++++++++++---------------------------- 1 file changed, 101 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12f347ddb..ac000bf91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.13" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.39" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" [[package]] name = "atty" @@ -45,11 +45,10 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bincode" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] @@ -114,15 +113,15 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" -version = "1.3.4" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.60" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" [[package]] name = "cfg-if" @@ -192,9 +191,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime", @@ -220,9 +219,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fn-error-context" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac0b92c51c8b8183a0c101a7b2ea5fac11d2f1e01057f91e390284c75d76ef44" +checksum = "7dbe237cce37ed07377a50ccd977c78ee936f0f64b731caaab25ea5553b2d149" dependencies = [ "proc-macro2", "quote", @@ -256,49 +255,49 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" dependencies = [ "typenum", ] [[package]] name = "getrandom" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "heck" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -321,15 +320,15 @@ dependencies = [ [[package]] name = "humantime" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "itoa" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "lazy_static" @@ -339,9 +338,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.89" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "libsystemd" @@ -369,9 +368,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "nix" @@ -412,9 +411,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", "num-traits", @@ -422,18 +421,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opaque-debug" @@ -443,9 +442,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openat" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cdc0668b258e022a16a9c71a77f69b73e8d32b6f20bb3082b623f6396438b8" +checksum = "95aa7c05907b3ebde2610d602f4ddd992145cc6a84493647c30396f30ba83abe" dependencies = [ "libc", ] @@ -492,15 +491,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "ppv-lite86" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "proc-macro-error" @@ -528,18 +527,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] @@ -550,7 +549,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.15", + "getrandom 0.1.16", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -559,14 +558,14 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c24fcd450d3fa2b592732565aa4f17a27a61c65ece4726353e000939b0edee34" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.1", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -581,12 +580,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.1", + "rand_core 0.6.3", ] [[package]] @@ -595,16 +594,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.15", + "getrandom 0.1.16", ] [[package]] name = "rand_core" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.1", + "getrandom 0.2.3", ] [[package]] @@ -618,39 +617,38 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.1", + "rand_core 0.6.3", ] [[package]] name = "redox_syscall" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.3.9" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.18" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" @@ -669,18 +667,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.124" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.124" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -718,9 +716,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" dependencies = [ "clap", "lazy_static", @@ -729,9 +727,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" dependencies = [ "heck", "proc-macro-error", @@ -748,9 +746,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "syn" -version = "1.0.60" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -765,7 +763,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.1", + "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", @@ -773,9 +771,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] @@ -789,37 +787,27 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - [[package]] name = "time" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] name = "typenum" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-segmentation" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" @@ -829,24 +817,24 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "uuid" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ "serde", ] [[package]] name = "vcpkg" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -856,9 +844,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "void" @@ -874,9 +862,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" From eaa730766751b57306a42c585ac6c4cd44a919ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:30:36 +0000 Subject: [PATCH 217/641] build(deps): bump anyhow from 1.0.39 to 1.0.43 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.39 to 1.0.43. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.39...1.0.43) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac000bf91..78eea9c40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" [[package]] name = "atty" From 70a8b5626304d331a31b8236f760877790ea6034 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:30:41 +0000 Subject: [PATCH 218/641] build(deps): bump libsystemd from 0.2.1 to 0.3.1 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.2.1 to 0.3.1. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.2.1...v0.3.1) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 148 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 73 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac000bf91..b66861921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,25 +60,13 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.7.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", - "byte-tools", - "byteorder", "generic-array", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - [[package]] name = "bootupd" version = "0.2.5" @@ -105,18 +93,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "cc" version = "1.0.68" @@ -164,11 +140,20 @@ dependencies = [ "vec_map", ] +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "crypto-mac" -version = "0.7.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "generic-array", "subtle", @@ -176,9 +161,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ "generic-array", ] @@ -202,21 +187,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "version_check", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fn-error-context" version = "0.1.2" @@ -255,11 +225,12 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.12.4" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", + "version_check", ] [[package]] @@ -310,9 +281,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.7.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ "crypto-mac", "digest", @@ -338,22 +309,23 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.97" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" [[package]] name = "libsystemd" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a64961e79726a5b05e0db592097ca895831d755484203578fe75b580847262" +checksum = "e3860855cc74484f60fa02d1397892c4fe80d929d5a28caef690570665616743" dependencies = [ - "error-chain", "hmac", "libc", - "nix 0.17.0", + "log", + "nix 0.22.1", "serde", "sha2", + "thiserror", "uuid", ] @@ -373,16 +345,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] -name = "nix" -version = "0.17.0" +name = "memoffset" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", - "void", + "autocfg", ] [[package]] @@ -409,6 +377,19 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -436,9 +417,9 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opaque-debug" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openat" @@ -698,13 +679,14 @@ dependencies = [ [[package]] name = "sha2" -version = "0.8.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", "digest", - "fake-simd", "opaque-debug", ] @@ -740,9 +722,9 @@ dependencies = [ [[package]] name = "subtle" -version = "1.0.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" @@ -787,6 +769,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.43" @@ -848,12 +850,6 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index e1aaaafc5..6611073ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" libc = "^0.2" -libsystemd = "^0.2" +libsystemd = "^0.3" log = "^0.4" nix = "0.20.0" openat = "0.1.20" From c3d732358ccb3cd4f990768a9ad7749fb1647126 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:30:42 +0000 Subject: [PATCH 219/641] build(deps): bump fn-error-context from 0.1.1 to 0.2.0 Bumps [fn-error-context](https://github.com/andrewhickman/fn-error-context) from 0.1.1 to 0.2.0. - [Release notes](https://github.com/andrewhickman/fn-error-context/releases) - [Changelog](https://github.com/andrewhickman/fn-error-context/blob/master/CHANGELOG.md) - [Commits](https://github.com/andrewhickman/fn-error-context/compare/v0.1.1...v0.2.0) --- updated-dependencies: - dependency-name: fn-error-context dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac000bf91..e5e7d1b03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -219,9 +219,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fn-error-context" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbe237cce37ed07377a50ccd977c78ee936f0f64b731caaab25ea5553b2d149" +checksum = "236b4e4ae2b8be5f7a5652f6108c4a0f2627c569db4e7923333d31c7dbfed0fb" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e1aaaafc5..77d8b6468 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" env_logger = "^0.8" -fn-error-context = "0.1.1" +fn-error-context = "0.2.0" fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" From 842546267e5b073d50098ba8d719f089e074cc85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:31:17 +0000 Subject: [PATCH 220/641] build(deps): bump structopt from 0.3.22 to 0.3.23 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.22 to 0.3.23. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.22...v0.3.23) --- updated-dependencies: - dependency-name: structopt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac000bf91..832c5acf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -716,9 +716,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" +checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" dependencies = [ "clap", "lazy_static", @@ -727,9 +727,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" +checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" dependencies = [ "heck", "proc-macro-error", From fded072dcd25e60f93163cbc93f5e0ac13cf4f0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:31:46 +0000 Subject: [PATCH 221/641] build(deps): bump openat-ext from 0.1.13 to 0.2.2 Bumps [openat-ext](https://github.com/coreos/openat-ext) from 0.1.13 to 0.2.2. - [Release notes](https://github.com/coreos/openat-ext/releases) - [Commits](https://github.com/coreos/openat-ext/compare/v0.1.13...v0.2.2) --- updated-dependencies: - dependency-name: openat-ext dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 101 +++++++---------------------------------------------- Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac000bf91..6af602621 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,12 +183,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "drop_bomb" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" - [[package]] name = "env_logger" version = "0.8.4" @@ -262,17 +256,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.3" @@ -281,7 +264,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -385,18 +368,6 @@ dependencies = [ "void", ] -[[package]] -name = "nix" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", -] - [[package]] name = "nix" version = "0.20.0" @@ -451,15 +422,14 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.1.13" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c55e17c28995df7ff51cc9b2a9a4e548dde9ffa46efdd2750d22fe4ac64499" +checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" dependencies = [ - "drop_bomb", "libc", - "nix 0.18.0", + "nix 0.20.0", "openat", - "rand 0.7.3", + "rand", ] [[package]] @@ -543,19 +513,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - [[package]] name = "rand" version = "0.8.4" @@ -563,19 +520,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] @@ -585,16 +532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -603,16 +541,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -621,7 +550,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.3", + "rand_core", ] [[package]] @@ -763,7 +692,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.4", + "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -854,12 +783,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index e1aaaafc5..eb8d1f878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ libsystemd = "^0.2" log = "^0.4" nix = "0.20.0" openat = "0.1.20" -openat-ext = "^0.1.13" +openat-ext = "^0.2.2" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 7a91a266835cea1b52a7b812deede2751a719ce6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:33:08 +0000 Subject: [PATCH 222/641] build(deps): bump serde_json from 1.0.64 to 1.0.67 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.64 to 1.0.67. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.64...v1.0.67) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1f732da9..21c92d59a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,12 +99,6 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -233,7 +227,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -318,7 +312,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -344,7 +338,7 @@ checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", ] @@ -356,7 +350,7 @@ checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "memoffset", ] @@ -408,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" dependencies = [ "libc", - "nix 0.20.0", + "nix 0.22.1", "openat", "rand", ] @@ -420,7 +414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" dependencies = [ "bitflags", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -597,9 +591,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", @@ -613,7 +607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", "opaque-debug", @@ -672,7 +666,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", From a8eb59b446b297ab818263d582c063a4be813d78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:33:56 +0000 Subject: [PATCH 223/641] build(deps): bump openssl from 0.10.33 to 0.10.36 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.33 to 0.10.36. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.33...openssl-v0.10.36) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1f732da9..0e21ab61e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,12 +99,6 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -233,7 +227,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -318,7 +312,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -344,7 +338,7 @@ checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", ] @@ -356,7 +350,7 @@ checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "memoffset", ] @@ -408,19 +402,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" dependencies = [ "libc", - "nix 0.20.0", + "nix 0.22.1", "openat", "rand", ] [[package]] name = "openssl" -version = "0.10.35" +version = "0.10.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" +checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" dependencies = [ "bitflags", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -429,9 +423,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.65" +version = "0.9.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" +checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" dependencies = [ "autocfg", "cc", @@ -613,7 +607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", "opaque-debug", @@ -672,7 +666,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", From 087e983fdbd20e940634b2c52d77d1d87757cf22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 17:24:02 +0000 Subject: [PATCH 224/641] build(deps): bump nix from 0.20.0 to 0.22.1 Bumps [nix](https://github.com/nix-rust/nix) from 0.20.0 to 0.22.1. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/v0.22.1/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.20.0...v0.22.1) --- updated-dependencies: - dependency-name: nix dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 +++--------------- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 083f8e811..ddc63d066 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.20.0", + "nix", "openat", "openat-ext", "openssl", @@ -299,7 +299,7 @@ dependencies = [ "hmac", "libc", "log", - "nix 0.22.1", + "nix", "serde", "sha2", "thiserror", @@ -330,18 +330,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "nix" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" -dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", -] - [[package]] name = "nix" version = "0.22.1" @@ -402,7 +390,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" dependencies = [ "libc", - "nix 0.22.1", + "nix", "openat", "rand", ] diff --git a/Cargo.toml b/Cargo.toml index a3dc1fed3..5029d9a02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.3" log = "^0.4" -nix = "0.20.0" +nix = "0.22.1" openat = "0.1.20" openat-ext = "^0.2.2" openssl = "^0.10" From 16c45fb6c7b125c484b3cde3d9a0723d8018306e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 17:24:03 +0000 Subject: [PATCH 225/641] build(deps): bump serde from 1.0.124 to 1.0.130 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.130. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.130) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 083f8e811..b19adf263 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -571,18 +571,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", From ddec40e4a0d836e01ba19c607037b89cb2f82dfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 18:21:42 +0000 Subject: [PATCH 226/641] build(deps): bump env_logger from 0.8.4 to 0.9.0 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.8.4 to 0.9.0. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.4...v0.9.0) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05b62e59e..a2559f3d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.8.4" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", "humantime", diff --git a/Cargo.toml b/Cargo.toml index 5029d9a02..070e4800a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" -env_logger = "^0.8" +env_logger = "^0.9" fn-error-context = "0.2.0" fs2 = "0.4.3" hex = "0.4.3" From 2c683a3fb10b32c598e8ea1a5e0555500f464e2e Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 3 Sep 2021 14:22:31 -0400 Subject: [PATCH 227/641] cargo: allow env_logger 0.8 Avoid a synchronous dependency bump in downstream packaging. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 070e4800a..fdee21948 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } clap = "~2.33" -env_logger = "^0.9" +env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" hex = "0.4.3" From df69312aed5b99811279b10d9a7421d5b2fa7c62 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 8 Sep 2021 08:04:38 +0000 Subject: [PATCH 228/641] cargo: add cargo-release metadata --- Cargo.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index fdee21948..92b040ce1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,3 +35,12 @@ tempfile = "^3.2" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo debug = true + +[package.metadata.release] +disable-publish = true +disable-push = true +post-release-commit-message = "cargo: development version bump" +pre-release-commit-message = "cargo: bootupd release {{version}}" +sign-commit = true +sign-tag = true +tag-message = "bootupd {{version}}" From 85d4d46aa79f8e54fc0d93187ffb2034004b16ce Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 8 Sep 2021 08:07:15 +0000 Subject: [PATCH 229/641] cargo: bootupd release 0.2.6 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2559f3d0..a1ec448a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.5" +version = "0.2.6" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 92b040ce1..9d261b5e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.5" +version = "0.2.6" authors = ["Colin Walters "] edition = "2018" From a8cee55a5a13053c3702dfde7919f64504353874 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Wed, 8 Sep 2021 08:07:17 +0000 Subject: [PATCH 230/641] cargo: development version bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1ec448a0..e1ba517a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.6" +version = "0.2.7-alpha.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 9d261b5e0..31586a734 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.6" +version = "0.2.7-alpha.0" authors = ["Colin Walters "] edition = "2018" From 0ce64ac2cedfc230c07a1e944e6bc6d24ed72896 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 1 Oct 2021 13:38:51 -0400 Subject: [PATCH 231/641] ci: Don't run basic scenarios We're downgrading to an old grub2 build that is broken, so we can't actually boot uefi after doing our hacks. The correct thing here is to change bootupd CI to generate synthetic RPMs instead of downloading old builds. Will do that at some point... --- .cci.jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 4d84b080b..2d433ad94 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -65,7 +65,7 @@ cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { // The previous e2e leaves things only having built an ostree update shwrap("cosa build") // bootupd really can't break upgrades for the OS - fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true) + fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true, skipBasicScenarios: true) } } finally { archiveArtifacts allowEmptyArchive: true, artifacts: 'tmp/console.txt' From 199fd1994268b5f188e8aa571ec763e85196745a Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 14 Sep 2021 13:42:25 -0400 Subject: [PATCH 232/641] README: drop redundant paragraph It doesn't add anything, and has a bit of an unhelpful undertone. --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index c0b3d2bb5..3790e5362 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,6 @@ how to separately download bootloaders and pass them to `bootupctl backend`. - Why is bootupd not part of ostree? -This question is really covered at the top of this file already - hopefully -you read that already, but this answer will rephrase and try to go in more depth. - A key advertised feature of ostree is that updates are truly transactional. There's even a [a test case](https://blog.verbum.org/2020/12/01/committed-to-the-integrity-of-your-root-filesystem/) that validates forcibly pulling the power during OS updates. A simple From 0b928b3a4487b0894b8b2ebe571a3d83f4f65d68 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 14 Sep 2021 13:42:57 -0400 Subject: [PATCH 233/641] README-design: fix section headings --- README-design.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README-design.md b/README-design.md index b22dc6b02..07d52b77f 100644 --- a/README-design.md +++ b/README-design.md @@ -1,9 +1,8 @@ -Overall design ---- +# Overall design The initial focus here is updating the [ESP](https://en.wikipedia.org/wiki/EFI_system_partition), but the overall design of bootupd contains a lot of abstraction to support different "components". -# Ideal case +## Ideal case In the ideal case, an OS builder uses `bootupd install` to install all bootloader data, and thereafter it is fully (exclusively) managed by bootupd. It would e.g. be a bug/error @@ -14,7 +13,7 @@ In other words, an end user system would simply invoke `bootupd update` as desir However, we're not in that ideal case. Thus bootupd has the concept of "adoption" where we start tracking the installed state as we find it. -# Handling adoption +## Handling adoption For Fedora CoreOS, currently the `EFI/fedora/grub.cfg` file is created outside of the ostree inside `create_disk.sh`. So we aren't including any updates for it in the OSTree. @@ -24,7 +23,7 @@ However, we need to be very cautious in handling this because we basically can't assume we own all of the state. We shouldn't touch any files that we don't know about. -# Upgrade edges +## Upgrade edges We don't necessarily want to update the bootloader data, even if a new update happens to be provided. For example, Fedora does "mass rebuilds" usually once a release, but it's not strictly necessary @@ -34,4 +33,4 @@ A common policy in fact might be "only update bootloader for security issue or i A "strictly necessary" upgrade would be one like the GRUB BLS parsing support. -There is not yet any support for upgrade edges in the code apart from a stub structure. \ No newline at end of file +There is not yet any support for upgrade edges in the code apart from a stub structure. From 4499353acf28112ed8f2be4b5d9c1e47c95680b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:54:41 +0000 Subject: [PATCH 234/641] build(deps): bump nix from 0.22.1 to 0.23.0 Bumps [nix](https://github.com/nix-rust/nix) from 0.22.1 to 0.23.0. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.22.1...v0.23.0) --- updated-dependencies: - dependency-name: nix dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 31 ++++++++++++++++++++++--------- Cargo.toml | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1ba517a9..662e58e97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" @@ -83,7 +83,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix", + "nix 0.23.0", "openat", "openat-ext", "openssl", @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libsystemd" @@ -299,7 +299,7 @@ dependencies = [ "hmac", "libc", "log", - "nix", + "nix 0.22.0", "serde", "sha2", "thiserror", @@ -332,9 +332,22 @@ dependencies = [ [[package]] name = "nix" -version = "0.22.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" +checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" dependencies = [ "bitflags", "cc", @@ -390,7 +403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" dependencies = [ "libc", - "nix", + "nix 0.22.0", "openat", "rand", ] diff --git a/Cargo.toml b/Cargo.toml index 31586a734..3965700dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.3" log = "^0.4" -nix = "0.22.1" +nix = "0.23.0" openat = "0.1.20" openat-ext = "^0.2.2" openssl = "^0.10" From dd01840789cda13e8cdcbe397e78ae00a1bf54f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:54:52 +0000 Subject: [PATCH 235/641] build(deps): bump libc from 0.2.101 to 0.2.103 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.101 to 0.2.103. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.101...0.2.103) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1ba517a9..6fd12b370 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libsystemd" From 029bfc83b0aad97aadc8152f0cdc0da01ea6277c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:55:01 +0000 Subject: [PATCH 236/641] build(deps): bump serde_json from 1.0.67 to 1.0.68 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.67 to 1.0.68. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.67...v1.0.68) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1ba517a9..dd98dddd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -579,9 +579,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", From 254624bf6db4618abe1f6c69e2615a48b7d86363 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:55:07 +0000 Subject: [PATCH 237/641] build(deps): bump anyhow from 1.0.43 to 1.0.44 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.43 to 1.0.44. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.43...1.0.44) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1ba517a9..3bdb5165d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" [[package]] name = "atty" From de795811d445e657603aa0dfe75c64a133d2563d Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 1 Oct 2021 18:56:00 -0400 Subject: [PATCH 238/641] cargo: allow nix 0.22.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3965700dc..dbb4853da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ lazy_static = "1.4.0" libc = "^0.2" libsystemd = "^0.3" log = "^0.4" -nix = "0.23.0" +nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" openat-ext = "^0.2.2" openssl = "^0.10" From 7e91c28cbfd132e6cced355e1ca4cebc83560fc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 01:18:56 +0000 Subject: [PATCH 239/641] build(deps): bump libc from 0.2.103 to 0.2.104 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.103 to 0.2.104. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.103...0.2.104) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2fbd01755..96d2e7212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" [[package]] name = "libsystemd" From 6343dc637d1ddbd05bb540928585b7da29780649 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Oct 2021 01:04:41 +0000 Subject: [PATCH 240/641] build(deps): bump structopt from 0.3.23 to 0.3.25 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.23 to 0.3.25. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.23...v0.3.25) --- updated-dependencies: - dependency-name: structopt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96d2e7212..186c70da8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,9 +622,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.23" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ "clap", "lazy_static", @@ -633,9 +633,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", From 5f79c3a0cdb9599a984c35639f8d956483078e66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 01:27:36 +0000 Subject: [PATCH 241/641] build(deps): bump libc from 0.2.104 to 0.2.105 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.104 to 0.2.105. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.104...0.2.105) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 186c70da8..f14a2a02a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" +checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" [[package]] name = "libsystemd" From d626ab2f3b1dc199731219c2a9e1a6d7614b6e17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Oct 2021 01:03:35 +0000 Subject: [PATCH 242/641] build(deps): bump openssl from 0.10.36 to 0.10.37 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.36 to 0.10.37. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.36...openssl-v0.10.37) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f14a2a02a..66795f73b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "2bc6b9e4403633698352880b22cbe2f0e45dd0177f6fabe4585536e56a3e4f75" dependencies = [ "bitflags", "cfg-if", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.66" +version = "0.9.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +checksum = "1c571f25d3f66dd427e417cebf73dbe2361d6125cf6e3a70d143fdf97c9f5150" dependencies = [ "autocfg", "cc", From ef41513557ce3255ea8f42221b66355e489f8cd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 01:03:40 +0000 Subject: [PATCH 243/641] build(deps): bump libsystemd from 0.3.1 to 0.4.0 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.3.1 to 0.4.0. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.3.1...v0.4.0) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66795f73b..d9e4efdba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,14 +292,14 @@ checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" [[package]] name = "libsystemd" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3860855cc74484f60fa02d1397892c4fe80d929d5a28caef690570665616743" +checksum = "3f269b3e3d7d2ce8e248164f21ec55623e4a65be1c147b8b37fb1e73c81f449a" dependencies = [ "hmac", "libc", "log", - "nix 0.22.0", + "nix 0.23.0", "serde", "sha2", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index dbb4853da..c16741f4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" libc = "^0.2" -libsystemd = "^0.3" +libsystemd = "^0.4" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" From 1d661e9d58dcd0d0de1faf28f4b23d20abc2924c Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 28 Oct 2021 21:31:55 -0400 Subject: [PATCH 244/641] cargo: allow libsystemd 0.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c16741f4b..f3567f2b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" libc = "^0.2" -libsystemd = "^0.4" +libsystemd = ">= 0.3, < 0.5" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" From 62daafe177b571f81096b765d369172eae869a84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 01:19:50 +0000 Subject: [PATCH 245/641] build(deps): bump openssl from 0.10.37 to 0.10.38 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.37 to 0.10.38. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.37...openssl-v0.10.38) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9e4efdba..d519e3038 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.37" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc6b9e4403633698352880b22cbe2f0e45dd0177f6fabe4585536e56a3e4f75" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.68" +version = "0.9.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c571f25d3f66dd427e417cebf73dbe2361d6125cf6e3a70d143fdf97c9f5150" +checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf" dependencies = [ "autocfg", "cc", From ee41c13f196df8cba41377360f7e296e9ad8d7b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 01:19:56 +0000 Subject: [PATCH 246/641] build(deps): bump libc from 0.2.105 to 0.2.106 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.105 to 0.2.106. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.105...0.2.106) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9e4efdba..84d3f2bc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" +checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" [[package]] name = "libsystemd" From 6dcc05ab062b32d740e0ee3eb12104953977dd78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Nov 2021 01:05:57 +0000 Subject: [PATCH 247/641] build(deps): bump anyhow from 1.0.44 to 1.0.45 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.44 to 1.0.45. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.44...1.0.45) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2489a579a..8a18b84e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" [[package]] name = "atty" From 86cd900d34f56b1805138261e30e886d7b40faf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Nov 2021 01:17:31 +0000 Subject: [PATCH 248/641] build(deps): bump libc from 0.2.106 to 0.2.107 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.106 to 0.2.107. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.106...0.2.107) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a18b84e5..39baad614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.106" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "libsystemd" From 737f956cb9f89263ad2dd8f29a87dd87ccfc2d01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Nov 2021 01:17:40 +0000 Subject: [PATCH 249/641] build(deps): bump serde_json from 1.0.68 to 1.0.69 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.68 to 1.0.69. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.68...v1.0.69) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a18b84e5..7f15e1065 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -592,9 +592,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" dependencies = [ "itoa", "ryu", From 0b459f99308e8fef2b4f6d8cd6b6ca04beccd08f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 29 Nov 2021 13:07:38 -0500 Subject: [PATCH 250/641] ci: Bump to F35 grub This is the F35 equivalent of https://github.com/coreos/bootupd/pull/203 Closes: https://github.com/coreos/bootupd/issues/242 --- tests/e2e-update/e2e-update.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index d09ee053e..8e036f4ea 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -79,13 +79,15 @@ undo_manifest_fork() { if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm - add_override grub2-2.06-2.fc34 + # Version from F35 Beta, and different from F35 Final + add_override grub2-2.06-5.fc35 runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" - add_override grub2-2.06~rc1-3.fc34 + # Version queued in current f35 updates + add_override grub2-2.06-8.fc35 mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree From 16e31f17f8772e7733409b5215b74082811a7ea0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Nov 2021 01:04:45 +0000 Subject: [PATCH 251/641] build(deps): bump anyhow from 1.0.45 to 1.0.51 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.45 to 1.0.51. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.45...1.0.51) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a42dd5d74..39241e16d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.45" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" [[package]] name = "atty" From a53f6ef7f829a1a20e3a761acef27a114cd4ab33 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 8 Dec 2021 14:21:22 -0500 Subject: [PATCH 252/641] ci: Drop adoption test Trying to boot FCOS-Fedora-32 is not sustainable; it turns out that the recent update to coreos-assembler which passes a newer Ignition config version broke the adoption test. In the end, the adopt workflow was really a hack and I'd like to slowly deprecate it. In general, most people should be reprovisioning nodes anyways. Once they do that, they'll pick up the updated shim/grub naturally. --- .cci.jenkinsfile | 3 - tests/e2e-adopt/e2e-adopt-in-vm.sh | 135 ----------------------------- tests/e2e-adopt/e2e-adopt.sh | 92 -------------------- 3 files changed, 230 deletions(-) delete mode 100755 tests/e2e-adopt/e2e-adopt-in-vm.sh delete mode 100755 tests/e2e-adopt/e2e-adopt.sh diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 2d433ad94..af38c1e11 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -54,9 +54,6 @@ cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { // The e2e-adopt test will use the ostree commit we just generated above // but a static qemu base image. try { - stage("e2e adopt test") { - shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-adopt/e2e-adopt.sh") - } // Now a test that upgrades using bootupd stage("e2e upgrade test") { shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") diff --git a/tests/e2e-adopt/e2e-adopt-in-vm.sh b/tests/e2e-adopt/e2e-adopt-in-vm.sh deleted file mode 100755 index 76cd800e1..000000000 --- a/tests/e2e-adopt/e2e-adopt-in-vm.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/bash -# Run inside the vm spawned from e2e.sh -set -euo pipefail - -dn=$(cd $(dirname $0) && pwd) -bn=$(basename $0) -. ${dn}/../kola/data/libtest.sh - -cd $(mktemp -d) - -echo "Starting $0" - -enable_bootupd() { - systemctl start bootupd.socket -} - -current_commit=$(rpm-ostree status --json | jq -r .deployments[0].checksum) - -reboot_with_mark() { - mark=$1; shift - runv echo ${mark} > ${reboot_mark_path} - sync ${reboot_mark_path} - runv systemd-run -- systemctl reboot - touch /run/rebooting - sleep infinity -} - -status_ok_no_update() { - bootupctl status | tee out.txt - assert_file_has_content_literal out.txt 'Component EFI' - assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' - assert_file_has_content_literal out.txt 'Update: At latest version' - assert_file_has_content out.txt 'CoreOS aleph image ID: .*coreos.*-qemu' - bootupctl validate - ok status and validate -} - -reboot_mark_path=/etc/${bn}.rebootstamp -reboot_mark= -if test -f "${reboot_mark_path}"; then - reboot_mark=$(cat ${reboot_mark_path}) -fi -case "${reboot_mark}" in - "") - if test "${current_commit}" = ${TARGET_COMMIT}; then - fatal "already at ${TARGET_COMMIT}" - fi - - # This system wasn't built via bootupd - assert_not_has_file /boot/bootupd-state.json - - # FIXME - # https://github.com/coreos/rpm-ostree/issues/2210 - runv setenforce 0 - runv rpm-ostree rebase /run/cosadir/tmp/repo:${TARGET_COMMIT} - reboot_with_mark first - ;; - first) - if test "${current_commit}" != ${TARGET_COMMIT}; then - fatal "not at ${TARGET_COMMIT}" - fi - # NOTE Fall through NOTE - ;; - second) - enable_bootupd - status_ok_no_update - touch /run/testtmp/success - sync - # TODO maybe try to make this use more of the exttest infrastructure? - exec poweroff -ff - ;; -esac - -enable_bootupd - -# We did setenforce 0 above for https://github.com/coreos/rpm-ostree/issues/2210 -# Validate that on reboot we're still enforcing. -semode=$(getenforce) -if test "$semode" != Enforcing; then - fatal "SELinux mode is ${semode}" -fi - -# Mount the EFI partition. -tmpefimount=$(mount_tmp_efi) - -source_grub_cfg=$(find ${tmpefimount}/EFI -name grub.cfg) -test -f "${source_grub_cfg}" - -source_grub=$(find ${tmpefimount}/EFI -name grubx64.efi) -test -f ${source_grub} -source_grub_sha256=$(sha256sum ${source_grub} | cut -f 1 -d ' ') - -update_grub=$(find /usr/lib/bootupd/updates/EFI/ -name grubx64.efi) -test -f ${update_grub} -update_grub_sha256=$(sha256sum ${update_grub} | cut -f 1 -d ' ') -if test "${source_grub_sha256}" = "${update_grub_sha256}"; then - fatal "Already have target grubx64.efi" -fi - -bootupctl status | tee out.txt -assert_file_has_content_literal out.txt 'No components installed.' -assert_file_has_content out.txt 'Detected: EFI: .*coreos.*-qemu.*' - -bootupctl validate | tee out.txt -assert_file_has_content_literal out.txt 'No components installed.' -assert_not_file_has_content_literal out.txt "Validated" -# Shouldn't write state just starting and validating -assert_not_has_file /boot/bootupd-state.json -ok validate - -# Explicitly testing https://github.com/coreos/bootupd/issues/103 -bootupctl update | tee out.txt -assert_file_has_content out.txt 'Adopted and updated: EFI: grub2-efi-x64' -ok adoption - -status_ok_no_update - -bootupctl validate | tee out.txt -assert_not_file_has_content_literal out.txt "Validated EFI" - -new_grub_sha256=$(sha256sum ${source_grub} | cut -f 1 -d ' ') -if test "${new_grub_sha256}" != "${update_grub_sha256}"; then - fatal "Failed to update grub" -fi -ok updated grub - -# We shouldn't have deleted the config file which was unmanaged -test -f "${source_grub_cfg}" -ok still have grub.cfg - -tap_finish - -# And now do another reboot to validate that things are good -reboot_with_mark second - diff --git a/tests/e2e-adopt/e2e-adopt.sh b/tests/e2e-adopt/e2e-adopt.sh deleted file mode 100755 index 9f3c2116a..000000000 --- a/tests/e2e-adopt/e2e-adopt.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# Given an old FCOS build (pre-bootupd), upgrade -# to the latest build in ${COSA_DIR} and run through -# the adoption procedure to update the ESP. -set -euo pipefail - -# There was a grub2-efi-x64 change after this -PRE_BOOTUPD_FCOS=https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20200907.3.0/x86_64/meta.json - -dn=$(cd $(dirname $0) && pwd) -testprefix=$(cd ${dn} && git rev-parse --show-prefix) -. ${dn}/../kola/data/libtest.sh - -if test -z "${COSA_DIR:-}"; then - fatal "COSA_DIR must be set" -fi -# Validate source directory -bootupd_git=$(cd ${dn} && git rev-parse --show-toplevel) -test -f ${bootupd_git}/systemd/bootupd.service - -testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) -export test_tmpdir=${testtmp} -cd ${test_tmpdir} -runv curl -sSL -o meta.json ${PRE_BOOTUPD_FCOS} -jq .images.qemu < meta.json > qemu.json -qemu_image_xz=$(jq -r .path < qemu.json) -qemu_image=${qemu_image_xz%%.xz} -if test -f "${COSA_DIR}/tmp/${qemu_image}"; then - qemu_image="${COSA_DIR}/tmp/${qemu_image}" -else - runv curl -sSL $(dirname ${PRE_BOOTUPD_FCOS})/${qemu_image_xz} | xz -d > ${COSA_DIR}/tmp/${qemu_image}.tmp - mv ${COSA_DIR}/tmp/${qemu_image}{.tmp,} - qemu_image=${COSA_DIR}/tmp/${qemu_image} -fi - -# Start in cosa dir -cd ${COSA_DIR} -test -d builds - -echo "Preparing test" -target_commit=$(cosa meta --get-value ostree-commit) -echo "Target commit: ${target_commit}" - -execstop='test -f /run/rebooting || poweroff -ff' -if test -n "${e2e_debug:-}"; then - execstop= -fi -cat >${testtmp}/test.fcct << EOF -variant: fcos -version: 1.0.0 -systemd: - units: - - name: zincati.service - dropins: - - name: disabled.conf - contents: | - [Unit] - # Disable zincati, we're going to do our own updates - ConditionPathExists=/nosuchfile - - name: bootupd-test.service - enabled: true - contents: | - [Unit] - RequiresMountsFor=/run/testtmp - [Service] - Type=oneshot - RemainAfterExit=yes - Environment=TARGET_COMMIT=${target_commit} - Environment=SRCDIR=/run/bootupd-source - # Run via shell because selinux denies systemd writing to 9p apparently - ExecStart=/bin/sh -c '/run/bootupd-source/${testprefix}/e2e-adopt-in-vm.sh &>>/run/testtmp/out.txt; ${execstop}' - [Install] - WantedBy=multi-user.target -EOF -runv fcct -o ${testtmp}/test.ign ${testtmp}/test.fcct -cd ${testtmp} -qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${qemu_image}" --qemu-firmware uefi \ - -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw .,/run/testtmp) -if test -n "${e2e_debug:-}"; then - runv ${qemuexec_args[@]} --devshell -else - runv timeout 5m "${qemuexec_args[@]}" --console-to-file $(pwd)/console.txt -fi -if ! test -f ${testtmp}/success; then - if test -s ${testtmp}/out.txt; then - sed -e 's,^,# ,' < ${testtmp}/out.txt - else - echo "No out.txt created, systemd unit failed to start" - fi - fatal "test failed" -fi -echo "ok bootupd e2e" From d23b151c6264e50eeb8d999bc14b014ce8584087 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:29:20 +0000 Subject: [PATCH 253/641] build(deps): bump serde_json from 1.0.69 to 1.0.72 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.69 to 1.0.72. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.69...v1.0.72) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a42dd5d74..d33c12878 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -592,9 +592,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", From a45b84fb3c698d809a33b7f55cada98614319123 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:30:52 +0000 Subject: [PATCH 254/641] build(deps): bump libc from 0.2.107 to 0.2.109 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.107 to 0.2.109. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.107...0.2.109) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a42dd5d74..a8942ff6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.107" +version = "0.2.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" [[package]] name = "libsystemd" From ffa6726aff70635820225e2874873bf6c86e012a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Dec 2021 14:33:47 +0000 Subject: [PATCH 255/641] build(deps): bump clap from 2.33.3 to 2.34.0 Bumps [clap](https://github.com/clap-rs/clap) from 2.33.3 to 2.34.0. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/commits) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a42dd5d74..d7a77c393 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] @@ -121,9 +121,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", diff --git a/Cargo.toml b/Cargo.toml index f3567f2b9..dcd602db4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = "~2.33" +clap = "~2.34" env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" From 9c9dd8e26e2f227e9b710a1e0bfaa0fb926019e7 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 9 Dec 2021 09:34:40 -0500 Subject: [PATCH 256/641] cargo: allow clap 2.33 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index dcd602db4..8134e67d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = "~2.34" +clap = ">= 2.33, < 2.35" env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" From 66f2f963581f7bd70a952a6575c332a2abc52ea7 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 10 Nov 2021 00:01:39 -0500 Subject: [PATCH 257/641] *: fix clippy lints --- src/bootupd.rs | 2 +- src/daemon/mod.rs | 2 +- src/efi.rs | 3 +-- src/ipc.rs | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 17e1429e0..7579039ab 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -110,7 +110,7 @@ pub(crate) fn update(name: &str) -> Result { let sysroot = openat::Dir::open("/")?; let update = component.query_update(&sysroot)?; let update = match update.as_ref() { - Some(p) if inst.meta.can_upgrade_to(&p) => p, + Some(p) if inst.meta.can_upgrade_to(p) => p, _ => return Ok(ComponentUpdateResult::AtLatestVersion), }; diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index bcc317739..b83ba74fd 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -95,7 +95,7 @@ fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { break; } - let msg = bincode::deserialize(&buf)?; + let msg = bincode::deserialize(buf)?; log::trace!("processing request: {:?}", &msg); let r = match msg { ClientRequest::Update { component } => { diff --git a/src/efi.rs b/src/efi.rs index 51dc14ba8..0e83e0505 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -26,7 +26,6 @@ use crate::util::CommandRunExt; /// The ESP partition label pub(crate) const ESP_PART_LABEL: &str = "EFI-SYSTEM"; -#[macro_use] lazy_static! { /// The path to a temporary ESP mount static ref MOUNT_PATH: PathBuf = { @@ -142,7 +141,7 @@ impl Component for Efi { } fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { - let meta = if let Some(meta) = get_component_update(&src_root, self)? { + let meta = if let Some(meta) = get_component_update(src_root, self)? { meta } else { anyhow::bail!("No update metadata for component {} found", self.name()); diff --git a/src/ipc.rs b/src/ipc.rs index 524d9039b..c57b0caa0 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -83,7 +83,7 @@ impl ClientToDaemonConnection { if buf.is_empty() { bail!("Server sent an empty reply"); } - bincode::deserialize(&buf).context("client parsing reply")? + bincode::deserialize(buf).context("client parsing reply")? }; match reply { DaemonToClientReply::Success::(r) => Ok(r), From edc3d2c9513dde7e541513b0363d87a0700779e9 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 10 Nov 2021 00:02:00 -0500 Subject: [PATCH 258/641] workflows: bump pinned Rust to 1.56 --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7261b8c52..2e08122cd 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -15,7 +15,7 @@ env: # Minimum supported Rust version (MSRV) ACTION_MSRV_TOOLCHAIN: 1.49.0 # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.53.0 + ACTION_LINTS_TOOLCHAIN: 1.56.0 jobs: tests-stable: From 07b1d03afac4bcc9ac07e16f1124d68cd9e5ebfd Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Thu, 9 Dec 2021 09:39:21 -0500 Subject: [PATCH 259/641] tests/e2e-update: s/fcct/butane/ --- tests/e2e-update/e2e-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 8e036f4ea..73d441201 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -106,7 +106,7 @@ target_commit=$(cosa meta --get-value ostree-commit) echo "Target commit: ${target_commit}" # For some reason 9p can't write to tmpfs -cat >${testtmp}/test.fcct << EOF +cat >${testtmp}/test.bu << EOF variant: fcos version: 1.0.0 systemd: @@ -128,7 +128,7 @@ systemd: [Install] WantedBy=multi-user.target EOF -runv fcct -o ${testtmp}/test.ign ${testtmp}/test.fcct +runv butane -o ${testtmp}/test.ign ${testtmp}/test.bu cd ${testtmp} qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${prev_image}" --qemu-firmware uefi \ -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw .,/run/testtmp) From 6c89cf07c3fcd567e94085a909295f159574a3f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Dec 2021 15:10:05 +0000 Subject: [PATCH 260/641] build(deps): bump libsystemd from 0.4.0 to 0.4.1 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.4.0...v0.4.1) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79d86b344..6a0dc6ea3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,14 +292,15 @@ checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" [[package]] name = "libsystemd" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f269b3e3d7d2ce8e248164f21ec55623e4a65be1c147b8b37fb1e73c81f449a" +checksum = "6f4f0b5b062ba67aa075e331de778082c09e66b5ef32970ea5a1e9c37c9555d1" dependencies = [ "hmac", "libc", "log", "nix 0.23.0", + "once_cell", "serde", "sha2", "thiserror", From 19855547b4b62d339700075f3d3f6356dc01ba83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Dec 2021 01:07:27 +0000 Subject: [PATCH 261/641] build(deps): bump serde from 1.0.130 to 1.0.131 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 489207855..6a70ab502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,18 +573,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" dependencies = [ "proc-macro2", "quote", From 125889328e475474cfe76ccf428b088ccb77f405 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Dec 2021 01:07:30 +0000 Subject: [PATCH 262/641] build(deps): bump libc from 0.2.109 to 0.2.110 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.109 to 0.2.110. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.109...0.2.110) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 489207855..df655aab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.109" +version = "0.2.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" +checksum = "b58a4469763e4e3a906c4ed786e1c70512d16aa88f84dded826da42640fc6a1c" [[package]] name = "libsystemd" From 9ad223e5f87b763b1b4d6932cf955e647db24386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Dec 2021 01:20:07 +0000 Subject: [PATCH 263/641] build(deps): bump libc from 0.2.110 to 0.2.111 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.110 to 0.2.111. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.110...0.2.111) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccaf071ea..ecb2c270c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.110" +version = "0.2.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58a4469763e4e3a906c4ed786e1c70512d16aa88f84dded826da42640fc6a1c" +checksum = "8e167738f1866a7ec625567bae89ca0d44477232a4f7c52b1c7f2adc2c98804f" [[package]] name = "libsystemd" From 18f6cf5120fc5dd705112e05b1a6e98c3a803198 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Dec 2021 01:04:15 +0000 Subject: [PATCH 264/641] build(deps): bump libc from 0.2.111 to 0.2.112 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.111 to 0.2.112. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.111...0.2.112) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecb2c270c..d1a04f689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,9 +286,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.111" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e167738f1866a7ec625567bae89ca0d44477232a4f7c52b1c7f2adc2c98804f" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libsystemd" From 9f54a77ad5039abcff229626f550aa804f52b402 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Dec 2021 01:04:21 +0000 Subject: [PATCH 265/641] build(deps): bump serde_json from 1.0.72 to 1.0.73 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.72 to 1.0.73. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.72...v1.0.73) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecb2c270c..fe366ada5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -274,9 +274,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lazy_static" @@ -593,9 +593,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", From 82a546b7de907c127972e55da1c445ea7baf9020 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Dec 2021 01:03:52 +0000 Subject: [PATCH 266/641] build(deps): bump serde from 1.0.131 to 1.0.132 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b137211f1..379a2e18d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,18 +573,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", From 0f4c7fb89f94ac8e10c5167460dc4b2d66b36ada Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 17 Dec 2021 00:33:51 -0500 Subject: [PATCH 267/641] Disable Rust 1.57 warning We don't read the lockfile; we just hold the lockfile. --- src/backend/statefile.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/statefile.rs b/src/backend/statefile.rs index bc903eb63..379c472c4 100644 --- a/src/backend/statefile.rs +++ b/src/backend/statefile.rs @@ -90,6 +90,7 @@ impl SavedState { #[derive(Debug)] pub(crate) struct StateLockGuard { pub(crate) sysroot: openat::Dir, + #[allow(dead_code)] lockfile: Option, } From a016aaaee4aaaf7752a0af3689acc4ce80f2af87 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 17 Dec 2021 00:34:00 -0500 Subject: [PATCH 268/641] workflows: bump pinned Rust to 1.57 --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2e08122cd..52fdfa859 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -15,7 +15,7 @@ env: # Minimum supported Rust version (MSRV) ACTION_MSRV_TOOLCHAIN: 1.49.0 # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.56.0 + ACTION_LINTS_TOOLCHAIN: 1.57.0 jobs: tests-stable: From 419e9e1252fb112555f9f9573ddc9f54a9a1b027 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Dec 2021 01:24:09 +0000 Subject: [PATCH 269/641] build(deps): bump nix from 0.23.0 to 0.23.1 Bumps [nix](https://github.com/nix-rust/nix) from 0.23.0 to 0.23.1. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.23.0...v0.23.1) --- updated-dependencies: - dependency-name: nix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 379a2e18d..bf1f1b00d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.23.0", + "nix 0.23.1", "openat", "openat-ext", "openssl", @@ -299,7 +299,7 @@ dependencies = [ "hmac", "libc", "log", - "nix 0.23.0", + "nix 0.23.1", "once_cell", "serde", "sha2", @@ -346,9 +346,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", From d37c3cafdf6371f71ceeb9de85862ccf28c185b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Dec 2021 01:04:02 +0000 Subject: [PATCH 270/641] build(deps): bump anyhow from 1.0.51 to 1.0.52 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf1f1b00d..e8543a9f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "atty" From 6ab2dc09b46f54fbb7c26ca2753f63c7e2e34006 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jan 2022 01:18:14 +0000 Subject: [PATCH 271/641] build(deps): bump clap from 2.34.0 to 3.0.0 Bumps [clap](https://github.com/clap-rs/clap) from 2.34.0 to 3.0.0. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v2.34.0...clap_complete-v3.0.0) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Cargo.lock | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 2 +- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8543a9f6..8ec516366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ dependencies = [ "anyhow", "bincode", "chrono", - "clap", + "clap 3.0.0", "env_logger", "fn-error-context", "fs2", @@ -128,12 +128,27 @@ dependencies = [ "ansi_term", "atty", "bitflags", - "strsim", - "textwrap", + "strsim 0.8.0", + "textwrap 0.11.0", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" +dependencies = [ + "atty", + "bitflags", + "indexmap", + "os_str_bytes", + "strsim 0.10.0", + "termcolor", + "textwrap 0.14.2", +] + [[package]] name = "cpufeatures" version = "0.2.1" @@ -232,6 +247,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" version = "0.3.3" @@ -272,6 +293,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.1" @@ -436,6 +467,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + [[package]] name = "pkg-config" version = "0.3.19" @@ -621,13 +661,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ - "clap", + "clap 2.34.0", "lazy_static", "structopt-derive", ] @@ -694,6 +740,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" + [[package]] name = "thiserror" version = "1.0.28" diff --git a/Cargo.toml b/Cargo.toml index 8134e67d2..51e4b641a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = ">= 2.33, < 2.35" +clap = ">= 2.33, < 3.1" env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" From c918f62e519cb57cd9994e1decd0dde35364cd81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jan 2022 01:18:23 +0000 Subject: [PATCH 272/641] build(deps): bump serde_json from 1.0.73 to 1.0.74 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.73 to 1.0.74. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.73...v1.0.74) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8543a9f6..40d8a456e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,9 +593,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ "itoa", "ryu", From e9c038e411e651d54bdaf64fe166c00dcbf0e023 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jan 2022 08:17:43 +0000 Subject: [PATCH 273/641] build(deps): bump serde from 1.0.132 to 1.0.133 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40d8a456e..0c5d222f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,18 +573,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", From 1db28d27bbefafa495d590c3978dac3b78e4b434 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 3 Jan 2022 10:52:10 +0000 Subject: [PATCH 274/641] ci: bump minimum Rust toolchain to 1.54 --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 52fdfa859..b684c3ed0 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -13,7 +13,7 @@ permissions: env: CARGO_TERM_COLOR: always # Minimum supported Rust version (MSRV) - ACTION_MSRV_TOOLCHAIN: 1.49.0 + ACTION_MSRV_TOOLCHAIN: 1.54.0 # Pinned toolchain for linting ACTION_LINTS_TOOLCHAIN: 1.57.0 From d4e1cb7683c5179e3a1bf108ba95cd96ba255bdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 01:03:11 +0000 Subject: [PATCH 275/641] build(deps): bump clap from 3.0.0 to 3.0.1 Bumps [clap](https://github.com/clap-rs/clap) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.0.0...clap_complete-v3.0.1) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a01741317..be3bd3217 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ dependencies = [ "anyhow", "bincode", "chrono", - "clap 3.0.0", + "clap 3.0.1", "env_logger", "fn-error-context", "fs2", @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" +checksum = "b1121e32687f7f90b905d4775273305baa4f32cd418923e9b0fa726533221857" dependencies = [ "atty", "bitflags", From 75d75106f7c5900dc983a13620d99bce7b64d19b Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 10 Jan 2022 10:38:00 +0000 Subject: [PATCH 276/641] Revert "build(deps): bump clap from 3.0.0 to 3.0.1" This reverts commit d4e1cb7683c5179e3a1bf108ba95cd96ba255bdf. --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be3bd3217..a01741317 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ dependencies = [ "anyhow", "bincode", "chrono", - "clap 3.0.1", + "clap 3.0.0", "env_logger", "fn-error-context", "fs2", @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1121e32687f7f90b905d4775273305baa4f32cd418923e9b0fa726533221857" +checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" dependencies = [ "atty", "bitflags", From dbaf624b1900701c9b4ff5e5ceecf35911d1da98 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 10 Jan 2022 10:38:18 +0000 Subject: [PATCH 277/641] Revert "ci: bump minimum Rust toolchain to 1.54" This reverts commit 1db28d27bbefafa495d590c3978dac3b78e4b434. --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b684c3ed0..52fdfa859 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -13,7 +13,7 @@ permissions: env: CARGO_TERM_COLOR: always # Minimum supported Rust version (MSRV) - ACTION_MSRV_TOOLCHAIN: 1.54.0 + ACTION_MSRV_TOOLCHAIN: 1.49.0 # Pinned toolchain for linting ACTION_LINTS_TOOLCHAIN: 1.57.0 From 69332949e94296dc3e5587e3e5398d08bf00a52a Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Mon, 10 Jan 2022 10:38:30 +0000 Subject: [PATCH 278/641] Revert "build(deps): bump clap from 2.34.0 to 3.0.0" This reverts commit 6ab2dc09b46f54fbb7c26ca2753f63c7e2e34006. --- Cargo.lock | 60 ++++-------------------------------------------------- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a01741317..0c5d222f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ dependencies = [ "anyhow", "bincode", "chrono", - "clap 3.0.0", + "clap", "env_logger", "fn-error-context", "fs2", @@ -128,27 +128,12 @@ dependencies = [ "ansi_term", "atty", "bitflags", - "strsim 0.8.0", - "textwrap 0.11.0", + "strsim", + "textwrap", "unicode-width", "vec_map", ] -[[package]] -name = "clap" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9" -dependencies = [ - "atty", - "bitflags", - "indexmap", - "os_str_bytes", - "strsim 0.10.0", - "termcolor", - "textwrap 0.14.2", -] - [[package]] name = "cpufeatures" version = "0.2.1" @@ -247,12 +232,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "heck" version = "0.3.3" @@ -293,16 +272,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "1.0.1" @@ -467,15 +436,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] - [[package]] name = "pkg-config" version = "0.3.19" @@ -661,19 +621,13 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "structopt" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ - "clap 2.34.0", + "clap", "lazy_static", "structopt-derive", ] @@ -740,12 +694,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "textwrap" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" - [[package]] name = "thiserror" version = "1.0.28" diff --git a/Cargo.toml b/Cargo.toml index 51e4b641a..8134e67d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = ">= 2.33, < 3.1" +clap = ">= 2.33, < 2.35" env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" From e4eb7c076caf73ff340fbec1d3d12a5b21a28d75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jan 2022 15:02:58 +0000 Subject: [PATCH 279/641] build(deps): bump tempfile from 3.2.0 to 3.3.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/Stebalien/tempfile/releases) - [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 24 +++++++++++++++++++++--- Cargo.toml | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c5d222f9..a602c2520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,6 +175,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + [[package]] name = "fn-error-context" version = "0.2.0" @@ -272,6 +281,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "itoa" version = "1.0.1" @@ -664,13 +682,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", diff --git a/Cargo.toml b/Cargo.toml index 8134e67d2..870caf4bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" structopt = "0.3" -tempfile = "^3.2" +tempfile = "^3.3" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo From dc5eb6da06c687b9d95258f9a1a0875b05db3de5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 01:05:18 +0000 Subject: [PATCH 280/641] build(deps): bump libsystemd from 0.4.1 to 0.5.0 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.4.1 to 0.5.0. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.4.1...v0.5.0) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 57 ++++++++++++++++++++++++++++++++---------------------- Cargo.toml | 2 +- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a602c2520..c5a327b5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" dependencies = [ "generic-array", ] @@ -144,22 +144,24 @@ dependencies = [ ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "crypto-common" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" dependencies = [ "generic-array", - "subtle", ] [[package]] name = "digest" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ + "block-buffer", + "crypto-common", "generic-array", + "subtle", ] [[package]] @@ -267,11 +269,10 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" dependencies = [ - "crypto-mac", "digest", ] @@ -310,14 +311,15 @@ checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libsystemd" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4f0b5b062ba67aa075e331de778082c09e66b5ef32970ea5a1e9c37c9555d1" +checksum = "8144587c71c16756b1055d3dcb0c75cb605a10ecd6523cc33702d5f90902bf6d" dependencies = [ "hmac", "libc", "log", "nix 0.23.1", + "nom", "once_cell", "serde", "sha2", @@ -349,6 +351,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "nix" version = "0.22.0" @@ -375,6 +383,17 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -400,12 +419,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openat" version = "0.1.21" @@ -622,15 +635,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.6" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", "digest", - "opaque-debug", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 870caf4bb..07f9a20d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ fs2 = "0.4.3" hex = "0.4.3" lazy_static = "1.4.0" libc = "^0.2" -libsystemd = ">= 0.3, < 0.5" +libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" From 3e3950fe93f95db3ab6d70484895d69045f64c0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jan 2022 01:28:04 +0000 Subject: [PATCH 281/641] build(deps): bump serde_json from 1.0.74 to 1.0.75 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.74 to 1.0.75. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.74...v1.0.75) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a602c2520..01fd37d19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" dependencies = [ "itoa", "ryu", From 842d6e4447f2c93cb51ffbdcca57c74583e89acd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jan 2022 01:06:58 +0000 Subject: [PATCH 282/641] build(deps): bump structopt from 0.3.25 to 0.3.26 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.25 to 0.3.26. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.25...v0.3.26) --- updated-dependencies: - dependency-name: structopt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87219dff9..504fb16e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -652,9 +652,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", From 85e1ee5ebe6eddd574a751d7a6bd46c28c0ba632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jan 2022 01:05:28 +0000 Subject: [PATCH 283/641] build(deps): bump libc from 0.2.112 to 0.2.113 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.112 to 0.2.113. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.112...0.2.113) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 504fb16e1..42e6bc877 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9" [[package]] name = "libsystemd" From a16981e08150aa62d0097176f016c7f72f12e76b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 01:14:01 +0000 Subject: [PATCH 284/641] build(deps): bump serde_json from 1.0.75 to 1.0.78 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.75 to 1.0.78. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.75...v1.0.78) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42e6bc877..64a126d3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ "itoa", "ryu", From 0efd3e99c739e494aeb217172ce38e5e218efaf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 01:14:07 +0000 Subject: [PATCH 285/641] build(deps): bump anyhow from 1.0.52 to 1.0.53 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.52 to 1.0.53. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.52...1.0.53) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42e6bc877..70a3fb2e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "atty" From bddc69f8ed24dc8122540e98a803fc75e1028e36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 01:14:11 +0000 Subject: [PATCH 286/641] build(deps): bump serde from 1.0.133 to 1.0.135 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.133 to 1.0.135. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.133...v1.0.135) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42e6bc877..4c8f667d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,18 +604,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d" dependencies = [ "proc-macro2", "quote", From 72e16c59330bd09ecef24f7454a5e2427e248688 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jan 2022 01:04:24 +0000 Subject: [PATCH 287/641] build(deps): bump serde from 1.0.135 to 1.0.136 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.135 to 1.0.136. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.135...v1.0.136) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f0b753f4..8cd36f48f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -604,18 +604,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", From fb0cb343b74b460ad5615bef49756171ec05e387 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jan 2022 01:04:29 +0000 Subject: [PATCH 288/641] build(deps): bump libc from 0.2.113 to 0.2.114 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.113 to 0.2.114. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.113...0.2.114) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f0b753f4..0bf8d24bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.113" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9" +checksum = "b0005d08a8f7b65fb8073cb697aa0b12b631ed251ce73d862ce50eeb52ce3b50" [[package]] name = "libsystemd" From 4ff182217a74cdabf59606542134cc6ecd95c048 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Feb 2022 01:05:55 +0000 Subject: [PATCH 289/641] build(deps): bump libc from 0.2.114 to 0.2.117 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.114 to 0.2.117. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.114...0.2.117) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfc6545f5..aee4bbd44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0005d08a8f7b65fb8073cb697aa0b12b631ed251ce73d862ce50eeb52ce3b50" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "libsystemd" From a9dbc5add81e2e43fb75d400c541c9d9187ac356 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Feb 2022 01:04:43 +0000 Subject: [PATCH 290/641] build(deps): bump serde_json from 1.0.78 to 1.0.79 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.78...v1.0.79) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aee4bbd44..f1772ff04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", From 334e3096401da45ea6a0bd084bb468923314ca05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Feb 2022 01:06:51 +0000 Subject: [PATCH 291/641] build(deps): bump libc from 0.2.117 to 0.2.118 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.117 to 0.2.118. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.117...0.2.118) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1772ff04..6aecbe0fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "libsystemd" From c2e3dc3aac4bc52396f3e7486a9c53af6ad05309 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Wed, 16 Feb 2022 23:48:50 -0500 Subject: [PATCH 292/641] templates/release-checklist: add Fedora/RHCOS packaging instructions --- .github/ISSUE_TEMPLATE/release-checklist.md | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index 066ffc377..344107db8 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -61,6 +61,51 @@ This guide requires: - [ ] `cargo clean` - [ ] `git checkout main` +- Fedora packaging: + - [ ] update the `rust-bootupd` spec file in [Fedora](https://src.fedoraproject.org/rpms/rust-bootupd) + - bump the `Version` + - switch the `Release` back to `1%{?dist}` + - remove any patches obsoleted by the new release + - update changelog + - [ ] run `spectool -g -S rust-bootupd.spec` + - [ ] run `kinit your_fas_account@FEDORAPROJECT.ORG` + - [ ] run `fedpkg new-sources ` + - [ ] PR the changes in [Fedora](https://src.fedoraproject.org/rpms/rust-bootupd) + - [ ] once the PR merges to rawhide, merge rawhide into the other relevant branches (e.g. f35) then push those, for example: + ```bash + git checkout rawhide + git pull --ff-only + git checkout f35 + git merge --ff-only rawhide + git push origin f35 + ``` + - [ ] on each of those branches run `fedpkg build` + - [ ] once the builds have finished, submit them to [bodhi](https://bodhi.fedoraproject.org/updates/new), filling in: + - `rust-bootupd` for `Packages` + - selecting the build(s) that just completed, except for the rawhide one (which gets submitted automatically) + - writing brief release notes like "New upstream release; see release notes at `link to GitHub release`" + - leave `Update name` blank + - `Type`, `Severity` and `Suggestion` can be left as `unspecified` unless it is a security release. In that case select `security` with the appropriate severity. + - `Stable karma` and `Unstable` karma can be set to `2` and `-1`, respectively. + - [ ] [submit a fast-track](https://github.com/coreos/fedora-coreos-config/actions/workflows/add-override.yml) for FCOS testing-devel + - [ ] [submit a fast-track](https://github.com/coreos/fedora-coreos-config/actions/workflows/add-override.yml) for FCOS next-devel if it is [open](https://github.com/coreos/fedora-coreos-pipeline/blob/main/next-devel/README.md) + +- RHCOS packaging: + - [ ] update the `rust-bootupd` spec file + - bump the `Version` + - switch the `Release` back to `1%{?dist}` + - remove any patches obsoleted by the new release + - update changelog + - [ ] run `spectool -g -S rust-bootupd.spec` + - [ ] run `kinit your_account@REDHAT.COM` + - [ ] run `rhpkg new-sources ` + - [ ] PR the changes + - [ ] get the PR reviewed and merge it + - [ ] update your local repo and run `rhpkg build` + +CentOS Stream 9 packaging: + - [ ] to be written + [rustup]: https://rustup.rs/ [crates-io]: https://crates.io/ [GPG setup]: https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification From b9405d319b89ecf43b58d4d86b439e80977a3941 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Feb 2022 01:17:58 +0000 Subject: [PATCH 293/641] build(deps): bump libc from 0.2.118 to 0.2.119 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.118 to 0.2.119. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.118...0.2.119) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6aecbe0fe..b2a1e3845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.118" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "libsystemd" From ef191e4e4b95172cd5b643d024b357162bf7b4e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Feb 2022 01:18:03 +0000 Subject: [PATCH 294/641] build(deps): bump anyhow from 1.0.53 to 1.0.54 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.53 to 1.0.54. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.53...1.0.54) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6aecbe0fe..a911f45da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "7a99269dff3bc004caa411f38845c20303f1e393ca2bd6581576fa3a7f59577d" [[package]] name = "atty" From 28254b591ca50f40938e99672b4b33e9f1b1b2c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Feb 2022 01:04:20 +0000 Subject: [PATCH 295/641] build(deps): bump anyhow from 1.0.54 to 1.0.55 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.54 to 1.0.55. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.54...1.0.55) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f61262676..9b96fa508 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a99269dff3bc004caa411f38845c20303f1e393ca2bd6581576fa3a7f59577d" +checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" [[package]] name = "atty" From 28c69349d5473c88854751d63f8c01f740228ae0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Feb 2022 01:11:54 +0000 Subject: [PATCH 296/641] build(deps): bump openat-ext from 0.2.2 to 0.2.3 Bumps [openat-ext](https://github.com/coreos/openat-ext) from 0.2.2 to 0.2.3. - [Release notes](https://github.com/coreos/openat-ext/releases) - [Commits](https://github.com/coreos/openat-ext/compare/v0.2.2...v0.2.3) --- updated-dependencies: - dependency-name: openat-ext dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 23 +++++------------------ Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b96fa508..41bed9ad8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.23.1", + "nix", "openat", "openat-ext", "openssl", @@ -318,7 +318,7 @@ dependencies = [ "hmac", "libc", "log", - "nix 0.23.1", + "nix", "nom", "once_cell", "serde", @@ -357,19 +357,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "nix" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" -dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", - "memoffset", -] - [[package]] name = "nix" version = "0.23.1" @@ -430,12 +417,12 @@ dependencies = [ [[package]] name = "openat-ext" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ebe55c8d6ada962ca7ddaef14f020dae1af91748bea3d36e8c941036b5d85b" +checksum = "2cf3e4baa7f516441f58373f58aaf6e91a5dfa2e2b50e68a0d313b082014c61d" dependencies = [ "libc", - "nix 0.22.0", + "nix", "openat", "rand", ] diff --git a/Cargo.toml b/Cargo.toml index 07f9a20d7..bcd4778ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" -openat-ext = "^0.2.2" +openat-ext = "^0.2.3" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 7df6a48c75eb5afe969572df3abc8b294636e0f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Mar 2022 01:07:43 +0000 Subject: [PATCH 297/641] build(deps): bump anyhow from 1.0.55 to 1.0.56 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.55 to 1.0.56. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.55...1.0.56) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b96fa508..42bfbd22f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.55" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] name = "atty" From d102e0dc5d01058d4b0292959a227b7bf8b0b066 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 01:04:55 +0000 Subject: [PATCH 298/641] build(deps): bump libc from 0.2.119 to 0.2.120 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.119 to 0.2.120. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.119...0.2.120) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42bfbd22f..ea3347921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" [[package]] name = "libsystemd" From 27b15dc519bbeacbe08d6c9d902d29782abdfb53 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 15 Mar 2022 13:31:44 -0400 Subject: [PATCH 299/641] cargo: accept openat-ext 0.2.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bcd4778ae..6dc2f3f11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" -openat-ext = "^0.2.3" +openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 0f558b6df88acc2627d683e9cd56a1cd3162bbce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 01:21:34 +0000 Subject: [PATCH 300/641] build(deps): bump libc from 0.2.120 to 0.2.121 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.120 to 0.2.121. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.120...0.2.121) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f84e8f148..cbe2bb003 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,9 +305,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" +checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" [[package]] name = "libsystemd" From 3d747b8989a384490fe5d5b5c91a243e09a4087c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Mar 2022 01:04:41 +0000 Subject: [PATCH 301/641] build(deps): bump log from 0.4.14 to 0.4.16 Bumps [log](https://github.com/rust-lang/log) from 0.4.14 to 0.4.16. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/commits) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbe2bb003..f4208d24a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -329,9 +329,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if", ] From ec2dcdd155f126d641986aca823854a29cc5fa2a Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 4 Apr 2022 23:20:11 -0400 Subject: [PATCH 302/641] Update clippy to 1.59.0 --- .github/workflows/rust.yml | 2 +- src/bootupd.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 52fdfa859..d1d0ba2bf 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -15,7 +15,7 @@ env: # Minimum supported Rust version (MSRV) ACTION_MSRV_TOOLCHAIN: 1.49.0 # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.57.0 + ACTION_LINTS_TOOLCHAIN: 1.59.0 jobs: tests-stable: diff --git a/src/bootupd.rs b/src/bootupd.rs index 7579039ab..616d94dc4 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -191,11 +191,7 @@ pub(crate) fn status() -> Result { .remove(name.as_str()) .ok_or_else(|| anyhow!("Unknown component installed: {}", name))?; let component = component.as_ref(); - let interrupted = state - .pending - .as_ref() - .map(|p| p.get(name.as_str())) - .flatten(); + let interrupted = state.pending.as_ref().and_then(|p| p.get(name.as_str())); let update = component.query_update(&sysroot)?; let updatable = ComponentUpdatable::from_metadata(&ic.meta, update.as_ref()); let adopted_from = ic.adopted_from.clone(); From 607ace516bf94650476f523ab6e67273a2e4ec0c Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 4 Apr 2022 23:20:51 -0400 Subject: [PATCH 303/641] cargo: update to Rust 2021; bump MSRV to 1.56.0 `cargo fix --edition` makes no code changes. --- .github/workflows/rust.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d1d0ba2bf..4e91fc4b2 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -13,7 +13,7 @@ permissions: env: CARGO_TERM_COLOR: always # Minimum supported Rust version (MSRV) - ACTION_MSRV_TOOLCHAIN: 1.49.0 + ACTION_MSRV_TOOLCHAIN: 1.56.0 # Pinned toolchain for linting ACTION_LINTS_TOOLCHAIN: 1.59.0 diff --git a/Cargo.toml b/Cargo.toml index 6dc2f3f11..402c297f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ description = "Bootloader updater" license = "Apache-2.0" version = "0.2.7-alpha.0" authors = ["Colin Walters "] -edition = "2018" +edition = "2021" [[bin]] name = "bootupd" From c8849da436558ae946781b0109d4120818589650 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 4 Apr 2022 23:25:52 -0400 Subject: [PATCH 304/641] cargo: declare MSRV in Cargo.toml This is supported starting in Rust 1.56.0. --- .github/workflows/rust.yml | 10 +++++++--- Cargo.toml | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4e91fc4b2..9c3a60d5d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,8 +12,6 @@ permissions: env: CARGO_TERM_COLOR: always - # Minimum supported Rust version (MSRV) - ACTION_MSRV_TOOLCHAIN: 1.56.0 # Pinned toolchain for linting ACTION_LINTS_TOOLCHAIN: 1.59.0 @@ -54,10 +52,16 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + - name: Detect crate MSRV + run: | + msrv=$(cargo metadata --format-version 1 --no-deps | \ + jq -r '.packages | .[].rust_version') + echo "Crate MSRV: $msrv" + echo "MSRV=$msrv" >> $GITHUB_ENV - name: Install toolchain uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env['ACTION_MSRV_TOOLCHAIN'] }} + toolchain: ${{ env.MSRV }} default: true - name: cargo build (release) run: cargo build --release diff --git a/Cargo.toml b/Cargo.toml index 402c297f4..fd127af9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ license = "Apache-2.0" version = "0.2.7-alpha.0" authors = ["Colin Walters "] edition = "2021" +rust-version = "1.56.0" [[bin]] name = "bootupd" From 0f906fe983d9b07deff1b30d54cd674ce83e11ea Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 5 Apr 2022 12:40:06 -0400 Subject: [PATCH 305/641] cli: move to clap 3.1 Just get it running for now. #[clap(subcommand)] is now required on subcommands that contain subcommands. Explicitly disable color help at build time. clap 2 defaulted to enabling the code at build time but disabling it by default, while clap 3 builds and enables it by default. --- Cargo.lock | 128 ++++++++++++++++++------------------------- Cargo.toml | 3 +- src/cli/bootupctl.rs | 6 +- src/cli/bootupd.rs | 4 +- src/cli/mod.rs | 2 +- src/main.rs | 2 +- 6 files changed, 62 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4208d24a..536e560c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,15 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.56" @@ -89,7 +80,6 @@ dependencies = [ "openssl", "serde", "serde_json", - "structopt", "tempfile", ] @@ -121,17 +111,30 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" dependencies = [ - "ansi_term", - "atty", "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", "strsim", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -243,14 +246,17 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -282,6 +288,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "instant" version = "0.1.12" @@ -454,6 +470,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + [[package]] name = "pkg-config" version = "0.3.19" @@ -492,9 +517,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -633,33 +658,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" @@ -669,9 +670,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.73" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" dependencies = [ "proc-macro2", "quote", @@ -703,12 +704,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" @@ -746,18 +744,6 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - [[package]] name = "unicode-xid" version = "0.2.2" @@ -779,12 +765,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index fd127af9f..2200ad982 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = ">= 2.33, < 2.35" +clap = { version = "3.1", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" @@ -30,7 +30,6 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -structopt = "0.3" tempfile = "^3.3" [profile.release] diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index fb67a377b..436c0a54b 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -2,16 +2,15 @@ use crate::bootupd; use crate::ipc::ClientToDaemonConnection; use crate::model::Status; use anyhow::Result; +use clap::{AppSettings, StructOpt}; use log::LevelFilter; -use structopt::clap::AppSettings; -use structopt::StructOpt; /// `bootupctl` sub-commands. #[derive(Debug, StructOpt)] #[structopt(name = "bootupctl", about = "Bootupd client application")] pub struct CtlCommand { /// Verbosity level (higher is more verbose). - #[structopt(short = "v", parse(from_occurrences), global = true)] + #[structopt(short = 'v', parse(from_occurrences), global = true)] verbosity: u8, /// CLI sub-command. @@ -37,6 +36,7 @@ pub enum CtlVerb { // FIXME(lucab): drop this after refreshing // https://github.com/coreos/fedora-coreos-config/pull/595 #[structopt(name = "backend", setting = AppSettings::Hidden)] + #[clap(subcommand)] Backend(CtlBackend), #[structopt(name = "status", about = "Show components status")] Status(StatusOpts), diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index efd58ddea..22fe28743 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -1,14 +1,14 @@ use crate::bootupd; use anyhow::{Context, Result}; +use clap::StructOpt; use log::LevelFilter; -use structopt::StructOpt; /// `bootupd` sub-commands. #[derive(Debug, StructOpt)] #[structopt(name = "bootupd", about = "Bootupd backend commands")] pub struct DCommand { /// Verbosity level (higher is more verbose). - #[structopt(short = "v", parse(from_occurrences), global = true)] + #[structopt(short = 'v', parse(from_occurrences), global = true)] verbosity: u8, /// CLI sub-command. diff --git a/src/cli/mod.rs b/src/cli/mod.rs index bcd68cc3e..f7881bc81 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,8 +1,8 @@ //! Command-line interface (CLI) logic. use anyhow::Result; +use clap::StructOpt; use log::LevelFilter; -use structopt::StructOpt; mod bootupctl; mod bootupd; diff --git a/src/main.rs b/src/main.rs index 740c0db55..a22aab082 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ mod ostreeutil; mod sha512string; mod util; -use structopt::clap::crate_name; +use clap::crate_name; /// Binary entrypoint, for both daemon and client logic. fn main() { From d00e133c48de5ea0d994beebcf28aa62437782e4 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 5 Apr 2022 12:45:17 -0400 Subject: [PATCH 306/641] cli: update structopt-derived names --- src/cli/bootupctl.rs | 35 +++++++++++++++++------------------ src/cli/bootupd.rs | 24 ++++++++++++------------ 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 436c0a54b..9e7ac263c 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -2,19 +2,19 @@ use crate::bootupd; use crate::ipc::ClientToDaemonConnection; use crate::model::Status; use anyhow::Result; -use clap::{AppSettings, StructOpt}; +use clap::{AppSettings, Parser}; use log::LevelFilter; /// `bootupctl` sub-commands. -#[derive(Debug, StructOpt)] -#[structopt(name = "bootupctl", about = "Bootupd client application")] +#[derive(Debug, Parser)] +#[clap(name = "bootupctl", about = "Bootupd client application")] pub struct CtlCommand { /// Verbosity level (higher is more verbose). - #[structopt(short = 'v', parse(from_occurrences), global = true)] + #[clap(short = 'v', parse(from_occurrences), global = true)] verbosity: u8, /// CLI sub-command. - #[structopt(subcommand)] + #[clap(subcommand)] pub cmd: CtlVerb, } @@ -31,41 +31,40 @@ impl CtlCommand { } /// CLI sub-commands. -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub enum CtlVerb { // FIXME(lucab): drop this after refreshing // https://github.com/coreos/fedora-coreos-config/pull/595 - #[structopt(name = "backend", setting = AppSettings::Hidden)] - #[clap(subcommand)] + #[clap(name = "backend", setting = AppSettings::Hidden, subcommand)] Backend(CtlBackend), - #[structopt(name = "status", about = "Show components status")] + #[clap(name = "status", about = "Show components status")] Status(StatusOpts), - #[structopt(name = "update", about = "Update all components")] + #[clap(name = "update", about = "Update all components")] Update, - #[structopt(name = "adopt-and-update", about = "Update all adoptable components")] + #[clap(name = "adopt-and-update", about = "Update all adoptable components")] AdoptAndUpdate, - #[structopt(name = "validate", about = "Validate system state")] + #[clap(name = "validate", about = "Validate system state")] Validate, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub enum CtlBackend { - #[structopt(name = "generate-update-metadata", setting = AppSettings::Hidden)] + #[clap(name = "generate-update-metadata", setting = AppSettings::Hidden)] Generate(super::bootupd::GenerateOpts), - #[structopt(name = "install", setting = AppSettings::Hidden)] + #[clap(name = "install", setting = AppSettings::Hidden)] Install(super::bootupd::InstallOpts), } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct StatusOpts { /// If there are updates available, output `Updates available: ` to standard output; /// otherwise output nothing. Avoid parsing this, just check whether or not /// the output is empty. - #[structopt(long)] + #[clap(long)] print_if_available: bool, /// Output JSON - #[structopt(long)] + #[clap(long)] json: bool, } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 22fe28743..0f40bb1d1 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -1,18 +1,18 @@ use crate::bootupd; use anyhow::{Context, Result}; -use clap::StructOpt; +use clap::Parser; use log::LevelFilter; /// `bootupd` sub-commands. -#[derive(Debug, StructOpt)] -#[structopt(name = "bootupd", about = "Bootupd backend commands")] +#[derive(Debug, Parser)] +#[clap(name = "bootupd", about = "Bootupd backend commands")] pub struct DCommand { /// Verbosity level (higher is more verbose). - #[structopt(short = 'v', parse(from_occurrences), global = true)] + #[clap(short = 'v', parse(from_occurrences), global = true)] verbosity: u8, /// CLI sub-command. - #[structopt(subcommand)] + #[clap(subcommand)] pub cmd: DVerb, } @@ -29,26 +29,26 @@ impl DCommand { } /// CLI sub-commands. -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub enum DVerb { - #[structopt(name = "daemon", about = "Run service logic")] + #[clap(name = "daemon", about = "Run service logic")] Daemon, - #[structopt(name = "generate-update-metadata", about = "Generate metadata")] + #[clap(name = "generate-update-metadata", about = "Generate metadata")] GenerateUpdateMetadata(GenerateOpts), - #[structopt(name = "install", about = "Install components")] + #[clap(name = "install", about = "Install components")] Install(InstallOpts), } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct InstallOpts { /// Source root - #[structopt(long, default_value = "/")] + #[clap(long, default_value = "/")] src_root: String, /// Target root dest_root: String, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub struct GenerateOpts { /// Physical root mountpoint sysroot: String, From a3fbb0c44a248998fe26815bc0f6b98cb9c1bc91 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 5 Apr 2022 12:52:12 -0400 Subject: [PATCH 307/641] cli: fix clap deprecation warnings --- src/cli/bootupctl.rs | 8 ++++---- src/cli/mod.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 9e7ac263c..c1d7efdf1 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -2,7 +2,7 @@ use crate::bootupd; use crate::ipc::ClientToDaemonConnection; use crate::model::Status; use anyhow::Result; -use clap::{AppSettings, Parser}; +use clap::Parser; use log::LevelFilter; /// `bootupctl` sub-commands. @@ -35,7 +35,7 @@ impl CtlCommand { pub enum CtlVerb { // FIXME(lucab): drop this after refreshing // https://github.com/coreos/fedora-coreos-config/pull/595 - #[clap(name = "backend", setting = AppSettings::Hidden, subcommand)] + #[clap(name = "backend", hide = true, subcommand)] Backend(CtlBackend), #[clap(name = "status", about = "Show components status")] Status(StatusOpts), @@ -49,9 +49,9 @@ pub enum CtlVerb { #[derive(Debug, Parser)] pub enum CtlBackend { - #[clap(name = "generate-update-metadata", setting = AppSettings::Hidden)] + #[clap(name = "generate-update-metadata", hide = true)] Generate(super::bootupd::GenerateOpts), - #[clap(name = "install", setting = AppSettings::Hidden)] + #[clap(name = "install", hide = true)] Install(super::bootupd::InstallOpts), } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index f7881bc81..02da56af9 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -27,8 +27,8 @@ impl MultiCall { }; #[allow(clippy::wildcard_in_or_patterns)] match exe_name.as_bytes() { - b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::from_iter(args)), - b"bootupd" | _ => MultiCall::D(bootupd::DCommand::from_iter(args)), + b"bootupctl" => MultiCall::Ctl(bootupctl::CtlCommand::parse_from(args)), + b"bootupd" | _ => MultiCall::D(bootupd::DCommand::parse_from(args)), } } From 174382001e3529739445fef71d705f680ce66f8a Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 5 Apr 2022 13:01:55 -0400 Subject: [PATCH 308/641] cli: add clap self-tests --- src/cli/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 02da56af9..c89c86615 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -52,6 +52,13 @@ impl MultiCall { mod tests { use super::*; + #[test] + fn clap_apps() { + use clap::CommandFactory; + bootupctl::CtlCommand::command().debug_assert(); + bootupd::DCommand::command().debug_assert(); + } + #[test] fn test_multicall_dispatch() { { From 8ceec29aec793fe9f3f99c524bf1bd0b3f986095 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Apr 2022 01:09:50 +0000 Subject: [PATCH 309/641] build(deps): bump libc from 0.2.121 to 0.2.122 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.121 to 0.2.122. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.121...0.2.122) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 536e560c0..a8d0ab2c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,9 +321,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" [[package]] name = "libsystemd" From 73fa2e7ac48821cc9bda2d21f9f29a10546c2787 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Apr 2022 01:06:40 +0000 Subject: [PATCH 310/641] build(deps): bump libc from 0.2.122 to 0.2.123 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.122 to 0.2.123. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.122...0.2.123) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8d0ab2c6..a7b8a73e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,9 +321,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" [[package]] name = "libsystemd" From 95fec2c437e24781d2132bb4518b72e080ed9414 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Apr 2022 01:25:22 +0000 Subject: [PATCH 311/641] build(deps): bump clap from 3.1.8 to 3.1.9 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.8 to 3.1.9. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.8...v3.1.9) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7b8a73e7..60cff8600 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,15 +111,15 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.8" +version = "3.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe" dependencies = [ "bitflags", "clap_derive", + "clap_lex", "indexmap", "lazy_static", - "os_str_bytes", "strsim", "textwrap", ] @@ -137,6 +137,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cpufeatures" version = "0.2.1" @@ -475,9 +484,6 @@ name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] [[package]] name = "pkg-config" From 55923d0fdae6f3746ecfa39b7941506f76b0765d Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 18 Apr 2022 18:05:18 -0400 Subject: [PATCH 312/641] cli: reinstate --version flag It was lost in the switch to clap 3.1. --- src/cli/bootupctl.rs | 2 +- src/cli/bootupd.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index c1d7efdf1..e401a7fff 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -7,7 +7,7 @@ use log::LevelFilter; /// `bootupctl` sub-commands. #[derive(Debug, Parser)] -#[clap(name = "bootupctl", about = "Bootupd client application")] +#[clap(name = "bootupctl", about = "Bootupd client application", version)] pub struct CtlCommand { /// Verbosity level (higher is more verbose). #[clap(short = 'v', parse(from_occurrences), global = true)] diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 0f40bb1d1..87276672f 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -5,7 +5,7 @@ use log::LevelFilter; /// `bootupd` sub-commands. #[derive(Debug, Parser)] -#[clap(name = "bootupd", about = "Bootupd backend commands")] +#[clap(name = "bootupd", about = "Bootupd backend commands", version)] pub struct DCommand { /// Verbosity level (higher is more verbose). #[clap(short = 'v', parse(from_occurrences), global = true)] From 572f2dceeb62dcc682667d77ef7895fffb6dd2a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Apr 2022 01:06:06 +0000 Subject: [PATCH 313/641] build(deps): bump libc from 0.2.123 to 0.2.124 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.123 to 0.2.124. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.123...0.2.124) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60cff8600..751755b7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.123" +version = "0.2.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" [[package]] name = "libsystemd" From d9dcbc31484fd0eab1d1a7a79c01e4ff94275ee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 01:04:41 +0000 Subject: [PATCH 314/641] build(deps): bump clap from 3.1.9 to 3.1.10 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 751755b7c..94467a7fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.9" +version = "3.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe" +checksum = "3124f3f75ce09e22d1410043e1e24f2ecc44fad3afe4f08408f1f7663d68da2b" dependencies = [ "bitflags", "clap_derive", From 737e1ffed8cccb6cbe59ae2f54f88d90c5b8d553 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Apr 2022 01:05:31 +0000 Subject: [PATCH 315/641] build(deps): bump anyhow from 1.0.56 to 1.0.57 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.56 to 1.0.57. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.56...1.0.57) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94467a7fc..ea0d04f5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "atty" From d86add4749cf2261bae224ac01c2df4aed7efb14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 02:13:08 +0000 Subject: [PATCH 316/641] build(deps): bump clap from 3.1.10 to 3.1.12 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.10 to 3.1.12. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.10...v3.1.12) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea0d04f5b..748dbd67b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.10" +version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3124f3f75ce09e22d1410043e1e24f2ecc44fad3afe4f08408f1f7663d68da2b" +checksum = "7c167e37342afc5f33fd87bbc870cedd020d2a6dffa05d45ccd9241fbdd146db" dependencies = [ "bitflags", "clap_derive", From dfeb718b69cd2d92a43320fee596753518eba2d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 01:26:18 +0000 Subject: [PATCH 317/641] build(deps): bump libc from 0.2.124 to 0.2.125 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.124 to 0.2.125. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.124...0.2.125) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 748dbd67b..66d8f0023 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.124" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "libsystemd" From 6c2101a0c410a9164687e3186a467d6c45f79989 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 01:26:25 +0000 Subject: [PATCH 318/641] build(deps): bump serde from 1.0.136 to 1.0.137 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.136 to 1.0.137. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.136...v1.0.137) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 748dbd67b..3b08a7b5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,18 +622,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", From 209939d91644cc4622e0a1d5779c92ea50498425 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 01:26:33 +0000 Subject: [PATCH 319/641] build(deps): bump clap from 3.1.12 to 3.1.14 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.12 to 3.1.14. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.12...v3.1.14) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 748dbd67b..928700c82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.12" +version = "3.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c167e37342afc5f33fd87bbc870cedd020d2a6dffa05d45ccd9241fbdd146db" +checksum = "535434c063ced786eb04aaf529308092c5ab60889e8fe24275d15de07b01fa97" dependencies = [ "bitflags", "clap_derive", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" dependencies = [ "os_str_bytes", ] From 81a0be0ca4c5d9133a41451bf6237bbcbea19833 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 May 2022 01:26:40 +0000 Subject: [PATCH 320/641] build(deps): bump serde_json from 1.0.79 to 1.0.80 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.79 to 1.0.80. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.79...v1.0.80) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 748dbd67b..0e7e8aa0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944" dependencies = [ "itoa", "ryu", From ba687e69db2ae127b3d39b189f969dca35ba152b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 May 2022 01:05:17 +0000 Subject: [PATCH 321/641] build(deps): bump log from 0.4.16 to 0.4.17 Bumps [log](https://github.com/rust-lang/log) from 0.4.16 to 0.4.17. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/commits/0.4.17) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 040ae236e..f893fc705 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,9 +354,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] From 96f7fac011af1761a127fa11288c75f92ea05f64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 May 2022 01:05:21 +0000 Subject: [PATCH 322/641] build(deps): bump clap from 3.1.14 to 3.1.15 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.14 to 3.1.15. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.14...v3.1.15) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 040ae236e..7cd09b2f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.14" +version = "3.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535434c063ced786eb04aaf529308092c5ab60889e8fe24275d15de07b01fa97" +checksum = "85a35a599b11c089a7f49105658d089b8f2cf0882993c17daf6de15285c2c35d" dependencies = [ "bitflags", "clap_derive", From ac3393775d8a0ec12db547c7cd052e2d98bc6f39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 May 2022 01:04:25 +0000 Subject: [PATCH 323/641] build(deps): bump serde_json from 1.0.80 to 1.0.81 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.80 to 1.0.81. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.80...v1.0.81) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cbf52243..a77f6fd37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", From 4b7cda439bacd78e4ed3b0ceab624276c5e17bf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 May 2022 01:05:23 +0000 Subject: [PATCH 324/641] build(deps): bump openssl from 0.10.38 to 0.10.40 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.38 to 0.10.40. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.38...openssl-v0.10.40) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a77f6fd37..795ed6f40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,23 +454,35 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-sys" -version = "0.9.70" +version = "0.9.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf" +checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" dependencies = [ "autocfg", "cc", From 9f216114bc3c65cc8799ee0af4cccb2c6cfee18e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 02:04:09 +0000 Subject: [PATCH 325/641] build(deps): bump clap from 3.1.15 to 3.1.17 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.15 to 3.1.17. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.15...v3.1.17) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 795ed6f40..2d047c2a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.15" +version = "3.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a35a599b11c089a7f49105658d089b8f2cf0882993c17daf6de15285c2c35d" +checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0" dependencies = [ "bitflags", "clap_derive", From 9ebc78096c541042924717fb2a0fed03e1f07773 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 13 May 2022 04:05:45 -0400 Subject: [PATCH 326/641] ci: fix e2e-update test with current Git Tell Git that the current directory is safe, even though it's not owned by the current user. Fixes https://github.com/coreos/bootupd/issues/333. --- .cci.jenkinsfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index af38c1e11..35c6dc2af 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -56,7 +56,10 @@ cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { try { // Now a test that upgrades using bootupd stage("e2e upgrade test") { - shwrap("env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh") + shwrap(""" + git config --global --add safe.directory "\$(pwd)" + env COSA_DIR=${env.WORKSPACE} ./tests/e2e-update/e2e-update.sh + """) } stage("Kola testing") { // The previous e2e leaves things only having built an ostree update From c721bf9f384b097b8b5bbee8f2d08736ee00b626 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 9 May 2022 14:26:58 -0400 Subject: [PATCH 327/641] dependabot: switch to weekly cadence Daily Dependabot updates are generating too much PR noise. Reduce to weekly. --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 582dadd78..bf123a68f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: cargo directory: "/" schedule: - interval: daily + interval: weekly open-pull-requests-limit: 10 labels: - area/dependencies From fd7c26d5f576461229b8f5dcb437a7d39f6a7362 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 May 2022 22:02:03 +0000 Subject: [PATCH 328/641] build(deps): bump clap from 3.1.17 to 3.1.18 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.17 to 3.1.18. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.17...v3.1.18) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d047c2a6..a0b6977b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.17" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" dependencies = [ "bitflags", "clap_derive", @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.7" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" dependencies = [ "heck", "proc-macro-error", From 44abaabd2117dcb75deed48152e1d665d55dc055 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 May 2022 01:04:23 +0000 Subject: [PATCH 329/641] build(deps): bump libc from 0.2.125 to 0.2.126 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.125 to 0.2.126. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.125...0.2.126) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0b6977b4..20f9e8f10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libsystemd" From 2523005da58bb8011920f9fc3e5fc41a67187aa9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 14:36:49 +0000 Subject: [PATCH 330/641] build(deps): bump regex from 1.5.4 to 1.5.6 Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.6. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.6) --- updated-dependencies: - dependency-name: regex dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20f9e8f10..580d49c56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -613,9 +613,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "remove_dir_all" From 8c39ddad1696e31d4e726b6b31ae52e13768c967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 01:25:35 +0000 Subject: [PATCH 331/641] build(deps): bump clap from 3.1.18 to 3.2.2 Bumps [clap](https://github.com/clap-rs/clap) from 3.1.18 to 3.2.2. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.1.18...v3.2.2) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 580d49c56..a26fcc901 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "8e538f9ee5aa3b3963f09a997035f883677966ed50fce0292611927ce6f6d8c6" dependencies = [ "bitflags", "clap_derive", @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.18" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "a7f98063cac4652f23ccda556b8d04347a7fc4b2cff1f7577cc8c6546e0d8078" dependencies = [ "heck", "proc-macro-error", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" dependencies = [ "os_str_bytes", ] diff --git a/Cargo.toml b/Cargo.toml index 2200ad982..2a07fa721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.11", features = ["serde"] } -clap = { version = "3.1", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } +clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" From 6ef795eb3750b767388c7a5582dc36f33cb20d9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 01:25:39 +0000 Subject: [PATCH 332/641] build(deps): bump anyhow from 1.0.57 to 1.0.58 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.57 to 1.0.58. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.57...1.0.58) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 580d49c56..76bb276cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" [[package]] name = "atty" From e02fd9925e245465a63d1892ac5ab103e8cea131 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Jul 2022 01:41:58 +0000 Subject: [PATCH 333/641] build(deps): bump openssl from 0.10.40 to 0.10.41 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.40 to 0.10.41. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.40...openssl-v0.10.41) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76bb276cf..214e688e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,9 +454,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.40" +version = "0.10.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ "bitflags", "cfg-if", @@ -480,9 +480,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.73" +version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ "autocfg", "cc", From f1edd873e4216fd00d0b6160af3af8eed346f104 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Jul 2022 01:28:56 +0000 Subject: [PATCH 334/641] build(deps): bump serde from 1.0.137 to 1.0.139 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.137 to 1.0.139. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.137...v1.0.139) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76bb276cf..ebb85b149 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,18 +634,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" dependencies = [ "proc-macro2", "quote", From eebd9dce6a6ac3bb1e26be94b40eb618600fd23a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jul 2022 17:47:47 -0400 Subject: [PATCH 335/641] cli: Update to use `ArgAction` --- src/cli/bootupctl.rs | 2 +- src/cli/bootupd.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index e401a7fff..a175d25f2 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -10,7 +10,7 @@ use log::LevelFilter; #[clap(name = "bootupctl", about = "Bootupd client application", version)] pub struct CtlCommand { /// Verbosity level (higher is more verbose). - #[clap(short = 'v', parse(from_occurrences), global = true)] + #[clap(short = 'v', action = clap::ArgAction::Count, global = true)] verbosity: u8, /// CLI sub-command. diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 87276672f..55c99e36a 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -8,7 +8,7 @@ use log::LevelFilter; #[clap(name = "bootupd", about = "Bootupd backend commands", version)] pub struct DCommand { /// Verbosity level (higher is more verbose). - #[clap(short = 'v', parse(from_occurrences), global = true)] + #[clap(short = 'v', action = clap::ArgAction::Count, global = true)] verbosity: u8, /// CLI sub-command. From b21d8807fca44a88c236d547f3ef6a69c0c71bf4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jul 2022 17:52:33 -0400 Subject: [PATCH 336/641] cli: Update to latest clap APIs Honestly I'm not sure this was worth the churn, but whatever. --- src/cli/bootupctl.rs | 4 ++-- src/cli/bootupd.rs | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index a175d25f2..3883a7a72 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -60,11 +60,11 @@ pub struct StatusOpts { /// If there are updates available, output `Updates available: ` to standard output; /// otherwise output nothing. Avoid parsing this, just check whether or not /// the output is empty. - #[clap(long)] + #[clap(long, action)] print_if_available: bool, /// Output JSON - #[clap(long)] + #[clap(long, action)] json: bool, } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 55c99e36a..1ed5c3628 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -42,15 +42,17 @@ pub enum DVerb { #[derive(Debug, Parser)] pub struct InstallOpts { /// Source root - #[clap(long, default_value = "/")] + #[clap(long, value_parser, default_value_t = String::from("/"))] src_root: String, /// Target root + #[clap(value_parser)] dest_root: String, } #[derive(Debug, Parser)] pub struct GenerateOpts { /// Physical root mountpoint + #[clap(value_parser)] sysroot: String, } From f8e8447f88e8374d9802a1fec68a7c6fe5b53e03 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jul 2022 17:55:21 -0400 Subject: [PATCH 337/641] Bump MSRV To pick up the latest inline format bits at least. Matches other projects in coreos/ GH org. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2200ad982..54e6b1a39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ license = "Apache-2.0" version = "0.2.7-alpha.0" authors = ["Colin Walters "] edition = "2021" -rust-version = "1.56.0" +rust-version = "1.58.1" [[bin]] name = "bootupd" From c009f9fd8146066eefe0aa9506581e459ed0fd45 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jul 2022 17:38:15 -0400 Subject: [PATCH 338/641] Use inline `format!` in a few places Just a minor cleanup. --- src/filetree.rs | 4 ++-- src/util.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index 2ac89a8e8..93289253c 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -312,13 +312,13 @@ pub(crate) fn apply_diff( let pathtmp = tmpname_for_path(path); destdir .local_rename(&pathtmp, path) - .with_context(|| format!("renaming {}", path))?; + .with_context(|| format!("renaming {path}"))?; } if !opts.skip_removals { for path in diff.removals.iter() { destdir .remove_file(path) - .with_context(|| format!("removing {}", path))?; + .with_context(|| format!("removing {path}"))?; } } // A second full filesystem sync to narrow any races rather than diff --git a/src/util.rs b/src/util.rs index 1b8a64e9a..75651d158 100644 --- a/src/util.rs +++ b/src/util.rs @@ -45,7 +45,7 @@ pub(crate) fn filenames(dir: &openat::Dir) -> Result> { }; match dir.get_file_type(&entry)? { openat::SimpleType::File => { - ret.insert(format!("/{}", name)); + ret.insert(format!("/{name}")); } openat::SimpleType::Dir => { let child = dir.sub_dir(name)?; From ecd5d2a2744230d2b974312cbe9e84afb120960f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Jul 2022 17:39:58 -0400 Subject: [PATCH 339/641] Add `package.metadata.vendor-filter` To reduce the size of our vendor tarball, xref https://github.com/coreos/fedora-coreos-tracker/issues/1240 --- Cargo.toml | 4 ++++ ci/prepare-release.sh | 8 +------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2200ad982..8f3bbff0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ authors = ["Colin Walters "] edition = "2021" rust-version = "1.56.0" +# See https://github.com/cgwalters/cargo-vendor-filterer +[package.metadata.vendor-filter] +platforms = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"] + [[bin]] name = "bootupd" path = "src/main.rs" diff --git a/ci/prepare-release.sh b/ci/prepare-release.sh index 1a653cbc8..c47c545f7 100755 --- a/ci/prepare-release.sh +++ b/ci/prepare-release.sh @@ -9,12 +9,6 @@ commit=$(git rev-parse HEAD) # Generate a vendor tarball of sources to attach to a release # in order to support offline builds. vendor_dest=target/${name}-${version}-vendor.tar.gz -rm vendor ${vendor_dest} -rf -cargo vendor -# Trim off Windows pre-built libraries that make the vendor/ dir much larger -find vendor/ -name '*.a' -delete -tar czvf ${vendor_dest}.tmp vendor/ -rm vendor -rf -mv -Tf ${vendor_dest}{.tmp,} +cargo vendor-filterer --format=tar.gz "${vendor_dest}" echo "Prepared ${version} at commit ${commit}" From ffdbc652149936a623e62c3a27f580bdd84ac7a0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Jul 2022 17:15:39 -0400 Subject: [PATCH 340/641] Release 0.2.7 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 880e18810..feae94f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.7-alpha.0" +version = "0.2.7" authors = ["Colin Walters "] edition = "2021" rust-version = "1.58.1" From 65b67130b3186be42d9071d123c1c97454cdb509 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 01:27:09 +0000 Subject: [PATCH 341/641] build(deps): bump serde from 1.0.139 to 1.0.140 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.139 to 1.0.140. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.139...v1.0.140) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10218fe22..ef87c6073 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,18 +634,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", From 0d16659b158c27f4d3ca18e2856ec893a9655760 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Jul 2022 09:58:24 -0400 Subject: [PATCH 342/641] Update lockfile --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ef87c6073..088c08061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,7 +60,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.7-alpha.0" +version = "0.2.7" dependencies = [ "anyhow", "bincode", From 5a9d15ec81b75aef57809864122012a886fcff68 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 1 Aug 2022 10:40:45 -0400 Subject: [PATCH 343/641] =?UTF-8?q?Port=20from=20`lazy=5Fstatic`=20?= =?UTF-8?q?=E2=86=92=20`once=5Fcell`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The latter is likely to end up in `std` at some point. --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- src/efi.rs | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 088c08061..ec2edde31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,11 +70,11 @@ dependencies = [ "fn-error-context", "fs2", "hex", - "lazy_static", "libc", "libsystemd", "log", "nix", + "once_cell", "openat", "openat-ext", "openssl", @@ -427,9 +427,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "openat" diff --git a/Cargo.toml b/Cargo.toml index feae94f8b..9e08978be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,11 +24,11 @@ env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" fs2 = "0.4.3" hex = "0.4.3" -lazy_static = "1.4.0" libc = "^0.2" libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" +once_cell = "1.13.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" diff --git a/src/efi.rs b/src/efi.rs index 0e83e0505..d1431f4df 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -14,7 +14,7 @@ use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; use chrono::prelude::*; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use crate::component::*; use crate::filetree; @@ -26,13 +26,13 @@ use crate::util::CommandRunExt; /// The ESP partition label pub(crate) const ESP_PART_LABEL: &str = "EFI-SYSTEM"; -lazy_static! { - /// The path to a temporary ESP mount - static ref MOUNT_PATH: PathBuf = { - // Create new directory in /tmp with randomly generated name at runtime for ESP mount path. - tempfile::tempdir_in("/tmp").expect("Failed to create temp dir for EFI mount").into_path() - }; -} +/// The path to a temporary ESP mount +static MOUNT_PATH: Lazy = Lazy::new(|| { + // Create new directory in /tmp with randomly generated name at runtime for ESP mount path. + tempfile::tempdir_in("/tmp") + .expect("Failed to create temp dir for EFI mount") + .into_path() +}); #[derive(Default)] pub(crate) struct Efi {} From ce1cf6a28d2575369d97075c1dcc632eebef4b0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 01:29:31 +0000 Subject: [PATCH 344/641] build(deps): bump chrono from 0.4.19 to 0.4.22 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.19 to 0.4.22. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.19...v0.4.22) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 088c08061..c685a55ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7ed72e1635e121ca3e79420540282af22da58be50de153d36f81ddc6b83aa9e" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.58" @@ -83,6 +92,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + [[package]] name = "cc" version = "1.0.68" @@ -97,15 +112,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", "time", + "wasm-bindgen", "winapi", ] @@ -146,6 +163,12 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + [[package]] name = "cpufeatures" version = "0.2.1" @@ -297,6 +320,19 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf7d67cf4a22adc5be66e75ebdf769b3f2ea032041437a7061f97a63dad4b" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "js-sys", + "wasm-bindgen", + "winapi", +] + [[package]] name = "indexmap" version = "1.8.1" @@ -322,6 +358,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "js-sys" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -427,9 +472,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "openat" @@ -795,6 +840,60 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasm-bindgen" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index feae94f8b..e25205138 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.11", features = ["serde"] } +chrono = { version = "0.4.22", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" From 6f089186753ff26f0d53c721a4d7dfff83775395 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 01:29:36 +0000 Subject: [PATCH 345/641] build(deps): bump libc from 0.2.126 to 0.2.131 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.126 to 0.2.131. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.126...0.2.131) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 088c08061..bcdeb8720 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" [[package]] name = "libsystemd" From 1b0d7a75a25153a9a2ed6601948ecd0986882b4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 01:27:02 +0000 Subject: [PATCH 346/641] build(deps): bump libc from 0.2.131 to 0.2.132 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.131 to 0.2.132. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.131...0.2.132) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9567248f..ecbb204e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.131" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libsystemd" From b5bbfa56932c2253e171bebcf3c743f507fbbc7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 01:27:35 +0000 Subject: [PATCH 347/641] build(deps): bump serde_json from 1.0.81 to 1.0.85 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.81 to 1.0.85. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.81...v1.0.85) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9567248f..fe1c2b61c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", From 1a32ef8402a50712278896ff2cad358d0344a098 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 16:04:53 +0000 Subject: [PATCH 348/641] build(deps): bump once_cell from 1.13.0 to 1.14.0 Bumps [once_cell](https://github.com/matklad/once_cell) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/matklad/once_cell/releases) - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a77feaf2..35986883d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "openat" diff --git a/Cargo.toml b/Cargo.toml index da07de767..dc8d868d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ libc = "^0.2" libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" -once_cell = "1.13.0" +once_cell = "1.14.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" From 2f8a1ee8bd26ecb339973e2ce33bbb3209a0a9f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 16:05:05 +0000 Subject: [PATCH 349/641] build(deps): bump serde from 1.0.140 to 1.0.144 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.140 to 1.0.144. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.140...v1.0.144) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a77feaf2..b3f239cff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -679,18 +679,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.140" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.140" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", From cb6808e2d892091f9abcef7d102ffd0800c31405 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 01:32:03 +0000 Subject: [PATCH 350/641] build(deps): bump clap from 3.2.2 to 3.2.22 Bumps [clap](https://github.com/clap-rs/clap) from 3.2.2 to 3.2.22. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/v3.2.22/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v3.2.2...v3.2.22) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35986883d..4fcc4f25b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,24 +128,24 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.2" +version = "3.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e538f9ee5aa3b3963f09a997035f883677966ed50fce0292611927ce6f6d8c6" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" dependencies = [ "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim", "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.2" +version = "3.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f98063cac4652f23ccda556b8d04347a7fc4b2cff1f7577cc8c6546e0d8078" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" dependencies = [ "heck", "proc-macro-error", @@ -367,12 +367,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.132" @@ -767,9 +761,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" [[package]] name = "thiserror" From 9c88fc25df9eb1b3f35c0861c26344c5e22730af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 01:32:14 +0000 Subject: [PATCH 351/641] build(deps): bump anyhow from 1.0.58 to 1.0.65 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.58 to 1.0.65. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.58...1.0.65) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35986883d..1a98a0854 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.58" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "atty" From bd1028ba03ee6241b62eecf4fa6d825910ce9802 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 01:32:21 +0000 Subject: [PATCH 352/641] build(deps): bump env_logger from 0.9.0 to 0.9.1 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.9.0 to 0.9.1. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/commits) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35986883d..c494dd9a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" dependencies = [ "atty", "humantime", From 85f01877f1accd1ff5d9b0874f1b0a24b9336bcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 18:50:59 +0000 Subject: [PATCH 353/641] build(deps): bump iana-time-zone from 0.1.44 to 0.1.48 Bumps [iana-time-zone](https://github.com/strawlab/iana-time-zone) from 0.1.44 to 0.1.48. - [Release notes](https://github.com/strawlab/iana-time-zone/releases) - [Changelog](https://github.com/strawlab/iana-time-zone/blob/main/CHANGELOG.md) - [Commits](https://github.com/strawlab/iana-time-zone/compare/0.1.44...v0.1.48) --- updated-dependencies: - dependency-name: iana-time-zone dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27f873484..639939440 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "android_system_properties" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ed72e1635e121ca3e79420540282af22da58be50de153d36f81ddc6b83aa9e" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] @@ -322,13 +322,14 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.44" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf7d67cf4a22adc5be66e75ebdf769b3f2ea032041437a7061f97a63dad4b" +checksum = "237a0714f28b1ee39ccec0770ccb544eb02c9ef2c82bb096230eefcffa6468b0" dependencies = [ "android_system_properties", "core-foundation-sys", "js-sys", + "once_cell", "wasm-bindgen", "winapi", ] From f7e091f4eff32e94c2aeaa2c74f6a497fbe5e7e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 01:31:28 +0000 Subject: [PATCH 354/641] build(deps): bump libc from 0.2.132 to 0.2.133 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.132 to 0.2.133. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.132...0.2.133) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 639939440..3d3428f3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,9 +370,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.132" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "libsystemd" From f570743f14345aa6f3d653af84f41d5ed13792b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 01:31:31 +0000 Subject: [PATCH 355/641] build(deps): bump once_cell from 1.14.0 to 1.15.0 Bumps [once_cell](https://github.com/matklad/once_cell) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/matklad/once_cell/releases) - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.14.0...v1.15.0) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 639939440..3562a7c87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,9 +467,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "openat" diff --git a/Cargo.toml b/Cargo.toml index dc8d868d0..25e9ab079 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ libc = "^0.2" libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" -once_cell = "1.14.0" +once_cell = "1.15.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" From afec3f1446a783fa4617b51019ec46a9ca914d02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 01:31:37 +0000 Subject: [PATCH 356/641] build(deps): bump serde from 1.0.144 to 1.0.145 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.144 to 1.0.145. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.144...v1.0.145) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 639939440..42d4344c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,18 +674,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", From 9daff4ea99740d311c609ec054c2540c5aa05896 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 30 Sep 2022 13:20:01 -0400 Subject: [PATCH 357/641] efi: Inline helper for path It's not necessary to have a separate function for this; it was called twice pointlessly. --- src/efi.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index d1431f4df..9973ba842 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -42,16 +42,13 @@ impl Efi { Path::new(&*MOUNT_PATH).join("EFI") } - fn esp_device(&self) -> PathBuf { - Path::new("/dev/disk/by-partlabel/").join(ESP_PART_LABEL) - } - fn open_esp_optional(&self) -> Result> { self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; let esp = sysroot.sub_dir_optional(&self.esp_path())?; Ok(esp) } + fn open_esp(&self) -> Result { self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; @@ -60,18 +57,18 @@ impl Efi { } fn ensure_mounted_esp(&self) -> Result<()> { + let esp_device = Path::new("/dev/disk/by-partlabel/").join(ESP_PART_LABEL); let mount_point = &Path::new("/").join(&*MOUNT_PATH); let output = std::process::Command::new("mountpoint") .arg(mount_point) .output()?; if !output.status.success() { - let esp_device = &self.esp_device(); if !esp_device.exists() { log::error!("Single ESP device not found; ESP on multiple independent filesystems currently unsupported"); anyhow::bail!("Could not find {:?}", esp_device); } let status = std::process::Command::new("mount") - .arg(&self.esp_device()) + .arg(&esp_device) .arg(mount_point) .status()?; if !status.success() { From ca9f7d95e47f6f671dfbccd65162890c543c525e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 30 Sep 2022 14:07:15 -0400 Subject: [PATCH 358/641] efi/install: Don't pointlessly try to append destdir to mount path I was doing a larger cleanup and was really confused by this bit of code - we do `Path::new(destdir).join(/tmp/tmp.efiXXXXXX`) and I couldn't understand how that worked until I realized that `Path::join` will ignore the prefix for absolute paths. This code has never actually used the destination root at all; we look for the ESP in `/dev/disk/by-label`, which has nothing to do with any target filesystem root. We should just drop the target root command line argument here at all, and document that we instead require an ESP. But for now, drop the dead code. --- src/efi.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 9973ba842..bf2da6be4 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -137,7 +137,8 @@ impl Component for Efi { }) } - fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { + // TODO: Remove dest_root; it was never actually used + fn install(&self, src_root: &openat::Dir, _dest_root: &str) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta } else { @@ -146,9 +147,9 @@ impl Component for Efi { let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; self.ensure_mounted_esp()?; - let destdir = Path::new(dest_root).join(&*MOUNT_PATH); + let destdir = &*MOUNT_PATH; { - let destd = openat::Dir::open(&destdir) + let destd = openat::Dir::open(destdir) .with_context(|| format!("opening dest dir {}", destdir.display()))?; validate_esp(&destd)?; } From bbb07718e0b5f389e9fffd463093ca653a92f9ea Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 30 Sep 2022 14:10:32 -0400 Subject: [PATCH 359/641] efi: Rework/cleanup ESP mounting code Right now we hardcode finding the ESP by the label we chose for Fedora CoreOS. This is preparatory work for generalizing that to support finding the ESP on systems installed via Anaconda and ideally others. --- Cargo.lock | 1 - Cargo.toml | 1 - src/efi.rs | 64 ++++++++++++++++++++++++------------------------------ 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ba2c858f..d6b27d8d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,6 @@ dependencies = [ "libsystemd", "log", "nix", - "once_cell", "openat", "openat-ext", "openssl", diff --git a/Cargo.toml b/Cargo.toml index 25e9ab079..148ff27a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,6 @@ libc = "^0.2" libsystemd = ">= 0.3, < 0.6" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" -once_cell = "1.15.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" diff --git a/src/efi.rs b/src/efi.rs index bf2da6be4..90896eee4 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +use std::cell::RefCell; use std::collections::{BTreeMap, BTreeSet}; use std::io::prelude::*; use std::os::unix::io::AsRawFd; @@ -14,7 +15,6 @@ use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; use chrono::prelude::*; -use once_cell::sync::Lazy; use crate::component::*; use crate::filetree; @@ -26,56 +26,49 @@ use crate::util::CommandRunExt; /// The ESP partition label pub(crate) const ESP_PART_LABEL: &str = "EFI-SYSTEM"; -/// The path to a temporary ESP mount -static MOUNT_PATH: Lazy = Lazy::new(|| { - // Create new directory in /tmp with randomly generated name at runtime for ESP mount path. - tempfile::tempdir_in("/tmp") - .expect("Failed to create temp dir for EFI mount") - .into_path() -}); - #[derive(Default)] -pub(crate) struct Efi {} +pub(crate) struct Efi { + mountpoint: RefCell>, +} impl Efi { - fn esp_path(&self) -> PathBuf { - Path::new(&*MOUNT_PATH).join("EFI") + fn esp_path(&self) -> Result { + self.ensure_mounted_esp().map(|v| v.join("EFI")) } fn open_esp_optional(&self) -> Result> { - self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; - let esp = sysroot.sub_dir_optional(&self.esp_path())?; + let esp = sysroot.sub_dir_optional(&self.esp_path()?)?; Ok(esp) } fn open_esp(&self) -> Result { self.ensure_mounted_esp()?; let sysroot = openat::Dir::open("/")?; - let esp = sysroot.sub_dir(&self.esp_path())?; + let esp = sysroot.sub_dir(&self.esp_path()?)?; Ok(esp) } - fn ensure_mounted_esp(&self) -> Result<()> { + fn ensure_mounted_esp(&self) -> Result { + let mut mountpoint = self.mountpoint.borrow_mut(); + if let Some(mountpoint) = mountpoint.as_deref() { + return Ok(mountpoint.to_owned()); + } let esp_device = Path::new("/dev/disk/by-partlabel/").join(ESP_PART_LABEL); - let mount_point = &Path::new("/").join(&*MOUNT_PATH); - let output = std::process::Command::new("mountpoint") - .arg(mount_point) - .output()?; - if !output.status.success() { - if !esp_device.exists() { - log::error!("Single ESP device not found; ESP on multiple independent filesystems currently unsupported"); - anyhow::bail!("Could not find {:?}", esp_device); - } - let status = std::process::Command::new("mount") - .arg(&esp_device) - .arg(mount_point) - .status()?; - if !status.success() { - anyhow::bail!("Failed to mount {:?}", esp_device); - } - }; - Ok(()) + if !esp_device.exists() { + log::error!("Single ESP device not found; ESP on multiple independent filesystems currently unsupported"); + anyhow::bail!("Could not find {:?}", esp_device); + } + let tmppath = tempfile::tempdir_in("/tmp")?.into_path(); + let status = std::process::Command::new("mount") + .arg(&esp_device) + .arg(&tmppath) + .status()?; + if !status.success() { + anyhow::bail!("Failed to mount {:?}", esp_device); + } + *mountpoint = Some(tmppath); + Ok(mountpoint.as_deref().unwrap().to_owned()) } } @@ -146,8 +139,7 @@ impl Component for Efi { }; let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; - self.ensure_mounted_esp()?; - let destdir = &*MOUNT_PATH; + let destdir = &self.ensure_mounted_esp()?; { let destd = openat::Dir::open(destdir) .with_context(|| format!("opening dest dir {}", destdir.display()))?; From b1908a83bc1bc28f1eff5585b93e9fd65ff15de5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 01:30:02 +0000 Subject: [PATCH 360/641] build(deps): bump openssl from 0.10.41 to 0.10.42 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.41 to 0.10.42. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.42) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ba2c858f..c671a2ad8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -494,9 +494,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.41" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if", @@ -520,9 +520,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.75" +version = "0.9.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" +checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" dependencies = [ "autocfg", "cc", From a180d4a536dff60ca830c2318545c40637a0c9e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 01:30:07 +0000 Subject: [PATCH 361/641] build(deps): bump libc from 0.2.133 to 0.2.134 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.133 to 0.2.134. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.133...0.2.134) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ba2c858f..bd0337b49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,9 +370,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.133" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "libsystemd" From cb31dfe6a7ff69a6ea89bd0775ae4dd5b23b0a63 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 4 Oct 2022 10:37:14 -0400 Subject: [PATCH 362/641] efi: Unmount partition on drop This way we'll avoid leaking the mount in non-systemd cases. Closes: https://github.com/coreos/bootupd/issues/367 --- src/efi.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/efi.rs b/src/efi.rs index 90896eee4..ab2217695 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -70,6 +70,16 @@ impl Efi { *mountpoint = Some(tmppath); Ok(mountpoint.as_deref().unwrap().to_owned()) } + + fn unmount(&self) -> Result<()> { + if let Some(mount) = self.mountpoint.borrow_mut().take() { + let status = Command::new("umount").arg(&mount).status()?; + if !status.success() { + anyhow::bail!("Failed to unmount {mount:?}: {status:?}"); + } + } + Ok(()) + } } impl Component for Efi { @@ -301,6 +311,12 @@ impl Component for Efi { } } +impl Drop for Efi { + fn drop(&mut self) { + let _ = self.unmount(); + } +} + fn validate_esp(dir: &openat::Dir) -> Result<()> { let stat = nix::sys::statfs::fstatfs(dir)?; let fstype = stat.filesystem_type(); From 6e0755b681e1f47b40391845727defb990a2548c Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 13 Oct 2022 14:08:56 -0400 Subject: [PATCH 363/641] ci: migrate to new directory and method names The previous `fcos*` ones are deprecated. See: https://github.com/coreos/coreos-ci-lib/pull/122 --- .cci.jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 35c6dc2af..67cc55ef1 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -65,7 +65,7 @@ cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { // The previous e2e leaves things only having built an ostree update shwrap("cosa build") // bootupd really can't break upgrades for the OS - fcosKola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true, skipBasicScenarios: true) + kola(cosaDir: "${env.WORKSPACE}", extraArgs: "ext.*bootupd*", skipUpgrade: true, skipBasicScenarios: true) } } finally { archiveArtifacts allowEmptyArchive: true, artifacts: 'tmp/console.txt' From 7a1cafebb6473a785ce7e4b8860cdc1ba74dfdbe Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Fri, 14 Oct 2022 13:11:24 +0000 Subject: [PATCH 364/641] ci: Bump memory request This tweaks memory request in order to successfully run the testsuite again, adapting to the CI changes in https://github.com/coreos/coreos-ci-lib/pull/116 --- .cci.jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 67cc55ef1..12eaed3d4 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -32,7 +32,7 @@ codestyle: { // Build FCOS and do a kola basic run // FIXME update to main branch once https://github.com/coreos/fedora-coreos-config/pull/595 merges -cosaPod(runAsUser: 0, memory: "3072Mi", cpu: "4") { +cosaPod(runAsUser: 0, memory: "4608Mi", cpu: "4") { stage("Build FCOS") { checkout scm unstash 'build' From 0a5d6eea14c6e8fd5c218d4bde23adbe47368842 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 14 Oct 2022 15:13:55 -0400 Subject: [PATCH 365/641] Add support for Anaconda-based installs This finds the ESP as created by Anaconda based systems, and adds support for a working `bootupctl adopt-and-update`. --- src/efi.rs | 57 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index ab2217695..02f8056a7 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -23,8 +23,9 @@ use crate::ostreeutil; use crate::util; use crate::util::CommandRunExt; -/// The ESP partition label -pub(crate) const ESP_PART_LABEL: &str = "EFI-SYSTEM"; +/// The ESP partition label on Fedora CoreOS derivatives +pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; +pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition"; #[derive(Default)] pub(crate) struct Efi { @@ -54,11 +55,17 @@ impl Efi { if let Some(mountpoint) = mountpoint.as_deref() { return Ok(mountpoint.to_owned()); } - let esp_device = Path::new("/dev/disk/by-partlabel/").join(ESP_PART_LABEL); - if !esp_device.exists() { - log::error!("Single ESP device not found; ESP on multiple independent filesystems currently unsupported"); - anyhow::bail!("Could not find {:?}", esp_device); + let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL] + .into_iter() + .map(|p| Path::new("/dev/disk/by-partlabel/").join(p)); + let mut esp_device = None; + for path in esp_devices { + if path.exists() { + esp_device = Some(path); + break; + } } + let esp_device = esp_device.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?; let tmppath = tempfile::tempdir_in("/tmp")?.into_path(); let status = std::process::Command::new("mount") .arg(&esp_device) @@ -94,21 +101,33 @@ impl Component for Efi { return Ok(None); }; // This would be extended with support for other operating systems later - let coreos_aleph = if let Some(a) = crate::coreos::get_aleph_version()? { - a + if let Some(coreos_aleph) = crate::coreos::get_aleph_version()? { + let meta = ContentMetadata { + timestamp: coreos_aleph.ts, + version: coreos_aleph.aleph.imgid, + }; + log::trace!("EFI adoptable: {:?}", &meta); + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); } else { log::trace!("No CoreOS aleph detected"); - return Ok(None); - }; - let meta = ContentMetadata { - timestamp: coreos_aleph.ts, - version: coreos_aleph.aleph.imgid, - }; - log::trace!("EFI adoptable: {:?}", &meta); - Ok(Some(Adoptable { - version: meta, - confident: true, - })) + } + let ostree_deploy_dir = Path::new("/ostree/deploy"); + if ostree_deploy_dir.exists() { + let btime = ostree_deploy_dir.metadata()?.created()?; + let timestamp = chrono::DateTime::from(btime); + let meta = ContentMetadata { + timestamp, + version: "unknown".to_string(), + }; + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); + } + Ok(None) } /// Given an adoptable system and an update, perform the update. From 78e2df782b4321a952dbc4f6a496c3af3d837692 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 01:28:01 +0000 Subject: [PATCH 366/641] build(deps): bump libc from 0.2.134 to 0.2.135 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.134 to 0.2.135. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.134...0.2.135) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0acd38445..07f9a96c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.134" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "libsystemd" From 93b53241a86e05955452602b809d7eb883d3947a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Oct 2022 09:53:10 -0400 Subject: [PATCH 367/641] Release 0.28 Mainly to get the Anaconda-based handling out. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0acd38445..6a64a5129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.7" +version = "0.2.8" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 148ff27a5..a016bfe70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.7" +version = "0.2.8" authors = ["Colin Walters "] edition = "2021" rust-version = "1.58.1" From 4195320f6afb4638ab81ff3caae932b47838f2aa Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Oct 2022 10:07:10 -0400 Subject: [PATCH 368/641] doc: Add docs about distribution/OS integration Since e.g. we still need to do the second phase for Anaconda based systems. --- README-devel.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README-devel.md b/README-devel.md index a885dd073..dba1a33f6 100644 --- a/README-devel.md +++ b/README-devel.md @@ -41,3 +41,38 @@ $ ls target/release/bootupd target/release/bootupd $ ``` + +## Integrating bootupd into a distribution/OS + +Today, bootupd only really works on systems that use RPMs and ostree. +(Which usually means rpm-ostree, but not strictly necessarily) + +Many bootupd developers (and current CI flows) target Fedora CoreOS +and derivatives, so it can be used as a "reference" for integration. + +There's two parts to integration: + +### Generating an update payload + +Bootupd's concept of an "update payload" needs to be generated as +part of an OS image (e.g. ostree commit). +A good reference for this is +https://github.com/coreos/fedora-coreos-config/blob/88af117d1d2c5e828e5e039adfa03c7cc66fc733/manifests/bootupd.yaml#L12 + +Specifically, you'll need to invoke +`bootupctl backend generate-update-metadata /` as part of update payload generation. +This scrapes metadata (e.g. RPM versions) about shim/grub and puts them along with +their component files in `/usr/lib/bootupd/updates/`. + +### Installing to generated disk images + +In order to correctly manage updates, bootupd also needs to be responsible +for laying out files in initial disk images. A good reference for this is +https://github.com/coreos/coreos-assembler/blob/93efb63dcbd63dc04a782e2c6c617ae0cd4a51c8/src/create_disk.sh#L401 + +Specifically, you'll need to invoke +`/usr/bin/bootupctl backend install --src-root /path/to/ostree/deploy /sysroot` +where the first path is an ostree deployment root, and the second is the physical +root partition. + +This will e.g. inject the initial files into the mounted EFI system partition. From f14633a6d2b5edbd8a384892b22ffa051b0d4ba6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 01:28:42 +0000 Subject: [PATCH 369/641] build(deps): bump anyhow from 1.0.65 to 1.0.66 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.65 to 1.0.66. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.65...1.0.66) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a64a5129..0099a5a1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "atty" From 581d0c045b8c31e9102c4b8dbdcc912b497c62b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 01:28:49 +0000 Subject: [PATCH 370/641] build(deps): bump serde_json from 1.0.85 to 1.0.87 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.85 to 1.0.87. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.85...v1.0.87) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a64a5129..b5cda432f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -693,9 +693,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", From f700fd39ae4ceb9447a768a6c5aa48cdd143471c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 01:03:33 +0000 Subject: [PATCH 371/641] build(deps): bump libc from 0.2.135 to 0.2.137 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.135 to 0.2.137. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.135...0.2.137) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c67b43f2..5e022d138 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.135" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libsystemd" From d26202d89b9694df3e6acede384ee7baef158c54 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 1 Nov 2022 10:23:38 -0400 Subject: [PATCH 372/641] Statically enable bootupd.socket The fact that we're a systemd unit is mostly an implementation detail so that we get a natural locking mechanism and can reuse systemd sandboxing. If you have the software installed, we want the socket to be enabled. Having to work through adding this into presets is just compounding pain for shipping it in multiple places. Instead, install a static symlink. --- Makefile | 2 ++ packaging/rust-bootupd.spec | 9 --------- tests/e2e-update/e2e-update-in-vm.sh | 2 -- tests/kola/test-bootupd | 2 -- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 68ed075ca..42b2b4e7d 100644 --- a/Makefile +++ b/Makefile @@ -42,3 +42,5 @@ install: install-units mkdir -p "${DESTDIR}$(PREFIX)/bin" "${DESTDIR}$(LIBEXECDIR)" install -D -t "${DESTDIR}$(LIBEXECDIR)" target/${PROFILE}/bootupd ln -f ${DESTDIR}$(LIBEXECDIR)/bootupd ${DESTDIR}$(PREFIX)/bin/bootupctl + install -d "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" + ln -s ../bootupd.socket "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" diff --git a/packaging/rust-bootupd.spec b/packaging/rust-bootupd.spec index 164d15c9a..4817949a3 100644 --- a/packaging/rust-bootupd.spec +++ b/packaging/rust-bootupd.spec @@ -53,15 +53,6 @@ License: ASL 2.0 %install %make_install INSTALL="install -p -c" -%post -n %{crate} -%systemd_post bootupd.service bootupd.socket - -%preun -n %{crate} -%systemd_preun bootupd.service bootupd.socket - -%postun -n %{crate} -%systemd_postun bootupd.service bootupd.socket - %changelog * Fri Sep 11 2020 Colin Walters - 0.1.0-3 - Initial package diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index ac3340a29..17919f99a 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -48,8 +48,6 @@ if ! test -n "${TARGET_GRUB_PKG}"; then fatal "Missing TARGET_GRUB_PKG" fi -systemctl start bootupd.socket - bootupctl validate ok validate diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 13fac40bc..8824c809e 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -40,8 +40,6 @@ prepare_efi_update() { rm -rf ${efiupdir} ${bootupdir}/EFI.json } -systemctl start bootupd.socket - bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' From 80217c0ab3deef1f7a6bb9313a0a7324fa5bdbe6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 01:01:29 +0000 Subject: [PATCH 373/641] build(deps): bump chrono from 0.4.22 to 0.4.23 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.22 to 0.4.23. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.22...v0.4.23) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c67b43f2..049b9bf84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index a016bfe70..4b9f88f01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.22", features = ["serde"] } +chrono = { version = "0.4.23", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" From d44320f9fea5c3f9191e8a89617491dc96061056 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 07:46:10 +0000 Subject: [PATCH 374/641] build(deps): bump env_logger from 0.9.1 to 0.9.3 Bumps [env_logger](https://github.com/env-logger-rs/env_logger) from 0.9.1 to 0.9.3. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.9.1...v0.9.3) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c910da0f8..73495500b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", From 01a5d78198e7fbf37d0647536217fb1d6f73a8a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 07:46:11 +0000 Subject: [PATCH 375/641] build(deps): bump clap from 3.2.22 to 3.2.23 Bumps [clap](https://github.com/clap-rs/clap) from 3.2.22 to 3.2.23. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/v3.2.23/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v3.2.22...v3.2.23) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c910da0f8..585a152b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.22" +version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "bitflags", "clap_derive", @@ -761,9 +761,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" From 62d4ef0fd041461f589f7248b96687951b1f3236 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 07:46:12 +0000 Subject: [PATCH 376/641] build(deps): bump serde from 1.0.145 to 1.0.147 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.145 to 1.0.147. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.145...v1.0.147) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c910da0f8..8de3f42b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -673,18 +673,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", From ebbf379615c4eaa55568cd1f0fb567cc5040b890 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Nov 2022 13:04:39 -0500 Subject: [PATCH 377/641] README.md: We're not really a daemon Motivated by discussion on fedora-devel-list. --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 3790e5362..bd8215f28 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,28 @@ But out of conservatism currently today for e.g. Fedora CoreOS, bootupd is disab by default. On the other hand, if your OS update mechanism isn't transactional, then you may want to enable bootupd by default. +- Why is bootupd a daemon? + +It's not, really. The name was intended to be "bootloader-upDater" +not "bootloader-updater-Daemon"; the choice of a "d" suffix is +in retrospect probably too confusing. + +At a technical level, yes there is a socket-activated systemd service +which will spawn a `bootupd.service`. However - the service will +*very quickly* auto exit. There's nothing long-running, so it's +not really a daemon. + +The rationale behind this design is: + +- Using a systemd service provides a robust natural "locking" + mechanism. +- Using a systemd service ensures that critical logging metadata + always consistently ends up in the systemd journal, not e.g. + a transient client SSH connection. +- systemd services can easily have sandboxing applied, and + while bootupd is obviously privileged we can still make use + of some of this. +- Ultimately, we do probably want a non-CLI API (whether that's + DBus or Cap'n Proto or varlink or something else). Having + a socket (without a defined stable API) is preparatory work for that. + From 8ac4aa160759511470c8af540f1b39162cfd4efd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 20 Dec 2022 16:46:28 -0500 Subject: [PATCH 378/641] ci: Use f37 for overrides This should fix CI. --- tests/e2e-update/e2e-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 73d441201..47f879300 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -79,15 +79,15 @@ undo_manifest_fork() { if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm - # Version from F35 Beta, and different from F35 Final - add_override grub2-2.06-5.fc35 + # Version from F37 GA + add_override grub2-2.06-58.fc37 runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" - # Version queued in current f35 updates - add_override grub2-2.06-8.fc35 + # Version queued in current updates + add_override grub2-2.06-70.fc37 mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree From 23889622e12676faeb28c1d1eb7e519239c4826f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 12 Dec 2022 13:33:08 -0500 Subject: [PATCH 379/641] efi: Reuse existing mountpoint if available This is an even better fix for https://github.com/coreos/bootupd/issues/367 Basically in coreos-assembler today we're already mounting the ESP, so let's just reuse that existing mount if it's present. This is also what we want for other systems that pre-mount the ESP. (At least for now - long term to support redundant ESPs we'll need to fully own all of this, but that can come later) --- src/efi.rs | 33 ++++++++++++++++++++++++++------- src/main.rs | 2 ++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 02f8056a7..88fbf570e 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -23,6 +23,9 @@ use crate::ostreeutil; use crate::util; use crate::util::CommandRunExt; +/// Well-known paths to the ESP that may have been mounted external to us. +pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi"]; + /// The ESP partition label on Fedora CoreOS derivatives pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition"; @@ -34,7 +37,8 @@ pub(crate) struct Efi { impl Efi { fn esp_path(&self) -> Result { - self.ensure_mounted_esp().map(|v| v.join("EFI")) + self.ensure_mounted_esp(Path::new("/")) + .map(|v| v.join("EFI")) } fn open_esp_optional(&self) -> Result> { @@ -44,17 +48,31 @@ impl Efi { } fn open_esp(&self) -> Result { - self.ensure_mounted_esp()?; + self.ensure_mounted_esp(Path::new("/"))?; let sysroot = openat::Dir::open("/")?; let esp = sysroot.sub_dir(&self.esp_path()?)?; Ok(esp) } - fn ensure_mounted_esp(&self) -> Result { + fn ensure_mounted_esp(&self, root: &Path) -> Result { let mut mountpoint = self.mountpoint.borrow_mut(); if let Some(mountpoint) = mountpoint.as_deref() { return Ok(mountpoint.to_owned()); } + for &mnt in ESP_MOUNTS { + let mnt = root.join(mnt); + if !mnt.exists() { + continue; + } + let st = nix::sys::statfs::statfs(&mnt) + .with_context(|| format!("statfs failed for {mnt:?}"))?; + if st.filesystem_type() != nix::sys::statfs::MSDOS_SUPER_MAGIC { + continue; + } + log::debug!("Reusing existing {mnt:?}"); + return Ok(mnt); + } + let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL] .into_iter() .map(|p| Path::new("/dev/disk/by-partlabel/").join(p)); @@ -74,6 +92,7 @@ impl Efi { if !status.success() { anyhow::bail!("Failed to mount {:?}", esp_device); } + log::debug!("Mounted at {tmppath:?}"); *mountpoint = Some(tmppath); Ok(mountpoint.as_deref().unwrap().to_owned()) } @@ -160,7 +179,7 @@ impl Component for Efi { } // TODO: Remove dest_root; it was never actually used - fn install(&self, src_root: &openat::Dir, _dest_root: &str) -> Result { + fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta } else { @@ -168,7 +187,7 @@ impl Component for Efi { }; let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; - let destdir = &self.ensure_mounted_esp()?; + let destdir = &self.ensure_mounted_esp(Path::new(dest_root))?; { let destd = openat::Dir::open(destdir) .with_context(|| format!("opening dest dir {}", destdir.display()))?; @@ -207,7 +226,7 @@ impl Component for Efi { .context("opening update dir")?; let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?; let diff = currentf.diff(&updatef)?; - self.ensure_mounted_esp()?; + self.ensure_mounted_esp(Path::new("/"))?; let destdir = self.open_esp().context("opening EFI dir")?; validate_esp(&destdir)?; log::trace!("applying diff: {}", &diff); @@ -311,7 +330,7 @@ impl Component for Efi { .filetree .as_ref() .ok_or_else(|| anyhow::anyhow!("No filetree for installed EFI found!"))?; - self.ensure_mounted_esp()?; + self.ensure_mounted_esp(Path::new("/"))?; let efidir = self.open_esp()?; let diff = currentf.relative_diff_to(&efidir)?; let mut errs = Vec::new(); diff --git a/src/main.rs b/src/main.rs index a22aab082..6250a0e50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,8 @@ fn run_cli() -> i32 { .filter(Some(crate_name!()), cli_opts.loglevel()) .init(); + log::trace!("executing cli"); + // Dispatch CLI subcommand. match cli_opts.run() { Ok(_) => libc::EXIT_SUCCESS, From 473b91f002d24fa0d161f1da3c5fb85256727aa5 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 3 Jan 2023 15:59:04 -0500 Subject: [PATCH 380/641] workflows: replace actions-rs/toolchain with dtolnay/rust-toolchain actions-rs/toolchain is unmaintained. --- .github/workflows/rust.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 9c3a60d5d..4a94ba9b4 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -23,10 +23,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@v1 with: - toolchain: "stable" - default: true + toolchain: stable - name: cargo build run: cargo build - name: cargo test @@ -38,10 +37,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@v1 with: - toolchain: "stable" - default: true + toolchain: stable - name: cargo build (release) run: cargo build --release - name: cargo test (release) @@ -59,10 +57,9 @@ jobs: echo "Crate MSRV: $msrv" echo "MSRV=$msrv" >> $GITHUB_ENV - name: Install toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.MSRV }} - default: true - name: cargo build (release) run: cargo build --release - name: cargo test (release) @@ -74,10 +71,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env['ACTION_LINTS_TOOLCHAIN'] }} - default: true components: rustfmt, clippy - name: cargo clippy (warnings) run: cargo clippy -- -D warnings @@ -96,10 +92,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - name: Install toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ matrix.channel }} - default: true - name: cargo build run: cargo build - name: cargo test From 5e41b94578db06f3131f1272242d7584d1850920 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Tue, 3 Jan 2023 15:59:08 -0500 Subject: [PATCH 381/641] workflows: update actions to current major versions Fixes deprecation warnings for Node.js 12: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/ --- .github/workflows/rust.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4a94ba9b4..7aa2f9c12 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 with: @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 with: @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Detect crate MSRV run: | msrv=$(cargo metadata --format-version 1 --no-deps | \ @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 with: @@ -90,7 +90,7 @@ jobs: - "nightly" steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 with: From 14d9673612a4b9968d8bee2117ca09c70498ff10 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Thu, 12 Jan 2023 10:02:25 +0800 Subject: [PATCH 382/641] util.rs: move some code to function to reuse - Move code to func `parse_rpm_metadata` to parse the output of `rpm -q` - Move code to func `rpm_query` to query rpm database, list the package and build times --- src/efi.rs | 48 +++------------------------------------- src/util.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 88fbf570e..18df58cca 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -5,7 +5,6 @@ */ use std::cell::RefCell; -use std::collections::{BTreeMap, BTreeSet}; use std::io::prelude::*; use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; @@ -14,8 +13,6 @@ use std::process::Command; use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; -use chrono::prelude::*; - use crate::component::*; use crate::filetree; use crate::model::*; @@ -267,56 +264,17 @@ impl Component for Efi { Command::new("mv").args(&[&efisrc, &dest_efidir]).run()?; } - let src_efidir = openat::Dir::open(&dest_efidir)?; // Query the rpm database and list the package and build times for all the // files in the EFI system partition. If any files are not owned it is considered // and error condition. - let rpmout = { - let mut c = ostreeutil::rpm_cmd(sysroot_path); - c.args(&["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); - c.args(util::filenames(&src_efidir)?.drain().map(|mut f| { - f.insert_str(0, "/boot/efi/EFI/"); - f - })); - c - } - .output()?; + let mut rpmout = util::rpm_query(sysroot_path, &dest_efidir)?; + let rpmout = rpmout.output()?; if !rpmout.status.success() { std::io::stderr().write_all(&rpmout.stderr)?; bail!("Failed to invoke rpm -qf"); } - let pkgs = std::str::from_utf8(&rpmout.stdout)? - .split_whitespace() - .map(|s| -> Result<_> { - let parts: Vec<_> = s.splitn(2, ',').collect(); - let name = parts[0]; - if let Some(ts) = parts.get(1) { - let nt = NaiveDateTime::parse_from_str(ts, "%s") - .context("Failed to parse rpm buildtime")?; - Ok((name, DateTime::::from_utc(nt, Utc))) - } else { - bail!("Failed to parse: {}", s); - } - }) - .collect::>>>()?; - if pkgs.is_empty() { - bail!("Failed to find any RPM packages matching files in source efidir"); - } - let timestamps: BTreeSet<&DateTime> = pkgs.values().collect(); - // Unwrap safety: We validated pkgs has at least one value above - let largest_timestamp = timestamps.iter().last().unwrap(); - let version = pkgs.keys().fold("".to_string(), |mut s, n| { - if !s.is_empty() { - s.push(','); - } - s.push_str(n); - s - }); - let meta = ContentMetadata { - timestamp: **largest_timestamp, - version, - }; + let meta = util::parse_rpm_metadata(rpmout.stdout)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/util.rs b/src/util.rs index 75651d158..4d7eee888 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,11 +1,16 @@ use std::collections::HashSet; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; use std::path::Path; use std::process::Command; +use crate::model::*; +use crate::ostreeutil; +use chrono::prelude::*; +use std::collections::{BTreeMap, BTreeSet}; + pub(crate) trait CommandRunExt { fn run(&mut self) -> Result<()>; } @@ -83,3 +88,59 @@ pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { } Ok(()) } + +/// Parse the output of `rpm -q` +pub(crate) fn parse_rpm_metadata(stdout: Vec) -> Result { + let pkgs = std::str::from_utf8(&stdout)? + .split_whitespace() + .map(|s| -> Result<_> { + let parts: Vec<_> = s.splitn(2, ',').collect(); + let name = parts[0]; + if let Some(ts) = parts.get(1) { + let nt = NaiveDateTime::parse_from_str(ts, "%s") + .context("Failed to parse rpm buildtime")?; + Ok((name, DateTime::::from_utc(nt, Utc))) + } else { + bail!("Failed to parse: {}", s); + } + }) + .collect::>>>()?; + if pkgs.is_empty() { + bail!("Failed to find any RPM packages matching files in source efidir"); + } + let timestamps: BTreeSet<&DateTime> = pkgs.values().collect(); + // Unwrap safety: We validated pkgs has at least one value above + let largest_timestamp = timestamps.iter().last().unwrap(); + let version = pkgs.keys().fold("".to_string(), |mut s, n| { + if !s.is_empty() { + s.push(','); + } + s.push_str(n); + s + }); + Ok(ContentMetadata { + timestamp: **largest_timestamp, + version, + }) +} + +/// Query the rpm database and list the package and build times, for all the +/// files in the EFI system partition, or for grub2-install file +pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { + let mut c = ostreeutil::rpm_cmd(sysroot_path); + c.args(&["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); + + match path.file_name().expect("filename").to_str() { + Some("EFI") => { + let efidir = openat::Dir::open(path)?; + c.args(filenames(&efidir)?.drain().map(|mut f| { + f.insert_str(0, "/boot/efi/EFI/"); + f + })); + } + _ => { + bail!("Unsupported file/directory {:?}", path) + } + } + Ok(c) +} From e65468ddffee4ac0beb7fe08955f7631e7518254 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 13 Jan 2023 16:50:39 -0500 Subject: [PATCH 383/641] Release 0.2.9 Mainly because bootc work depends on the new EFI handling. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 551b33ffa..347d85af2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.8" +version = "0.2.9" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 4b9f88f01..737ece486 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.8" +version = "0.2.9" authors = ["Colin Walters "] edition = "2021" rust-version = "1.58.1" From 46a39e4c1a09ac66b7f09380e8e4db13523bc1b2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 21 Jan 2023 11:46:37 -0500 Subject: [PATCH 384/641] Copy xtask packaging bits from bootc This copies the logic from https://github.com/containers/bootc/pull/36/commits/b274b315c24de933e67a538a5fccbcf904854af8 into this project with the same motivation of enabling COPR builds. --- .cargo/config.toml | 2 + .copr/Makefile | 7 ++ contrib/packaging/bootupd.spec | 64 +++++++++++ packaging/rust-bootupd.spec | 59 ----------- xtask/.gitignore | 5 + xtask/Cargo.toml | 13 +++ xtask/src/main.rs | 187 +++++++++++++++++++++++++++++++++ 7 files changed, 278 insertions(+), 59 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 .copr/Makefile create mode 100644 contrib/packaging/bootupd.spec delete mode 100644 packaging/rust-bootupd.spec create mode 100644 xtask/.gitignore create mode 100644 xtask/Cargo.toml create mode 100644 xtask/src/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 000000000..d8c2032b4 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --manifest-path ./xtask/Cargo.toml --" diff --git a/.copr/Makefile b/.copr/Makefile new file mode 100644 index 000000000..011fb2ad8 --- /dev/null +++ b/.copr/Makefile @@ -0,0 +1,7 @@ +srpm: + dnf -y install cargo git openssl-devel + # similar to https://github.com/actions/checkout/issues/760, but for COPR + git config --global --add safe.directory '*' + cargo install cargo-vendor-filterer + cargo xtask package-srpm + mv target/*.src.rpm $$outdir diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec new file mode 100644 index 000000000..83aafdab2 --- /dev/null +++ b/contrib/packaging/bootupd.spec @@ -0,0 +1,64 @@ +%bcond_without check +%global __cargo_skip_build 0 + +%global crate bootupd + +Name: bootupd +Version: 0.2.9 +Release: 1%{?dist} +Summary: Bootloader updater + +License: ASL 2.0 +URL: https://crates.io/crates/bootupd +Source0: https://github.com/coreos/bootupd/releases/download/v%{version}/bootupd-%{version}.tar.zstd +Source1: https://github.com/coreos/bootupd/releases/download/v%{version}/bootupd-%{version}-vendor.tar.zstd + +# For now, see upstream +ExclusiveArch: x86_64 aarch64 +BuildRequires: make +BuildRequires: cargo +# For autosetup -Sgit +BuildRequires: git +BuildRequires: openssl-devel +BuildRequires: systemd-devel + +%description +%{summary} + +%files +%license LICENSE +%doc README.md +%{_bindir}/bootupctl +%{_libexecdir}/bootupd +%{_unitdir}/* + +%prep +%autosetup -n %{crate}-%{version} -p1 -Sgit +tar -xv -f %{SOURCE1} +mkdir -p .cargo +cat >.cargo/config << EOF +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendor" +EOF + +%build +cargo build --release + +%install +%make_install INSTALL="install -p -c" + +%post -n %{crate} +%systemd_post bootupd.service bootupd.socket + +%preun -n %{crate} +%systemd_preun bootupd.service bootupd.socket + +%postun -n %{crate} +%systemd_postun bootupd.service bootupd.socket + +%changelog +* Tue Oct 18 2022 Colin Walters - 0.2.8-3 +- Dummy changelog \ No newline at end of file diff --git a/packaging/rust-bootupd.spec b/packaging/rust-bootupd.spec deleted file mode 100644 index 4817949a3..000000000 --- a/packaging/rust-bootupd.spec +++ /dev/null @@ -1,59 +0,0 @@ -%bcond_without check -%global __cargo_skip_build 0 - -%global crate bootupd - -Name: rust-%{crate} -Version: 0.1.0 -Release: 3%{?dist} -Summary: Bootloader updater - -License: ASL 2.0 -URL: https://crates.io/crates/bootupd -Source: %{crates_source} - -# For now, see upstream -ExclusiveArch: x86_64 -BuildRequires: openssl-devel -%if 0%{?rhel} && !0%{?eln} -BuildRequires: rust-toolset -%else -BuildRequires: rust-packaging -%endif -BuildRequires: systemd - -%global _description %{expand: -Bootloader updater} -%description %{_description} - -%package -n %{crate} -Summary: %{summary} -License: ASL 2.0 -%{?systemd_requires} - -%description -n %{crate} %{_description} - -%files -n %{crate} -%license LICENSE -%doc README.md -%{_bindir}/bootupctl -%{_libexecdir}/bootupd -%{_unitdir}/* - -%prep -%autosetup -n %{crate}-%{version_no_tilde} -p1 -%cargo_prep - -%generate_buildrequires -%cargo_generate_buildrequires - -%build -%cargo_build - -%install -%make_install INSTALL="install -p -c" - -%changelog -* Fri Sep 11 2020 Colin Walters - 0.1.0-3 -- Initial package - diff --git a/xtask/.gitignore b/xtask/.gitignore new file mode 100644 index 000000000..4906db3f4 --- /dev/null +++ b/xtask/.gitignore @@ -0,0 +1,5 @@ +/target +fastbuild*.qcow2 +_kola_temp +.cosa +Cargo.lock diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 000000000..45e13256b --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.68" +camino = "1.0" +fn-error-context = "0.2.0" +tempfile = "3.3" +xshell = { version = "0.2" } diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 000000000..43dcca709 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,187 @@ +use std::fs::File; +use std::io::{BufRead, BufReader, BufWriter, Write}; +use std::process::{Command, Stdio}; + +use anyhow::{Context, Result}; +use camino::{Utf8Path, Utf8PathBuf}; +use fn_error_context::context; +use xshell::{cmd, Shell}; + +const NAME: &str = "bootupd"; +const VENDORPATH: &str = "vendor.tar.zstd"; + +fn main() { + if let Err(e) = try_main() { + eprintln!("error: {e:#}"); + std::process::exit(1); + } +} + +fn try_main() -> Result<()> { + let task = std::env::args().nth(1); + let sh = xshell::Shell::new()?; + if let Some(cmd) = task.as_deref() { + let f = match cmd { + "vendor" => vendor, + "package" => package, + "package-srpm" => package_srpm, + _ => print_help, + }; + f(&sh)?; + } else { + print_help(&sh)?; + } + Ok(()) +} + +fn get_target_dir() -> Result { + let target = Utf8Path::new("target"); + std::fs::create_dir_all(&target)?; + Ok(target.to_owned()) +} + +fn vendor(sh: &Shell) -> Result<()> { + let _targetdir = get_target_dir()?; + let target = VENDORPATH; + cmd!( + sh, + "cargo vendor-filterer --prefix=vendor --format=tar.zstd {target}" + ) + .run()?; + Ok(()) +} + +fn gitrev_to_version(v: &str) -> String { + let v = v.trim().trim_start_matches('v'); + v.replace('-', ".") +} + +#[context("Finding gitrev")] +fn gitrev(sh: &Shell) -> Result { + if let Ok(rev) = cmd!(sh, "git describe --tags").ignore_stderr().read() { + Ok(gitrev_to_version(&rev)) + } else { + let mut desc = cmd!(sh, "git describe --tags --always").read()?; + desc.insert_str(0, "0."); + Ok(desc) + } +} + +struct Package { + version: String, + srcpath: Utf8PathBuf, +} + +#[context("Packaging")] +fn impl_package(sh: &Shell) -> Result { + let v = gitrev(sh)?; + println!("Using version {v}"); + let namev = format!("{NAME}-{v}"); + let target = get_target_dir()?; + let p = target.join(format!("{namev}.tar.zstd")); + let o = File::create(&p).context("Creating output file")?; + let prefix = format!("{namev}/"); + let st = Command::new("git") + .args([ + "archive", + "--format=tar", + "--prefix", + prefix.as_str(), + "HEAD", + ]) + .stdout(Stdio::from(o)) + .status() + .context("Executing git archive")?; + if !st.success() { + anyhow::bail!("Failed to run {st:?}"); + } + Ok(Package { + version: v, + srcpath: p, + }) +} + +fn package(sh: &Shell) -> Result<()> { + let p = impl_package(sh)?.srcpath; + println!("Generated: {p}"); + Ok(()) +} + +fn impl_srpm(sh: &Shell) -> Result { + let pkg = impl_package(sh)?; + vendor(sh)?; + let td = tempfile::tempdir_in("target").context("Allocating tmpdir")?; + let td = td.into_path(); + let td: &Utf8Path = td.as_path().try_into().unwrap(); + let srcpath = td.join(pkg.srcpath.file_name().unwrap()); + std::fs::rename(pkg.srcpath, srcpath)?; + let v = pkg.version; + let vendorpath = td.join(format!("{NAME}-{v}-vendor.tar.zstd")); + std::fs::rename(VENDORPATH, vendorpath)?; + { + let specin = File::open(format!("contrib/packaging/{NAME}.spec")) + .map(BufReader::new) + .context("Opening spec")?; + let mut o = File::create(td.join(format!("{NAME}.spec"))).map(BufWriter::new)?; + for line in specin.lines() { + let line = line?; + if line.starts_with("Version:") { + writeln!(o, "# Replaced by cargo xtask package-srpm")?; + writeln!(o, "Version: {v}")?; + } else { + writeln!(o, "{}", line)?; + } + } + } + let d = sh.push_dir(td); + let mut cmd = cmd!(sh, "rpmbuild"); + for k in [ + "_sourcedir", + "_specdir", + "_builddir", + "_srcrpmdir", + "_rpmdir", + ] { + cmd = cmd.arg("--define"); + cmd = cmd.arg(format!("{k} {td}")); + } + let spec = format!("{NAME}.spec"); + cmd.arg("--define") + .arg(format!("_buildrootdir {td}/.build")) + .args(["-bs", spec.as_str()]) + .run()?; + drop(d); + let mut srpm = None; + for e in std::fs::read_dir(td)? { + let e = e?; + let n = e.file_name(); + let n = if let Some(n) = n.to_str() { + n + } else { + continue; + }; + if n.ends_with(".src.rpm") { + srpm = Some(td.join(n)); + break; + } + } + let srpm = srpm.ok_or_else(|| anyhow::anyhow!("Failed to find generated .src.rpm"))?; + let dest = Utf8Path::new("target").join(srpm.file_name().unwrap()); + std::fs::rename(&srpm, &dest)?; + Ok(dest) +} + +fn package_srpm(sh: &Shell) -> Result<()> { + let srpm = impl_srpm(sh)?; + println!("Generated: {srpm}"); + Ok(()) +} + +fn print_help(_sh: &Shell) -> Result<()> { + eprintln!( + "Tasks: + - vendor +" + ); + Ok(()) +} From 21b2d1af8edf96df06ea7dc9d8e9f2099b1724b5 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 15:21:53 +0800 Subject: [PATCH 385/641] bootupd: Prepare bootupd update directory for both components Prepare bootupd update directory which will save component metadata files for both components. --- src/bootupd.rs | 4 ++++ src/efi.rs | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 616d94dc4..bea8d5020 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -70,6 +70,10 @@ pub(crate) fn get_components() -> Components { } pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { + // create bootupd update dir which will save component metadata files for both components + let updates_dir = Path::new(sysroot_path).join(crate::model::BOOTUPD_UPDATES_DIR); + std::fs::create_dir_all(&updates_dir) + .with_context(|| format!("Failed to create updates dir {:?}", &updates_dir))?; for component in get_components().values() { let v = component.generate_update_metadata(sysroot_path)?; println!( diff --git a/src/efi.rs b/src/efi.rs index 18df58cca..34481343a 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -257,10 +257,6 @@ impl Component for Efi { // Fork off mv() because on overlayfs one can't rename() a lower level // directory today, and this will handle the copy fallback. - let parent = dest_efidir - .parent() - .ok_or_else(|| anyhow::anyhow!("Expected parent directory"))?; - std::fs::create_dir_all(&parent)?; Command::new("mv").args(&[&efisrc, &dest_efidir]).run()?; } From 8f857bad2d4b95f4b2eada13e9f243f7d9c67465 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 15:38:14 +0800 Subject: [PATCH 386/641] Add bios.rs and implement `generate_update_metadata` This will generate `/usr/lib/bootupd/updates/BIOS.json`, which will have the version and timestamp of `grub2-tools`. --- src/bios.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bootupd.rs | 5 ++-- src/component.rs | 1 + src/main.rs | 2 ++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/bios.rs diff --git a/src/bios.rs b/src/bios.rs new file mode 100644 index 000000000..1ecf605ad --- /dev/null +++ b/src/bios.rs @@ -0,0 +1,71 @@ +use std::io::prelude::*; +use std::path::Path; + +use crate::component::*; +use crate::model::*; +use anyhow::{bail, Result}; + +use crate::util; + +// grub2-install file path +pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; + +#[derive(Default)] +pub(crate) struct Bios {} + +impl Component for Bios { + fn name(&self) -> &'static str { + "BIOS" + } + + fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { + todo!(); + } + + fn generate_update_metadata(&self, sysroot_path: &str) -> Result { + let grub_install = Path::new(sysroot_path).join(GRUB_BIN); + if !grub_install.exists() { + bail!("Failed to find {:?}", grub_install); + } + + // Query the rpm database and list the package and build times for /usr/sbin/grub2-install + let mut rpmout = util::rpm_query(sysroot_path, &grub_install)?; + let rpmout = rpmout.output()?; + if !rpmout.status.success() { + std::io::stderr().write_all(&rpmout.stderr)?; + bail!("Failed to invoke rpm -qf"); + } + + let meta = util::parse_rpm_metadata(rpmout.stdout)?; + write_update_metadata(sysroot_path, self, &meta)?; + Ok(meta) + } + + fn query_adopt(&self) -> Result> { + todo!(); + } + + fn adopt_update( + &self, + sysroot: &openat::Dir, + update: &ContentMetadata, + ) -> Result { + todo!(); + } + + fn query_update(&self, sysroot: &openat::Dir) -> Result> { + todo!(); + } + + fn run_update( + &self, + sysroot: &openat::Dir, + current: &InstalledContent, + ) -> Result { + todo!(); + } + + fn validate(&self, current: &InstalledContent) -> Result { + todo!(); + } +} \ No newline at end of file diff --git a/src/bootupd.rs b/src/bootupd.rs index bea8d5020..0f5811cb8 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,3 +1,4 @@ +use crate::bios; use crate::component::{Component, ValidationResult}; use crate::coreos; use crate::efi; @@ -63,8 +64,8 @@ pub(crate) fn get_components() -> Components { #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] insert_component(&mut components, Box::new(efi::Efi::default())); - // #[cfg(target_arch = "x86_64")] - // components.push(Box::new(bios::BIOS::new())); + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] + insert_component(&mut components, Box::new(bios::Bios::default())); components } diff --git a/src/component.rs b/src/component.rs index a0787838e..a9511e1de 100644 --- a/src/component.rs +++ b/src/component.rs @@ -71,6 +71,7 @@ pub(crate) trait Component { pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { "EFI" => Box::new(crate::efi::Efi::default()), + "BIOS" => Box::new(crate::bios::Bios::default()), _ => anyhow::bail!("No component {}", name), }; Ok(r) diff --git a/src/main.rs b/src/main.rs index 6250a0e50..257060800 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,8 @@ Refs: #![deny(unused_must_use)] mod backend; +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] +mod bios; mod bootupd; mod cli; mod component; From 30c2a54ed9859f247ab621429f7c68e3265c9a95 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 16:07:56 +0800 Subject: [PATCH 387/641] util: Add `cmd_output` func to run command --- src/util.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/util.rs b/src/util.rs index 4d7eee888..d49c5ee30 100644 --- a/src/util.rs +++ b/src/util.rs @@ -138,9 +138,28 @@ pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { f })); } + Some("grub2-install") => { + c.arg(&path); + } _ => { bail!("Unsupported file/directory {:?}", path) } } Ok(c) } + +/// Runs the provided Command object, captures its stdout, and swallows its stderr except on +/// failure. Returns a Result describing whether the command failed, and if not, its +/// standard output. Output is assumed to be UTF-8. Errors are adequately prefixed with the full +/// command. +pub(crate) fn cmd_output(cmd: &mut Command) -> Result { + let result = cmd + .output() + .with_context(|| format!("running {:#?}", cmd))?; + if !result.status.success() { + eprintln!("{}", String::from_utf8_lossy(&result.stderr)); + bail!("{:#?} failed with {}", cmd, result.status); + } + String::from_utf8(result.stdout) + .with_context(|| format!("decoding as UTF-8 output of `{:#?}`", cmd)) +} From bd6f1c82f380e281f17ff0bed40ffa2e3ca3fafa Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 16:11:01 +0800 Subject: [PATCH 388/641] bios: implement BIOS (grub) install function - Add `--device ` option to install BIOS bootloader (grub) - If call function without `--device`, will only install EFI. --- src/bios.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++-- src/bootupd.rs | 13 ++++++++++-- src/cli/bootupd.rs | 5 ++++- src/component.rs | 8 +++++++- src/efi.rs | 7 ++++++- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index 1ecf605ad..7352afa78 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -13,13 +13,60 @@ pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; #[derive(Default)] pub(crate) struct Bios {} +impl Bios { + // Run grub2-install + fn run_grub_install(&self, dest_root: &str, device: &str) -> Result<()> { + let grub_install = Path::new("/").join(GRUB_BIN); + if !grub_install.exists() { + bail!("Failed to find {:?}", grub_install); + } + + let mut cmd = Command::new(grub_install); + let boot_dir = Path::new(dest_root).join("boot"); + #[cfg(target_arch = "x86_64")] + cmd.args(&["--target", "i386-pc"]) + .args(&["--boot-directory", boot_dir.to_str().unwrap()]) + .args(&["--modules", "mdraid1x"]) + .arg(device); + + #[cfg(target_arch = "powerpc64")] + cmd.args(&["--target", "powerpc-ieee1275"]) + .args(&["--boot-directory", boot_dir.to_str().unwrap()]) + .arg("--no-nvram") + .arg(device); + + let cmdout = cmd.output()?; + if !cmdout.status.success() { + std::io::stderr().write_all(&cmdout.stderr)?; + bail!("Failed to run {:?}", cmd); + } + Ok(()) + } +} + impl Component for Bios { fn name(&self) -> &'static str { "BIOS" } - fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { - todo!(); + fn install( + &self, + src_root: &openat::Dir, + dest_root: &str, + device: &str, + ) -> Result { + let meta = if let Some(meta) = get_component_update(src_root, self)? { + meta + } else { + anyhow::bail!("No update metadata for component {} found", self.name()); + }; + + self.run_grub_install(dest_root, device)?; + Ok(InstalledContent { + meta, + filetree: None, + adopted_from: None, + }) } fn generate_update_metadata(&self, sysroot_path: &str) -> Result { diff --git a/src/bootupd.rs b/src/bootupd.rs index 0f5811cb8..9aa79e27d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -24,7 +24,7 @@ pub(crate) enum ClientRequest { Status, } -pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { +pub(crate) fn install(source_root: &str, dest_root: &str, device: &str) -> Result<()> { let source_root = openat::Dir::open(source_root)?; SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; @@ -37,8 +37,17 @@ pub(crate) fn install(source_root: &str, dest_root: &str) -> Result<()> { let mut state = SavedState::default(); for component in components.values() { + // skip for BIOS if device is empty + if component.name() == "BIOS" && device.trim().is_empty() { + println!( + "Skip installing component {} without target device", + component.name() + ); + continue; + } + let meta = component - .install(&source_root, dest_root) + .install(&source_root, dest_root, device) .with_context(|| format!("installing component {}", component.name()))?; state.installed.insert(component.name().into(), meta); } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 1ed5c3628..2a6437792 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -47,6 +47,9 @@ pub struct InstallOpts { /// Target root #[clap(value_parser)] dest_root: String, + /// Target device, used by bios bootloader installation + #[clap(long, value_parser, default_value_t = String::from(""))] + device: String, } #[derive(Debug, Parser)] @@ -74,7 +77,7 @@ impl DCommand { /// Runner for `install` verb. pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { - bootupd::install(&opts.src_root, &opts.dest_root) + bootupd::install(&opts.src_root, &opts.dest_root, &opts.device) .context("boot data installation failed")?; Ok(()) } diff --git a/src/component.rs b/src/component.rs index a9511e1de..ab1eb8bff 100644 --- a/src/component.rs +++ b/src/component.rs @@ -44,7 +44,13 @@ pub(crate) trait Component { /// of a filesystem root, the component should query the mount point to /// determine the block device. /// This will be run during a disk image build process. - fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result; + fn install( + &self, + src_root: &openat::Dir, + dest_root: &str, + device: &str, + ) -> Result; + /// Implementation of `bootupd generate-update-metadata` for a given component. /// This expects to be run during an "image update build" process. For CoreOS diff --git a/src/efi.rs b/src/efi.rs index 34481343a..6806b451b 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -176,7 +176,12 @@ impl Component for Efi { } // TODO: Remove dest_root; it was never actually used - fn install(&self, src_root: &openat::Dir, dest_root: &str) -> Result { + fn install( + &self, + src_root: &openat::Dir, + dest_root: &str, + _: &str, + ) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta } else { From 52731215af80bca769dbd3d2272ee3b00ca911cf Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 16:39:21 +0800 Subject: [PATCH 389/641] bios: implement `run_update` to support `bootupctl update` This is the same action as `install` --- src/bios.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index 7352afa78..e0424fdc4 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -1,5 +1,6 @@ use std::io::prelude::*; use std::path::Path; +use std::process::Command; use crate::component::*; use crate::model::*; @@ -14,6 +15,40 @@ pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; pub(crate) struct Bios {} impl Bios { + // get target device for running update + fn get_device(&self) -> Result { + let mut cmd: Command; + #[cfg(target_arch = "x86_64")] + { + // find /boot partition + let boot_dir = Path::new("/").join("boot"); + cmd = Command::new("findmnt"); + cmd.arg("--noheadings") + .arg("--output") + .arg("SOURCE") + .arg(boot_dir); + let partition = util::cmd_output(&mut cmd)?; + + // lsblk to find parent device + cmd = Command::new("lsblk"); + cmd.arg("--paths") + .arg("--noheadings") + .arg("--output") + .arg("PKNAME") + .arg(partition.trim()); + } + + #[cfg(target_arch = "powerpc64")] + { + // get PowerPC-PReP-boot partition + cmd = Command::new("realpath"); + cmd.arg("/dev/disk/by-partlabel/PowerPC-PReP-boot"); + } + + let device = util::cmd_output(&mut cmd)?; + Ok(device) + } + // Run grub2-install fn run_grub_install(&self, dest_root: &str, device: &str) -> Result<()> { let grub_install = Path::new("/").join(GRUB_BIN); @@ -101,15 +136,21 @@ impl Component for Bios { } fn query_update(&self, sysroot: &openat::Dir) -> Result> { - todo!(); + get_component_update(sysroot, self) } - fn run_update( - &self, - sysroot: &openat::Dir, - current: &InstalledContent, - ) -> Result { - todo!(); + fn run_update(&self, sysroot: &openat::Dir, _: &InstalledContent) -> Result { + let updatemeta = self.query_update(sysroot)?.expect("update available"); + let device = self.get_device()?; + let device = device.trim(); + self.run_grub_install("/", device)?; + + let adopted_from = None; + Ok(InstalledContent { + meta: updatemeta, + filetree: None, + adopted_from, + }) } fn validate(&self, current: &InstalledContent) -> Result { From 1f5ef21c554f77c3c03459004fb2aea272a31af4 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 17:06:48 +0800 Subject: [PATCH 390/641] bios: return `Skipped` when run `bootupctl validate` for BIOS --- src/bios.rs | 6 +++--- src/bootupd.rs | 17 ++++++++++------- src/component.rs | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index e0424fdc4..d322ec5ab 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -153,7 +153,7 @@ impl Component for Bios { }) } - fn validate(&self, current: &InstalledContent) -> Result { - todo!(); + fn validate(&self, _: &InstalledContent) -> Result { + Ok(ValidationResult::Skip) } -} \ No newline at end of file +} diff --git a/src/bootupd.rs b/src/bootupd.rs index 9aa79e27d..cb6618ae1 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -39,13 +39,13 @@ pub(crate) fn install(source_root: &str, dest_root: &str, device: &str) -> Resul for component in components.values() { // skip for BIOS if device is empty if component.name() == "BIOS" && device.trim().is_empty() { - println!( - "Skip installing component {} without target device", - component.name() - ); - continue; - } - + println!( + "Skip installing component {} without target device", + component.name() + ); + continue; + } + let meta = component .install(&source_root, dest_root, device) .with_context(|| format!("installing component {}", component.name()))?; @@ -395,6 +395,9 @@ pub(crate) fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Resu ValidationResult::Valid => { println!("Validated: {}", name); } + ValidationResult::Skip => { + println!("Skipped: {}", name); + } ValidationResult::Errors(errs) => { for err in errs { eprintln!("{}", err); diff --git a/src/component.rs b/src/component.rs index ab1eb8bff..50bcb60d6 100644 --- a/src/component.rs +++ b/src/component.rs @@ -16,6 +16,7 @@ use crate::model::*; #[serde(rename_all = "kebab-case")] pub(crate) enum ValidationResult { Valid, + Skip, Errors(Vec), } @@ -50,7 +51,6 @@ pub(crate) trait Component { dest_root: &str, device: &str, ) -> Result; - /// Implementation of `bootupd generate-update-metadata` for a given component. /// This expects to be run during an "image update build" process. For CoreOS From 870023eb6a7073d93194c8688b86444f3d74f775 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 1 Feb 2023 17:11:01 +0800 Subject: [PATCH 391/641] bios: skip `query_adopt` To make CI green and will update in future patch. --- src/bios.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bios.rs b/src/bios.rs index d322ec5ab..f6501da7a 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -124,9 +124,10 @@ impl Component for Bios { } fn query_adopt(&self) -> Result> { - todo!(); + Ok(None) } + #[allow(unused_variables)] fn adopt_update( &self, sysroot: &openat::Dir, From f94fe663a90aaa37d4674562728fa19579bcef0b Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Thu, 2 Feb 2023 11:02:59 +0800 Subject: [PATCH 392/641] ppc64: fix build warning --- src/bootupd.rs | 2 ++ src/component.rs | 4 ++++ src/coreos.rs | 1 + src/filetree.rs | 20 ++++++++++++++++++++ src/ostreeutil.rs | 1 + src/sha512string.rs | 1 + 6 files changed, 29 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index cb6618ae1..a49925329 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,6 +1,8 @@ +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] use crate::bios; use crate::component::{Component, ValidationResult}; use crate::coreos; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use crate::efi; use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; use crate::util; diff --git a/src/component.rs b/src/component.rs index 50bcb60d6..eee5ed933 100644 --- a/src/component.rs +++ b/src/component.rs @@ -76,7 +76,9 @@ pub(crate) trait Component { /// Given a component name, create an implementation. pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] "EFI" => Box::new(crate::efi::Efi::default()), + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] "BIOS" => Box::new(crate::bios::Bios::default()), _ => anyhow::bail!("No component {}", name), }; @@ -85,12 +87,14 @@ pub(crate) fn new_from_name(name: &str) -> Result> { /// Returns the path to the payload directory for an available update for /// a component. +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn component_updatedirname(component: &dyn Component) -> PathBuf { Path::new(BOOTUPD_UPDATES_DIR).join(component.name()) } /// Returns the path to the payload directory for an available update for /// a component. +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn component_updatedir(sysroot: &str, component: &dyn Component) -> PathBuf { Path::new(sysroot).join(component_updatedirname(component)) } diff --git a/src/coreos.rs b/src/coreos.rs index 5e9fee79c..e8b91cdc9 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -24,6 +24,7 @@ pub(crate) struct Aleph { pub(crate) struct AlephWithTimestamp { pub(crate) aleph: Aleph, + #[allow(dead_code)] pub(crate) ts: chrono::DateTime, } diff --git a/src/filetree.rs b/src/filetree.rs index 93289253c..12a2d3a36 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -4,23 +4,32 @@ * SPDX-License-Identifier: Apache-2.0 */ +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use anyhow::{bail, Context, Result}; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use openat_ext::OpenatDirExt; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use openssl::hash::{Hasher, MessageDigest}; use serde::{Deserialize, Serialize}; +#[allow(unused_imports)] use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Display; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::os::unix::io::AsRawFd; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::os::unix::process::CommandExt; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::path::Path; /// The prefix we apply to our temporary files. +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) const TMP_PREFIX: &str = ".btmp."; // This module doesn't handle modes right now, because // we're only targeting FAT filesystems for UEFI. // In FAT there are no unix permission bits, usually // they're set by mount options. // See also https://github.com/coreos/fedora-coreos-config/commit/8863c2b34095a2ae5eae6fbbd121768a5f592091 +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] const DEFAULT_FILE_MODE: u32 = 0o700; use crate::sha512string::SHA512String; @@ -69,6 +78,7 @@ impl FileTreeDiff { } impl FileMetadata { + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn new_from_path( dir: &openat::Dir, name: P, @@ -88,6 +98,7 @@ impl FileMetadata { impl FileTree { // Internal helper to generate a sub-tree + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn unsorted_from_dir(dir: &openat::Dir) -> Result> { let mut ret = HashMap::new(); for entry in dir.list_dir(".")? { @@ -126,6 +137,7 @@ impl FileTree { } /// Create a FileTree from the target directory. + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn new_from_dir(dir: &openat::Dir) -> Result { let mut children = BTreeMap::new(); for (k, v) in Self::unsorted_from_dir(dir)?.drain() { @@ -136,6 +148,7 @@ impl FileTree { } /// Determine the changes *from* self to the updated tree + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn diff(&self, updated: &Self) -> Result { self.diff_impl(updated, true) } @@ -155,6 +168,7 @@ impl FileTree { current.diff_impl(self, false) } + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn diff_impl(&self, updated: &Self, check_additions: bool) -> Result { let mut additions = HashSet::new(); let mut removals = HashSet::new(); @@ -186,6 +200,7 @@ impl FileTree { /// Create a diff from a target directory. This will ignore /// any files or directories that are not part of the original tree. + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn relative_diff_to(&self, dir: &openat::Dir) -> Result { let mut removals = HashSet::new(); let mut changes = HashSet::new(); @@ -219,6 +234,7 @@ impl FileTree { } // Recursively remove all files in the directory that start with our TMP_PREFIX +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { for entry in dir.list_dir(".")? { let entry = entry?; @@ -246,6 +262,7 @@ fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { } #[derive(Default, Clone)] +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) struct ApplyUpdateOptions { pub(crate) skip_removals: bool, pub(crate) skip_sync: bool, @@ -255,6 +272,7 @@ pub(crate) struct ApplyUpdateOptions { // to be bound in nix today. I found https://github.com/XuShaohua/nc // but that's a nontrivial dependency with not a lot of code review. // Let's just fork off a helper process for now. +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { let d = d.sub_dir(".").expect("subdir"); let mut c = std::process::Command::new("sync"); @@ -272,6 +290,7 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { Ok(()) } +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn tmpname_for_path>(path: P) -> std::path::PathBuf { let path = path.as_ref(); let mut buf = path.file_name().expect("filename").to_os_string(); @@ -280,6 +299,7 @@ fn tmpname_for_path>(path: P) -> std::path::PathBuf { } /// Given two directories, apply a diff generated from srcdir to destdir +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn apply_diff( srcdir: &openat::Dir, destdir: &openat::Dir, diff --git a/src/ostreeutil.rs b/src/ostreeutil.rs index 4f4624f0d..e38a9d9fd 100644 --- a/src/ostreeutil.rs +++ b/src/ostreeutil.rs @@ -7,6 +7,7 @@ use std::path::Path; /// https://github.com/coreos/rpm-ostree/pull/969/commits/dc0e8db5bd92e1f478a0763d1a02b48e57022b59 +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) const BOOT_PREFIX: &str = "usr/lib/ostree-boot"; pub(crate) fn rpm_cmd>(sysroot: P) -> std::process::Command { diff --git a/src/sha512string.rs b/src/sha512string.rs index 4c473b1ad..eb8e6c14d 100644 --- a/src/sha512string.rs +++ b/src/sha512string.rs @@ -18,6 +18,7 @@ impl fmt::Display for SHA512String { } impl SHA512String { + #[allow(dead_code)] pub(crate) fn from_hasher(hasher: &mut Hasher) -> Self { Self(format!( "sha512:{}", From 36af2fbf8f24aaad9b772ea4d5e5635f7e624f1c Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Thu, 2 Feb 2023 15:03:52 +0800 Subject: [PATCH 393/641] aarch64: fix build warning --- src/util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util.rs b/src/util.rs index d49c5ee30..16cee8186 100644 --- a/src/util.rs +++ b/src/util.rs @@ -152,6 +152,7 @@ pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { /// failure. Returns a Result describing whether the command failed, and if not, its /// standard output. Output is assumed to be UTF-8. Errors are adequately prefixed with the full /// command. +#[allow(dead_code)] pub(crate) fn cmd_output(cmd: &mut Command) -> Result { let result = cmd .output() From b2c443b971e91c531f7748676c4a49d30f3d3d43 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 7 Feb 2023 16:52:50 -0500 Subject: [PATCH 394/641] xtask: Add timestamp to version This is a copy of https://github.com/containers/bootc/commit/0c8c6834f0aecdf18d8b9eec07a3810743ad0d37 I was hitting an issue with our COPR builds where we were getting *earlier* builds because the git hash was the first component of the version, and the leading numbers there don't increment, and RPM wants higher versions. Force newer-is-better by injecting the date (up to the minute, not second because we're not going to build more than one a second). --- xtask/Cargo.toml | 1 + xtask/src/main.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 45e13256b..aea18c755 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] anyhow = "1.0.68" camino = "1.0" +chrono = { version = "0.4.23", default_features = false, features = ["std"] } fn-error-context = "0.2.0" tempfile = "3.3" xshell = { version = "0.2" } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 43dcca709..09b2c2a2e 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -67,6 +67,17 @@ fn gitrev(sh: &Shell) -> Result { } } +/// Return a string formatted version of the git commit timestamp, up to the minute +/// but not second because, well, we're not going to build more than once a second. +#[context("Finding git timestamp")] +fn git_timestamp(sh: &Shell) -> Result { + let ts = cmd!(sh, "git show -s --format=%ct").read()?; + let ts = ts.trim().parse::()?; + let ts = chrono::NaiveDateTime::from_timestamp_opt(ts, 0) + .ok_or_else(|| anyhow::anyhow!("Failed to parse timestamp"))?; + Ok(ts.format("%Y%m%d%H%M").to_string()) +} + struct Package { version: String, srcpath: Utf8PathBuf, @@ -75,6 +86,9 @@ struct Package { #[context("Packaging")] fn impl_package(sh: &Shell) -> Result { let v = gitrev(sh)?; + let timestamp = git_timestamp(sh)?; + // We always inject the timestamp first to ensure that newer is better. + let v = format!("{timestamp}.{v}"); println!("Using version {v}"); let namev = format!("{NAME}-{v}"); let target = get_target_dir()?; From c4c58ef621d365a520b6f23e2ca2ad01109cee1b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 25 Feb 2023 11:19:57 -0500 Subject: [PATCH 395/641] bios: Always add `part_gpt` This fixes https://github.com/containers/bootc/issues/64 I didn't chase through what was going wrong in grub; there's a whole lot of layers here. But for the CoreOS use case we know the modules we need, so we should specify them. --- src/bios.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bios.rs b/src/bios.rs index f6501da7a..374042c17 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -58,10 +58,13 @@ impl Bios { let mut cmd = Command::new(grub_install); let boot_dir = Path::new(dest_root).join("boot"); + // We forcibly inject mdraid1x because it's needed by CoreOS's default of "install raw disk image" + // We also add part_gpt because in some cases probing of the partition map can fail such + // as in a container, but we always use GPT. #[cfg(target_arch = "x86_64")] cmd.args(&["--target", "i386-pc"]) .args(&["--boot-directory", boot_dir.to_str().unwrap()]) - .args(&["--modules", "mdraid1x"]) + .args(&["--modules", "mdraid1x part_gpt"]) .arg(device); #[cfg(target_arch = "powerpc64")] From fec3b330614c8926fbbbdbad3abc9fe3bbbc9d29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 02:36:53 +0000 Subject: [PATCH 396/641] build(deps): bump tempfile from 3.3.0 to 3.4.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/Stebalien/tempfile/releases) - [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS) - [Commits](https://github.com/Stebalien/tempfile/commits) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 140 +++++++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 2 +- 2 files changed, 132 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 347d85af2..f60308db2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,6 +211,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.6.0" @@ -352,6 +373,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "itoa" version = "1.0.1" @@ -391,6 +422,12 @@ dependencies = [ "uuid", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "log" version = "0.4.17" @@ -657,12 +694,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "rustix" +version = "0.36.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ - "winapi", + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", ] [[package]] @@ -738,16 +780,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.42.0", ] [[package]] @@ -918,3 +959,84 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/Cargo.toml b/Cargo.toml index 737ece486..af760558e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.3" +tempfile = "^3.4" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo From dce8bad671c35c4bc1b90665c3af0d3f45e8d4fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 02:08:00 +0000 Subject: [PATCH 397/641] build(deps): bump serde_json from 1.0.87 to 1.0.94 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.87 to 1.0.94. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.87...v1.0.94) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f60308db2..c7fa211d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", From e52b2ce4f3616e320a7f4b6988932eccd251a252 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 02:00:49 +0000 Subject: [PATCH 398/641] build(deps): bump libc from 0.2.137 to 0.2.140 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.137 to 0.2.140. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.137...0.2.140) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f60308db2..65d12b604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libsystemd" From b3ab439da935d273404196117991f8c59df05372 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 02:01:18 +0000 Subject: [PATCH 399/641] build(deps): bump chrono from 0.4.23 to 0.4.24 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.23 to 0.4.24. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.23...v0.4.24) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f60308db2..90f44d449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index af760558e..1e27bcfb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.23", features = ["serde"] } +chrono = { version = "0.4.24", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" fn-error-context = "0.2.0" From f0d628fb36382e8dbd22febff97f41a39f33ac78 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 15 Mar 2023 15:44:46 -0400 Subject: [PATCH 400/641] README.md: Update status to reflect current reality Came up re https://github.com/coreos/fedora-coreos-tracker/issues/1441 Co-authored-by: Benjamin Gilbert --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bd8215f28..c566d01ca 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,18 @@ that's for tools like `grubby` and `ostree`. ## Status -Currently a work in progress and is not ready to ship for production -updates, but early feedback on the design is appreciated! +bootupd supports updating GRUB and shim for UEFI firmware on +x86_64 and aarch64, and GRUB for BIOS firmware on x86_64. +The project is [deployed in Fedora CoreOS](https://docs.fedoraproject.org/en-US/fedora-coreos/bootloader-updates/) and derivatives, +and is also used by the new [`bootc install`](https://github.com/containers/bootc/#using-bootc-install) +functionality. The bootupd CLI should be considered stable. + +bootupd does not yet perform updates in a way that is safe +against a power failure at the wrong moment, or +against a buggy bootloader update that fails to boot +the system. + +Therefore, by default, bootupd updates the bootloader only when manually instructed to do so. ## Relationship to other projects From 18701bdace1e27edc220f73b01d859097ec928de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 02:11:34 +0000 Subject: [PATCH 401/641] build(deps): bump openssl from 0.10.42 to 0.10.47 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.42 to 0.10.47. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.42...openssl-v0.10.47) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f60308db2..f14eb29c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" dependencies = [ "bitflags", "cfg-if", @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.76" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" +checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ "autocfg", "cc", From 5d9fd2c4610855ff65bc33c4c6309dec22f37707 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 21:22:48 +0000 Subject: [PATCH 402/641] build(deps): bump anyhow from 1.0.66 to 1.0.70 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.70. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.70) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e5948862..759c9ef02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" [[package]] name = "atty" From f2339b336c49a4954c9e3d477e79a329607f1b5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 21:29:53 +0000 Subject: [PATCH 403/641] build(deps): bump serde from 1.0.147 to 1.0.158 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.147 to 1.0.158. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.147...v1.0.158) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c37dd7698..36f9d77f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,7 +150,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.90", ] [[package]] @@ -249,7 +249,7 @@ checksum = "236b4e4ae2b8be5f7a5652f6108c4a0f2627c569db4e7923333d31c7dbfed0fb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.90", ] [[package]] @@ -551,7 +551,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.90", ] [[package]] @@ -594,7 +594,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.90", "version_check", ] @@ -611,18 +611,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -715,22 +715,22 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.4", ] [[package]] @@ -778,6 +778,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "syn" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c622ae390c9302e214c31013517c2061ecb2699935882c60a9b37f82f8625ae" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" version = "3.4.0" @@ -823,7 +834,7 @@ checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.90", ] [[package]] @@ -842,6 +853,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -896,7 +913,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.90", "wasm-bindgen-shared", ] @@ -918,7 +935,7 @@ checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 67eb44738e67acc312abb5ecc2eba111809db504 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 02:00:20 +0000 Subject: [PATCH 404/641] build(deps): bump fn-error-context from 0.2.0 to 0.2.1 Bumps [fn-error-context](https://github.com/andrewhickman/fn-error-context) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/andrewhickman/fn-error-context/releases) - [Changelog](https://github.com/andrewhickman/fn-error-context/blob/main/CHANGELOG.md) - [Commits](https://github.com/andrewhickman/fn-error-context/commits) --- updated-dependencies: - dependency-name: fn-error-context dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6cdc3387f..d822af5b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,13 +243,13 @@ dependencies = [ [[package]] name = "fn-error-context" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236b4e4ae2b8be5f7a5652f6108c4a0f2627c569db4e7923333d31c7dbfed0fb" +checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 1.0.90", + "syn 2.0.4", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1e27bcfb7..a3ce62847 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ bincode = "1.3.2" chrono = { version = "0.4.24", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = ">= 0.8, < 0.10" -fn-error-context = "0.2.0" +fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" libc = "^0.2" From 67d7da199cfbedee84614f03310ac0c553fdda6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 01:57:52 +0000 Subject: [PATCH 405/641] build(deps): bump serde from 1.0.158 to 1.0.159 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.158 to 1.0.159. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.158...v1.0.159) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d822af5b1..8508a3310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -715,18 +715,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", From 672b25637d582bec55a2213e4e27865ef78d4ba1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 01:57:59 +0000 Subject: [PATCH 406/641] build(deps): bump serde_json from 1.0.94 to 1.0.95 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.94 to 1.0.95. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.94...v1.0.95) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d822af5b1..458a05ea6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ "itoa", "ryu", From 86501f50b84f0d28de1fb0561caa4d69d677d8ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 01:56:45 +0000 Subject: [PATCH 407/641] build(deps): bump libc from 0.2.140 to 0.2.141 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.140 to 0.2.141. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.140...0.2.141) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d822af5b1..8cd12ba78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libsystemd" From d942db4d3b146df751f78ed4a64a3df19e255e57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 01:56:53 +0000 Subject: [PATCH 408/641] build(deps): bump openssl from 0.10.47 to 0.10.50 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.47 to 0.10.50. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.47...openssl-v0.10.50) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d822af5b1..5b5c21db1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.47" +version = "0.10.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9" +checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" dependencies = [ "bitflags", "cfg-if", @@ -556,11 +556,10 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.82" +version = "0.9.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" +checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", From be0764bec157b39a22af44b1ebcfb8964a38ea45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:12:11 +0000 Subject: [PATCH 409/641] build(deps): bump libsystemd from 0.5.0 to 0.6.0 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.5.0 to 0.6.0. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.5.0...v0.6.0) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 44 ++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 2 +- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bc41dd68..9a6928c7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,7 +82,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix", + "nix 0.23.1", "openat", "openat-ext", "openssl", @@ -406,14 +406,14 @@ checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libsystemd" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8144587c71c16756b1055d3dcb0c75cb605a10ecd6523cc33702d5f90902bf6d" +checksum = "88b9597a67aa1c81a6624603e6bd0bcefb9e0f94c9c54970ec53771082104b4e" dependencies = [ "hmac", "libc", "log", - "nix", + "nix 0.26.2", "nom", "once_cell", "serde", @@ -452,6 +452,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -468,7 +477,20 @@ dependencies = [ "cc", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.4", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.7.1", + "static_assertions", ] [[package]] @@ -523,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cf3e4baa7f516441f58373f58aaf6e91a5dfa2e2b50e68a0d313b082014c61d" dependencies = [ "libc", - "nix", + "nix 0.23.1", "openat", "rand", ] @@ -754,6 +776,12 @@ dependencies = [ "digest", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" @@ -866,9 +894,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "uuid" -version = "0.8.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index a3ce62847..bd254fec1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" libc = "^0.2" -libsystemd = ">= 0.3, < 0.6" +libsystemd = ">= 0.3, < 0.7" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" From 93cd0d11654e513ef547292bf23b32a8ac741255 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 01:56:54 +0000 Subject: [PATCH 410/641] build(deps): bump libc from 0.2.141 to 0.2.142 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.141 to 0.2.142. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.141...0.2.142) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bc41dd68..cbba46368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libsystemd" From 1b27e42205eb666cd1051b7418b69277515955b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 01:57:05 +0000 Subject: [PATCH 411/641] build(deps): bump openssl from 0.10.50 to 0.10.52 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.50 to 0.10.52. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.50...openssl-v0.10.52) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bc41dd68..f7b966f10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.50" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if", @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.85" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", From 3eaba99a9507a18cdce7c2e5c090faeb0341ece2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 01:57:16 +0000 Subject: [PATCH 412/641] build(deps): bump anyhow from 1.0.70 to 1.0.71 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.70 to 1.0.71. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.70...1.0.71) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bc41dd68..b340aaa72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "atty" From 58376208ddcc2ce8baab430b55f4e14dc94f83c6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 21 Mar 2023 18:50:00 -0400 Subject: [PATCH 413/641] Bump MSRV to 1.66.0 This is what we have elsewhere in coreos/ and I think will be prep for further PRs. Signed-off-by: Colin Walters --- .github/workflows/rust.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7aa2f9c12..9ef9e41bd 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -13,7 +13,7 @@ permissions: env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.59.0 + ACTION_LINTS_TOOLCHAIN: 1.66.0 jobs: tests-stable: diff --git a/Cargo.toml b/Cargo.toml index a3ce62847..8be7cd487 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ license = "Apache-2.0" version = "0.2.9" authors = ["Colin Walters "] edition = "2021" -rust-version = "1.58.1" +rust-version = "1.66.0" # See https://github.com/cgwalters/cargo-vendor-filterer [package.metadata.vendor-filter] From a3a46cec90419a62811f01666d246a2bf7d654f4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 4 May 2023 17:18:51 -0400 Subject: [PATCH 414/641] Allow clippy::box_default Because this code is right, and what `cargo clippy --fix` wants to do actually breaks compilation. Signed-off-by: Colin Walters --- src/bootupd.rs | 2 ++ src/component.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index a49925329..0266a7363 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -73,9 +73,11 @@ pub(crate) fn get_components() -> Components { } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] + #[allow(clippy::box_default)] insert_component(&mut components, Box::new(efi::Efi::default())); #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] + #[allow(clippy::box_default)] insert_component(&mut components, Box::new(bios::Bios::default())); components diff --git a/src/component.rs b/src/component.rs index eee5ed933..36992d0a8 100644 --- a/src/component.rs +++ b/src/component.rs @@ -77,8 +77,10 @@ pub(crate) trait Component { pub(crate) fn new_from_name(name: &str) -> Result> { let r: Box = match name { #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] + #[allow(clippy::box_default)] "EFI" => Box::new(crate::efi::Efi::default()), #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] + #[allow(clippy::box_default)] "BIOS" => Box::new(crate::bios::Bios::default()), _ => anyhow::bail!("No component {}", name), }; From 087f63beccf556809d7b49332483eb5dc81f0c6c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 4 May 2023 17:21:38 -0400 Subject: [PATCH 415/641] tree-wide: Fix various minor clippy lints The unnecessary borrows one always feels like the most churn for the least value, but let's do it. Signed-off-by: Colin Walters --- src/bios.rs | 6 +++--- src/component.rs | 2 +- src/efi.rs | 6 +++--- src/filetree.rs | 17 ++++++++--------- src/util.rs | 6 +++--- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index 374042c17..7dc7099cd 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -62,9 +62,9 @@ impl Bios { // We also add part_gpt because in some cases probing of the partition map can fail such // as in a container, but we always use GPT. #[cfg(target_arch = "x86_64")] - cmd.args(&["--target", "i386-pc"]) - .args(&["--boot-directory", boot_dir.to_str().unwrap()]) - .args(&["--modules", "mdraid1x part_gpt"]) + cmd.args(["--target", "i386-pc"]) + .args(["--boot-directory", boot_dir.to_str().unwrap()]) + .args(["--modules", "mdraid1x part_gpt"]) .arg(device); #[cfg(target_arch = "powerpc64")] diff --git a/src/component.rs b/src/component.rs index 36992d0a8..7ac0c7f05 100644 --- a/src/component.rs +++ b/src/component.rs @@ -116,7 +116,7 @@ pub(crate) fn write_update_metadata( let sysroot = openat::Dir::open(sysroot)?; let dir = sysroot.sub_dir(BOOTUPD_UPDATES_DIR)?; let name = component_update_data_name(component); - dir.write_file_with(&name, 0o644, |w| -> Result<_> { + dir.write_file_with(name, 0o644, |w| -> Result<_> { Ok(serde_json::to_writer(w, &meta)?) })?; Ok(()) diff --git a/src/efi.rs b/src/efi.rs index 6806b451b..d407788f9 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -198,9 +198,9 @@ impl Component for Efi { // TODO - add some sort of API that allows directly setting the working // directory to a file descriptor. let r = std::process::Command::new("cp") - .args(&["-rp", "--reflink=auto"]) + .args(["-rp", "--reflink=auto"]) .arg(&srcdir_name) - .arg(&destdir) + .arg(destdir) .current_dir(format!("/proc/self/fd/{}", src_root.as_raw_fd())) .status()?; if !r.success() { @@ -262,7 +262,7 @@ impl Component for Efi { // Fork off mv() because on overlayfs one can't rename() a lower level // directory today, and this will handle the copy fallback. - Command::new("mv").args(&[&efisrc, &dest_efidir]).run()?; + Command::new("mv").args([&efisrc, &dest_efidir]).run()?; } // Query the rpm database and list the package and build times for all the diff --git a/src/filetree.rs b/src/filetree.rs index 12a2d3a36..a55f8d9b9 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -276,7 +276,7 @@ pub(crate) struct ApplyUpdateOptions { pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { let d = d.sub_dir(".").expect("subdir"); let mut c = std::process::Command::new("sync"); - let c = c.args(&["-f", "."]); + let c = c.args(["-f", "."]); unsafe { c.pre_exec(move || { nix::unistd::fchdir(d.as_raw_fd()).expect("fchdir"); @@ -357,8 +357,8 @@ mod tests { use std::io::Write; fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { - let ta = FileTree::new_from_dir(&a)?; - let tb = FileTree::new_from_dir(&b)?; + let ta = FileTree::new_from_dir(a)?; + let tb = FileTree::new_from_dir(b)?; let diff = ta.diff(&tb)?; Ok(diff) } @@ -374,7 +374,7 @@ mod tests { let c = t.path().join("c"); let r = std::process::Command::new("cp") .arg("-rp") - .args(&[a, &c]) + .args([a, &c]) .status()?; if !r.success() { bail!("failed to cp"); @@ -415,9 +415,8 @@ mod tests { skip_removals: true, ..Default::default() }; - test_one_apply(&a, &b, None).context("testing apply (with removals)")?; - test_one_apply(&a, &b, Some(&skip_removals)) - .context("testing apply (skipping removals)")?; + test_one_apply(a, b, None).context("testing apply (with removals)")?; + test_one_apply(a, b, Some(&skip_removals)).context("testing apply (skipping removals)")?; Ok(()) } @@ -496,7 +495,7 @@ mod tests { let newsubp = Path::new(relp).join("subdir"); fs::create_dir_all(b.join(&newsubp))?; fs::write(b.join(&newsubp).join("newgrub.x64"), "newgrub data")?; - fs::remove_file(b.join(&relp).join("shim.x64"))?; + fs::remove_file(b.join(relp).join("shim.x64"))?; { let a = openat::Dir::open(&a)?; let b = openat::Dir::open(&b)?; @@ -516,7 +515,7 @@ mod tests { String::from_utf8(std::fs::read(a.join(&newsubp).join("newgrub.x64"))?)?, "newgrub data" ); - assert!(!a.join(&relp).join("shim.x64").exists()); + assert!(!a.join(relp).join("shim.x64").exists()); Ok(()) } } diff --git a/src/util.rs b/src/util.rs index 16cee8186..319796fe8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -80,7 +80,7 @@ pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { return Ok(()); } let status = std::process::Command::new("mount") - .args(&["-o", "remount,rw"]) + .args(["-o", "remount,rw"]) .arg(p) .status()?; if !status.success() { @@ -128,7 +128,7 @@ pub(crate) fn parse_rpm_metadata(stdout: Vec) -> Result { /// files in the EFI system partition, or for grub2-install file pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { let mut c = ostreeutil::rpm_cmd(sysroot_path); - c.args(&["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); + c.args(["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); match path.file_name().expect("filename").to_str() { Some("EFI") => { @@ -139,7 +139,7 @@ pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { })); } Some("grub2-install") => { - c.arg(&path); + c.arg(path); } _ => { bail!("Unsupported file/directory {:?}", path) From 1f32f947ecc5516e1f72056c9f26e73c16cb17e1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 4 May 2023 17:22:34 -0400 Subject: [PATCH 416/641] filetree: Use `.write_all()` in tests This clippy lint catches a real bug. Signed-off-by: Colin Walters --- src/filetree.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/filetree.rs b/src/filetree.rs index a55f8d9b9..fe1c67877 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -437,7 +437,7 @@ mod tests { assert_eq!(diff.count(), 0); { let mut bar = a.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; + bar.write_all("foobarcontents".as_bytes())?; } let diff = run_diff(&a, &b)?; assert_eq!(diff.count(), 1); @@ -456,14 +456,14 @@ mod tests { b.create_dir("foo", 0o755)?; { let mut bar = b.write_file("foo/bar", 0o644)?; - bar.write("foobarcontents".as_bytes())?; + bar.write_all("foobarcontents".as_bytes())?; } let diff = run_diff(&a, &b)?; assert_eq!(diff.count(), 0); test_apply(&pa, &pb).context("testing apply 2")?; { let mut bar2 = b.write_file("foo/bar", 0o644)?; - bar2.write("foobarcontents2".as_bytes())?; + bar2.write_all("foobarcontents2".as_bytes())?; } let diff = run_diff(&a, &b)?; assert_eq!(diff.count(), 1); From 0265197ca8ea9261142acacc86e7edac511326d3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 21 Mar 2023 18:06:05 -0400 Subject: [PATCH 417/641] Update env_logger to 0.10 Obsoletes https://github.com/coreos/bootupd/pull/406 --- Cargo.lock | 36 +++++++++++++++++------------------- Cargo.toml | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39dfb4872..9d6e9bd1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,17 +26,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -200,12 +189,12 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", @@ -312,12 +301,9 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "hex" @@ -383,6 +369,18 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "is-terminal" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "itoa" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 8be7cd487..93d7eab4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ anyhow = "1.0" bincode = "1.3.2" chrono = { version = "0.4.24", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } -env_logger = ">= 0.8, < 0.10" +env_logger = "0.10" fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" From 2b837682d70872a7bb72857eaaca6c305a13000c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 13:47:50 +0000 Subject: [PATCH 418/641] build(deps): bump serde from 1.0.159 to 1.0.162 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.159 to 1.0.162. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.159...1.0.162) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d6e9bd1c..90e6a8610 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -712,18 +712,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.159" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", From 4debd1c89fca0aa88f71e5cd256e55aeb63c2c75 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Sun, 26 Feb 2023 01:44:11 -0700 Subject: [PATCH 419/641] efi: Skip adopting for systemd-boot and systemd-stub If the system is booted with systemd-boot or systemd-stub then `bootctl` will handle updating the boot components. Both of these components write identifying information to EFI variables as NUL terminated UTF-16 strings. Check these variables to detect if either systemd-boot or systemd-stub are in use and skip adoption if so. --- Cargo.lock | 7 ++++++ Cargo.toml | 1 + src/efi.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 9d6e9bd1c..ffc4b46e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,6 +78,7 @@ dependencies = [ "serde", "serde_json", "tempfile", + "widestring", ] [[package]] @@ -943,6 +944,12 @@ version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 93d7eab4f..5991c0d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.4" +widestring = "1.0.2" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo diff --git a/src/efi.rs b/src/efi.rs index d407788f9..7c4245d4a 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -12,6 +12,7 @@ use std::process::Command; use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; +use widestring::U16CString; use crate::component::*; use crate::filetree; @@ -27,6 +28,10 @@ pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi"]; pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition"; +/// Systemd boot loader info EFI variable names +const LOADER_INFO_VAR_STR: &str = "LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; +const STUB_INFO_VAR_STR: &str = "StubInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; + #[derive(Default)] pub(crate) struct Efi { mountpoint: RefCell>, @@ -105,6 +110,70 @@ impl Efi { } } +/// Convert a nul-terminated UTF-16 byte array to a String. +fn string_from_utf16_bytes(slice: &[u8]) -> String { + // For some reason, systemd appends 3 nul bytes after the string. + // Drop the last byte if there's an odd number. + let size = slice.len() / 2; + let v: Vec = (0..size) + .map(|i| u16::from_ne_bytes([slice[2 * i], slice[2 * i + 1]])) + .collect(); + U16CString::from_vec(v).unwrap().to_string_lossy() +} + +/// Read a nul-terminated UTF-16 string from an EFI variable. +fn read_efi_var_utf16_string(name: &str) -> Option { + let efivars = Path::new("/sys/firmware/efi/efivars"); + if !efivars.exists() { + log::warn!("No efivars mount at {:?}", efivars); + return None; + } + let path = efivars.join(name); + if !path.exists() { + log::trace!("No EFI variable {name}"); + return None; + } + match std::fs::read(&path) { + Ok(buf) => { + // Skip the first 4 bytes, those are the EFI variable attributes. + if buf.len() < 4 { + log::warn!("Read less than 4 bytes from {:?}", path); + return None; + } + Some(string_from_utf16_bytes(&buf[4..])) + } + Err(reason) => { + log::warn!("Failed reading {:?}: {reason}", path); + None + } + } +} + +/// Read the LoaderInfo EFI variable if it exists. +fn get_loader_info() -> Option { + read_efi_var_utf16_string(LOADER_INFO_VAR_STR) +} + +/// Read the StubInfo EFI variable if it exists. +fn get_stub_info() -> Option { + read_efi_var_utf16_string(STUB_INFO_VAR_STR) +} + +/// Whether to skip adoption if a systemd bootloader is found. +fn skip_systemd_bootloaders() -> bool { + if let Some(loader_info) = get_loader_info() { + if loader_info.starts_with("systemd") { + log::trace!("Skipping adoption for {:?}", loader_info); + return true; + } + } + if let Some(stub_info) = get_stub_info() { + log::trace!("Skipping adoption for {:?}", stub_info); + return true; + } + false +} + impl Component for Efi { fn name(&self) -> &'static str { "EFI" @@ -130,6 +199,11 @@ impl Component for Efi { } else { log::trace!("No CoreOS aleph detected"); } + // Don't adopt if the system is booted with systemd-boot or + // systemd-stub since those will be managed with bootctl. + if skip_systemd_bootloaders() { + return Ok(None); + } let ostree_deploy_dir = Path::new("/ostree/deploy"); if ostree_deploy_dir.exists() { let btime = ostree_deploy_dir.metadata()?.created()?; From 8c5d4e702cdc4a4dd90d3ebd37116acb8cd0e29f Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Tue, 11 Apr 2023 10:30:43 -0600 Subject: [PATCH 420/641] efi: Allow /boot as the ESP Some systems use the ESP as the entire `/boot` filesystem. This check needs to go before `boot/efi` since that would also detect the FAT filesystem but would expect the `EFI` directory at `/boot/efi/EFI` instead of `/boot/EFI`. A more typical system with the ESP mounted at `/boot/efi` would not have use FAT for the `/boot` filesystem and would be skipped in this check. --- src/efi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/efi.rs b/src/efi.rs index 7c4245d4a..12a051c46 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -22,7 +22,7 @@ use crate::util; use crate::util::CommandRunExt; /// Well-known paths to the ESP that may have been mounted external to us. -pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi"]; +pub(crate) const ESP_MOUNTS: &[&str] = &["boot", "boot/efi", "efi"]; /// The ESP partition label on Fedora CoreOS derivatives pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; From 9ce239e692d60756024d105d57e22a94517c0011 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 14:44:50 +0000 Subject: [PATCH 421/641] build(deps): bump serde_json from 1.0.95 to 1.0.96 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.95 to 1.0.96. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.95...v1.0.96) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffc4b46e7..ec3bcd5c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -733,9 +733,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", From 02c12c2ed82acec2206cc020845fdc4359b0948d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 14:45:04 +0000 Subject: [PATCH 422/641] build(deps): bump tempfile from 3.4.0 to 3.5.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/Stebalien/tempfile/releases) - [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS) - [Commits](https://github.com/Stebalien/tempfile/commits) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 138 ++++++++++++++++++++++++++++++++++++++++++----------- Cargo.toml | 2 +- 2 files changed, 111 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9b43caee..3bfc72ce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,6 +212,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -378,7 +389,7 @@ checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" dependencies = [ "hermit-abi", "io-lifetimes", - "rustix", + "rustix 0.36.8", "windows-sys 0.45.0", ] @@ -427,6 +438,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + [[package]] name = "log" version = "0.4.17" @@ -667,9 +684,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] @@ -698,10 +715,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", - "errno", + "errno 0.2.8", + "io-lifetimes", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.37.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +dependencies = [ + "bitflags", + "errno 0.3.1", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.7", "windows-sys 0.45.0", ] @@ -789,15 +820,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix", - "windows-sys 0.42.0", + "rustix 0.37.7", + "windows-sys 0.45.0", ] [[package]] @@ -983,26 +1014,20 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets 0.42.1", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -1011,13 +1036,28 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -1026,38 +1066,80 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml index 5991c0d35..86e48cc86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.4" +tempfile = "^3.5" widestring = "1.0.2" [profile.release] From 70998a9d0b6428bbc8ce2de33e03539c5db5e936 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 01:56:37 +0000 Subject: [PATCH 423/641] build(deps): bump libc from 0.2.142 to 0.2.143 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.142 to 0.2.143. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.142...0.2.143) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92272be96..b8df9d8ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.142" +version = "0.2.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" [[package]] name = "libsystemd" From 3f70082d1dee91cef53ad3a14959c619ea8be6bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 01:56:37 +0000 Subject: [PATCH 424/641] build(deps): bump libc from 0.2.143 to 0.2.144 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.143 to 0.2.144. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.143...0.2.144) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8df9d8ef..6835e2617 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.143" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libsystemd" From dda6508147e9e32787730da9f7998ddc7d9523d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 01:56:43 +0000 Subject: [PATCH 425/641] build(deps): bump serde from 1.0.162 to 1.0.163 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.162 to 1.0.163. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.162...v1.0.163) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8df9d8ef..1920796ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -766,18 +766,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", From 29499c7fdccfc219c60c63c6fcec07c713d6cd52 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Thu, 25 May 2023 17:39:15 +0000 Subject: [PATCH 426/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@4e8a0c41c898bb6b52e378f16c867914294592f9. --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bf123a68f..7f39fc80e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,7 @@ version: 2 updates: - package-ecosystem: cargo - directory: "/" + directory: / schedule: interval: weekly open-pull-requests-limit: 10 From 5b44dacb69bd1ef370479d7fe873637ae5eb0211 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Fri, 26 May 2023 18:44:05 +0000 Subject: [PATCH 427/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@343262aa91748aedf9af0230457b45f0549ce815. --- .github/dependabot.yml | 17 +++++++------ .github/workflows/rust.yml | 49 ++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7f39fc80e..b97ea3e85 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,12 @@ +# Maintained in https://github.com/coreos/repo-templates +# Do not edit downstream. + version: 2 updates: -- package-ecosystem: cargo - directory: / - schedule: - interval: weekly - open-pull-requests-limit: 10 - labels: - - area/dependencies + - package-ecosystem: cargo + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 10 + labels: + - area/dependencies diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 9ef9e41bd..d4053f5d0 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,26 +1,31 @@ ---- -name: Rust +# Maintained in https://github.com/coreos/repo-templates +# Do not edit downstream. +name: Rust on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] - + branches: [main] permissions: contents: read +# don't waste job slots on superseded code +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTION_LINTS_TOOLCHAIN: 1.66.0 + ACTIONS_LINTS_TOOLCHAIN: 1.66.0 jobs: tests-stable: - name: "Tests, stable toolchain" + name: Tests, stable toolchain runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Check out repository uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 @@ -31,10 +36,10 @@ jobs: - name: cargo test run: cargo test tests-release-stable: - name: "Tests (release), stable toolchain" + name: Tests (release), stable toolchain runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Check out repository uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 @@ -45,15 +50,15 @@ jobs: - name: cargo test (release) run: cargo test --release tests-release-msrv: - name: "Tests (release), minimum supported toolchain" + name: Tests (release), minimum supported toolchain runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Check out repository uses: actions/checkout@v3 - name: Detect crate MSRV run: | msrv=$(cargo metadata --format-version 1 --no-deps | \ - jq -r '.packages | .[].rust_version') + jq -r '.packages[0].rust_version') echo "Crate MSRV: $msrv" echo "MSRV=$msrv" >> $GITHUB_ENV - name: Install toolchain @@ -65,31 +70,29 @@ jobs: - name: cargo test (release) run: cargo test --release linting: - name: "Lints, pinned toolchain" + name: Lints, pinned toolchain runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Check out repository uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 with: - toolchain: ${{ env['ACTION_LINTS_TOOLCHAIN'] }} + toolchain: ${{ env.ACTIONS_LINTS_TOOLCHAIN }} components: rustfmt, clippy - - name: cargo clippy (warnings) - run: cargo clippy -- -D warnings - name: cargo fmt (check) run: cargo fmt -- --check -l + - name: cargo clippy (warnings) + run: cargo clippy -- -D warnings tests-other-channels: - name: "Tests, unstable toolchain" + name: Tests, unstable toolchain runs-on: ubuntu-latest continue-on-error: true strategy: matrix: - channel: - - "beta" - - "nightly" + channel: [beta, nightly] steps: - - name: Checkout repository + - name: Check out repository uses: actions/checkout@v3 - name: Install toolchain uses: dtolnay/rust-toolchain@v1 From 5390b6a38d8d222d6f14160b71bf2fbde08f6b5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 01:56:47 +0000 Subject: [PATCH 428/641] build(deps): bump log from 0.4.17 to 0.4.18 Bumps [log](https://github.com/rust-lang/log) from 0.4.17 to 0.4.18. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.17...0.4.18) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a17ae39df..ed8c086c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,12 +446,9 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" [[package]] name = "memchr" From 1e9a6b47823c523c9704f040f377edce1cf2c80c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 30 May 2023 09:41:33 -0400 Subject: [PATCH 429/641] build-sys: Use new tier = 2 for cargo-vendor-filterer While the architecture list here was right today, there's no reason not to just expand our vendoring set. --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9f126cfa6..b949f22a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,10 @@ authors = ["Colin Walters "] edition = "2021" rust-version = "1.66.0" -# See https://github.com/cgwalters/cargo-vendor-filterer +# See https://github.com/coreos/cargo-vendor-filterer [package.metadata.vendor-filter] -platforms = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"] +platforms = ["*-unknown-linux-gnu"] +tier = "2" [[bin]] name = "bootupd" From 7a82dfbf61e1d4b55c473c1441d481dc1071ec95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 15:54:48 +0000 Subject: [PATCH 430/641] build(deps): bump openssl from 0.10.52 to 0.10.53 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.52 to 0.10.53. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.52...openssl-v0.10.53) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed8c086c2..3a83cacbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -565,9 +565,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" dependencies = [ "bitflags", "cfg-if", @@ -591,9 +591,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", From 860e0c5dea6836b251431a907a6f0fcc32b8b1a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 15:54:53 +0000 Subject: [PATCH 431/641] build(deps): bump chrono from 0.4.24 to 0.4.25 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.24 to 0.4.25. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.24...v0.4.25) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 22 +++++++++------------- Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed8c086c2..074ce319f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -101,13 +107,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "fdbc37d37da9e5bce8173f3a41b71d9bf3c674deebbaceacd0ebdabde76efb03" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", "time", @@ -517,16 +523,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.14" diff --git a/Cargo.toml b/Cargo.toml index b949f22a9..ac4f25c09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.24", features = ["serde"] } +chrono = { version = "0.4.25", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From 7897484b4bb903e3271d6b2020f67854fd04eacd Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Tue, 30 May 2023 20:58:11 +0000 Subject: [PATCH 432/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@2e7a1b1e64d836647ccd200e73dbfe64d4ab0de8. --- .github/workflows/rust.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d4053f5d0..171f1b09a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -31,6 +31,8 @@ jobs: uses: dtolnay/rust-toolchain@v1 with: toolchain: stable + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2 - name: cargo build run: cargo build - name: cargo test @@ -45,6 +47,8 @@ jobs: uses: dtolnay/rust-toolchain@v1 with: toolchain: stable + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2 - name: cargo build (release) run: cargo build --release - name: cargo test (release) @@ -65,6 +69,8 @@ jobs: uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.MSRV }} + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2 - name: cargo build (release) run: cargo build --release - name: cargo test (release) @@ -80,6 +86,8 @@ jobs: with: toolchain: ${{ env.ACTIONS_LINTS_TOOLCHAIN }} components: rustfmt, clippy + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2 - name: cargo fmt (check) run: cargo fmt -- --check -l - name: cargo clippy (warnings) @@ -98,6 +106,8 @@ jobs: uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ matrix.channel }} + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2 - name: cargo build run: cargo build - name: cargo test From ca6dd32ada3d89da1e0843dff8804eb4aab40de1 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Fri, 2 Jun 2023 00:40:21 +0000 Subject: [PATCH 433/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@77d4eb103dc1b45a2d4c9ffed86c6f533bf75060. --- .github/workflows/rust.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 171f1b09a..32a4e08c7 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -34,9 +34,9 @@ jobs: - name: Cache build artifacts uses: Swatinem/rust-cache@v2 - name: cargo build - run: cargo build + run: cargo build --all-targets - name: cargo test - run: cargo test + run: cargo test --all-targets tests-release-stable: name: Tests (release), stable toolchain runs-on: ubuntu-latest @@ -50,9 +50,9 @@ jobs: - name: Cache build artifacts uses: Swatinem/rust-cache@v2 - name: cargo build (release) - run: cargo build --release + run: cargo build --all-targets --release - name: cargo test (release) - run: cargo test --release + run: cargo test --all-targets --release tests-release-msrv: name: Tests (release), minimum supported toolchain runs-on: ubuntu-latest @@ -72,9 +72,9 @@ jobs: - name: Cache build artifacts uses: Swatinem/rust-cache@v2 - name: cargo build (release) - run: cargo build --release + run: cargo build --all-targets --release - name: cargo test (release) - run: cargo test --release + run: cargo test --all-targets --release linting: name: Lints, pinned toolchain runs-on: ubuntu-latest @@ -91,7 +91,7 @@ jobs: - name: cargo fmt (check) run: cargo fmt -- --check -l - name: cargo clippy (warnings) - run: cargo clippy -- -D warnings + run: cargo clippy --all-targets -- -D warnings tests-other-channels: name: Tests, unstable toolchain runs-on: ubuntu-latest @@ -109,6 +109,6 @@ jobs: - name: Cache build artifacts uses: Swatinem/rust-cache@v2 - name: cargo build - run: cargo build + run: cargo build --all-targets - name: cargo test - run: cargo test + run: cargo test --all-targets From 4a2b4d3105632714459abfeb424c4914b0c1b129 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 01:56:53 +0000 Subject: [PATCH 434/641] build(deps): bump chrono from 0.4.25 to 0.4.26 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.25 to 0.4.26. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.25...v0.4.26) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 017da9869..34665877f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,9 +107,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbc37d37da9e5bce8173f3a41b71d9bf3c674deebbaceacd0ebdabde76efb03" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index ac4f25c09..217a45046 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.25", features = ["serde"] } +chrono = { version = "0.4.26", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From e0596f746bd36948b766eabfb4db4ba97dd80a7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 01:57:04 +0000 Subject: [PATCH 435/641] build(deps): bump openssl from 0.10.53 to 0.10.54 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.53 to 0.10.54. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.53...openssl-v0.10.54) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 017da9869..f979e61f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -561,9 +561,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.53" +version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df40a956736488b7b44fe79fe12d4f245bb5b3f5a1f6095e499760015be392" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags", "cfg-if", From f4639e119672834f6ac3ace748716dd467806852 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 01:57:12 +0000 Subject: [PATCH 436/641] build(deps): bump libc from 0.2.144 to 0.2.145 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.144 to 0.2.145. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.144...0.2.145) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 017da9869..185f2afbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,9 +416,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81" [[package]] name = "libsystemd" From b882cd180ffe88a42f861e5f06ef6f45cfbdc7c5 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Mon, 5 Jun 2023 10:02:56 +0000 Subject: [PATCH 437/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@780abcb15410ca16de2c54436a4a185fc288a17b. --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 32a4e08c7..b35250cfb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,7 +18,7 @@ concurrency: env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTIONS_LINTS_TOOLCHAIN: 1.66.0 + ACTIONS_LINTS_TOOLCHAIN: 1.70.0 jobs: tests-stable: From 920bd613da130d9aa79c43a9e87d5e6d81ef5a11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 01:56:37 +0000 Subject: [PATCH 438/641] build(deps): bump libc from 0.2.145 to 0.2.146 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.145 to 0.2.146. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.145...0.2.146) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79ed42d4f..5c65e30e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,9 +416,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.145" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libsystemd" From e6220d7ddd372ae1b56caefebe944d8f61e2f3e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 01:56:42 +0000 Subject: [PATCH 439/641] build(deps): bump log from 0.4.18 to 0.4.19 Bumps [log](https://github.com/rust-lang/log) from 0.4.18 to 0.4.19. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.18...0.4.19) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79ed42d4f..dcadd7925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,9 +452,9 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memchr" From 20ad9c420447f059fe93bb5c36ea84c7cf62a65d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 01:56:50 +0000 Subject: [PATCH 440/641] build(deps): bump serde from 1.0.163 to 1.0.164 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.163 to 1.0.164. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.163...v1.0.164) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79ed42d4f..15cc158cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -759,18 +759,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", From 041afa0eb58eafaac4256b4bdeff2d5e33da6c75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 01:56:54 +0000 Subject: [PATCH 441/641] build(deps): bump tempfile from 3.5.0 to 3.6.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.5.0 to 3.6.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.5.0...v3.6.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 22 ++++++++++++---------- Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79ed42d4f..792e09ada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,12 +379,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -739,16 +740,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.7" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags", "errno 0.3.1", "io-lifetimes", "libc", "linux-raw-sys 0.3.7", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -841,15 +842,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.7", - "windows-sys 0.45.0", + "rustix 0.37.20", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 217a45046..4f98d138f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.5" +tempfile = "^3.6" widestring = "1.0.2" [profile.release] From feb2ba6ae63a8b0ac6eca2da5ccbddca1c8fe48a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 01:56:34 +0000 Subject: [PATCH 442/641] build(deps): bump serde_json from 1.0.96 to 1.0.97 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.96 to 1.0.97. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.96...v1.0.97) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1da10bc0f..e70f91214 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa", "ryu", From 4e871e4892af6fde48aadecb02840ed47b6ce334 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 01:23:26 +0000 Subject: [PATCH 443/641] build(deps): bump serde_json from 1.0.97 to 1.0.99 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.97 to 1.0.99. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.97...v1.0.99) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e70f91214..1400a076a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" dependencies = [ "itoa", "ryu", From b1dffd10dc9322e8f426bb53f3422985a2fe8a60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 01:23:48 +0000 Subject: [PATCH 444/641] build(deps): bump openssl from 0.10.54 to 0.10.55 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.54 to 0.10.55. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.54...openssl-v0.10.55) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e70f91214..639b21ffb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -562,9 +562,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.54" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ "bitflags", "cfg-if", @@ -588,9 +588,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.88" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", From 00237bf56c9dea4ce674faaded2c47fe2c2a2150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 18:45:13 +0000 Subject: [PATCH 445/641] build(deps): bump libc from 0.2.146 to 0.2.147 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.146 to 0.2.147. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.146...0.2.147) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 182729012..93c351f9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libsystemd" From e0641841f508c2b8ca823df53063f5723e53da91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 01:19:12 +0000 Subject: [PATCH 446/641] build(deps): bump serde from 1.0.164 to 1.0.171 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.164 to 1.0.171. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.164...v1.0.171) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93c351f9f..37981f848 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,7 +256,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.4", + "syn 2.0.25", ] [[package]] @@ -642,18 +642,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.52" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -760,22 +760,22 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.4", + "syn 2.0.25", ] [[package]] @@ -831,9 +831,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.4" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c622ae390c9302e214c31013517c2061ecb2699935882c60a9b37f82f8625ae" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", From 138c491400a4da1c29fe87e72c743b97c9786595 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Thu, 13 Jul 2023 21:23:57 +0000 Subject: [PATCH 447/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@407d83aecbd91b6d8db6704281284c76459c0cc8. --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b35250cfb..495635a4f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,7 +18,7 @@ concurrency: env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTIONS_LINTS_TOOLCHAIN: 1.70.0 + ACTIONS_LINTS_TOOLCHAIN: 1.71.0 jobs: tests-stable: From b28a2ae04d9cc31fc66409a0f16aff0df1531bb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 01:23:32 +0000 Subject: [PATCH 448/641] build(deps): bump anyhow from 1.0.71 to 1.0.72 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.71 to 1.0.72. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.71...1.0.72) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37981f848..ebcb51d34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "autocfg" From e43f91c5c37f9adf5c35e06a7dba56c9eb1decfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 01:23:40 +0000 Subject: [PATCH 449/641] build(deps): bump serde_json from 1.0.99 to 1.0.103 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.99 to 1.0.103. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.99...v1.0.103) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37981f848..91a451f56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", From be3009108e7f52c77115fed889e0f8961d288d32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 01:45:58 +0000 Subject: [PATCH 450/641] build(deps): bump serde from 1.0.171 to 1.0.174 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.171 to 1.0.174. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.171...v1.0.174) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d75bf7541..5a136ef44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -760,18 +760,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" dependencies = [ "proc-macro2", "quote", From 59315acba062808cd9e46b2044115778d3e33b37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 01:46:10 +0000 Subject: [PATCH 451/641] build(deps): bump tempfile from 3.6.0 to 3.7.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.6.0 to 3.7.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.6.0...v3.7.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 54 +++++++++++++++++++++++------------------------------- Cargo.toml | 2 +- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d75bf7541..10b382e99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,6 +53,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "block-buffer" version = "0.10.0" @@ -127,7 +133,7 @@ version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", "indexmap", @@ -241,12 +247,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.6.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fn-error-context" @@ -368,15 +371,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -447,9 +441,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.7" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "log" @@ -493,7 +487,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if", "libc", @@ -506,7 +500,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", @@ -566,7 +560,7 @@ version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -704,7 +698,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -730,7 +724,7 @@ version = "0.36.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.2.8", "io-lifetimes", "libc", @@ -740,15 +734,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags", + "bitflags 2.3.3", "errno 0.3.1", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.7", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -842,15 +835,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.20", + "rustix 0.38.4", "windows-sys 0.48.0", ] diff --git a/Cargo.toml b/Cargo.toml index 4f98d138f..273969e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.6" +tempfile = "^3.7" widestring = "1.0.2" [profile.release] From bb3228bab18a5becaac02800dece13ca54ecb62c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 01:21:27 +0000 Subject: [PATCH 452/641] build(deps): bump serde_json from 1.0.103 to 1.0.104 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.103 to 1.0.104. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.103...v1.0.104) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2067faef7..6b3cad88d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -773,9 +773,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", From cc83cbd2038bffc78d37ffc76c3536979e841ed0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 01:21:43 +0000 Subject: [PATCH 453/641] build(deps): bump serde from 1.0.174 to 1.0.179 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.174 to 1.0.179. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.174...v1.0.179) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2067faef7..2c24b234a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -753,18 +753,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.174" +version = "1.0.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" +checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.174" +version = "1.0.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" +checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" dependencies = [ "proc-macro2", "quote", From ddb52bce65aa9fea44acd53bfc7b42694d8d46bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 01:22:58 +0000 Subject: [PATCH 454/641] build(deps): bump openssl from 0.10.55 to 0.10.56 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.55 to 0.10.56. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.55...openssl-v0.10.56) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97daf82d5..31ef73bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -582,9 +582,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", From 9d23a4dcc0c845a0d48afe27ed34436f74d12b35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 01:23:12 +0000 Subject: [PATCH 455/641] build(deps): bump serde from 1.0.179 to 1.0.182 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.179 to 1.0.182. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.179...v1.0.182) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97daf82d5..b4c76e3df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,7 +259,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.28", ] [[package]] @@ -753,22 +753,22 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.179" +version = "1.0.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" +checksum = "bdb30a74471f5b7a1fa299f40b4bf1be93af61116df95465b2b5fc419331e430" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.179" +version = "1.0.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" +checksum = "6f4c2c6ea4bc09b5c419012eafcdb0fcef1d9119d626c8f3a0708a5b92d38a70" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.28", ] [[package]] @@ -824,9 +824,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", From bc86f5c72b760b0ae9f4b332ebdd688f7738e053 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 01:23:23 +0000 Subject: [PATCH 456/641] build(deps): bump tempfile from 3.7.0 to 3.7.1 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.7.0 to 3.7.1. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.7.0...v3.7.1) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97daf82d5..c6f2f2cb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -835,9 +835,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ "cfg-if", "fastrand", From ed938b59ed6614d3e225c1ad0b5191eddb91ab08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:42:48 +0000 Subject: [PATCH 457/641] build(deps): bump log from 0.4.19 to 0.4.20 Bumps [log](https://github.com/rust-lang/log) from 0.4.19 to 0.4.20. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.19...0.4.20) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0060353f5..8e358a25a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,9 +447,9 @@ checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" From 9fcbf6c0bcdb27efdaf6b84416c0c8f65e7aaedf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:43:07 +0000 Subject: [PATCH 458/641] build(deps): bump serde from 1.0.182 to 1.0.183 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.182 to 1.0.183. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.182...v1.0.183) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0060353f5..c47f26991 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -753,18 +753,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.182" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb30a74471f5b7a1fa299f40b4bf1be93af61116df95465b2b5fc419331e430" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.182" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4c2c6ea4bc09b5c419012eafcdb0fcef1d9119d626c8f3a0708a5b92d38a70" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", From 98dc20387873f61f461a44817ab76466cc4423b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 01:35:23 +0000 Subject: [PATCH 459/641] build(deps): bump tempfile from 3.7.1 to 3.8.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.7.1 to 3.8.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.7.1...v3.8.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32bddaad1..f5fb9963f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -835,9 +835,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", diff --git a/Cargo.toml b/Cargo.toml index 273969e2d..7c3559dae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.7" +tempfile = "^3.8" widestring = "1.0.2" [profile.release] From fa81b1d9131cd3045bdbd8daf8af7349ab041707 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 01:35:30 +0000 Subject: [PATCH 460/641] build(deps): bump anyhow from 1.0.72 to 1.0.75 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.72 to 1.0.75. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.72...1.0.75) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32bddaad1..127eb2b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" From 38cfe627da2c2faff0461d1f716f3564bb1b7b03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 01:35:40 +0000 Subject: [PATCH 461/641] build(deps): bump serde_json from 1.0.104 to 1.0.105 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.104 to 1.0.105. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.104...v1.0.105) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32bddaad1..a832bce27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -773,9 +773,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", From 9b33ed68f0cd89da6790b078ee610c4c3c8eb375 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 01:44:17 +0000 Subject: [PATCH 462/641] build(deps): bump serde from 1.0.183 to 1.0.188 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.183 to 1.0.188. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.183...v1.0.188) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53f68257a..24c3e03b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -753,18 +753,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", From eec50fce3f9dcc267d989637554f19e7f093615f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 01:44:27 +0000 Subject: [PATCH 463/641] build(deps): bump openssl from 0.10.56 to 0.10.57 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.56 to 0.10.57. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.56...openssl-v0.10.57) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53f68257a..035afdf7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,11 +556,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.3.3", "cfg-if", "foreign-types", "libc", @@ -582,9 +582,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", From 3b16e867b0621f72fe2a7ec449509d3ea3d9646b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Sep 2023 16:58:55 -0400 Subject: [PATCH 464/641] Bump rust-version = 1.70.0 It's what's in C9S and we can rely on that. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7c3559dae..6f782b743 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ license = "Apache-2.0" version = "0.2.9" authors = ["Colin Walters "] edition = "2021" -rust-version = "1.66.0" +rust-version = "1.70.0" # See https://github.com/coreos/cargo-vendor-filterer [package.metadata.vendor-filter] From 4de496078b773ef7d118cdb419c012d4ab57bcb3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Sep 2023 16:59:35 -0400 Subject: [PATCH 465/641] Release 0.2.10 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc8a3d221..5fb9f52a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.9" +version = "0.2.10" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 6f782b743..cb807436f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.9" +version = "0.2.10" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 1d9e04feef20f6ba915f599c30ce098e0803a7e0 Mon Sep 17 00:00:00 2001 From: Alejo Diaz Date: Wed, 13 Sep 2023 22:18:52 -0300 Subject: [PATCH 466/641] Fix removal in non-existent files --- src/filetree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filetree.rs b/src/filetree.rs index fe1c67877..c1e58a882 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -337,7 +337,7 @@ pub(crate) fn apply_diff( if !opts.skip_removals { for path in diff.removals.iter() { destdir - .remove_file(path) + .remove_file_optional(path) .with_context(|| format!("removing {path}"))?; } } From 26ebe3b368e348434631cd1a5d7b74199ade0ad4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 11 Sep 2023 18:18:06 -0400 Subject: [PATCH 467/641] Cargo.lock: Mass update Since we got way behind and dependabot isn't going to catch up. --- Cargo.lock | 521 +++++++++++++++++++++-------------------------------- 1 file changed, 205 insertions(+), 316 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fb9f52a1..cea30690e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -34,9 +34,9 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bincode" @@ -55,15 +55,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -83,7 +83,7 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.23.1", + "nix 0.23.2", "openat", "openat-ext", "openssl", @@ -95,15 +95,18 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -113,25 +116,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "bitflags 1.3.2", "clap_derive", @@ -144,59 +146,59 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.90", + "syn 1.0.109", ] [[package]] name = "clap_lex" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crypto-common" -version = "0.1.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "typenum", ] [[package]] name = "digest" -version = "0.10.1" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", - "generic-array", "subtle", ] @@ -215,24 +217,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -259,7 +250,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.32", ] [[package]] @@ -289,9 +280,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -299,9 +290,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -310,21 +301,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -334,9 +325,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddca131f3e7f2ce2df364b57949a9d47915cfbd35e46cfee355ccebbf794d6a2" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ "digest", ] @@ -349,62 +340,59 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.48" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a0714f28b1ee39ccec0770ccb544eb02c9ef2c82bb096230eefcffa6468b0" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", "wasm-bindgen", - "winapi", + "windows", ] [[package]] -name = "indexmap" -version = "1.8.1" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "autocfg", - "hashbrown", + "cc", ] [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", + "autocfg", + "hashbrown", ] [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "io-lifetimes", - "rustix 0.36.8", - "windows-sys 0.45.0", + "rustix", + "windows-sys", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -424,7 +412,7 @@ dependencies = [ "hmac", "libc", "log", - "nix 0.26.2", + "nix 0.26.4", "nom", "once_cell", "serde", @@ -435,15 +423,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - -[[package]] -name = "linux-raw-sys" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "log" @@ -453,15 +435,15 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.4.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -483,55 +465,53 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nix" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ "bitflags 1.3.2", "cc", "cfg-if", "libc", - "memoffset 0.6.4", + "memoffset 0.6.5", ] [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", - "static_assertions", ] [[package]] name = "nom" -version = "7.1.0" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", - "version_check", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openat" @@ -549,7 +529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cf3e4baa7f516441f58373f58aaf6e91a5dfa2e2b50e68a0d313b082014c61d" dependencies = [ "libc", - "nix 0.23.1", + "nix 0.23.2", "openat", "rand", ] @@ -560,7 +540,7 @@ version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -571,20 +551,20 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.90", + "syn 2.0.32", ] [[package]] name = "openssl-sys" -version = "0.9.92" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -594,21 +574,21 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -619,7 +599,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.90", + "syn 1.0.109", "version_check", ] @@ -636,32 +616,31 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -676,22 +655,13 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -703,53 +673,51 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", + "regex-automata", "regex-syntax", ] [[package]] -name = "regex-syntax" -version = "0.6.26" +name = "regex-automata" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] [[package]] -name = "rustix" -version = "0.36.8" +name = "regex-syntax" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" -dependencies = [ - "bitflags 1.3.2", - "errno 0.2.8", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", -] +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags 2.3.3", - "errno 0.3.1", + "bitflags 2.4.0", + "errno", "libc", - "linux-raw-sys 0.4.3", - "windows-sys 0.48.0", + "linux-raw-sys", + "windows-sys", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" @@ -768,14 +736,14 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.32", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" dependencies = [ "itoa", "ryu", @@ -784,21 +752,15 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.1" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.10.0" @@ -807,26 +769,26 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "1.0.90" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] name = "syn" -version = "2.0.28" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", @@ -842,15 +804,15 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix 0.38.4", - "windows-sys 0.48.0", + "rustix", + "windows-sys", ] [[package]] name = "termcolor" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -863,57 +825,41 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.28" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.28" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 1.0.90", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", + "syn 2.0.32", ] [[package]] name = "typenum" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" - -[[package]] -name = "unicode-xid" -version = "0.2.2" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "uuid" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "serde", ] @@ -926,21 +872,21 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -948,24 +894,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.90", + "syn 2.0.32", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -973,22 +919,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.90", + "syn 2.0.32", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "widestring" @@ -1028,12 +974,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.42.1", + "windows-targets", ] [[package]] @@ -1042,119 +988,62 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" From 23ead3ce02b83fab43a9ebcf4e33b4cd3348998a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 11 Sep 2023 20:16:19 -0400 Subject: [PATCH 468/641] build-sys: Switch to `include` The immediate goal is to drop out `.cargo` which has a `config.toml` which conflicts with the `cargo vendor`-injected `.cargo/config` and causes our vendor builds to fail. --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index cb807436f..3e4e1d67a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,8 @@ authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" +include = ["src", "LICENSE"] + # See https://github.com/coreos/cargo-vendor-filterer [package.metadata.vendor-filter] platforms = ["*-unknown-linux-gnu"] From 1292b7d7d9f9750de5c6ddc2f7e552fbf752e8c4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 16 Sep 2023 13:57:57 -0400 Subject: [PATCH 469/641] Port to non-deprecated chrono APIs To silence clippy. --- src/model_legacy.rs | 2 +- src/util.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/model_legacy.rs b/src/model_legacy.rs index a584025ea..0487d2dcc 100644 --- a/src/model_legacy.rs +++ b/src/model_legacy.rs @@ -45,7 +45,7 @@ pub(crate) struct SavedState01 { impl ContentMetadata01 { pub(crate) fn upconvert(self) -> NewContentMetadata { - let timestamp = DateTime::::from_utc(self.timestamp, Utc); + let timestamp = self.timestamp.and_utc(); NewContentMetadata { timestamp, version: self.version, diff --git a/src/util.rs b/src/util.rs index 319796fe8..90eed3243 100644 --- a/src/util.rs +++ b/src/util.rs @@ -97,9 +97,10 @@ pub(crate) fn parse_rpm_metadata(stdout: Vec) -> Result { let parts: Vec<_> = s.splitn(2, ',').collect(); let name = parts[0]; if let Some(ts) = parts.get(1) { - let nt = NaiveDateTime::parse_from_str(ts, "%s") - .context("Failed to parse rpm buildtime")?; - Ok((name, DateTime::::from_utc(nt, Utc))) + let nt = DateTime::parse_from_str(ts, "%s") + .context("Failed to parse rpm buildtime")? + .with_timezone(&chrono::Utc); + Ok((name, nt)) } else { bail!("Failed to parse: {}", s); } From ffbe10c1dbbc1bcd515395917f24a9d0d360efc1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Sep 2023 12:10:30 -0400 Subject: [PATCH 470/641] ci: use explicit path This may be a regression from the virtiofs work. --- tests/e2e-update/e2e-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 47f879300..b06893a8a 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -131,7 +131,7 @@ EOF runv butane -o ${testtmp}/test.ign ${testtmp}/test.bu cd ${testtmp} qemuexec_args=(kola qemuexec --propagate-initramfs-failure --qemu-image "${prev_image}" --qemu-firmware uefi \ - -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw .,/run/testtmp) + -i test.ign --bind-ro ${COSA_DIR},/run/cosadir --bind-ro ${bootupd_git},/run/bootupd-source --bind-rw ${testtmp},/run/testtmp) if test -n "${e2e_debug:-}"; then runv ${qemuexec_args[@]} --devshell else From 1a526737653822dc1418960b9e2027e9ed470dc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:58:01 +0000 Subject: [PATCH 471/641] build(deps): bump libc from 0.2.147 to 0.2.148 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.147 to 0.2.148. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.147...0.2.148) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cea30690e..95973613c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libsystemd" From 120841d22d995b021a2ee4734bb9af1b552d304c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:58:02 +0000 Subject: [PATCH 472/641] build(deps): bump chrono from 0.4.26 to 0.4.31 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.26 to 0.4.31. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.26...v0.4.31) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cea30690e..0ff930d5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 3e4e1d67a..002428bfc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.26", features = ["serde"] } +chrono = { version = "0.4.31", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From 41caa42a1396455b10b3f76b76a35c624257bfa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:58:05 +0000 Subject: [PATCH 473/641] build(deps): bump serde_json from 1.0.105 to 1.0.107 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.105 to 1.0.107. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.105...v1.0.107) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cea30690e..5e085fb46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,9 +741,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", From 01bb8fc25da40984cb092a785a28c94c34be876d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Sep 2023 13:04:25 -0400 Subject: [PATCH 474/641] Release 0.2.11 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- ci/prepare-release.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cea30690e..3f336dba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.10" +version = "0.2.11" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 3e4e1d67a..4465b2838 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,12 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.10" +version = "0.2.11" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" -include = ["src", "LICENSE"] +include = ["src", "LICENSE", "Makefile", "systemd"] # See https://github.com/coreos/cargo-vendor-filterer [package.metadata.vendor-filter] diff --git a/ci/prepare-release.sh b/ci/prepare-release.sh index c47c545f7..7a678976e 100755 --- a/ci/prepare-release.sh +++ b/ci/prepare-release.sh @@ -9,6 +9,6 @@ commit=$(git rev-parse HEAD) # Generate a vendor tarball of sources to attach to a release # in order to support offline builds. vendor_dest=target/${name}-${version}-vendor.tar.gz -cargo vendor-filterer --format=tar.gz "${vendor_dest}" +cargo vendor-filterer --prefix=vendor --format=tar.gz "${vendor_dest}" echo "Prepared ${version} at commit ${commit}" From 965faf9f1cce072a56568e6f23757df1ae238bba Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Sep 2023 17:16:49 -0400 Subject: [PATCH 475/641] install: Add support for selecting components So one can use e.g. `--component=EFI` to only install UEFI. --- src/bootupd.rs | 34 +++++++++++++++++++++++++++++----- src/cli/bootupd.rs | 18 ++++++++++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0266a7363..e4e2fd194 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -26,21 +26,45 @@ pub(crate) enum ClientRequest { Status, } -pub(crate) fn install(source_root: &str, dest_root: &str, device: &str) -> Result<()> { +pub(crate) fn install( + source_root: &str, + dest_root: &str, + device: Option<&str>, + target_components: Option<&[String]>, +) -> Result<()> { + // TODO: Change this to an Option<&str>; though this probably balloons into having + // DeviceComponent and FileBasedComponent + let device = device.unwrap_or(""); let source_root = openat::Dir::open(source_root)?; SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; - let components = get_components(); - if components.is_empty() { + let all_components = get_components(); + if all_components.is_empty() { println!("No components available for this platform."); return Ok(()); } + let target_components = if let Some(target_components) = target_components { + target_components + .iter() + .map(|name| { + all_components + .get(name.as_str()) + .ok_or_else(|| anyhow!("Unknown component: {name}")) + }) + .collect::>>()? + } else { + all_components.values().collect() + }; + + if target_components.is_empty() { + anyhow::bail!("No components specified"); + } let mut state = SavedState::default(); - for component in components.values() { + for component in target_components { // skip for BIOS if device is empty - if component.name() == "BIOS" && device.trim().is_empty() { + if component.name() == "BIOS" && device.is_empty() { println!( "Skip installing component {} without target device", component.name() diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 2a6437792..a15563ae8 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -47,9 +47,14 @@ pub struct InstallOpts { /// Target root #[clap(value_parser)] dest_root: String, + /// Target device, used by bios bootloader installation - #[clap(long, value_parser, default_value_t = String::from(""))] - device: String, + #[clap(long)] + device: Option, + + #[clap(long = "component")] + /// Only install these components + components: Option>, } #[derive(Debug, Parser)] @@ -77,8 +82,13 @@ impl DCommand { /// Runner for `install` verb. pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { - bootupd::install(&opts.src_root, &opts.dest_root, &opts.device) - .context("boot data installation failed")?; + bootupd::install( + &opts.src_root, + &opts.dest_root, + opts.device.as_deref(), + opts.components.as_deref(), + ) + .context("boot data installation failed")?; Ok(()) } } From b849ca38b0c2a40e3682b92e4489ece6038b6ecd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Sep 2023 13:30:44 -0400 Subject: [PATCH 476/641] Import static grub configuration Pull this from coreos-assembler; prep for moving ownership of it into bootupd. The big change though is the addition of sourcing a `platform.cfg` which is where we'll put the stuff that currently lives in `platforms.yaml` in FCOS as well as the Ignition glue. This glue can be used as is by Sagano, where the base images don't need the Ignition glue or platforms.yaml. --- Makefile | 3 ++ contrib/packaging/bootupd.spec | 10 ++++ src/grub2/README.md | 3 ++ src/grub2/grub-static-efi.cfg | 19 ++++++++ src/grub2/grub-static.cfg | 83 ++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 src/grub2/README.md create mode 100644 src/grub2/grub-static-efi.cfg create mode 100644 src/grub2/grub-static.cfg diff --git a/Makefile b/Makefile index 42b2b4e7d..28d1a5278 100644 --- a/Makefile +++ b/Makefile @@ -44,3 +44,6 @@ install: install-units ln -f ${DESTDIR}$(LIBEXECDIR)/bootupd ${DESTDIR}$(PREFIX)/bin/bootupctl install -d "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" ln -s ../bootupd.socket "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" + +install-grub-static: + install -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg \ No newline at end of file diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec index 83aafdab2..e6b00aa49 100644 --- a/contrib/packaging/bootupd.spec +++ b/contrib/packaging/bootupd.spec @@ -44,11 +44,21 @@ replace-with = "vendored-sources" directory = "vendor" EOF +%package grub2-static +Summary: Static grub2 configuration files for CoreOS-alike systems + +%description grub2-static +This package includes static grub2 configuration files. + +%files grub2-static +%{_prefix}/lib/bootupd + %build cargo build --release %install %make_install INSTALL="install -p -c" +make install-grub-static DESTDIR=%{?buildroot} INSTALL="%{__install} -p" %post -n %{crate} %systemd_post bootupd.service bootupd.socket diff --git a/src/grub2/README.md b/src/grub2/README.md new file mode 100644 index 000000000..79d9b8891 --- /dev/null +++ b/src/grub2/README.md @@ -0,0 +1,3 @@ +# Static GRUB configuration files + +These static files were taken from https://github.com/coreos/coreos-assembler/blob/5824720ec3a9ec291532b23b349b6d8d8b2e9edd/src/grub.cfg diff --git a/src/grub2/grub-static-efi.cfg b/src/grub2/grub-static-efi.cfg new file mode 100644 index 000000000..bf38ca906 --- /dev/null +++ b/src/grub2/grub-static-efi.cfg @@ -0,0 +1,19 @@ +if [ -e (md/md-boot) ]; then + # The search command might pick a RAID component rather than the RAID, + # since the /boot RAID currently uses superblock 1.0. See the comment in + # the main grub.cfg. + set prefix=md/md-boot +else + if [ -f ${config_directory}/bootuuid.cfg ]; then + source ${config_directory}/bootuuid.cfg + fi + if [ -n "${BOOT_UUID}" ]; then + search --fs-uuid "${BOOT_UUID}" --set prefix --no-floppy + else + search --label boot --set prefix --no-floppy + fi +fi +set prefix=($prefix)/grub2 +configfile $prefix/grub.cfg +boot + diff --git a/src/grub2/grub-static.cfg b/src/grub2/grub-static.cfg new file mode 100644 index 000000000..878357d1f --- /dev/null +++ b/src/grub2/grub-static.cfg @@ -0,0 +1,83 @@ +# This file is copied from https://github.com/coreos/coreos-assembler/blob/main/src/grub.cfg +# Changes: +# - Dropped Ignition glue, that can be injected into platform.cfg +set pager=1 +# petitboot doesn't support -e and doesn't support an empty path part +if [ -d (md/md-boot)/grub2 ]; then + # fcct currently creates /boot RAID with superblock 1.0, which allows + # component partitions to be read directly as filesystems. This is + # necessary because transposefs doesn't yet rerun grub2-install on BIOS, + # so GRUB still expects /boot to be a partition on the first disk. + # + # There are two consequences: + # 1. On BIOS and UEFI, the search command might pick an individual RAID + # component, but we want it to use the full RAID in case there are bad + # sectors etc. The undocumented --hint option is supposed to support + # this sort of override, but it doesn't seem to work, so we set $boot + # directly. + # 2. On BIOS, the "normal" module has already been loaded from an + # individual RAID component, and $prefix still points there. We want + # future module loads to come from the RAID, so we reset $prefix. + # (On UEFI, the stub grub.cfg has already set $prefix properly.) + set boot=md/md-boot + set prefix=($boot)/grub2 +else + if [ -f ${config_directory}/bootuuid.cfg ]; then + source ${config_directory}/bootuuid.cfg + fi + if [ -n "${BOOT_UUID}" ]; then + search --fs-uuid "${BOOT_UUID}" --set boot --no-floppy + else + search --label boot --set boot --no-floppy + fi +fi +set root=$boot + +if [ -f ${config_directory}/grubenv ]; then + load_env -f ${config_directory}/grubenv +elif [ -s $prefix/grubenv ]; then + load_env +fi + +if [ x"${feature_menuentry_id}" = xy ]; then + menuentry_id_option="--id" +else + menuentry_id_option="" +fi + +function load_video { + if [ x$feature_all_video_module = xy ]; then + insmod all_video + else + insmod efi_gop + insmod efi_uga + insmod ieee1275_fb + insmod vbe + insmod vga + insmod video_bochs + insmod video_cirrus + fi +} + +# tracker: https://github.com/coreos/fedora-coreos-tracker/issues/805 +if [ -f $prefix/platform.cfg ]; then + source $prefix/platform.cfg +fi + +if [ x$feature_timeout_style = xy ] ; then + set timeout_style=menu + set timeout=1 +# Fallback normal timeout code in case the timeout_style feature is +# unavailable. +else + set timeout=1 +fi + +# Import user defined configuration +# tracker: https://github.com/coreos/fedora-coreos-tracker/issues/805 +if [ -f $prefix/user.cfg ]; then + source $prefix/user.cfg +fi + +blscfg + From 935dc6bedf22773c6883dce34624f82eee9f803f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 09:51:20 -0400 Subject: [PATCH 477/641] Add a few more debug log messages I was trying to debug something and these were helpful. --- src/bootupd.rs | 1 + src/efi.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0266a7363..9092470d6 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -51,6 +51,7 @@ pub(crate) fn install(source_root: &str, dest_root: &str, device: &str) -> Resul let meta = component .install(&source_root, dest_root, device) .with_context(|| format!("installing component {}", component.name()))?; + log::info!("Installed {} {}", component.name(), meta.meta.version); state.installed.insert(component.name().into(), meta); } diff --git a/src/efi.rs b/src/efi.rs index 12a051c46..ddabd986d 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -105,6 +105,7 @@ impl Efi { if !status.success() { anyhow::bail!("Failed to unmount {mount:?}: {status:?}"); } + log::trace!("Unmounted"); } Ok(()) } @@ -261,6 +262,7 @@ impl Component for Efi { } else { anyhow::bail!("No update metadata for component {} found", self.name()); }; + log::debug!("Found metadata {}", meta.version); let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; let destdir = &self.ensure_mounted_esp(Path::new(dest_root))?; From e58af896fe32fe07b48359bd7a5e419a942bb6d4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 16:29:07 -0400 Subject: [PATCH 478/641] ci: Test fast tracking virtiofsd Let's see if this unbreaks our CI. --- .cci.jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index 12eaed3d4..df7a1a9ba 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -36,6 +36,8 @@ cosaPod(runAsUser: 0, memory: "4608Mi", cpu: "4") { stage("Build FCOS") { checkout scm unstash 'build' + // Fast track https://bodhi.fedoraproject.org/updates/FEDORA-2023-5041615f94 + shwrap("sudo dnf -y update https://kojipkgs.fedoraproject.org//packages/virtiofsd/1.7.0/5.fc38/x86_64/virtiofsd-1.7.0-5.fc38.x86_64.rpm") // Note that like {rpm-,}ostree we want to install to both / and overrides/rootfs // because bootupd is used both during the `rpm-ostree compose tree` as well as // inside the target operating system. From 512c177b0ef12e41b1bbea8758e714c89af4a55d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 16:14:42 -0400 Subject: [PATCH 479/641] Refactor rpm bits into packagesystem module Prep for cleaning this up and making it more generic to support non-rpm systems in a pluggable way. --- src/bios.rs | 5 ++-- src/efi.rs | 7 ++--- src/main.rs | 1 + src/packagesystem.rs | 69 +++++++++++++++++++++++++++++++++++++++++++ src/util.rs | 70 ++------------------------------------------ 5 files changed, 78 insertions(+), 74 deletions(-) create mode 100644 src/packagesystem.rs diff --git a/src/bios.rs b/src/bios.rs index 7dc7099cd..de7533d5c 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -4,6 +4,7 @@ use std::process::Command; use crate::component::*; use crate::model::*; +use crate::packagesystem; use anyhow::{bail, Result}; use crate::util; @@ -114,14 +115,14 @@ impl Component for Bios { } // Query the rpm database and list the package and build times for /usr/sbin/grub2-install - let mut rpmout = util::rpm_query(sysroot_path, &grub_install)?; + let mut rpmout = packagesystem::query(sysroot_path, &grub_install)?; let rpmout = rpmout.output()?; if !rpmout.status.success() { std::io::stderr().write_all(&rpmout.stderr)?; bail!("Failed to invoke rpm -qf"); } - let meta = util::parse_rpm_metadata(rpmout.stdout)?; + let meta = packagesystem::parse_metadata(rpmout.stdout)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/efi.rs b/src/efi.rs index ddabd986d..7021f3eff 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -14,12 +14,11 @@ use anyhow::{bail, Context, Result}; use openat_ext::OpenatDirExt; use widestring::U16CString; -use crate::component::*; use crate::filetree; use crate::model::*; use crate::ostreeutil; -use crate::util; use crate::util::CommandRunExt; +use crate::{component::*, packagesystem}; /// Well-known paths to the ESP that may have been mounted external to us. pub(crate) const ESP_MOUNTS: &[&str] = &["boot", "boot/efi", "efi"]; @@ -344,14 +343,14 @@ impl Component for Efi { // Query the rpm database and list the package and build times for all the // files in the EFI system partition. If any files are not owned it is considered // and error condition. - let mut rpmout = util::rpm_query(sysroot_path, &dest_efidir)?; + let mut rpmout = packagesystem::query(sysroot_path, &dest_efidir)?; let rpmout = rpmout.output()?; if !rpmout.status.success() { std::io::stderr().write_all(&rpmout.stderr)?; bail!("Failed to invoke rpm -qf"); } - let meta = util::parse_rpm_metadata(rpmout.stdout)?; + let meta = packagesystem::parse_metadata(rpmout.stdout)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/main.rs b/src/main.rs index 257060800..46d676a88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ mod ipc; mod model; mod model_legacy; mod ostreeutil; +mod packagesystem; mod sha512string; mod util; diff --git a/src/packagesystem.rs b/src/packagesystem.rs new file mode 100644 index 000000000..46648ccae --- /dev/null +++ b/src/packagesystem.rs @@ -0,0 +1,69 @@ +use std::collections::{BTreeMap, BTreeSet}; +use std::path::Path; +use std::process::Command; + +use anyhow::{bail, Context, Result}; +use chrono::prelude::*; + +use crate::model::*; +use crate::ostreeutil; + +/// Parse the output of `rpm -q` +pub(crate) fn parse_metadata(stdout: Vec) -> Result { + let pkgs = std::str::from_utf8(&stdout)? + .split_whitespace() + .map(|s| -> Result<_> { + let parts: Vec<_> = s.splitn(2, ',').collect(); + let name = parts[0]; + if let Some(ts) = parts.get(1) { + let nt = DateTime::parse_from_str(ts, "%s") + .context("Failed to parse rpm buildtime")? + .with_timezone(&chrono::Utc); + Ok((name, nt)) + } else { + bail!("Failed to parse: {}", s); + } + }) + .collect::>>>()?; + if pkgs.is_empty() { + bail!("Failed to find any RPM packages matching files in source efidir"); + } + let timestamps: BTreeSet<&DateTime> = pkgs.values().collect(); + // Unwrap safety: We validated pkgs has at least one value above + let largest_timestamp = timestamps.iter().last().unwrap(); + let version = pkgs.keys().fold("".to_string(), |mut s, n| { + if !s.is_empty() { + s.push(','); + } + s.push_str(n); + s + }); + Ok(ContentMetadata { + timestamp: **largest_timestamp, + version, + }) +} + +/// Query the rpm database and list the package and build times, for all the +/// files in the EFI system partition, or for grub2-install file +pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result { + let mut c = ostreeutil::rpm_cmd(sysroot_path); + c.args(["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); + + match path.file_name().expect("filename").to_str() { + Some("EFI") => { + let efidir = openat::Dir::open(path)?; + c.args(crate::util::filenames(&efidir)?.drain().map(|mut f| { + f.insert_str(0, "/boot/efi/EFI/"); + f + })); + } + Some("grub2-install") => { + c.arg(path); + } + _ => { + bail!("Unsupported file/directory {:?}", path) + } + } + Ok(c) +} diff --git a/src/util.rs b/src/util.rs index 90eed3243..c88d173e8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,15 +1,9 @@ use std::collections::HashSet; - -use anyhow::{bail, Context, Result}; -use openat_ext::OpenatDirExt; - use std::path::Path; use std::process::Command; -use crate::model::*; -use crate::ostreeutil; -use chrono::prelude::*; -use std::collections::{BTreeMap, BTreeSet}; +use anyhow::{bail, Context, Result}; +use openat_ext::OpenatDirExt; pub(crate) trait CommandRunExt { fn run(&mut self) -> Result<()>; @@ -89,66 +83,6 @@ pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { Ok(()) } -/// Parse the output of `rpm -q` -pub(crate) fn parse_rpm_metadata(stdout: Vec) -> Result { - let pkgs = std::str::from_utf8(&stdout)? - .split_whitespace() - .map(|s| -> Result<_> { - let parts: Vec<_> = s.splitn(2, ',').collect(); - let name = parts[0]; - if let Some(ts) = parts.get(1) { - let nt = DateTime::parse_from_str(ts, "%s") - .context("Failed to parse rpm buildtime")? - .with_timezone(&chrono::Utc); - Ok((name, nt)) - } else { - bail!("Failed to parse: {}", s); - } - }) - .collect::>>>()?; - if pkgs.is_empty() { - bail!("Failed to find any RPM packages matching files in source efidir"); - } - let timestamps: BTreeSet<&DateTime> = pkgs.values().collect(); - // Unwrap safety: We validated pkgs has at least one value above - let largest_timestamp = timestamps.iter().last().unwrap(); - let version = pkgs.keys().fold("".to_string(), |mut s, n| { - if !s.is_empty() { - s.push(','); - } - s.push_str(n); - s - }); - Ok(ContentMetadata { - timestamp: **largest_timestamp, - version, - }) -} - -/// Query the rpm database and list the package and build times, for all the -/// files in the EFI system partition, or for grub2-install file -pub(crate) fn rpm_query(sysroot_path: &str, path: &Path) -> Result { - let mut c = ostreeutil::rpm_cmd(sysroot_path); - c.args(["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); - - match path.file_name().expect("filename").to_str() { - Some("EFI") => { - let efidir = openat::Dir::open(path)?; - c.args(filenames(&efidir)?.drain().map(|mut f| { - f.insert_str(0, "/boot/efi/EFI/"); - f - })); - } - Some("grub2-install") => { - c.arg(path); - } - _ => { - bail!("Unsupported file/directory {:?}", path) - } - } - Ok(c) -} - /// Runs the provided Command object, captures its stdout, and swallows its stderr except on /// failure. Returns a Result describing whether the command failed, and if not, its /// standard output. Output is assumed to be UTF-8. Errors are adequately prefixed with the full From a37b1e64b6e68db21eb9455868dfd6562c98ed5b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 16:17:49 -0400 Subject: [PATCH 480/641] De-duplicate package querying There's no reason to have two separate functions here. --- src/bios.rs | 9 +-------- src/efi.rs | 13 +------------ src/packagesystem.rs | 15 +++++++++++---- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index de7533d5c..ba6ac7b13 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -115,14 +115,7 @@ impl Component for Bios { } // Query the rpm database and list the package and build times for /usr/sbin/grub2-install - let mut rpmout = packagesystem::query(sysroot_path, &grub_install)?; - let rpmout = rpmout.output()?; - if !rpmout.status.success() { - std::io::stderr().write_all(&rpmout.stderr)?; - bail!("Failed to invoke rpm -qf"); - } - - let meta = packagesystem::parse_metadata(rpmout.stdout)?; + let meta = packagesystem::query(sysroot_path, &grub_install)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/efi.rs b/src/efi.rs index 7021f3eff..5fdba3969 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -5,7 +5,6 @@ */ use std::cell::RefCell; -use std::io::prelude::*; use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; use std::process::Command; @@ -340,17 +339,7 @@ impl Component for Efi { Command::new("mv").args([&efisrc, &dest_efidir]).run()?; } - // Query the rpm database and list the package and build times for all the - // files in the EFI system partition. If any files are not owned it is considered - // and error condition. - let mut rpmout = packagesystem::query(sysroot_path, &dest_efidir)?; - let rpmout = rpmout.output()?; - if !rpmout.status.success() { - std::io::stderr().write_all(&rpmout.stderr)?; - bail!("Failed to invoke rpm -qf"); - } - - let meta = packagesystem::parse_metadata(rpmout.stdout)?; + let meta = packagesystem::query(sysroot_path, &dest_efidir)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/packagesystem.rs b/src/packagesystem.rs index 46648ccae..d64add1da 100644 --- a/src/packagesystem.rs +++ b/src/packagesystem.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; +use std::io::Write; use std::path::Path; -use std::process::Command; use anyhow::{bail, Context, Result}; use chrono::prelude::*; @@ -9,7 +9,7 @@ use crate::model::*; use crate::ostreeutil; /// Parse the output of `rpm -q` -pub(crate) fn parse_metadata(stdout: Vec) -> Result { +fn rpm_parse_metadata(stdout: Vec) -> Result { let pkgs = std::str::from_utf8(&stdout)? .split_whitespace() .map(|s| -> Result<_> { @@ -46,7 +46,7 @@ pub(crate) fn parse_metadata(stdout: Vec) -> Result { /// Query the rpm database and list the package and build times, for all the /// files in the EFI system partition, or for grub2-install file -pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result { +pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result { let mut c = ostreeutil::rpm_cmd(sysroot_path); c.args(["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); @@ -65,5 +65,12 @@ pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result { bail!("Unsupported file/directory {:?}", path) } } - Ok(c) + + let rpmout = c.output()?; + if !rpmout.status.success() { + std::io::stderr().write_all(&rpmout.stderr)?; + bail!("Failed to invoke rpm -qf"); + } + + rpm_parse_metadata(rpmout.stdout) } From 981aa0ab814c8298bcdead6280015a368c077480 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 16:33:06 -0400 Subject: [PATCH 481/641] packagesystem: Add a unit test On general principle. --- src/packagesystem.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/packagesystem.rs b/src/packagesystem.rs index d64add1da..4ddde0edf 100644 --- a/src/packagesystem.rs +++ b/src/packagesystem.rs @@ -9,7 +9,7 @@ use crate::model::*; use crate::ostreeutil; /// Parse the output of `rpm -q` -fn rpm_parse_metadata(stdout: Vec) -> Result { +fn rpm_parse_metadata(stdout: &[u8]) -> Result { let pkgs = std::str::from_utf8(&stdout)? .split_whitespace() .map(|s| -> Result<_> { @@ -72,5 +72,15 @@ pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result bail!("Failed to invoke rpm -qf"); } - rpm_parse_metadata(rpmout.stdout) + rpm_parse_metadata(&rpmout.stdout) +} + +#[test] +fn test_parse_rpmout() { + let testdata = "grub2-efi-x64-1:2.06-95.fc38.x86_64,1681321788 grub2-efi-x64-1:2.06-95.fc38.x86_64,1681321788 shim-x64-15.6-2.x86_64,1657222566 shim-x64-15.6-2.x86_64,1657222566 shim-x64-15.6-2.x86_64,1657222566"; + let parsed = rpm_parse_metadata(testdata.as_bytes()).unwrap(); + assert_eq!( + parsed.version, + "grub2-efi-x64-1:2.06-95.fc38.x86_64,shim-x64-15.6-2.x86_64" + ); } From 50c98500fdf8824502d63dd3ba68706e2476dc29 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 17:21:59 -0400 Subject: [PATCH 482/641] backend: Make --generate-update-metadata require a sysroot of / As of right now all known callers of this pass `/`. More generally we now expect bootupd to run in a container inside its target root; never outside of it. xref https://github.com/coreos/coreos-assembler/pull/3631 --- src/cli/bootupd.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index a15563ae8..1e5384f7e 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -61,7 +61,7 @@ pub struct InstallOpts { pub struct GenerateOpts { /// Physical root mountpoint #[clap(value_parser)] - sysroot: String, + sysroot: Option, } impl DCommand { @@ -76,7 +76,11 @@ impl DCommand { /// Runner for `generate-install-metadata` verb. pub(crate) fn run_generate_meta(opts: GenerateOpts) -> Result<()> { - bootupd::generate_update_metadata(&opts.sysroot).context("generating metadata failed")?; + let sysroot = opts.sysroot.as_deref().unwrap_or("/"); + if sysroot != "/" { + anyhow::bail!("Using a non-default sysroot is not supported: {}", sysroot); + } + bootupd::generate_update_metadata(sysroot).context("generating metadata failed")?; Ok(()) } From 14cdf1bb4dddb90105c19bc8f9c65dfec9b67d57 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 17:24:11 -0400 Subject: [PATCH 483/641] Fix clippy lint --- src/packagesystem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packagesystem.rs b/src/packagesystem.rs index 4ddde0edf..15ffdff51 100644 --- a/src/packagesystem.rs +++ b/src/packagesystem.rs @@ -10,7 +10,7 @@ use crate::ostreeutil; /// Parse the output of `rpm -q` fn rpm_parse_metadata(stdout: &[u8]) -> Result { - let pkgs = std::str::from_utf8(&stdout)? + let pkgs = std::str::from_utf8(stdout)? .split_whitespace() .map(|s| -> Result<_> { let parts: Vec<_> = s.splitn(2, ',').collect(); From 5b5d0e6c95bcf2aad06efc32761ad50056ab860a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Sep 2023 10:26:43 -0400 Subject: [PATCH 484/641] packagesystem: More API cleanup It doesn't make sense to hardcode the file list inside the query function; just have the caller pass it the files it needs. Now the packagesystem module is independent of the content. --- src/bios.rs | 2 +- src/efi.rs | 8 +++++++- src/packagesystem.rs | 28 ++++++++++------------------ 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index ba6ac7b13..e2a253125 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -115,7 +115,7 @@ impl Component for Bios { } // Query the rpm database and list the package and build times for /usr/sbin/grub2-install - let meta = packagesystem::query(sysroot_path, &grub_install)?; + let meta = packagesystem::query_files(sysroot_path, [&grub_install])?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/efi.rs b/src/efi.rs index 5fdba3969..b6d04ba42 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -339,7 +339,13 @@ impl Component for Efi { Command::new("mv").args([&efisrc, &dest_efidir]).run()?; } - let meta = packagesystem::query(sysroot_path, &dest_efidir)?; + let efidir = openat::Dir::open(&dest_efidir)?; + let files = crate::util::filenames(&efidir)?.into_iter().map(|mut f| { + f.insert_str(0, "/boot/efi/EFI/"); + f + }); + + let meta = packagesystem::query_files(sysroot_path, files)?; write_update_metadata(sysroot_path, self, &meta)?; Ok(meta) } diff --git a/src/packagesystem.rs b/src/packagesystem.rs index 15ffdff51..2536a93cc 100644 --- a/src/packagesystem.rs +++ b/src/packagesystem.rs @@ -44,26 +44,18 @@ fn rpm_parse_metadata(stdout: &[u8]) -> Result { }) } -/// Query the rpm database and list the package and build times, for all the -/// files in the EFI system partition, or for grub2-install file -pub(crate) fn query(sysroot_path: &str, path: &Path) -> Result { +/// Query the rpm database and list the package and build times. +pub(crate) fn query_files( + sysroot_path: &str, + paths: impl IntoIterator, +) -> Result +where + T: AsRef, +{ let mut c = ostreeutil::rpm_cmd(sysroot_path); c.args(["-q", "--queryformat", "%{nevra},%{buildtime} ", "-f"]); - - match path.file_name().expect("filename").to_str() { - Some("EFI") => { - let efidir = openat::Dir::open(path)?; - c.args(crate::util::filenames(&efidir)?.drain().map(|mut f| { - f.insert_str(0, "/boot/efi/EFI/"); - f - })); - } - Some("grub2-install") => { - c.arg(path); - } - _ => { - bail!("Unsupported file/directory {:?}", path) - } + for arg in paths { + c.arg(arg.as_ref()); } let rpmout = c.output()?; From ec064c000c87ec1b145ca9c2d3254c84ed554f75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 01:28:01 +0000 Subject: [PATCH 485/641] build(deps): bump libc from 0.2.148 to 0.2.149 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.148 to 0.2.149. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.148...0.2.149) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index daa21e749..d7a9121bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libsystemd" From e48eb319837fda7dbd32187fe17ec7d18baa993b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 01:23:30 +0000 Subject: [PATCH 486/641] build(deps): bump serde from 1.0.188 to 1.0.189 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.188 to 1.0.189. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.188...v1.0.189) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7a9121bb..59ef42a99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,18 +721,18 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", From d299ba4986320cb5112b2d9a9c7e4ade4f130844 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 16 Oct 2023 12:25:44 -0400 Subject: [PATCH 487/641] efi: Rework mount order This ensures that we'll use `/boot/efi` first, which is what is more commonly expected in our current ecosystem. --- src/efi.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index b6d04ba42..331b607b6 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -20,7 +20,7 @@ use crate::util::CommandRunExt; use crate::{component::*, packagesystem}; /// Well-known paths to the ESP that may have been mounted external to us. -pub(crate) const ESP_MOUNTS: &[&str] = &["boot", "boot/efi", "efi"]; +pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi", "boot"]; /// The ESP partition label on Fedora CoreOS derivatives pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; @@ -54,7 +54,7 @@ impl Efi { Ok(esp) } - fn ensure_mounted_esp(&self, root: &Path) -> Result { + pub(crate) fn ensure_mounted_esp(&self, root: &Path) -> Result { let mut mountpoint = self.mountpoint.borrow_mut(); if let Some(mountpoint) = mountpoint.as_deref() { return Ok(mountpoint.to_owned()); @@ -84,16 +84,22 @@ impl Efi { } } let esp_device = esp_device.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?; - let tmppath = tempfile::tempdir_in("/tmp")?.into_path(); - let status = std::process::Command::new("mount") - .arg(&esp_device) - .arg(&tmppath) - .status()?; - if !status.success() { - anyhow::bail!("Failed to mount {:?}", esp_device); + for &mnt in ESP_MOUNTS.iter() { + let mnt = root.join(mnt); + if !mnt.exists() { + continue; + } + let status = std::process::Command::new("mount") + .arg(&esp_device) + .arg(&mnt) + .status()?; + if !status.success() { + anyhow::bail!("Failed to mount {:?}", esp_device); + } + log::debug!("Mounted at {mnt:?}"); + *mountpoint = Some(mnt); + break; } - log::debug!("Mounted at {tmppath:?}"); - *mountpoint = Some(tmppath); Ok(mountpoint.as_deref().unwrap().to_owned()) } @@ -380,6 +386,7 @@ impl Component for Efi { impl Drop for Efi { fn drop(&mut self) { + log::debug!("Unmounting"); let _ = self.unmount(); } } From 1475f2587d7fb652f21b07f8defb4581d6c50754 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Sep 2023 17:52:54 -0400 Subject: [PATCH 488/641] Add support for installing static grub configs Currently these are duplicated in osbuild and coreos-assembler. We will aim to deduplicate them here. Ideally we'd add support for "day 2" updates of these; I started on a patch for that but it's sadly messy. This is an incremental improvement. Signed-off-by: Colin Walters --- Makefile | 3 +- src/bootupd.rs | 22 +++- src/cli/bootupd.rs | 5 + src/grub2/configs.d/README.md | 4 + src/grub2/grub-static-post.cfg | 17 +++ .../{grub-static.cfg => grub-static-pre.cfg} | 23 +--- src/grubconfigs.rs | 111 ++++++++++++++++++ src/main.rs | 6 + 8 files changed, 164 insertions(+), 27 deletions(-) create mode 100644 src/grub2/configs.d/README.md create mode 100644 src/grub2/grub-static-post.cfg rename src/grub2/{grub-static.cfg => grub-static-pre.cfg} (79%) create mode 100644 src/grubconfigs.rs diff --git a/Makefile b/Makefile index 28d1a5278..2799f5e24 100644 --- a/Makefile +++ b/Makefile @@ -46,4 +46,5 @@ install: install-units ln -s ../bootupd.socket "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" install-grub-static: - install -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg \ No newline at end of file + install -m 644 -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg + install -m 755 -d ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static/configs.d diff --git a/src/bootupd.rs b/src/bootupd.rs index 285adfec9..b7a92ffa8 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -30,12 +30,13 @@ pub(crate) fn install( source_root: &str, dest_root: &str, device: Option<&str>, + with_static_configs: bool, target_components: Option<&[String]>, ) -> Result<()> { // TODO: Change this to an Option<&str>; though this probably balloons into having // DeviceComponent and FileBasedComponent let device = device.unwrap_or(""); - let source_root = openat::Dir::open(source_root)?; + let source_root = openat::Dir::open(source_root).context("Opening source root")?; SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; @@ -62,7 +63,8 @@ pub(crate) fn install( } let mut state = SavedState::default(); - for component in target_components { + let mut installed_efi = false; + for &component in target_components.iter() { // skip for BIOS if device is empty if component.name() == "BIOS" && device.is_empty() { println!( @@ -77,10 +79,22 @@ pub(crate) fn install( .with_context(|| format!("installing component {}", component.name()))?; log::info!("Installed {} {}", component.name(), meta.meta.version); state.installed.insert(component.name().into(), meta); + // Yes this is a hack...the Component thing just turns out to be too generic. + if component.name() == "EFI" { + installed_efi = true; + } + } + let sysroot = &openat::Dir::open(dest_root)?; + + if with_static_configs { + crate::grubconfigs::install(sysroot, installed_efi)?; } - let sysroot = openat::Dir::open(dest_root)?; - let mut state_guard = SavedState::unlocked(sysroot).context("failed to acquire write lock")?; + // Unmount the ESP, etc. + drop(target_components); + + let mut state_guard = + SavedState::unlocked(sysroot.try_clone()?).context("failed to acquire write lock")?; state_guard .update_state(&state) .context("failed to update state")?; diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 1e5384f7e..f7b08678d 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -52,6 +52,10 @@ pub struct InstallOpts { #[clap(long)] device: Option, + /// Enable installation of the built-in static config files + #[clap(long)] + with_static_configs: bool, + #[clap(long = "component")] /// Only install these components components: Option>, @@ -90,6 +94,7 @@ impl DCommand { &opts.src_root, &opts.dest_root, opts.device.as_deref(), + opts.with_static_configs, opts.components.as_deref(), ) .context("boot data installation failed")?; diff --git a/src/grub2/configs.d/README.md b/src/grub2/configs.d/README.md new file mode 100644 index 000000000..a278f521d --- /dev/null +++ b/src/grub2/configs.d/README.md @@ -0,0 +1,4 @@ +Add drop-in grub fragments into this directory to have +them be installed into the final config. + +The filenames must end in `.cfg`. diff --git a/src/grub2/grub-static-post.cfg b/src/grub2/grub-static-post.cfg new file mode 100644 index 000000000..e426e3907 --- /dev/null +++ b/src/grub2/grub-static-post.cfg @@ -0,0 +1,17 @@ +if [ x$feature_timeout_style = xy ] ; then + set timeout_style=menu + set timeout=1 +# Fallback normal timeout code in case the timeout_style feature is +# unavailable. +else + set timeout=1 +fi + +# Import user defined configuration +# tracker: https://github.com/coreos/fedora-coreos-tracker/issues/805 +if [ -f $prefix/user.cfg ]; then + source $prefix/user.cfg +fi + +blscfg + diff --git a/src/grub2/grub-static.cfg b/src/grub2/grub-static-pre.cfg similarity index 79% rename from src/grub2/grub-static.cfg rename to src/grub2/grub-static-pre.cfg index 878357d1f..8ebab325c 100644 --- a/src/grub2/grub-static.cfg +++ b/src/grub2/grub-static-pre.cfg @@ -59,25 +59,4 @@ function load_video { fi } -# tracker: https://github.com/coreos/fedora-coreos-tracker/issues/805 -if [ -f $prefix/platform.cfg ]; then - source $prefix/platform.cfg -fi - -if [ x$feature_timeout_style = xy ] ; then - set timeout_style=menu - set timeout=1 -# Fallback normal timeout code in case the timeout_style feature is -# unavailable. -else - set timeout=1 -fi - -# Import user defined configuration -# tracker: https://github.com/coreos/fedora-coreos-tracker/issues/805 -if [ -f $prefix/user.cfg ]; then - source $prefix/user.cfg -fi - -blscfg - +# Other package code will be injected from here diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs new file mode 100644 index 000000000..01f6b3ea7 --- /dev/null +++ b/src/grubconfigs.rs @@ -0,0 +1,111 @@ +use std::fmt::Write; +use std::os::unix::prelude::OsStrExt; +use std::path::{Path, PathBuf}; + +use anyhow::{anyhow, Context, Result}; +use fn_error_context::context; +use openat_ext::OpenatDirExt; + +/// The subdirectory of /boot we use +const GRUB2DIR: &str = "grub2"; +const CONFIGDIR: &str = "/usr/lib/bootupd/grub2-static"; +const DROPINDIR: &str = "configs.d"; + +#[context("Locating EFI vendordir")] +pub(crate) fn find_efi_vendordir(efidir: &openat::Dir) -> Result { + for d in efidir.list_dir(".")? { + let d = d?; + if d.file_name().as_bytes() == b"BOOT" { + continue; + } + let meta = efidir.metadata(d.file_name())?; + if !meta.is_dir() { + continue; + } + return Ok(d.file_name().into()); + } + anyhow::bail!("Failed to find EFI vendor dir") +} + +/// Install the static GRUB config files. +#[context("Installing static GRUB configs")] +pub(crate) fn install(target_root: &openat::Dir, efi: bool) -> Result<()> { + let bootdir = &target_root.sub_dir("boot").context("Opening /boot")?; + + let mut config = std::fs::read_to_string(Path::new(CONFIGDIR).join("grub-static-pre.cfg"))?; + + let dropindir = openat::Dir::open(&Path::new(CONFIGDIR).join(DROPINDIR))?; + // Sort the files for reproducibility + let mut entries = dropindir + .list_dir(".")? + .map(|e| e.map_err(anyhow::Error::msg)) + .collect::>>()?; + entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); + for ent in entries { + let name = ent.file_name(); + let name = name + .to_str() + .ok_or_else(|| anyhow!("Invalid UTF-8: {name:?}"))?; + if !name.ends_with(".cfg") { + log::debug!("Ignoring {name}"); + continue; + } + writeln!(config, "source $prefix/{name}")?; + dropindir + .copy_file_at(name, bootdir, format!("{GRUB2DIR}/{name}")) + .with_context(|| format!("Copying {name}"))?; + println!("Installed {name}"); + } + + { + let post = std::fs::read_to_string(Path::new(CONFIGDIR).join("grub-static-post.cfg"))?; + config.push_str(post.as_str()); + } + + bootdir + .write_file_contents(format!("{GRUB2DIR}/grub.cfg"), 0o644, config.as_bytes()) + .context("Copying grub-static.cfg")?; + println!("Installed: grub.cfg"); + + let efidir = efi + .then(|| { + target_root + .sub_dir_optional("boot/efi/EFI") + .context("Opening /boot/efi/EFI") + }) + .transpose()? + .flatten(); + if let Some(efidir) = efidir.as_ref() { + let vendordir = find_efi_vendordir(efidir)?; + log::debug!("vendordir={:?}", &vendordir); + let target = &vendordir.join("grub.cfg"); + efidir + .copy_file(&Path::new(CONFIGDIR).join("grub-static-efi.cfg"), target) + .context("Copying static EFI")?; + println!("Installed: {target:?}"); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[ignore] + fn test_install() -> Result<()> { + env_logger::init(); + let td = tempfile::tempdir()?; + let tdp = td.path(); + let td = openat::Dir::open(tdp)?; + std::fs::create_dir_all(tdp.join("boot/grub2"))?; + std::fs::create_dir_all(tdp.join("boot/efi/EFI/BOOT"))?; + std::fs::create_dir_all(tdp.join("boot/efi/EFI/fedora"))?; + install(&td, true).unwrap(); + + assert!(td.exists("boot/grub2/grub.cfg")?); + assert!(td.exists("boot/efi/EFI/fedora/grub.cfg")?); + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 46d676a88..61b73ff81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,12 @@ mod daemon; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; mod filetree; +#[cfg(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64" +))] +mod grubconfigs; mod ipc; mod model; mod model_legacy; From 5741833f50dfd6d112d67758714ea54026480f68 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 20 Oct 2023 09:22:33 -0400 Subject: [PATCH 489/641] Release 0.1.12 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59ef42a99..7587d59be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.11" +version = "0.2.12" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 45c42edcc..e5f0bf4bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.11" +version = "0.2.12" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From e32a8d574fd046aad96c72654c2ee4bc6c57d89e Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 20 Oct 2023 10:01:23 -0400 Subject: [PATCH 490/641] grub.cfg: drop `set pager=1` This was in the very first commit that added a GRUB config to cosa. If set, it causes GRUB to pause output if the screen is full of messages until the user presses a key. That's just incompatible with automation, so nuke it. Any warnings from GRUB should end up in the serial console logs still. One way this can happen is if booting from multipath. GRUB tries each path in turn until it can read from it. For each tried path that's non- optimized, it'll log a message. So if the device has a large enough number of paths, we can trigger the pager functionality and hang boot. Probably fixes: https://issues.redhat.com/browse/OCPBUGS-20123 --- src/grub2/grub-static-pre.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/src/grub2/grub-static-pre.cfg b/src/grub2/grub-static-pre.cfg index 8ebab325c..7784834d6 100644 --- a/src/grub2/grub-static-pre.cfg +++ b/src/grub2/grub-static-pre.cfg @@ -1,7 +1,6 @@ # This file is copied from https://github.com/coreos/coreos-assembler/blob/main/src/grub.cfg # Changes: # - Dropped Ignition glue, that can be injected into platform.cfg -set pager=1 # petitboot doesn't support -e and doesn't support an empty path part if [ -d (md/md-boot)/grub2 ]; then # fcct currently creates /boot RAID with superblock 1.0, which allows From 8a6f3cd099e4afe41f06f62b2797e4c822b17b89 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 24 Oct 2023 10:03:00 -0400 Subject: [PATCH 491/641] packaging: Move static configs into main package No reason to have them be separate, that's what I ended up doing in Fedora. (We should probably delete this spec file...) --- contrib/packaging/bootupd.spec | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec index e6b00aa49..056658f34 100644 --- a/contrib/packaging/bootupd.spec +++ b/contrib/packaging/bootupd.spec @@ -31,6 +31,7 @@ BuildRequires: systemd-devel %{_bindir}/bootupctl %{_libexecdir}/bootupd %{_unitdir}/* +%{_prefix}/lib/bootupd/grub2-static/ %prep %autosetup -n %{crate}-%{version} -p1 -Sgit @@ -44,15 +45,6 @@ replace-with = "vendored-sources" directory = "vendor" EOF -%package grub2-static -Summary: Static grub2 configuration files for CoreOS-alike systems - -%description grub2-static -This package includes static grub2 configuration files. - -%files grub2-static -%{_prefix}/lib/bootupd - %build cargo build --release From b154db288aa60a711e6ef7174eb5eb8e8d072e96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 01:14:02 +0000 Subject: [PATCH 492/641] build(deps): bump tempfile from 3.8.0 to 3.8.1 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.8.0 to 3.8.1. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/commits) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7587d59be..897ef4254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "log" @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -702,9 +702,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rustix" -version = "0.38.13" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.0", "errno", @@ -797,9 +797,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", From 1c8cc596dd19b69b1367dac21515c1e58b2b5830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 01:14:11 +0000 Subject: [PATCH 493/641] build(deps): bump serde from 1.0.189 to 1.0.190 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7587d59be..509223b2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,18 +721,18 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", From 5ee0483a64d5dcadc8c94b49951f2df6146dbb50 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 31 Oct 2023 14:50:03 -0400 Subject: [PATCH 494/641] Add `backend install --auto` This drains the code from https://github.com/containers/bootc/pull/155/commits/20aa19ce6da58078999368e4f6dd948b2e3d990b Because it will also be what Anaconda wants to do by default. --- src/bootupd.rs | 38 ++++++++++++++++++++++++++++++++------ src/cli/bootupd.rs | 10 +++++++++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index b7a92ffa8..bbb771916 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -32,6 +32,7 @@ pub(crate) fn install( device: Option<&str>, with_static_configs: bool, target_components: Option<&[String]>, + auto_components: bool, ) -> Result<()> { // TODO: Change this to an Option<&str>; though this probably balloons into having // DeviceComponent and FileBasedComponent @@ -40,12 +41,14 @@ pub(crate) fn install( SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; - let all_components = get_components(); + let all_components = get_components_impl(auto_components); if all_components.is_empty() { println!("No components available for this platform."); return Ok(()); } let target_components = if let Some(target_components) = target_components { + // Checked by CLI parser + assert!(!auto_components); target_components .iter() .map(|name| { @@ -104,24 +107,47 @@ pub(crate) fn install( type Components = BTreeMap<&'static str, Box>; -pub(crate) fn get_components() -> Components { +#[allow(clippy::box_default)] +/// Return the set of known components; if `auto` is specified then the system +/// filters to the target booted state. +pub(crate) fn get_components_impl(auto: bool) -> Components { let mut components = BTreeMap::new(); fn insert_component(components: &mut Components, component: Box) { components.insert(component.name(), component); } - #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] - #[allow(clippy::box_default)] + #[cfg(target_arch = "x86_64")] + { + if auto { + let is_efi_booted = Path::new("/sys/firmware/efi").exists(); + log::info!( + "System boot method: {}", + if is_efi_booted { "EFI" } else { "BIOS" } + ); + if is_efi_booted { + insert_component(&mut components, Box::new(efi::Efi::default())); + } else { + insert_component(&mut components, Box::new(bios::Bios::default())); + } + } else { + insert_component(&mut components, Box::new(bios::Bios::default())); + insert_component(&mut components, Box::new(efi::Efi::default())); + } + } + #[cfg(target_arch = "aarch64")] insert_component(&mut components, Box::new(efi::Efi::default())); - #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] - #[allow(clippy::box_default)] + #[cfg(target_arch = "powerpc64")] insert_component(&mut components, Box::new(bios::Bios::default())); components } +pub(crate) fn get_components() -> Components { + get_components_impl(false) +} + pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { // create bootupd update dir which will save component metadata files for both components let updates_dir = Path::new(sysroot_path).join(crate::model::BOOTUPD_UPDATES_DIR); diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index f7b08678d..b2cfd5989 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -56,9 +56,16 @@ pub struct InstallOpts { #[clap(long)] with_static_configs: bool, - #[clap(long = "component")] + #[clap(long = "component", conflicts_with = "auto")] /// Only install these components components: Option>, + + /// Automatically choose components based on booted host state. + /// + /// For example on x86_64, if the host system is booted via EFI, + /// then only enable installation to the ESP. + #[clap(long)] + auto: bool, } #[derive(Debug, Parser)] @@ -96,6 +103,7 @@ impl DCommand { opts.device.as_deref(), opts.with_static_configs, opts.components.as_deref(), + opts.auto, ) .context("boot data installation failed")?; Ok(()) From 254224ed41b2e8b08b32029dfa8437a37003e1e9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 1 Nov 2023 16:59:56 -0400 Subject: [PATCH 495/641] install: Just no-op with `--auto` if no components This is part of being a no-op on s390x. --- src/bootupd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index bbb771916..f6c92475f 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -61,7 +61,7 @@ pub(crate) fn install( all_components.values().collect() }; - if target_components.is_empty() { + if target_components.is_empty() && !auto_components { anyhow::bail!("No components specified"); } From e81c38ecded27c118bb259cd468b4853bcc276d3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Nov 2023 10:07:21 -0400 Subject: [PATCH 496/641] No-op static configs on s390x Nothing to do there. --- src/bootupd.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootupd.rs b/src/bootupd.rs index f6c92475f..560f38bf4 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -90,7 +90,13 @@ pub(crate) fn install( let sysroot = &openat::Dir::open(dest_root)?; if with_static_configs { + #[cfg(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64" + ))] crate::grubconfigs::install(sysroot, installed_efi)?; + // On other architectures, assume that there's nothing to do. } // Unmount the ESP, etc. From c2fab543003537184da8e4a9b27d934da1fc537f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Nov 2023 14:30:23 -0400 Subject: [PATCH 497/641] Release 0.2.13 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89bbe9d55..ff678be76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.12" +version = "0.2.13" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index e5f0bf4bb..5bafdcac5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.12" +version = "0.2.13" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 539a65acc37bde1d8a4d39efb6243747e7596d9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 01:55:16 +0000 Subject: [PATCH 498/641] build(deps): bump openssl from 0.10.57 to 0.10.59 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.57 to 0.10.59. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.57...openssl-v0.10.59) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff678be76..65653b268 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -536,9 +536,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -562,9 +562,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" dependencies = [ "cc", "libc", From 49a25763cbf24133b629ba76f55894dc80c1fba3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 01:55:21 +0000 Subject: [PATCH 499/641] build(deps): bump serde_json from 1.0.107 to 1.0.108 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.108. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.108) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff678be76..66f27f9d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,9 +741,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", From beaba720a7e8525d2a9d6b8ddb40bb2375106459 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 01:55:27 +0000 Subject: [PATCH 500/641] build(deps): bump libc from 0.2.149 to 0.2.150 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.150. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.149...0.2.150) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff678be76..422a9209c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libsystemd" From ece9120cb43b1834ff4b7268308886cd89a47e54 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 9 Nov 2023 19:17:57 -0500 Subject: [PATCH 501/641] grubconfigs: Ensure grub2 dir exists I hit this when testing `bootc install` in a loop, it seems like we could be implicitly depending on this directory already having been created. --- src/grubconfigs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index 01f6b3ea7..dcdf986cc 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -62,6 +62,10 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool) -> Result<()> { config.push_str(post.as_str()); } + if !bootdir.exists(GRUB2DIR)? { + bootdir.create_dir(GRUB2DIR, 0o700)?; + } + bootdir .write_file_contents(format!("{GRUB2DIR}/grub.cfg"), 0o644, config.as_bytes()) .context("Copying grub-static.cfg")?; From 581102abe0488ef20df830f271b4c882face108d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 10 Nov 2023 10:35:24 -0500 Subject: [PATCH 502/641] Improve EFI, add support for root=boot and writing UUID file In FCOS we never tried to support root=boot, but for bootupd to do alongside installs in the general case we have to. There were two things to fix here: - Tweak the EFI "trampoline" to check for both $prefix/grub.cfg and $prefix/boot/grub.cfg - Add support for writing the boot UUID into both places (This avoids higher level tools like bootupd needing to know about how to find the EFI vendor dir) Then the bigger issue here is that we need to support invoking `efibootmgr` to re-synchronize the firmware. This is particularly important in cases like bootc "alongside" installs where we're taking over the target OS. --- src/bios.rs | 1 + src/bootupd.rs | 42 ++++++++++---- src/cli/bootupd.rs | 21 ++++++- src/component.rs | 1 + src/efi.rs | 105 ++++++++++++++++++++++++++++++++-- src/filesystem.rs | 44 ++++++++++++++ src/grub2/grub-static-efi.cfg | 9 ++- src/grubconfigs.rs | 34 ++++++++++- src/main.rs | 1 + 9 files changed, 235 insertions(+), 23 deletions(-) create mode 100644 src/filesystem.rs diff --git a/src/bios.rs b/src/bios.rs index e2a253125..9f2546e90 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -93,6 +93,7 @@ impl Component for Bios { src_root: &openat::Dir, dest_root: &str, device: &str, + _update_firmware: bool, ) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta diff --git a/src/bootupd.rs b/src/bootupd.rs index 560f38bf4..c323d68e2 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -26,11 +26,28 @@ pub(crate) enum ClientRequest { Status, } +pub(crate) enum ConfigMode { + None, + Static, + WithUUID, +} + +impl ConfigMode { + pub(crate) fn enabled_with_uuid(&self) -> Option { + match self { + ConfigMode::None => None, + ConfigMode::Static => Some(false), + ConfigMode::WithUUID => Some(true), + } + } +} + pub(crate) fn install( source_root: &str, dest_root: &str, device: Option<&str>, - with_static_configs: bool, + configs: ConfigMode, + update_firmware: bool, target_components: Option<&[String]>, auto_components: bool, ) -> Result<()> { @@ -78,7 +95,7 @@ pub(crate) fn install( } let meta = component - .install(&source_root, dest_root, device) + .install(&source_root, dest_root, device, update_firmware) .with_context(|| format!("installing component {}", component.name()))?; log::info!("Installed {} {}", component.name(), meta.meta.version); state.installed.insert(component.name().into(), meta); @@ -89,14 +106,17 @@ pub(crate) fn install( } let sysroot = &openat::Dir::open(dest_root)?; - if with_static_configs { - #[cfg(any( - target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "powerpc64" - ))] - crate::grubconfigs::install(sysroot, installed_efi)?; - // On other architectures, assume that there's nothing to do. + match configs.enabled_with_uuid() { + Some(uuid) => { + #[cfg(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64" + ))] + crate::grubconfigs::install(sysroot, installed_efi, uuid)?; + // On other architectures, assume that there's nothing to do. + } + None => {} } // Unmount the ESP, etc. @@ -126,7 +146,7 @@ pub(crate) fn get_components_impl(auto: bool) -> Components { #[cfg(target_arch = "x86_64")] { if auto { - let is_efi_booted = Path::new("/sys/firmware/efi").exists(); + let is_efi_booted = crate::efi::is_efi_booted().unwrap(); log::info!( "System boot method: {}", if is_efi_booted { "EFI" } else { "BIOS" } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index b2cfd5989..d22337613 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -1,4 +1,4 @@ -use crate::bootupd; +use crate::bootupd::{self, ConfigMode}; use anyhow::{Context, Result}; use clap::Parser; use log::LevelFilter; @@ -56,6 +56,15 @@ pub struct InstallOpts { #[clap(long)] with_static_configs: bool, + /// Implies `--with-static-configs`. When present, this also writes a + /// file with the UUID of the target filesystems. + #[clap(long)] + write_uuid: bool, + + /// On EFI systems, invoke `efibootmgr` to update the firmware. + #[clap(long)] + update_firmware: bool, + #[clap(long = "component", conflicts_with = "auto")] /// Only install these components components: Option>, @@ -97,11 +106,19 @@ impl DCommand { /// Runner for `install` verb. pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { + let configmode = if opts.write_uuid { + ConfigMode::WithUUID + } else if opts.with_static_configs { + ConfigMode::Static + } else { + ConfigMode::None + }; bootupd::install( &opts.src_root, &opts.dest_root, opts.device.as_deref(), - opts.with_static_configs, + configmode, + opts.update_firmware, opts.components.as_deref(), opts.auto, ) diff --git a/src/component.rs b/src/component.rs index 7ac0c7f05..dc1c6068a 100644 --- a/src/component.rs +++ b/src/component.rs @@ -50,6 +50,7 @@ pub(crate) trait Component { src_root: &openat::Dir, dest_root: &str, device: &str, + update_firmware: bool, ) -> Result; /// Implementation of `bootupd generate-update-metadata` for a given component. diff --git a/src/efi.rs b/src/efi.rs index 331b607b6..4d18bdcee 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::{bail, Context, Result}; +use fn_error_context::context; use openat_ext::OpenatDirExt; use widestring::U16CString; @@ -22,6 +23,10 @@ use crate::{component::*, packagesystem}; /// Well-known paths to the ESP that may have been mounted external to us. pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi", "boot"]; +/// The binary to change EFI boot ordering +const EFIBOOTMGR: &str = "efibootmgr"; +const SHIM: &str = "shimx64.efi"; + /// The ESP partition label on Fedora CoreOS derivatives pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition"; @@ -30,6 +35,13 @@ pub(crate) const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition"; const LOADER_INFO_VAR_STR: &str = "LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; const STUB_INFO_VAR_STR: &str = "StubInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; +/// Return `true` if the system is booted via EFI +pub(crate) fn is_efi_booted() -> Result { + Path::new("/sys/firmware/efi") + .try_exists() + .map_err(Into::into) +} + #[derive(Default)] pub(crate) struct Efi { mountpoint: RefCell>, @@ -113,6 +125,17 @@ impl Efi { } Ok(()) } + + #[context("Updating EFI firmware variables")] + fn update_firmware(&self, device: &str, espdir: &openat::Dir) -> Result<()> { + let efidir = &espdir.sub_dir("EFI").context("Opening EFI")?; + let vendordir = super::grubconfigs::find_efi_vendordir(efidir)?; + let vendordir = vendordir + .to_str() + .ok_or_else(|| anyhow::anyhow!("Invalid non-UTF-8 vendordir"))?; + clear_efi_current()?; + set_efi_current(device, espdir, vendordir) + } } /// Convert a nul-terminated UTF-16 byte array to a String. @@ -259,7 +282,8 @@ impl Component for Efi { &self, src_root: &openat::Dir, dest_root: &str, - _: &str, + device: &str, + update_firmware: bool, ) -> Result { let meta = if let Some(meta) = get_component_update(src_root, self)? { meta @@ -270,11 +294,11 @@ impl Component for Efi { let srcdir_name = component_updatedirname(self); let ft = crate::filetree::FileTree::new_from_dir(&src_root.sub_dir(&srcdir_name)?)?; let destdir = &self.ensure_mounted_esp(Path::new(dest_root))?; - { - let destd = openat::Dir::open(destdir) - .with_context(|| format!("opening dest dir {}", destdir.display()))?; - validate_esp(&destd)?; - } + + let destd = &openat::Dir::open(destdir) + .with_context(|| format!("opening dest dir {}", destdir.display()))?; + validate_esp(destd)?; + // TODO - add some sort of API that allows directly setting the working // directory to a file descriptor. let r = std::process::Command::new("cp") @@ -286,6 +310,9 @@ impl Component for Efi { if !r.success() { anyhow::bail!("Failed to copy"); } + if update_firmware { + self.update_firmware(device, destd)? + } Ok(InstalledContent { meta, filetree: Some(ft), @@ -399,3 +426,69 @@ fn validate_esp(dir: &openat::Dir) -> Result<()> { }; Ok(()) } + +#[context("Clearing current EFI boot entry")] +pub(crate) fn clear_efi_current() -> Result<()> { + const BOOTCURRENT: &str = "BootCurrent"; + if !crate::efi::is_efi_booted()? { + log::debug!("System is not booted via EFI"); + return Ok(()); + } + let output = Command::new(EFIBOOTMGR).output()?; + if !output.status.success() { + anyhow::bail!("Failed to invoke {EFIBOOTMGR}") + } + let output = String::from_utf8(output.stdout)?; + let current = output + .lines() + .filter_map(|l| l.split_once(':')) + .filter_map(|(k, v)| (k == BOOTCURRENT).then_some(v.trim())) + .next() + .ok_or_else(|| anyhow::anyhow!("Failed to find BootCurrent"))?; + let output = Command::new(EFIBOOTMGR) + .args(["-b", current, "-B"]) + .output()?; + if !output.status.success() { + std::io::copy( + &mut std::io::Cursor::new(output.stderr), + &mut std::io::stderr().lock(), + )?; + anyhow::bail!("Failed to invoke {EFIBOOTMGR}"); + } + anyhow::Ok(()) +} + +#[context("Adding new EFI boot entry")] +pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &str) -> Result<()> { + let fsinfo = crate::filesystem::inspect_filesystem(espdir, ".")?; + let source = fsinfo.source; + let devname = source + .rsplit_once('/') + .ok_or_else(|| anyhow::anyhow!("Failed to parse {source}"))? + .1; + let partition_path = format!("/sys/class/block/{devname}/partition"); + let partition_number = std::fs::read_to_string(&partition_path) + .with_context(|| format!("Failed to read {partition_path}"))?; + let shim = format!("{vendordir}/{SHIM}"); + if espdir.exists(&shim)? { + anyhow::bail!("Failed to find {SHIM}"); + } + let loader = format!("\\EFI\\{}\\shimx64.efi", vendordir); + let st = Command::new(EFIBOOTMGR) + .args([ + "--create", + "--disk", + device, + "--part", + partition_number.as_str(), + "--loader", + loader.as_str(), + "--label", + vendordir, + ]) + .status()?; + if !st.success() { + anyhow::bail!("Failed to invoke {EFIBOOTMGR}") + } + anyhow::Ok(()) +} diff --git a/src/filesystem.rs b/src/filesystem.rs new file mode 100644 index 000000000..f09ceb34a --- /dev/null +++ b/src/filesystem.rs @@ -0,0 +1,44 @@ +use std::os::fd::AsRawFd; +use std::os::unix::process::CommandExt; +use std::process::Command; + +use anyhow::{Context, Result}; +use fn_error_context::context; +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +#[allow(dead_code)] +pub(crate) struct Filesystem { + pub(crate) source: String, + pub(crate) fstype: String, + pub(crate) options: String, + pub(crate) uuid: Option, +} + +#[derive(Deserialize, Debug)] +pub(crate) struct Findmnt { + pub(crate) filesystems: Vec, +} + +#[context("Inspecting filesystem {path:?}")] +pub(crate) fn inspect_filesystem(root: &openat::Dir, path: &str) -> Result { + let rootfd = root.as_raw_fd(); + // SAFETY: This is unsafe just for the pre_exec, when we port to cap-std we can use cap-std-ext + let o = unsafe { + Command::new("findmnt") + .args(["-J", "-v", "--output-all", path]) + .pre_exec(move || nix::unistd::fchdir(rootfd).map_err(Into::into)) + .output()? + }; + let st = o.status; + if !st.success() { + anyhow::bail!("findmnt failed: {st:?}"); + } + let o: Findmnt = serde_json::from_reader(std::io::Cursor::new(&o.stdout)) + .context("Parsing findmnt output")?; + o.filesystems + .into_iter() + .next() + .ok_or_else(|| anyhow::anyhow!("findmnt returned no data")) +} diff --git a/src/grub2/grub-static-efi.cfg b/src/grub2/grub-static-efi.cfg index bf38ca906..3d552c307 100644 --- a/src/grub2/grub-static-efi.cfg +++ b/src/grub2/grub-static-efi.cfg @@ -13,7 +13,12 @@ else search --label boot --set prefix --no-floppy fi fi -set prefix=($prefix)/grub2 -configfile $prefix/grub.cfg +if [ -d ($prefix)/grub2 ]; then + set prefix=($prefix)/grub2 + configfile $prefix/grub.cfg +else + set prefix=($prefix)/boot/grub2 + configfile $prefix/grub.cfg +fi boot diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index dcdf986cc..8b4b0c90b 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -29,8 +29,14 @@ pub(crate) fn find_efi_vendordir(efidir: &openat::Dir) -> Result { /// Install the static GRUB config files. #[context("Installing static GRUB configs")] -pub(crate) fn install(target_root: &openat::Dir, efi: bool) -> Result<()> { +pub(crate) fn install(target_root: &openat::Dir, efi: bool, write_uuid: bool) -> Result<()> { let bootdir = &target_root.sub_dir("boot").context("Opening /boot")?; + let boot_is_mount = { + let root_dev = target_root.self_metadata()?.stat().st_dev; + let boot_dev = bootdir.self_metadata()?.stat().st_dev; + log::debug!("root_dev={root_dev} boot_dev={boot_dev}"); + root_dev != boot_dev + }; let mut config = std::fs::read_to_string(Path::new(CONFIGDIR).join("grub-static-pre.cfg"))?; @@ -71,6 +77,22 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool) -> Result<()> { .context("Copying grub-static.cfg")?; println!("Installed: grub.cfg"); + let uuid_path = if write_uuid { + let target_fs = if boot_is_mount { bootdir } else { target_root }; + let bootfs_meta = crate::filesystem::inspect_filesystem(target_fs, ".")?; + let bootfs_uuid = bootfs_meta + .uuid + .ok_or_else(|| anyhow::anyhow!("Failed to find UUID for boot"))?; + let grub2_uuid_contents = format!("set BOOT_UUID=\"{bootfs_uuid}\"\n"); + let uuid_path = format!("{GRUB2DIR}/bootuuid.cfg"); + bootdir + .write_file_contents(&uuid_path, 0o644, grub2_uuid_contents) + .context("Writing bootuuid.cfg")?; + Some(uuid_path) + } else { + None + }; + let efidir = efi .then(|| { target_root @@ -87,6 +109,14 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool) -> Result<()> { .copy_file(&Path::new(CONFIGDIR).join("grub-static-efi.cfg"), target) .context("Copying static EFI")?; println!("Installed: {target:?}"); + if let Some(uuid_path) = uuid_path { + // SAFETY: we always have a filename + let filename = Path::new(&uuid_path).file_name().unwrap(); + let target = &vendordir.join(filename); + bootdir + .copy_file_at(uuid_path, efidir, target) + .context("Writing bootuuid.cfg to efi dir")?; + } } Ok(()) @@ -106,7 +136,7 @@ mod tests { std::fs::create_dir_all(tdp.join("boot/grub2"))?; std::fs::create_dir_all(tdp.join("boot/efi/EFI/BOOT"))?; std::fs::create_dir_all(tdp.join("boot/efi/EFI/fedora"))?; - install(&td, true).unwrap(); + install(&td, true, false).unwrap(); assert!(td.exists("boot/grub2/grub.cfg")?); assert!(td.exists("boot/efi/EFI/fedora/grub.cfg")?); diff --git a/src/main.rs b/src/main.rs index 61b73ff81..133e9bbfc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ mod coreos; mod daemon; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; +mod filesystem; mod filetree; #[cfg(any( target_arch = "x86_64", From d07dd17013f0777ddfef1f1e2f95437f47e3fb73 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 19 Nov 2023 11:35:31 -0500 Subject: [PATCH 503/641] ci: Adapt for Fedora 39 Part of the every-6-months CI breakage. --- tests/e2e-update/e2e-update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index b06893a8a..2a3a13453 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -80,14 +80,14 @@ if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm # Version from F37 GA - add_override grub2-2.06-58.fc37 + add_override grub2-2.06-89.fc38 runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" # Version queued in current updates - add_override grub2-2.06-70.fc37 + add_override grub2-2.06-102.fc38 mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree From a2e455fadfa92ebb3ba327d566cb84863ca1a0a7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 19 Nov 2023 13:26:52 -0500 Subject: [PATCH 504/641] `allow(clippy::style)` The style lints are more annoying than useful as a general rule. --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index 133e9bbfc..5cbb02fd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,8 @@ Refs: !*/ #![deny(unused_must_use)] +// The style lints are more annoying than useful +#![allow(clippy::style)] mod backend; #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] From 93aa54274ebd1fa88d5b383927587deebbca07c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 19 Nov 2023 18:27:59 +0000 Subject: [PATCH 505/641] build(deps): bump libsystemd from 0.6.0 to 0.7.0 Bumps [libsystemd](https://github.com/lucab/libsystemd-rs) from 0.6.0 to 0.7.0. - [Release notes](https://github.com/lucab/libsystemd-rs/releases) - [Commits](https://github.com/lucab/libsystemd-rs/compare/v0.6.0...v0.7.0) --- updated-dependencies: - dependency-name: libsystemd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 +++++++++--------- Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33cee73fd..f5ba8f941 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,14 +405,14 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libsystemd" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b9597a67aa1c81a6624603e6bd0bcefb9e0f94c9c54970ec53771082104b4e" +checksum = "c592dc396b464005f78a5853555b9f240bc5378bf5221acc4e129910b2678869" dependencies = [ "hmac", "libc", "log", - "nix 0.26.4", + "nix 0.27.1", "nom", "once_cell", "serde", @@ -450,9 +450,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -478,14 +478,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset 0.9.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5bafdcac5..4551f3b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" libc = "^0.2" -libsystemd = ">= 0.3, < 0.7" +libsystemd = ">= 0.3, < 0.8" log = "^0.4" nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" From 9bae8e67d2fcb5e0c557edb85c9fc7bd926c4dfa Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 19 Nov 2023 16:14:53 -0500 Subject: [PATCH 506/641] efi: Only try to update firmware if booted via EFI Otherwise we'll just fail. --- src/efi.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/efi.rs b/src/efi.rs index 4d18bdcee..ffe4b8167 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -128,6 +128,10 @@ impl Efi { #[context("Updating EFI firmware variables")] fn update_firmware(&self, device: &str, espdir: &openat::Dir) -> Result<()> { + if !is_efi_booted()? { + log::debug!("Not booted via EFI, skipping firmware update"); + return Ok(()); + } let efidir = &espdir.sub_dir("EFI").context("Opening EFI")?; let vendordir = super::grubconfigs::find_efi_vendordir(efidir)?; let vendordir = vendordir From ccbfa176abd81d97408067304c6e9837b487e49f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 20 Nov 2023 09:20:32 -0500 Subject: [PATCH 507/641] Release 0.2.14 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5ba8f941..746008580 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.13" +version = "0.2.14" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 4551f3b05..2103cec30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.13" +version = "0.2.14" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 3d4dc04e3115b072774b5b4b53c3b4dd31156e74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:22:09 +0000 Subject: [PATCH 508/641] build(deps): bump serde from 1.0.190 to 1.0.192 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.192. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.192) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5ba8f941..9f8eae16e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,18 +721,18 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", From dab28bc191d5d7fadd215781601760fd70855806 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 20 Nov 2023 13:23:02 -0500 Subject: [PATCH 509/641] efi: Gracefully no-op if there's no `BootCurrent` This happens in a default virt-manager run for example. --- src/efi.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index ffe4b8167..81089f4bd 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -443,12 +443,17 @@ pub(crate) fn clear_efi_current() -> Result<()> { anyhow::bail!("Failed to invoke {EFIBOOTMGR}") } let output = String::from_utf8(output.stdout)?; - let current = output + let current = if let Some(current) = output .lines() .filter_map(|l| l.split_once(':')) .filter_map(|(k, v)| (k == BOOTCURRENT).then_some(v.trim())) .next() - .ok_or_else(|| anyhow::anyhow!("Failed to find BootCurrent"))?; + { + current + } else { + log::debug!("No EFI {BOOTCURRENT} found"); + return Ok(()); + }; let output = Command::new(EFIBOOTMGR) .args(["-b", current, "-B"]) .output()?; From 9fc12e98491363473e17feef1b6996574d29483f Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Tue, 21 Nov 2023 15:31:38 -0500 Subject: [PATCH 510/641] ci: cancel previous build on PR update This is an easy way to save CI resources; when a PR is updated, abort any previous build for that PR to focus on testing the latest push. --- .cci.jenkinsfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index df7a1a9ba..d8b92c986 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -1,5 +1,10 @@ // Documentation: https://github.com/coreos/coreos-ci/blob/main/README-upstream-ci.md +properties([ + // abort previous runs when a PR is updated to save resources + disableConcurrentBuilds(abortPrevious: true) +]) + stage("Build") { parallel build: { def n = 5 From 74556e6cdf91fa7c5c4ddd4dbcab9723532c93b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 01:21:19 +0000 Subject: [PATCH 511/641] build(deps): bump serde from 1.0.192 to 1.0.193 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2f7f1db8..2f1447953 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,18 +721,18 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", From 0f8b058b080cc9198bc9150710f9a6978d88431b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 01:21:32 +0000 Subject: [PATCH 512/641] build(deps): bump openssl from 0.10.59 to 0.10.60 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.59 to 0.10.60. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.59...openssl-v0.10.60) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2f7f1db8..c1755a9c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -536,9 +536,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.59" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -562,9 +562,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.95" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc", From 9eb1a190537664243ea9b32469d1e944aec0f22e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 28 Nov 2023 10:49:05 -0500 Subject: [PATCH 513/641] Release 0.2.15 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8ec05d9b..9ed19cedd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.14" +version = "0.2.15" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 2103cec30..89c55d575 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.14" +version = "0.2.15" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From aabe3ccb36022ab48470193ec3e4bbe7f199fe73 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Dec 2023 16:26:43 -0500 Subject: [PATCH 514/641] efi: Add more debugging for efibootmgr invocation - Show what `bootcurrent` is - Add the process exit status --- src/efi.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 81089f4bd..3cc44ae50 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -454,15 +454,17 @@ pub(crate) fn clear_efi_current() -> Result<()> { log::debug!("No EFI {BOOTCURRENT} found"); return Ok(()); }; + log::debug!("EFI current: {current}"); let output = Command::new(EFIBOOTMGR) .args(["-b", current, "-B"]) .output()?; - if !output.status.success() { + let st = output.status; + if !st.success() { std::io::copy( &mut std::io::Cursor::new(output.stderr), &mut std::io::stderr().lock(), )?; - anyhow::bail!("Failed to invoke {EFIBOOTMGR}"); + anyhow::bail!("Failed to invoke {EFIBOOTMGR}: {st:?}"); } anyhow::Ok(()) } From 157acb26370068decbf427323104ac29ad0917fb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Dec 2023 16:36:35 -0500 Subject: [PATCH 515/641] filesystem: Copy stderr on failure To aid debugging. --- src/filesystem.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/filesystem.rs b/src/filesystem.rs index f09ceb34a..2cd259a2a 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -1,3 +1,4 @@ +use std::io::Write; use std::os::fd::AsRawFd; use std::os::unix::process::CommandExt; use std::process::Command; @@ -33,6 +34,7 @@ pub(crate) fn inspect_filesystem(root: &openat::Dir, path: &str) -> Result Date: Thu, 7 Dec 2023 16:36:48 -0500 Subject: [PATCH 516/641] filesystem: Only capture needed columns This fixes compatibility with current c9s `findmnt`, which otherwise errors out with `findmnt: ACTION column is requested, but --poll is not enabled` --- src/filesystem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesystem.rs b/src/filesystem.rs index 2cd259a2a..c9060a700 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -28,7 +28,7 @@ pub(crate) fn inspect_filesystem(root: &openat::Dir, path: &str) -> Result Date: Mon, 11 Dec 2023 01:30:48 +0000 Subject: [PATCH 517/641] build(deps): bump libc from 0.2.150 to 0.2.151 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.150 to 0.2.151. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.150...0.2.151) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ed19cedd..9d8b0a5ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libsystemd" From 131bc043d76502a53076bc2544ff26e164e4994a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 01:30:55 +0000 Subject: [PATCH 518/641] build(deps): bump openssl from 0.10.60 to 0.10.61 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.60 to 0.10.61. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.60...openssl-v0.10.61) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ed19cedd..ad7418a83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -536,9 +536,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.60" +version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -562,9 +562,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.96" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" dependencies = [ "cc", "libc", From baccac315c53dc0c2bded144a70a72ead97646e6 Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Mon, 11 Dec 2023 10:37:40 -0500 Subject: [PATCH 519/641] grubconfigs: move the GRUB2DIR creation earlier We add the GRUB2DIR creation in ece9120 but there is an earlier use of that directory if there are dropins so let's move the creation of the directory earlier before the dropins are processed. I hit this because I'm testing out things on FCOS. Building a qemu and metal image works just fine, because in that case we are doing the MBR install using `grub2-install` and I guess that tool creates the directory. In the metal4k case, though, there is no BIOS install and thus we get here and the GRUB2DIR doesn't exist and bootupd fails. --- src/grubconfigs.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index 8b4b0c90b..dbf486990 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -38,6 +38,10 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool, write_uuid: bool) -> root_dev != boot_dev }; + if !bootdir.exists(GRUB2DIR)? { + bootdir.create_dir(GRUB2DIR, 0o700)?; + } + let mut config = std::fs::read_to_string(Path::new(CONFIGDIR).join("grub-static-pre.cfg"))?; let dropindir = openat::Dir::open(&Path::new(CONFIGDIR).join(DROPINDIR))?; @@ -68,10 +72,6 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool, write_uuid: bool) -> config.push_str(post.as_str()); } - if !bootdir.exists(GRUB2DIR)? { - bootdir.create_dir(GRUB2DIR, 0o700)?; - } - bootdir .write_file_contents(format!("{GRUB2DIR}/grub.cfg"), 0o644, config.as_bytes()) .context("Copying grub-static.cfg")?; From 9e61ce9bcb1ebb09d6562ace8993b3c1ddf86681 Mon Sep 17 00:00:00 2001 From: Joseph Marrero Date: Wed, 13 Dec 2023 11:39:50 -0500 Subject: [PATCH 520/641] Release 0.2.16 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e22a5b2d..7fa6e52e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.15" +version = "0.2.16" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 89c55d575..c6c456ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.15" +version = "0.2.16" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 65670572aa2a538e5488f11d1d37072a5b0562ad Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Fri, 15 Dec 2023 23:25:25 -0500 Subject: [PATCH 521/641] coreos: update aleph version handling In https://github.com/osbuild/osbuild/pull/1475 we are updating aleph version to have more information and some of the fields are changing slightly. Notably here `imgid` is no longer going to be populated and `build` -> `version` now. Let's make these tweaks and also just drop any fields from the definition here that we aren't using to tolerate changes better. --- src/bootupd.rs | 2 +- src/coreos.rs | 29 +++++++++++++++++++---------- src/efi.rs | 2 +- tests/kola/test-bootupd | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index c323d68e2..6baa32460 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -389,7 +389,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { } if let Some(coreos_aleph) = coreos::get_aleph_version()? { - println!("CoreOS aleph image ID: {}", coreos_aleph.aleph.imgid); + println!("CoreOS aleph version: {}", coreos_aleph.aleph.version); } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] diff --git a/src/coreos.rs b/src/coreos.rs index e8b91cdc9..2b552908f 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -15,11 +15,8 @@ use serde::{Deserialize, Serialize}; #[serde(rename_all = "kebab-case")] /// See https://github.com/coreos/fedora-coreos-tracker/blob/66d7d00bedd9d5eabc7287b9577f443dcefb7c04/internals/README-internals.md#aleph-version pub(crate) struct Aleph { - pub(crate) build: String, - #[serde(rename = "ref")] - pub(crate) ostree_ref: String, - pub(crate) ostree_commit: String, - pub(crate) imgid: String, + #[serde(alias = "build")] + pub(crate) version: String, } pub(crate) struct AlephWithTimestamp { @@ -52,7 +49,9 @@ mod test { use anyhow::Result; #[test] - fn test_parse_aleph() -> Result<()> { + fn test_parse_old_aleph() -> Result<()> { + // What the aleph file looked like before we changed it in + // https://github.com/osbuild/osbuild/pull/1475 let alephdata = r##" { "build": "32.20201002.dev.2", @@ -61,10 +60,20 @@ mod test { "imgid": "fedora-coreos-32.20201002.dev.2-qemu.x86_64.qcow2" }"##; let aleph: Aleph = serde_json::from_str(alephdata)?; - assert_eq!( - aleph.imgid, - "fedora-coreos-32.20201002.dev.2-qemu.x86_64.qcow2" - ); + assert_eq!(aleph.version, "32.20201002.dev.2"); + Ok(()) + } + + #[test] + fn test_parse_aleph() -> Result<()> { + let alephdata = r##" +{ + "version": "32.20201002.dev.2", + "ref": "fedora/x86_64/coreos/testing-devel", + "ostree-commit": "b2ea6159d6274e1bbbb49aa0ef093eda5d53a75c8a793dbe184f760ed64dc862" +}"##; + let aleph: Aleph = serde_json::from_str(alephdata)?; + assert_eq!(aleph.version, "32.20201002.dev.2"); Ok(()) } } diff --git a/src/efi.rs b/src/efi.rs index 3cc44ae50..265999d3b 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -221,7 +221,7 @@ impl Component for Efi { if let Some(coreos_aleph) = crate::coreos::get_aleph_version()? { let meta = ContentMetadata { timestamp: coreos_aleph.ts, - version: coreos_aleph.aleph.imgid, + version: coreos_aleph.aleph.version, }; log::trace!("EFI adoptable: {:?}", &meta); return Ok(Some(Adoptable { diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 8824c809e..7402c6fb6 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -44,7 +44,7 @@ bootupctl status > out.txt assert_file_has_content_literal out.txt 'Component EFI' assert_file_has_content_literal out.txt ' Installed: grub2-efi-x64-' assert_file_has_content_literal out.txt 'Update: At latest version' -assert_file_has_content out.txt '^CoreOS aleph image ID: .*-qemu.'$(arch)'.qcow2' +assert_file_has_content out.txt '^CoreOS aleph version:' ok status # Validate we auto-exited From 3c38e7eb911a8e456531ecfe0472bf5c8b3d4ed2 Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Fri, 15 Dec 2023 23:27:33 -0500 Subject: [PATCH 522/641] coreos: let aleph file be a symlink Once https://github.com/osbuild/osbuild/pull/1475 gets picked up and starts getting used the .coreos-aleph-version.json will be a symlink. Let's canonicalize and find the actual file before dropping into sysroot.open_file_optional() because the underlying code for that uses O_NOFOLLOW and will give an ELOOP (too many symbolic links) error. --- src/coreos.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/coreos.rs b/src/coreos.rs index 2b552908f..2ee700248 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -6,10 +6,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -use anyhow::Result; +use anyhow::{Context, Result}; use chrono::prelude::*; use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; +use std::fs::{canonicalize, symlink_metadata}; +use std::path::Path; #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] @@ -30,7 +32,21 @@ const ALEPH_PATH: &str = "/sysroot/.coreos-aleph-version.json"; pub(crate) fn get_aleph_version() -> Result> { let sysroot = openat::Dir::open("/")?; - if let Some(statusf) = sysroot.open_file_optional(ALEPH_PATH)? { + let mut path = ALEPH_PATH; + if !Path::new(ALEPH_PATH).exists() { + return Ok(None); + } + let target; + let is_link = symlink_metadata(path) + .with_context(|| format!("reading metadata for {}", path))? + .file_type() + .is_symlink(); + if is_link { + target = + canonicalize(path).with_context(|| format!("getting absolute path to {}", path))?; + path = target.to_str().unwrap() + } + if let Some(statusf) = sysroot.open_file_optional(path)? { let meta = statusf.metadata()?; let bufr = std::io::BufReader::new(statusf); let aleph: Aleph = serde_json::from_reader(bufr)?; From 8d746cd8036365491872efcfd2279f91e330af82 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Dec 2023 10:08:29 -0500 Subject: [PATCH 523/641] coreos: Change aleph API to take a root as a std path This makes it amenable to unit testing, and also since the previous code was always operating on `/` there's no good reason to use the `openat` APIs which don't follow symlinks by default, which breaks ergonomics. --- src/bootupd.rs | 2 +- src/coreos.rs | 92 +++++++++++++++++++++++++++++++------------------- src/efi.rs | 2 +- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 6baa32460..f5a8529d5 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -388,7 +388,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { } } - if let Some(coreos_aleph) = coreos::get_aleph_version()? { + if let Some(coreos_aleph) = coreos::get_aleph_version(Path::new("/"))? { println!("CoreOS aleph version: {}", coreos_aleph.aleph.version); } diff --git a/src/coreos.rs b/src/coreos.rs index 2ee700248..9977acef6 100644 --- a/src/coreos.rs +++ b/src/coreos.rs @@ -8,9 +8,8 @@ use anyhow::{Context, Result}; use chrono::prelude::*; -use openat_ext::OpenatDirExt; use serde::{Deserialize, Serialize}; -use std::fs::{canonicalize, symlink_metadata}; +use std::fs::File; use std::path::Path; #[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, PartialEq, Eq)] @@ -28,35 +27,21 @@ pub(crate) struct AlephWithTimestamp { } /// Path to the file, see above -const ALEPH_PATH: &str = "/sysroot/.coreos-aleph-version.json"; +const ALEPH_PATH: &str = "sysroot/.coreos-aleph-version.json"; -pub(crate) fn get_aleph_version() -> Result> { - let sysroot = openat::Dir::open("/")?; - let mut path = ALEPH_PATH; - if !Path::new(ALEPH_PATH).exists() { +pub(crate) fn get_aleph_version(root: &Path) -> Result> { + let path = &root.join(ALEPH_PATH); + if !path.exists() { return Ok(None); } - let target; - let is_link = symlink_metadata(path) - .with_context(|| format!("reading metadata for {}", path))? - .file_type() - .is_symlink(); - if is_link { - target = - canonicalize(path).with_context(|| format!("getting absolute path to {}", path))?; - path = target.to_str().unwrap() - } - if let Some(statusf) = sysroot.open_file_optional(path)? { - let meta = statusf.metadata()?; - let bufr = std::io::BufReader::new(statusf); - let aleph: Aleph = serde_json::from_reader(bufr)?; - Ok(Some(AlephWithTimestamp { - aleph, - ts: meta.created()?.into(), - })) - } else { - Ok(None) - } + let statusf = File::open(path).with_context(|| format!("Opening {path:?}"))?; + let meta = statusf.metadata()?; + let bufr = std::io::BufReader::new(statusf); + let aleph: Aleph = serde_json::from_reader(bufr)?; + Ok(Some(AlephWithTimestamp { + aleph, + ts: meta.created()?.into(), + })) } #[cfg(test)] @@ -64,6 +49,49 @@ mod test { use super::*; use anyhow::Result; + const V1_ALEPH_DATA: &str = r##" + { + "version": "32.20201002.dev.2", + "ref": "fedora/x86_64/coreos/testing-devel", + "ostree-commit": "b2ea6159d6274e1bbbb49aa0ef093eda5d53a75c8a793dbe184f760ed64dc862" + }"##; + + #[test] + fn test_parse_from_root_empty() -> Result<()> { + // Verify we're a no-op in an empty root + let root: &tempfile::TempDir = &tempfile::tempdir()?; + let root = root.path(); + assert!(get_aleph_version(root).unwrap().is_none()); + Ok(()) + } + + #[test] + fn test_parse_from_root() -> Result<()> { + let root: &tempfile::TempDir = &tempfile::tempdir()?; + let root = root.path(); + let sysroot = &root.join("sysroot"); + std::fs::create_dir(sysroot).context("Creating sysroot")?; + std::fs::write(root.join(ALEPH_PATH), V1_ALEPH_DATA).context("Writing aleph")?; + let aleph = get_aleph_version(root).unwrap().unwrap(); + assert_eq!(aleph.aleph.version, "32.20201002.dev.2"); + Ok(()) + } + + #[test] + fn test_parse_from_root_linked() -> Result<()> { + let root: &tempfile::TempDir = &tempfile::tempdir()?; + let root = root.path(); + let sysroot = &root.join("sysroot"); + std::fs::create_dir(sysroot).context("Creating sysroot")?; + let target_name = ".new-ostree-aleph.json"; + let target = &sysroot.join(target_name); + std::fs::write(root.join(target), V1_ALEPH_DATA).context("Writing aleph")?; + std::os::unix::fs::symlink(target_name, root.join(ALEPH_PATH)).context("Symlinking")?; + let aleph = get_aleph_version(root).unwrap().unwrap(); + assert_eq!(aleph.aleph.version, "32.20201002.dev.2"); + Ok(()) + } + #[test] fn test_parse_old_aleph() -> Result<()> { // What the aleph file looked like before we changed it in @@ -82,13 +110,7 @@ mod test { #[test] fn test_parse_aleph() -> Result<()> { - let alephdata = r##" -{ - "version": "32.20201002.dev.2", - "ref": "fedora/x86_64/coreos/testing-devel", - "ostree-commit": "b2ea6159d6274e1bbbb49aa0ef093eda5d53a75c8a793dbe184f760ed64dc862" -}"##; - let aleph: Aleph = serde_json::from_str(alephdata)?; + let aleph: Aleph = serde_json::from_str(V1_ALEPH_DATA)?; assert_eq!(aleph.version, "32.20201002.dev.2"); Ok(()) } diff --git a/src/efi.rs b/src/efi.rs index 265999d3b..7ffe69c44 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -218,7 +218,7 @@ impl Component for Efi { return Ok(None); }; // This would be extended with support for other operating systems later - if let Some(coreos_aleph) = crate::coreos::get_aleph_version()? { + if let Some(coreos_aleph) = crate::coreos::get_aleph_version(Path::new("/"))? { let meta = ContentMetadata { timestamp: coreos_aleph.ts, version: coreos_aleph.aleph.version, From c0515c604f368867021d57485f6fe47a1fa27fa7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Dec 2023 09:53:02 -0500 Subject: [PATCH 524/641] Cargo.lock: Update * Dependabot isn't keeping up. --- Cargo.lock | 283 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 169 insertions(+), 114 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fa6e52e7..0316471bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -55,9 +55,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "block-buffer" @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "cc" @@ -126,7 +126,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -168,15 +168,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -204,9 +204,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "humantime", "is-terminal", @@ -217,30 +217,19 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fn-error-context" @@ -250,7 +239,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", ] [[package]] @@ -290,9 +279,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -313,9 +302,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -340,16 +329,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -379,20 +368,20 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -423,9 +412,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "log" @@ -435,9 +424,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -482,7 +471,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "libc", "memoffset 0.9.0", @@ -500,18 +489,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openat" @@ -540,7 +529,7 @@ version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -557,7 +546,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", ] [[package]] @@ -574,9 +563,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "pkg-config" @@ -616,9 +605,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -673,9 +662,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -685,9 +674,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -696,28 +685,28 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" @@ -736,7 +725,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", ] [[package]] @@ -752,9 +741,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -786,9 +775,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -805,14 +794,14 @@ dependencies = [ "fastrand", "redox_syscall", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -825,41 +814,41 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "uuid" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "serde", ] @@ -884,9 +873,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -894,24 +883,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -919,22 +908,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "widestring" @@ -960,9 +949,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -974,12 +963,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -988,7 +977,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -997,13 +995,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1012,38 +1025,80 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" From 90a85ec6f54cf2c280262ef7d51c81728113cc30 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 19 Dec 2023 09:53:22 -0500 Subject: [PATCH 525/641] Release 0.2.17 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0316471bf..aec486335 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.16" +version = "0.2.17" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index c6c456ef1..175c685ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.16" +version = "0.2.17" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From bc80e592d81ac9f8bf40a0731d35bf7e50c7a02c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 01:10:16 +0000 Subject: [PATCH 526/641] build(deps): bump anyhow from 1.0.75 to 1.0.76 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.75 to 1.0.76. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.75...1.0.76) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aec486335..9e8321c10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" [[package]] name = "autocfg" From e28fa828f75cc9be45bb71026028a71133537f72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 01:10:31 +0000 Subject: [PATCH 527/641] build(deps): bump openssl from 0.10.61 to 0.10.62 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.61 to 0.10.62. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.61...openssl-v0.10.62) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aec486335..5fee11e8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.61" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.97" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", From fcbedda903ad9a55caedd577adb52ac0982207c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 01:46:57 +0000 Subject: [PATCH 528/641] build(deps): bump tempfile from 3.8.1 to 3.9.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.8.1 to 3.9.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.8.1...v3.9.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59bc4c626..d6cafef7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -786,15 +786,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 175c685ca..c95ed2db9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.8" +tempfile = "^3.9" widestring = "1.0.2" [profile.release] From 61e65448a604acd3be5d13b8563c630ac3e7e2c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 01:47:06 +0000 Subject: [PATCH 529/641] build(deps): bump anyhow from 1.0.76 to 1.0.78 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.76 to 1.0.78. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.76...1.0.78) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59bc4c626..2c2626054 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" +checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" [[package]] name = "autocfg" From 7261b8110622601fc80fa507313fdee7d5b3d78c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 01:47:14 +0000 Subject: [PATCH 530/641] build(deps): bump serde_json from 1.0.108 to 1.0.109 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.108 to 1.0.109. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.108...v1.0.109) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59bc4c626..7853980c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" dependencies = [ "itoa", "ryu", From 50160da694b88bda07a43b578f028e7722dfee2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:23:22 +0000 Subject: [PATCH 531/641] build(deps): bump serde from 1.0.193 to 1.0.195 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.195. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.195) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3a301e9f..1f6e95e72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -546,7 +546,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -605,18 +605,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -710,22 +710,22 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -775,9 +775,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -829,7 +829,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -892,7 +892,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -914,7 +914,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From 40f7886a254e32697569373bbd73d482cf6f7d83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:23:35 +0000 Subject: [PATCH 532/641] build(deps): bump anyhow from 1.0.78 to 1.0.79 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.78...1.0.79) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3a301e9f..fe70db673 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "autocfg" From b61a012ccaaa2efbeeadc0f0ccd104da8ab5b5fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:23:41 +0000 Subject: [PATCH 533/641] build(deps): bump serde_json from 1.0.109 to 1.0.111 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.109 to 1.0.111. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.109...v1.0.111) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3a301e9f..1e8736f68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -546,7 +546,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -605,18 +605,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -710,29 +710,29 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.109" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -775,9 +775,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -829,7 +829,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -892,7 +892,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -914,7 +914,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] From d795d4de52abd32d1c9a72ca29fa5427746486b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 01:23:48 +0000 Subject: [PATCH 534/641] build(deps): bump libc from 0.2.151 to 0.2.152 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.151 to 0.2.152. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.151...0.2.152) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3a301e9f..e9480e4b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libsystemd" From cf93e194f5d827ae2d65d53b45e6fff7b6003dbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 01:56:56 +0000 Subject: [PATCH 535/641] build(deps): bump openssl from 0.10.62 to 0.10.63 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.62 to 0.10.63. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...openssl-v0.10.63) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f0105a6f..57047b7da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", From 99db35881f7779f7c04aa02471b2eaf9e68cdbce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 01:34:56 +0000 Subject: [PATCH 536/641] build(deps): bump serde_json from 1.0.111 to 1.0.112 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.111 to 1.0.112. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.111...v1.0.112) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57047b7da..91a572d6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" dependencies = [ "itoa", "ryu", From f7a06b40608987f5ab42550b3b9e7ab705f1aa20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:59:07 +0000 Subject: [PATCH 537/641] build(deps): bump serde from 1.0.195 to 1.0.196 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.195 to 1.0.196. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.195...v1.0.196) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57047b7da..1a7b5448b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -710,18 +710,18 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", From 3adff832938ec178ad3887b83b391d399bfb0f9e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 31 Jan 2024 11:10:06 -0500 Subject: [PATCH 538/641] ci: Add a workflow which does an install via bootc This helps effectively test e2e things like `--with-static-configs`. --- .github/workflows/ci.yml | 48 ++++++++++++++++++++++++++++++++++++++++ Makefile | 5 +++++ ci/Containerfile.c9s | 13 +++++++++++ 3 files changed, 66 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 ci/Containerfile.c9s diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..3c31ae039 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: CI + +permissions: + actions: read + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + c9s-bootc-e2e: + runs-on: ubuntu-latest + steps: + # We use docker to build because it updates to the latest, whereas right now ubuntu-latest + # has podman and buildah from ~2021 (insane!) + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - uses: actions/checkout@v3 + - name: Cache Dependencies + uses: Swatinem/rust-cache@v2 + with: + key: "build-c9s" + - name: Build and export to Docker + uses: docker/build-push-action@v5 + with: + context: . + file: ci/Containerfile.c9s + load: true + tags: localhost/bootupd:latest + - name: Copy to podman + run: sudo skopeo copy docker-daemon:localhost/bootupd:latest containers-storage:localhost/bootupd:latest + - name: bootc install + run: | + set -xeuo pipefail + sudo podman run --rm -ti --privileged -v /:/target --pid=host --security-opt label=disable \ + -v /var/lib/containers:/var/lib/containers \ + localhost/bootupd:latest bootc install to-filesystem --skip-fetch-check \ + --disable-selinux --replace=alongside /target diff --git a/Makefile b/Makefile index 2799f5e24..93edc6132 100644 --- a/Makefile +++ b/Makefile @@ -48,3 +48,8 @@ install: install-units install-grub-static: install -m 644 -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg install -m 755 -d ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static/configs.d + +bin-archive: + rm target/inst -rf + $(MAKE) install install-grub-static DESTDIR=$$(pwd)/target/inst + tar -C target/inst -c --zstd -f target/bootupd.tar.zst . diff --git a/ci/Containerfile.c9s b/ci/Containerfile.c9s new file mode 100644 index 000000000..21abae7f6 --- /dev/null +++ b/ci/Containerfile.c9s @@ -0,0 +1,13 @@ +# This container build is just a demo effectively; it shows how one might +# build bootc in a container flow, using Fedora ELN as the target. +FROM quay.io/centos/centos:stream9 as build +RUN dnf -y install dnf-utils zstd && dnf builddep -y rust-bootupd +COPY . /build +WORKDIR /build +# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/ +# We aren't using the full recommendations there, just the simple bits. +RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome make && make bin-archive && mkdir -p /out && cp target/bootupd.tar.zst /out + +FROM quay.io/centos-bootc/centos-bootc-dev:stream9 +COPY --from=build /out/bootupd.tar.zst /tmp +RUN tar -C / --zstd -xvf /tmp/bootupd.tar.zst && rm -vf /tmp/* From fa9924e4fe403c3751392c041cd98614a2cc3611 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 31 Jan 2024 10:44:00 -0500 Subject: [PATCH 539/641] model: Add tracking of our own static config versions Currently our static configs don't directly support updates. (They really should) We also have a use case around simply introspecting the state that static configs were enabled (xref https://github.com/ostreedev/ostree/pull/3150) where we want to have ostree not run grub2-mkconfig in this case. In preparation for both of these things, add tracking of our *own* version of the static configs into the metadata. In theory of course, static configs could include other components (ignition, greenboot, etc.) and we should track those too. For now this at least gets us basic metadata. --- .github/workflows/ci.yml | 2 ++ src/bootupd.rs | 2 ++ src/model.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c31ae039..dc6eb6b24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,3 +46,5 @@ jobs: -v /var/lib/containers:/var/lib/containers \ localhost/bootupd:latest bootc install to-filesystem --skip-fetch-check \ --disable-selinux --replace=alongside /target + # Verify we injected static configs + jq -re '.["static-configs"].version' /boot/bootupd-state.json diff --git a/src/bootupd.rs b/src/bootupd.rs index f5a8529d5..0835fa234 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -108,6 +108,8 @@ pub(crate) fn install( match configs.enabled_with_uuid() { Some(uuid) => { + let self_meta = crate::packagesystem::query_files("/", ["/usr/bin/bootupctl"])?; + state.static_configs = Some(self_meta); #[cfg(any( target_arch = "x86_64", target_arch = "aarch64", diff --git a/src/model.rs b/src/model.rs index 89018d025..d7b2dff63 100644 --- a/src/model.rs +++ b/src/model.rs @@ -50,6 +50,8 @@ pub(crate) struct SavedState { pub(crate) installed: BTreeMap, /// Maps a component name to an in progress update pub(crate) pending: Option>, + /// If static bootloader configs are enabled, this contains the version + pub(crate) static_configs: Option, } /// The status of an individual component. From 6b450f451d383adbf6e40cf84ef0bfcfd8d9cf95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 21:01:35 +0000 Subject: [PATCH 540/641] build(deps): bump chrono from 0.4.31 to 0.4.33 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.31 to 0.4.33. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.31...v0.4.33) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7df6af60..b6a2908d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -126,7 +126,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c95ed2db9..45253cbdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.31", features = ["serde"] } +chrono = { version = "0.4.33", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From 598360e72c28e5f7be2ecc2d061e6a877d17de44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 01:20:34 +0000 Subject: [PATCH 541/641] build(deps): bump serde_json from 1.0.112 to 1.0.113 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.112 to 1.0.113. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.112...v1.0.113) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7df6af60..126dda1c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.112" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", From ad6a1d98a36b0eec7216fa7bada33ac8b96eac73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 01:20:45 +0000 Subject: [PATCH 542/641] build(deps): bump libc from 0.2.152 to 0.2.153 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.152 to 0.2.153. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.152...0.2.153) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7df6af60..bbfed63c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libsystemd" From ef80ebbf5488f487f84722ccf25f6e8430b6670a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:13:18 +0000 Subject: [PATCH 543/641] build(deps): bump chrono from 0.4.33 to 0.4.34 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.33 to 0.4.34. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.33...v0.4.34) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616cb1e5b..bbd127993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 45253cbdc..dcb5a5e6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.33", features = ["serde"] } +chrono = { version = "0.4.34", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From d952c755bb1e8016498788b920e5aafda6cde170 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 13 Feb 2024 12:47:51 -0500 Subject: [PATCH 544/641] Release 0.2.18 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7df6af60..0bdf0f92a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.17" +version = "0.2.18" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index c95ed2db9..400d6d5ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.17" +version = "0.2.18" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 38b971647d126f9c51545553d2a55cc77ff01d08 Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Mon, 19 Feb 2024 14:33:17 -0500 Subject: [PATCH 545/641] grub2: source in a console.cfg file if exists This will allow users or distro builders place console settings here that will get picked up on boot. This was discussed as part of https://github.com/coreos/fedora-coreos-tracker/issues/1671 --- src/grub2/grub-static-pre.cfg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/grub2/grub-static-pre.cfg b/src/grub2/grub-static-pre.cfg index 7784834d6..9717cfb9d 100644 --- a/src/grub2/grub-static-pre.cfg +++ b/src/grub2/grub-static-pre.cfg @@ -38,6 +38,11 @@ elif [ -s $prefix/grubenv ]; then load_env fi +if [ -f $prefix/console.cfg ]; then + # Source in any GRUB console settings if provided by the user/platform + source $prefix/console.cfg +fi + if [ x"${feature_menuentry_id}" = xy ]; then menuentry_id_option="--id" else From c9c61b31e95734dc054eb2586cc790119af53423 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 01:29:20 +0000 Subject: [PATCH 546/641] build(deps): bump anyhow from 1.0.79 to 1.0.80 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.79 to 1.0.80. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.79...1.0.80) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09aa948df..6736b307e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "autocfg" From a16c7b72ac39a519b672eaed3e0d778f1d268894 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 01:29:33 +0000 Subject: [PATCH 547/641] build(deps): bump openssl from 0.10.63 to 0.10.64 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.63 to 0.10.64. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.63...openssl-v0.10.64) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09aa948df..c05627d2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", From 8c1e4ed5b2cc000b9cbeee790b44d02631d7b48e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 01:29:44 +0000 Subject: [PATCH 548/641] build(deps): bump serde from 1.0.196 to 1.0.197 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.196 to 1.0.197. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.196...v1.0.197) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09aa948df..ea0b2aea8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -710,18 +710,18 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", From dc1e2c651cfc549f9926d02444e746bff467cff0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 01:29:55 +0000 Subject: [PATCH 549/641] build(deps): bump serde_json from 1.0.113 to 1.0.114 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.113 to 1.0.114. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.113...v1.0.114) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09aa948df..53df8bdbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", From 0d84c4548a93564fa8ed658bf02260721017b13d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 01:23:56 +0000 Subject: [PATCH 550/641] build(deps): bump tempfile from 3.9.0 to 3.10.1 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.9.0 to 3.10.1. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.9.0...v3.10.1) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 ++++-------------- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc8e704e1..ce673d819 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,15 +651,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex" version = "1.10.2" @@ -691,9 +682,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.1", "errno", @@ -786,13 +777,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] diff --git a/Cargo.toml b/Cargo.toml index b000cb043..4ab792b0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.9" +tempfile = "^3.10" widestring = "1.0.2" [profile.release] From 735a880b8d4cb9a3d310d5411023eed80256b0e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 01:24:12 +0000 Subject: [PATCH 551/641] build(deps): bump log from 0.4.20 to 0.4.21 Bumps [log](https://github.com/rust-lang/log) from 0.4.20 to 0.4.21. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.20...0.4.21) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc8e704e1..b5cf996a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -418,9 +418,9 @@ checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" From ac8dd7974c8f23afea21c658e93850eeab2d48e3 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 14 Mar 2024 15:55:23 +0800 Subject: [PATCH 552/641] deps-update: bump chrono from 0.4.34 to 0.4.35 Xerf to https://github.com/chronotope/chrono/pull/1450 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/model.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f899219e..13d7f1a12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 4ab792b0f..723970bbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.34", features = ["serde"] } +chrono = { version = "0.4.35", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" diff --git a/src/model.rs b/src/model.rs index d7b2dff63..86b866a95 100644 --- a/src/model.rs +++ b/src/model.rs @@ -135,7 +135,7 @@ mod test { version: "v1".into(), }; let b = ContentMetadata { - timestamp: t + Duration::seconds(1), + timestamp: t + Duration::try_seconds(1).unwrap(), version: "v2".into(), }; assert!(a.can_upgrade_to(&b)); From b71c25d04aad7c7efeb1042ad7fc94ab910761cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 01:43:46 +0000 Subject: [PATCH 553/641] build(deps): bump anyhow from 1.0.80 to 1.0.81 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.80 to 1.0.81. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.80...1.0.81) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f899219e..e965ee7e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "autocfg" From fef2cb836d919d85736c7e68013470d3c3c21d0d Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Tue, 26 Mar 2024 11:07:26 +0800 Subject: [PATCH 554/641] grubconfig: handle efi vendordir better Fix https://github.com/coreos/bootupd/issues/630 --- src/efi.rs | 2 +- src/grubconfigs.rs | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 7ffe69c44..6cd077a52 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -25,7 +25,7 @@ pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi", "boot"]; /// The binary to change EFI boot ordering const EFIBOOTMGR: &str = "efibootmgr"; -const SHIM: &str = "shimx64.efi"; +pub(crate) const SHIM: &str = "shimx64.efi"; /// The ESP partition label on Fedora CoreOS derivatives pub(crate) const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM"; diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index dbf486990..38c65501a 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -1,5 +1,4 @@ use std::fmt::Write; -use std::os::unix::prelude::OsStrExt; use std::path::{Path, PathBuf}; use anyhow::{anyhow, Context, Result}; @@ -15,14 +14,19 @@ const DROPINDIR: &str = "configs.d"; pub(crate) fn find_efi_vendordir(efidir: &openat::Dir) -> Result { for d in efidir.list_dir(".")? { let d = d?; - if d.file_name().as_bytes() == b"BOOT" { - continue; - } let meta = efidir.metadata(d.file_name())?; if !meta.is_dir() { continue; } - return Ok(d.file_name().into()); + // skip if not find shim under dir + let dir = efidir.sub_dir(d.file_name())?; + for entry in dir.list_dir(".")? { + let entry = entry?; + if entry.file_name() != super::efi::SHIM { + continue; + } + return Ok(d.file_name().into()); + } } anyhow::bail!("Failed to find EFI vendor dir") } @@ -142,4 +146,30 @@ mod tests { assert!(td.exists("boot/efi/EFI/fedora/grub.cfg")?); Ok(()) } + + #[test] + fn test_find_efi_vendordir() -> Result<()> { + let td = tempfile::tempdir()?; + let tdp = td.path(); + let efidir = tdp.join("EFI"); + std::fs::create_dir_all(efidir.join("BOOT"))?; + std::fs::create_dir_all(efidir.join("dell"))?; + std::fs::create_dir_all(efidir.join("fedora"))?; + let td = openat::Dir::open(&efidir)?; + + std::fs::write(efidir.join("dell").join("foo"), "foo data")?; + std::fs::write(efidir.join("fedora").join("grub.cfg"), "grub config")?; + std::fs::write(efidir.join("fedora").join("shimx64.efi"), "shim data")?; + + assert!(td.exists("BOOT")?); + assert!(td.exists("dell/foo")?); + assert!(td.exists("fedora/grub.cfg")?); + assert!(td.exists("fedora/shimx64.efi")?); + assert_eq!(find_efi_vendordir(&td)?.to_str(), Some("fedora")); + + std::fs::remove_file(efidir.join("fedora").join("shimx64.efi"))?; + let x = find_efi_vendordir(&td); + assert_eq!(x.is_err(), true); + Ok(()) + } } From 5b8e7f11ece6dce44d991a2f90cd75b22a1f0002 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 27 Mar 2024 09:47:18 +0800 Subject: [PATCH 555/641] aa64: Minor fix for efi vendordir Minor fix for https://github.com/coreos/bootupd/pull/633 --- src/efi.rs | 6 +++++- src/grubconfigs.rs | 12 +++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/efi.rs b/src/efi.rs index 6cd077a52..a8b7d5286 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -25,6 +25,10 @@ pub(crate) const ESP_MOUNTS: &[&str] = &["boot/efi", "efi", "boot"]; /// The binary to change EFI boot ordering const EFIBOOTMGR: &str = "efibootmgr"; +#[cfg(target_arch = "aarch64")] +pub(crate) const SHIM: &str = "shimaa64.efi"; + +#[cfg(target_arch = "x86_64")] pub(crate) const SHIM: &str = "shimx64.efi"; /// The ESP partition label on Fedora CoreOS derivatives @@ -484,7 +488,7 @@ pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &st if espdir.exists(&shim)? { anyhow::bail!("Failed to find {SHIM}"); } - let loader = format!("\\EFI\\{}\\shimx64.efi", vendordir); + let loader = format!("\\EFI\\{}\\{SHIM}", vendordir); let st = Command::new(EFIBOOTMGR) .args([ "--create", diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index 38c65501a..1ba9832be 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -5,6 +5,8 @@ use anyhow::{anyhow, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; +use crate::efi::SHIM; + /// The subdirectory of /boot we use const GRUB2DIR: &str = "grub2"; const CONFIGDIR: &str = "/usr/lib/bootupd/grub2-static"; @@ -22,13 +24,13 @@ pub(crate) fn find_efi_vendordir(efidir: &openat::Dir) -> Result { let dir = efidir.sub_dir(d.file_name())?; for entry in dir.list_dir(".")? { let entry = entry?; - if entry.file_name() != super::efi::SHIM { + if entry.file_name() != SHIM { continue; } return Ok(d.file_name().into()); } } - anyhow::bail!("Failed to find EFI vendor dir") + anyhow::bail!("Failed to find EFI vendor dir that contains {SHIM}") } /// Install the static GRUB config files. @@ -159,15 +161,15 @@ mod tests { std::fs::write(efidir.join("dell").join("foo"), "foo data")?; std::fs::write(efidir.join("fedora").join("grub.cfg"), "grub config")?; - std::fs::write(efidir.join("fedora").join("shimx64.efi"), "shim data")?; + std::fs::write(efidir.join("fedora").join(SHIM), "shim data")?; assert!(td.exists("BOOT")?); assert!(td.exists("dell/foo")?); assert!(td.exists("fedora/grub.cfg")?); - assert!(td.exists("fedora/shimx64.efi")?); + assert!(td.exists(format!("fedora/{SHIM}"))?); assert_eq!(find_efi_vendordir(&td)?.to_str(), Some("fedora")); - std::fs::remove_file(efidir.join("fedora").join("shimx64.efi"))?; + std::fs::remove_file(efidir.join("fedora").join(SHIM))?; let x = find_efi_vendordir(&td); assert_eq!(x.is_err(), true); Ok(()) From 2d05e59fcad109c6011b02515cd9481c9ce7533f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:36:17 +0000 Subject: [PATCH 556/641] build(deps): bump chrono from 0.4.35 to 0.4.37 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.35 to 0.4.37. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.35...v0.4.37) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b03970935..7a0dde87c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 723970bbd..95aed0fae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.35", features = ["serde"] } +chrono = { version = "0.4.37", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From 0c33738ca645af0ac6d9676cb166344cfa6312ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:36:25 +0000 Subject: [PATCH 557/641] build(deps): bump serde_json from 1.0.114 to 1.0.115 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.114 to 1.0.115. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.114...v1.0.115) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b03970935..1551953a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", From d55eef0627615547bb7185b595355f80a768397f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 01:54:40 +0000 Subject: [PATCH 558/641] build(deps): bump widestring from 1.0.2 to 1.1.0 Bumps [widestring](https://github.com/starkat99/widestring-rs) from 1.0.2 to 1.1.0. - [Release notes](https://github.com/starkat99/widestring-rs/releases) - [Changelog](https://github.com/starkat99/widestring-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/starkat99/widestring-rs/compare/v1.0.2...v1.1.0) --- updated-dependencies: - dependency-name: widestring dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 318f0c29b..c43cf2d62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -917,9 +917,9 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index 95aed0fae..14ae881b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ openssl = "^0.10" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.10" -widestring = "1.0.2" +widestring = "1.1.0" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo From bba1ea2420523b8d90134dd20252cf38cbe2e1db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 01:52:21 +0000 Subject: [PATCH 559/641] build(deps): bump anyhow from 1.0.81 to 1.0.82 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.81 to 1.0.82. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.81...1.0.82) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c43cf2d62..9873aca4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "autocfg" From 17c5628812297f99ed3e1d4c142b56426b2f03bb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 5 May 2023 10:57:25 -0400 Subject: [PATCH 560/641] Print previous version too when updating Keep current format to avoid having to update Fedora CoreOS tests as well. Based on: https://github.com/coreos/bootupd/pull/472 Co-authored-by: Colin Walters Closes: https://github.com/coreos/bootupd/issues/445 --- src/bootupd.rs | 3 ++- tests/e2e-update/e2e-update-in-vm.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0835fa234..be218b79d 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -431,7 +431,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result continue; } ComponentUpdateResult::Updated { - previous: _, + previous, interrupted, new, } => { @@ -441,6 +441,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result i.version, ); } + println!("Previous {}: {}", name, previous.version); println!("Updated {}: {}", name, new.version); } } diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index 17919f99a..066b50cb8 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -68,6 +68,7 @@ tmpefimount=$(mount_tmp_efi) assert_not_has_file ${tmpefimount}/EFI/fedora/test-bootupd.efi bootupctl update | tee out.txt +assert_file_has_content out.txt "Previous EFI: .*" assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd-payload-1.0" assert_file_has_content ${tmpefimount}/EFI/fedora/test-bootupd.efi test-payload From 888f6e4eafe4127de7fc749e1be56db370ae5f56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:21:21 +0000 Subject: [PATCH 561/641] build(deps): bump serde_json from 1.0.115 to 1.0.116 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.115 to 1.0.116. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.115...v1.0.116) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9873aca4b..4e9e4040a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", From 3e4dee31cb880d3261156bde593f0ab73ba29b72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:21:51 +0000 Subject: [PATCH 562/641] build(deps): bump chrono from 0.4.37 to 0.4.38 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.37 to 0.4.38. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.37...v0.4.38) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9873aca4b..61cbc3895 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 14ae881b0..9651cbf77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -chrono = { version = "0.4.37", features = ["serde"] } +chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" From 713ee952e554c4560d98838d028b1b14ae7d23d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 01:12:47 +0000 Subject: [PATCH 563/641] build(deps): bump serde from 1.0.197 to 1.0.198 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.198. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.198) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61cbc3895..d0d97068a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -701,18 +701,18 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", From 0b84c8d963aea300d3f034de0eee55ac8a1e33f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:28:43 +0000 Subject: [PATCH 564/641] build(deps): bump serde from 1.0.198 to 1.0.199 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.198 to 1.0.199. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.198...v1.0.199) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index beb14aa36..f783120b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -701,18 +701,18 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", From e5457c59c30c62473ea3d46d93444bf14f0a41a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 01:29:27 +0000 Subject: [PATCH 565/641] build(deps): bump libc from 0.2.153 to 0.2.154 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.153 to 0.2.154. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.153...0.2.154) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f783120b1..ed0507bac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libsystemd" From d8bc074f2b30b79c085e4c0040b7f55c4def5225 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 01:29:52 +0000 Subject: [PATCH 566/641] build(deps): bump serde from 1.0.199 to 1.0.200 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.199 to 1.0.200. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.199...v1.0.200) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f783120b1..7928553f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -701,18 +701,18 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "serde" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", From 3cd21cfe760c9e7633ee8c13232af33d9b43a0a9 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Mon, 6 May 2024 15:55:59 +0800 Subject: [PATCH 567/641] Add `get_efi_vendor` method to both the bios and efi backends See Colin's comment https://github.com/coreos/bootupd/pull/646#issuecomment-2089226909 --- Cargo.lock | 20 ++++++++++ Cargo.toml | 1 + src/bios.rs | 4 ++ src/bootupd.rs | 9 +++-- src/component.rs | 42 ++++++++++++++++++++ src/efi.rs | 53 +++++++++++++++++++++---- src/grubconfigs.rs | 98 ++++++++++++---------------------------------- 7 files changed, 143 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df0b26f1c..fe1758caf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,7 @@ dependencies = [ "serde", "serde_json", "tempfile", + "walkdir", "widestring", ] @@ -699,6 +700,15 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.200" @@ -855,6 +865,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 9651cbf77..d92820f31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.10" widestring = "1.1.0" +walkdir = "2.3.2" [profile.release] # We assume we're being delivered via e.g. RPM which supports split debuginfo diff --git a/src/bios.rs b/src/bios.rs index 9f2546e90..a3fb23fc1 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -155,4 +155,8 @@ impl Component for Bios { fn validate(&self, _: &InstalledContent) -> Result { Ok(ValidationResult::Skip) } + + fn get_efi_vendor(&self, _: &openat::Dir) -> Result> { + Ok(None) + } } diff --git a/src/bootupd.rs b/src/bootupd.rs index be218b79d..d0eef93c3 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -83,7 +83,7 @@ pub(crate) fn install( } let mut state = SavedState::default(); - let mut installed_efi = false; + let mut installed_efi_vendor = None; for &component in target_components.iter() { // skip for BIOS if device is empty if component.name() == "BIOS" && device.is_empty() { @@ -100,8 +100,9 @@ pub(crate) fn install( log::info!("Installed {} {}", component.name(), meta.meta.version); state.installed.insert(component.name().into(), meta); // Yes this is a hack...the Component thing just turns out to be too generic. - if component.name() == "EFI" { - installed_efi = true; + if let Some(vendor) = component.get_efi_vendor(&source_root)? { + assert!(installed_efi_vendor.is_none()); + installed_efi_vendor = Some(vendor); } } let sysroot = &openat::Dir::open(dest_root)?; @@ -115,7 +116,7 @@ pub(crate) fn install( target_arch = "aarch64", target_arch = "powerpc64" ))] - crate::grubconfigs::install(sysroot, installed_efi, uuid)?; + crate::grubconfigs::install(sysroot, installed_efi_vendor.as_deref(), uuid)?; // On other architectures, assume that there's nothing to do. } None => {} diff --git a/src/component.rs b/src/component.rs index dc1c6068a..65be68d15 100644 --- a/src/component.rs +++ b/src/component.rs @@ -72,6 +72,9 @@ pub(crate) trait Component { /// Used on the client to validate an installed version. fn validate(&self, current: &InstalledContent) -> Result; + + /// Locating efi vendor dir + fn get_efi_vendor(&self, sysroot: &openat::Dir) -> Result>; } /// Given a component name, create an implementation. @@ -140,3 +143,42 @@ pub(crate) fn get_component_update( Ok(None) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_efi_vendor() -> Result<()> { + let td = tempfile::tempdir()?; + let tdp = td.path(); + let tdp_updates = tdp.join("usr/lib/bootupd/updates"); + let td = openat::Dir::open(tdp)?; + std::fs::create_dir_all(tdp_updates.join("EFI/BOOT"))?; + std::fs::create_dir_all(tdp_updates.join("EFI/fedora"))?; + std::fs::create_dir_all(tdp_updates.join("EFI/centos"))?; + std::fs::write( + tdp_updates.join("EFI/fedora").join(crate::efi::SHIM), + "shim data", + )?; + std::fs::write( + tdp_updates.join("EFI/centos").join(crate::efi::SHIM), + "shim data", + )?; + + let all_components = crate::bootupd::get_components(); + let target_components: Vec<_> = all_components.values().collect(); + for &component in target_components.iter() { + if component.name() == "BIOS" { + assert_eq!(component.get_efi_vendor(&td)?, None); + } + if component.name() == "EFI" { + let x = component.get_efi_vendor(&td); + assert_eq!(x.is_err(), true); + std::fs::remove_dir_all(tdp_updates.join("EFI/centos"))?; + assert_eq!(component.get_efi_vendor(&td)?, Some("fedora".to_string())); + } + } + Ok(()) + } +} diff --git a/src/efi.rs b/src/efi.rs index a8b7d5286..e621726a0 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -12,6 +12,7 @@ use std::process::Command; use anyhow::{bail, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; +use walkdir::WalkDir; use widestring::U16CString; use crate::filetree; @@ -131,16 +132,11 @@ impl Efi { } #[context("Updating EFI firmware variables")] - fn update_firmware(&self, device: &str, espdir: &openat::Dir) -> Result<()> { + fn update_firmware(&self, device: &str, espdir: &openat::Dir, vendordir: &str) -> Result<()> { if !is_efi_booted()? { log::debug!("Not booted via EFI, skipping firmware update"); return Ok(()); } - let efidir = &espdir.sub_dir("EFI").context("Opening EFI")?; - let vendordir = super::grubconfigs::find_efi_vendordir(efidir)?; - let vendordir = vendordir - .to_str() - .ok_or_else(|| anyhow::anyhow!("Invalid non-UTF-8 vendordir"))?; clear_efi_current()?; set_efi_current(device, espdir, vendordir) } @@ -319,7 +315,9 @@ impl Component for Efi { anyhow::bail!("Failed to copy"); } if update_firmware { - self.update_firmware(device, destd)? + if let Some(vendordir) = self.get_efi_vendor(&src_root)? { + self.update_firmware(device, destd, &vendordir)? + } } Ok(InstalledContent { meta, @@ -417,6 +415,28 @@ impl Component for Efi { Ok(ValidationResult::Valid) } } + + fn get_efi_vendor(&self, sysroot: &openat::Dir) -> Result> { + let updated = sysroot + .sub_dir(&component_updatedirname(self)) + .context("opening update dir")?; + let shim_files = find_file_recursive(updated.recover_path()?, SHIM)?; + + // Does not support multiple shim for efi + if shim_files.len() > 1 { + anyhow::bail!("Found multiple {SHIM} in the image"); + } + if let Some(p) = shim_files.first() { + let p = p + .parent() + .unwrap() + .file_name() + .ok_or_else(|| anyhow::anyhow!("No file name found"))?; + Ok(Some(p.to_string_lossy().into_owned())) + } else { + anyhow::bail!("Failed to find {SHIM} in the image") + } + } } impl Drop for Efi { @@ -507,3 +527,22 @@ pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &st } anyhow::Ok(()) } + +#[context("Find target file recursively")] +fn find_file_recursive>(dir: P, target_file: &str) -> Result> { + let mut result = Vec::new(); + + for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { + if entry.file_type().is_file() { + if let Some(file_name) = entry.file_name().to_str() { + if file_name == target_file { + if let Some(path) = entry.path().to_str() { + result.push(path.into()); + } + } + } + } + } + + Ok(result) +} diff --git a/src/grubconfigs.rs b/src/grubconfigs.rs index 1ba9832be..09aeebfb3 100644 --- a/src/grubconfigs.rs +++ b/src/grubconfigs.rs @@ -5,37 +5,18 @@ use anyhow::{anyhow, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; -use crate::efi::SHIM; - /// The subdirectory of /boot we use const GRUB2DIR: &str = "grub2"; const CONFIGDIR: &str = "/usr/lib/bootupd/grub2-static"; const DROPINDIR: &str = "configs.d"; -#[context("Locating EFI vendordir")] -pub(crate) fn find_efi_vendordir(efidir: &openat::Dir) -> Result { - for d in efidir.list_dir(".")? { - let d = d?; - let meta = efidir.metadata(d.file_name())?; - if !meta.is_dir() { - continue; - } - // skip if not find shim under dir - let dir = efidir.sub_dir(d.file_name())?; - for entry in dir.list_dir(".")? { - let entry = entry?; - if entry.file_name() != SHIM { - continue; - } - return Ok(d.file_name().into()); - } - } - anyhow::bail!("Failed to find EFI vendor dir that contains {SHIM}") -} - /// Install the static GRUB config files. #[context("Installing static GRUB configs")] -pub(crate) fn install(target_root: &openat::Dir, efi: bool, write_uuid: bool) -> Result<()> { +pub(crate) fn install( + target_root: &openat::Dir, + installed_efi_vendor: Option<&str>, + write_uuid: bool, +) -> Result<()> { let bootdir = &target_root.sub_dir("boot").context("Opening /boot")?; let boot_is_mount = { let root_dev = target_root.self_metadata()?.stat().st_dev; @@ -99,29 +80,26 @@ pub(crate) fn install(target_root: &openat::Dir, efi: bool, write_uuid: bool) -> None }; - let efidir = efi - .then(|| { - target_root - .sub_dir_optional("boot/efi/EFI") - .context("Opening /boot/efi/EFI") - }) - .transpose()? - .flatten(); - if let Some(efidir) = efidir.as_ref() { - let vendordir = find_efi_vendordir(efidir)?; + if let Some(vendordir) = installed_efi_vendor { log::debug!("vendordir={:?}", &vendordir); - let target = &vendordir.join("grub.cfg"); - efidir - .copy_file(&Path::new(CONFIGDIR).join("grub-static-efi.cfg"), target) - .context("Copying static EFI")?; - println!("Installed: {target:?}"); - if let Some(uuid_path) = uuid_path { - // SAFETY: we always have a filename - let filename = Path::new(&uuid_path).file_name().unwrap(); - let target = &vendordir.join(filename); - bootdir - .copy_file_at(uuid_path, efidir, target) - .context("Writing bootuuid.cfg to efi dir")?; + let vendor = PathBuf::from(vendordir); + let target = &vendor.join("grub.cfg"); + let dest_efidir = target_root + .sub_dir_optional("boot/efi/EFI") + .context("Opening /boot/efi/EFI")?; + if let Some(efidir) = dest_efidir { + efidir + .copy_file(&Path::new(CONFIGDIR).join("grub-static-efi.cfg"), target) + .context("Copying static EFI")?; + println!("Installed: {target:?}"); + if let Some(uuid_path) = uuid_path { + // SAFETY: we always have a filename + let filename = Path::new(&uuid_path).file_name().unwrap(); + let target = &vendor.join(filename); + bootdir + .copy_file_at(uuid_path, &efidir, target) + .context("Writing bootuuid.cfg to efi dir")?; + } } } @@ -142,36 +120,10 @@ mod tests { std::fs::create_dir_all(tdp.join("boot/grub2"))?; std::fs::create_dir_all(tdp.join("boot/efi/EFI/BOOT"))?; std::fs::create_dir_all(tdp.join("boot/efi/EFI/fedora"))?; - install(&td, true, false).unwrap(); + install(&td, Some("fedora"), false).unwrap(); assert!(td.exists("boot/grub2/grub.cfg")?); assert!(td.exists("boot/efi/EFI/fedora/grub.cfg")?); Ok(()) } - - #[test] - fn test_find_efi_vendordir() -> Result<()> { - let td = tempfile::tempdir()?; - let tdp = td.path(); - let efidir = tdp.join("EFI"); - std::fs::create_dir_all(efidir.join("BOOT"))?; - std::fs::create_dir_all(efidir.join("dell"))?; - std::fs::create_dir_all(efidir.join("fedora"))?; - let td = openat::Dir::open(&efidir)?; - - std::fs::write(efidir.join("dell").join("foo"), "foo data")?; - std::fs::write(efidir.join("fedora").join("grub.cfg"), "grub config")?; - std::fs::write(efidir.join("fedora").join(SHIM), "shim data")?; - - assert!(td.exists("BOOT")?); - assert!(td.exists("dell/foo")?); - assert!(td.exists("fedora/grub.cfg")?); - assert!(td.exists(format!("fedora/{SHIM}"))?); - assert_eq!(find_efi_vendordir(&td)?.to_str(), Some("fedora")); - - std::fs::remove_file(efidir.join("fedora").join(SHIM))?; - let x = find_efi_vendordir(&td); - assert_eq!(x.is_err(), true); - Ok(()) - } } From f7c70f77d0d7fdc973e6bd88caf644aa35b6f46f Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 8 May 2024 19:36:31 +0800 Subject: [PATCH 568/641] ci: add `bootc install to-disk` test in c9s-bootc-e2e --- .github/workflows/ci.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc6eb6b24..0e6111914 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,23 @@ jobs: tags: localhost/bootupd:latest - name: Copy to podman run: sudo skopeo copy docker-daemon:localhost/bootupd:latest containers-storage:localhost/bootupd:latest - - name: bootc install + - name: bootc install to disk + run: | + set -xeuo pipefail + sudo truncate -s 10G myimage.raw + sudo podman run --rm -ti --privileged -v .:/target --pid=host --security-opt label=disable \ + -v /var/lib/containers:/var/lib/containers \ + -v /dev:/dev \ + localhost/bootupd:latest bootc install to-disk --skip-fetch-check \ + --disable-selinux --generic-image --via-loopback /target/myimage.raw + # Verify we installed grub.cfg and shim on the disk + sudo losetup -P -f myimage.raw + device=$(losetup --list --noheadings --output NAME,BACK-FILE | grep myimage.raw | awk '{print $1}') + sudo mount "${device}p2" /mnt/ + sudo ls /mnt/EFI/centos/{grub.cfg,shimx64.efi} + sudo losetup -D "${device}" + sudo rm -f myimage.raw + - name: bootc install to filesystem run: | set -xeuo pipefail sudo podman run --rm -ti --privileged -v /:/target --pid=host --security-opt label=disable \ From ecfb18dc1dc199b0357e593f5350bfd18262355f Mon Sep 17 00:00:00 2001 From: Joseph Marrero Date: Wed, 8 May 2024 15:05:02 -0400 Subject: [PATCH 569/641] Release 0.2.19 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe1758caf..3bdad9988 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.18" +version = "0.2.19" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index d92820f31..c03a04d37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.18" +version = "0.2.19" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 104c9ff90412753d9ef6c462ce2c59a601845dae Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 16 May 2024 10:32:13 +0800 Subject: [PATCH 570/641] ci: fix failed log --- ci/Containerfile.c9s | 2 +- tests/e2e-update/e2e-update-in-vm.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/Containerfile.c9s b/ci/Containerfile.c9s index 21abae7f6..c1b2f035e 100644 --- a/ci/Containerfile.c9s +++ b/ci/Containerfile.c9s @@ -10,4 +10,4 @@ RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/rooth FROM quay.io/centos-bootc/centos-bootc-dev:stream9 COPY --from=build /out/bootupd.tar.zst /tmp -RUN tar -C / --zstd -xvf /tmp/bootupd.tar.zst && rm -vf /tmp/* +RUN tar -C / --zstd -xvf /tmp/bootupd.tar.zst && rm -rvf /tmp/* diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index 066b50cb8..fd969cad7 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -59,7 +59,7 @@ assert_not_file_has_content out.txt ' Installed:.*'"${TARGET_GRUB_PKG}" assert_file_has_content out.txt 'Update: Available:.*'"${TARGET_GRUB_PKG}" assert_file_has_content out.txt 'Update: Available:.*test-bootupd-payload-1.0' bootupctl status --print-if-available > out.txt -assert_file_has_content_literal 'out.txt' 'Updates available: EFI' +assert_file_has_content_literal 'out.txt' 'Updates available: BIOS EFI' ok update avail # Mount the EFI partition. From bbf0ae93fda21a18d76e27f5c1aecfbf61f5bf67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 13:06:25 +0000 Subject: [PATCH 571/641] build(deps): bump libc from 0.2.154 to 0.2.155 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.154 to 0.2.155. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.154...0.2.155) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bdad9988..fd41aed97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,9 +389,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libsystemd" From 43e3e8ee6aa0b20003ff40cec87be7fe24fce6ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:52:16 +0000 Subject: [PATCH 572/641] build(deps): bump serde from 1.0.200 to 1.0.203 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.200 to 1.0.203. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.200...v1.0.203) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bdad9988..fe3ddbb8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -711,18 +711,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", From f8eb25558446b8265ac413b21163eebf09fd2021 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 08:07:51 +0000 Subject: [PATCH 573/641] build(deps): bump anyhow from 1.0.82 to 1.0.86 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.82 to 1.0.86. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.82...1.0.86) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53e16ff83..412187a1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "autocfg" From 31d7b59c382261f0cc60966cb1c7139ca7e948e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 09:43:12 +0000 Subject: [PATCH 574/641] build(deps): bump serde_json from 1.0.116 to 1.0.117 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.116...v1.0.117) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53e16ff83..c50aa341f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -731,9 +731,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", From 261fb5e7f28b9bd2c6099fd2d484f158adffb221 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Tue, 21 May 2024 22:09:08 +0800 Subject: [PATCH 575/641] Drop systemd service Fixes https://github.com/coreos/bootupd/issues/551 Get hints by https://github.com/coreos/bootupd/issues/551#issuecomment-2124477922, and copy the comment here: Basically we detect if we're running in systemd; if we're not, we re-exec ourselves via systemd-run. Then we can just directly run code in what is now the daemon. I think an important aspect of this is that we retain something like `--unit bootupd` which acts as a lock - only one unit with that name can run at a time to avoid two concurrent invocations breaking things. --- .github/workflows/ci.yml | 1 + Makefile | 12 +-- contrib/packaging/bootupd.spec | 9 -- src/bootupd.rs | 43 +++------ src/cli/bootupctl.rs | 79 ++++++++++----- src/cli/bootupd.rs | 3 - src/cli/mod.rs | 12 ++- src/daemon/mod.rs | 130 ------------------------- src/ipc.rs | 169 --------------------------------- src/main.rs | 2 - systemd/bootupd.service | 26 ----- systemd/bootupd.socket | 6 -- tests/e2e-update/e2e-update.sh | 3 +- tests/kola/test-bootupd | 7 +- 14 files changed, 79 insertions(+), 423 deletions(-) delete mode 100644 src/daemon/mod.rs delete mode 100644 src/ipc.rs delete mode 100644 systemd/bootupd.service delete mode 100644 systemd/bootupd.socket diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e6111914..3698ff1f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,7 @@ jobs: device=$(losetup --list --noheadings --output NAME,BACK-FILE | grep myimage.raw | awk '{print $1}') sudo mount "${device}p2" /mnt/ sudo ls /mnt/EFI/centos/{grub.cfg,shimx64.efi} + sudo umount /mnt sudo losetup -D "${device}" sudo rm -f myimage.raw - name: bootc install to filesystem diff --git a/Makefile b/Makefile index 93edc6132..f5292a4cb 100644 --- a/Makefile +++ b/Makefile @@ -18,10 +18,8 @@ ifeq ($(CONTAINER_RUNTIME), podman) IMAGE_PREFIX = localhost/ endif -units = $(addprefix systemd/, bootupd.service bootupd.socket) - .PHONY: all -all: $(units) +all: cargo build ${CARGO_ARGS} ln -f target/${PROFILE}/bootupd target/${PROFILE}/bootupctl @@ -33,17 +31,11 @@ create-build-container: build-in-container: create-build-container ${CONTAINER_RUNTIME} run -ti --rm -v .:/srv/bootupd:z ${IMAGE_PREFIX}${IMAGE_NAME} make -.PHONY: install-units -install-units: $(units) - for unit in $(units); do install -D -m 644 --target-directory=$(DESTDIR)$(PREFIX)/lib/systemd/system/ $$unit; done - .PHONY: install -install: install-units +install: mkdir -p "${DESTDIR}$(PREFIX)/bin" "${DESTDIR}$(LIBEXECDIR)" install -D -t "${DESTDIR}$(LIBEXECDIR)" target/${PROFILE}/bootupd ln -f ${DESTDIR}$(LIBEXECDIR)/bootupd ${DESTDIR}$(PREFIX)/bin/bootupctl - install -d "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" - ln -s ../bootupd.socket "${DESTDIR}$(PREFIX)/lib/systemd/system/multi-user.target.wants" install-grub-static: install -m 644 -D -t ${DESTDIR}$(PREFIX)/lib/bootupd/grub2-static src/grub2/*.cfg diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec index 056658f34..91da18f10 100644 --- a/contrib/packaging/bootupd.spec +++ b/contrib/packaging/bootupd.spec @@ -52,15 +52,6 @@ cargo build --release %make_install INSTALL="install -p -c" make install-grub-static DESTDIR=%{?buildroot} INSTALL="%{__install} -p" -%post -n %{crate} -%systemd_post bootupd.service bootupd.socket - -%preun -n %{crate} -%systemd_preun bootupd.service bootupd.socket - -%postun -n %{crate} -%systemd_postun bootupd.service bootupd.socket - %changelog * Tue Oct 18 2022 Colin Walters - 0.2.8-3 - Dummy changelog \ No newline at end of file diff --git a/src/bootupd.rs b/src/bootupd.rs index d0eef93c3..72d025d03 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -1,31 +1,18 @@ #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] use crate::bios; +use crate::component; use crate::component::{Component, ValidationResult}; use crate::coreos; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use crate::efi; use crate::model::{ComponentStatus, ComponentUpdatable, ContentMetadata, SavedState, Status}; use crate::util; -use crate::{component, ipc}; use anyhow::{anyhow, Context, Result}; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::collections::BTreeMap; use std::path::Path; -/// A message sent from client to server -#[derive(Debug, Serialize, Deserialize)] -pub(crate) enum ClientRequest { - /// Update a component - Update { component: String }, - /// Update a component via adoption - AdoptAndUpdate { component: String }, - /// Validate a component - Validate { component: String }, - /// Print the current state - Status, -} - pub(crate) enum ConfigMode { None, Static, @@ -408,8 +395,8 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { Ok(()) } -pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { - let status: Status = c.send(&ClientRequest::Status)?; +pub(crate) fn client_run_update() -> Result<()> { + let status: Status = status()?; if status.components.is_empty() && status.adoptable.is_empty() { println!("No components installed."); return Ok(()); @@ -420,9 +407,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result ComponentUpdatable::Upgradable => {} _ => continue, }; - match c.send(&ClientRequest::Update { - component: name.to_string(), - })? { + match update(name)? { ComponentUpdateResult::AtLatestVersion => { // Shouldn't happen unless we raced with another client eprintln!( @@ -450,9 +435,7 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result } for (name, adoptable) in status.adoptable.iter() { if adoptable.confident { - let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate { - component: name.to_string(), - })?; + let r: ContentMetadata = adopt_and_update(name)?; println!("Adopted and updated: {}: {}", name, r.version); updated = true; } else { @@ -465,32 +448,28 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result Ok(()) } -pub(crate) fn client_run_adopt_and_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { - let status: Status = c.send(&ClientRequest::Status)?; +pub(crate) fn client_run_adopt_and_update() -> Result<()> { + let status: Status = status()?; if status.adoptable.is_empty() { println!("No components are adoptable."); } else { for (name, _) in status.adoptable.iter() { - let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate { - component: name.to_string(), - })?; + let r: ContentMetadata = adopt_and_update(name)?; println!("Adopted and updated: {}: {}", name, r.version); } } Ok(()) } -pub(crate) fn client_run_validate(c: &mut ipc::ClientToDaemonConnection) -> Result<()> { - let status: Status = c.send(&ClientRequest::Status)?; +pub(crate) fn client_run_validate() -> Result<()> { + let status: Status = status()?; if status.components.is_empty() { println!("No components installed."); return Ok(()); } let mut caught_validation_error = false; for (name, _) in status.components.iter() { - match c.send(&ClientRequest::Validate { - component: name.to_string(), - })? { + match validate(name)? { ValidationResult::Valid => { println!("Validated: {}", name); } diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 3883a7a72..e8150b1e4 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -1,10 +1,23 @@ use crate::bootupd; -use crate::ipc::ClientToDaemonConnection; -use crate::model::Status; use anyhow::Result; use clap::Parser; use log::LevelFilter; +use std::os::unix::process::CommandExt; +use std::process::Command; + +static SYSTEMD_ARGS_BOOTUPD: &[&str] = &[ + "--unit", + "bootupd", + "--property", + "PrivateNetwork=yes", + "--property", + "ProtectHome=yes", + "--property", + "MountFlags=slave", + "--pipe", +]; + /// `bootupctl` sub-commands. #[derive(Debug, Parser)] #[clap(name = "bootupctl", about = "Bootupd client application", version)] @@ -87,10 +100,8 @@ impl CtlCommand { /// Runner for `status` verb. fn run_status(opts: StatusOpts) -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - - let r: Status = client.send(&bootupd::ClientRequest::Status)?; + ensure_running_in_systemd()?; + let r = bootupd::status()?; if opts.json { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); @@ -101,38 +112,54 @@ impl CtlCommand { bootupd::print_status(&r)?; } - client.shutdown()?; Ok(()) } /// Runner for `update` verb. fn run_update() -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - - bootupd::client_run_update(&mut client)?; - - client.shutdown()?; - Ok(()) + ensure_running_in_systemd()?; + bootupd::client_run_update() } /// Runner for `update` verb. fn run_adopt_and_update() -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - - bootupd::client_run_adopt_and_update(&mut client)?; - - client.shutdown()?; - Ok(()) + ensure_running_in_systemd()?; + bootupd::client_run_adopt_and_update() } /// Runner for `validate` verb. fn run_validate() -> Result<()> { - let mut client = ClientToDaemonConnection::new(); - client.connect()?; - bootupd::client_run_validate(&mut client)?; - client.shutdown()?; - Ok(()) + ensure_running_in_systemd()?; + bootupd::client_run_validate() + } +} + +/// Checks if the current process is (apparently at least) +/// running under systemd. +fn running_in_systemd() -> bool { + std::env::var_os("INVOCATION_ID").is_some() +} + +/// Require root permission +fn require_root_permission() -> Result<()> { + if !nix::unistd::Uid::effective().is_root() { + anyhow::bail!("This command requires root privileges") + } + Ok(()) +} + +/// Detect if we're running in systemd; if we're not, we re-exec ourselves via +/// systemd-run. Then we can just directly run code in what is now the daemon. +fn ensure_running_in_systemd() -> Result<()> { + require_root_permission()?; + let running_in_systemd = running_in_systemd(); + if !running_in_systemd { + let r = Command::new("systemd-run") + .args(SYSTEMD_ARGS_BOOTUPD) + .args(std::env::args()) + .exec(); + // If we got here, it's always an error + return Err(r.into()); } + Ok(()) } diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index d22337613..4a6b8cf19 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -31,8 +31,6 @@ impl DCommand { /// CLI sub-commands. #[derive(Debug, Parser)] pub enum DVerb { - #[clap(name = "daemon", about = "Run service logic")] - Daemon, #[clap(name = "generate-update-metadata", about = "Generate metadata")] GenerateUpdateMetadata(GenerateOpts), #[clap(name = "install", about = "Install components")] @@ -88,7 +86,6 @@ impl DCommand { /// Run CLI application. pub fn run(self) -> Result<()> { match self.cmd { - DVerb::Daemon => crate::daemon::run(), DVerb::Install(opts) => Self::run_install(opts), DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts), } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index c89c86615..98d45c0c6 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -62,7 +62,10 @@ mod tests { #[test] fn test_multicall_dispatch() { { - let d_argv = vec!["/usr/bin/bootupd".to_string(), "daemon".to_string()]; + let d_argv = vec![ + "/usr/bin/bootupd".to_string(), + "generate-update-metadata".to_string(), + ]; let cli = MultiCall::from_args(d_argv); match cli { MultiCall::Ctl(cmd) => panic!("{:?}", cmd), @@ -89,12 +92,15 @@ mod tests { #[test] fn test_verbosity() { - let default = MultiCall::from_args(vec!["bootupd".to_string(), "daemon".to_string()]); + let default = MultiCall::from_args(vec![ + "bootupd".to_string(), + "generate-update-metadata".to_string(), + ]); assert_eq!(default.loglevel(), LevelFilter::Warn); let info = MultiCall::from_args(vec![ "bootupd".to_string(), - "daemon".to_string(), + "generate-update-metadata".to_string(), "-v".to_string(), ]); assert_eq!(info.loglevel(), LevelFilter::Info); diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs deleted file mode 100644 index b83ba74fd..000000000 --- a/src/daemon/mod.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! Daemon logic. - -use crate::component::ValidationResult; -use crate::model::Status; -use crate::{bootupd, ipc}; -use anyhow::{bail, Context, Result}; -use nix::sys::socket as nixsocket; -use std::os::unix::io::RawFd; - -/// Accept a single client and then exit; we don't want to -/// persistently run as a daemon. The systemd unit is mostly -/// and implementation detail - it lets us use things like -/// systemd's built in sandboxing (ProtectHome=yes) etc. and also -/// ensures that only a single bootupd instance is running at -/// a time (i.e. don't support concurrent updates). -pub fn run() -> Result<()> { - let srvsock_fd = systemd_activation().context("systemd service activation error")?; - - // Accept an incoming client. - let client = match accept_authenticate_client(srvsock_fd) { - Ok(auth_client) => auth_client, - Err(e) => { - log::error!("failed to authenticate client: {}", e); - return Ok(()); - } - }; - - // Process all requests from this client. - if let Err(e) = process_client_requests(client) { - log::error!("failed to process request from client: {}", e); - } - - // Sleep for a half second to avoid triggering systemd service - // restart limits. - std::thread::sleep(std::time::Duration::from_secs_f32(0.5)); - - Ok(()) -} - -/// Perform initialization steps required by systemd service activation. -/// -/// This ensures that the system is running under systemd, then receives the -/// socket-FD for main IPC logic, and notifies systemd about ready-state. -fn systemd_activation() -> Result { - use libsystemd::daemon::{self, NotifyState}; - use std::os::unix::io::IntoRawFd; - - if !daemon::booted() { - bail!("daemon is not running as a systemd service"); - } - - let srvsock_fd = { - let mut fds = libsystemd::activation::receive_descriptors(true) - .map_err(|e| anyhow::anyhow!("failed to receive file-descriptors: {}", e))?; - let srvsock_fd = if let Some(fd) = fds.pop() { - fd - } else { - bail!("no socket-fd received on service activation"); - }; - srvsock_fd.into_raw_fd() - }; - - let sent = daemon::notify(true, &[NotifyState::Ready]) - .map_err(|e| anyhow::anyhow!("failed to notify ready-state: {}", e))?; - if !sent { - log::warn!("failed to notify ready-state: service notifications not supported"); - } - - Ok(srvsock_fd) -} - -/// Accept an incoming connection, then authenticate the client. -fn accept_authenticate_client(srvsock_fd: RawFd) -> Result { - let accepted = nixsocket::accept4(srvsock_fd, nixsocket::SockFlag::SOCK_CLOEXEC)?; - let client = ipc::UnauthenticatedClient::new(accepted); - - let authed = client.authenticate()?; - - Ok(authed) -} - -/// Process all requests from a given client. -/// -/// This sequentially processes all requests from a client, until it -/// disconnects or a connection error is encountered. -fn process_client_requests(client: ipc::AuthenticatedClient) -> Result<()> { - use crate::bootupd::ClientRequest; - - let mut buf = [0u8; ipc::MSGSIZE]; - loop { - let n = nixsocket::recv(client.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; - let buf = &buf[0..n]; - if buf.is_empty() { - log::trace!("client disconnected"); - break; - } - - let msg = bincode::deserialize(buf)?; - log::trace!("processing request: {:?}", &msg); - let r = match msg { - ClientRequest::Update { component } => { - bincode::serialize(&match bootupd::update(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - ClientRequest::AdoptAndUpdate { component } => { - bincode::serialize(&match bootupd::adopt_and_update(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - ClientRequest::Validate { component } => { - bincode::serialize(&match bootupd::validate(component.as_str()) { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })? - } - ClientRequest::Status => bincode::serialize(&match bootupd::status() { - Ok(v) => ipc::DaemonToClientReply::Success::(v), - Err(e) => ipc::DaemonToClientReply::Failure(format!("{:#}", e)), - })?, - }; - let written = nixsocket::send(client.fd, &r, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC)?; - if written != r.len() { - bail!("wrote {} bytes to client, expected {}", written, r.len()); - } - } - Ok(()) -} diff --git a/src/ipc.rs b/src/ipc.rs deleted file mode 100644 index c57b0caa0..000000000 --- a/src/ipc.rs +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -use anyhow::{bail, Context, Result}; -use fn_error_context::context; -use nix::sys::socket as nixsocket; -use serde::{Deserialize, Serialize}; -use std::os::unix::io::RawFd; - -pub(crate) const BOOTUPD_SOCKET: &str = "/run/bootupd.sock"; -pub(crate) const MSGSIZE: usize = 1_048_576; -/// Sent between processes along with SCM credentials -pub(crate) const BOOTUPD_HELLO_MSG: &str = "bootupd-hello\n"; - -#[derive(Debug, Serialize, Deserialize)] -pub(crate) enum DaemonToClientReply { - Success(T), - Failure(String), -} - -pub(crate) struct ClientToDaemonConnection { - fd: i32, -} - -impl Drop for ClientToDaemonConnection { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} - -impl ClientToDaemonConnection { - pub(crate) fn new() -> Self { - Self { fd: -1 } - } - - #[context("connecting to {}", BOOTUPD_SOCKET)] - pub(crate) fn connect(&mut self) -> Result<()> { - use nix::sys::uio::IoVec; - self.fd = nixsocket::socket( - nixsocket::AddressFamily::Unix, - nixsocket::SockType::SeqPacket, - nixsocket::SockFlag::SOCK_CLOEXEC, - None, - )?; - let addr = nixsocket::SockAddr::new_unix(BOOTUPD_SOCKET)?; - nixsocket::connect(self.fd, &addr)?; - let creds = libc::ucred { - pid: nix::unistd::getpid().as_raw(), - uid: nix::unistd::getuid().as_raw(), - gid: nix::unistd::getgid().as_raw(), - }; - let creds = nixsocket::UnixCredentials::from(creds); - let creds = nixsocket::ControlMessage::ScmCredentials(&creds); - let _ = nixsocket::sendmsg( - self.fd, - &[IoVec::from_slice(BOOTUPD_HELLO_MSG.as_bytes())], - &[creds], - nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, - None, - )?; - Ok(()) - } - - pub(crate) fn send( - &mut self, - msg: &S, - ) -> Result { - { - let serialized = bincode::serialize(msg)?; - let _ = nixsocket::send(self.fd, &serialized, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) - .context("client sending request")?; - } - let reply: DaemonToClientReply = { - let mut buf = [0u8; MSGSIZE]; - let n = nixsocket::recv(self.fd, &mut buf, nixsocket::MsgFlags::MSG_CMSG_CLOEXEC) - .context("client recv")?; - let buf = &buf[0..n]; - if buf.is_empty() { - bail!("Server sent an empty reply"); - } - bincode::deserialize(buf).context("client parsing reply")? - }; - match reply { - DaemonToClientReply::Success::(r) => Ok(r), - DaemonToClientReply::Failure(buf) => { - // For now we just prefix server - anyhow::bail!("internal error: {}", buf); - } - } - } - - pub(crate) fn shutdown(&mut self) -> Result<()> { - nixsocket::shutdown(self.fd, nixsocket::Shutdown::Both)?; - Ok(()) - } -} - -pub(crate) struct UnauthenticatedClient { - fd: RawFd, -} - -impl UnauthenticatedClient { - pub(crate) fn new(fd: RawFd) -> Self { - Self { fd } - } - - pub(crate) fn authenticate(mut self) -> Result { - use nix::sys::uio::IoVec; - let fd = self.fd; - let mut buf = [0u8; 1024]; - - nixsocket::setsockopt(fd, nix::sys::socket::sockopt::PassCred, &true)?; - let iov = IoVec::from_mut_slice(buf.as_mut()); - let mut cmsgspace = nix::cmsg_space!(nixsocket::UnixCredentials); - let msg = nixsocket::recvmsg( - fd, - &[iov], - Some(&mut cmsgspace), - nixsocket::MsgFlags::MSG_CMSG_CLOEXEC, - )?; - let mut creds = None; - for cmsg in msg.cmsgs() { - if let nixsocket::ControlMessageOwned::ScmCredentials(c) = cmsg { - creds = Some(c); - break; - } - } - if let Some(creds) = creds { - if creds.uid() != 0 { - bail!("unauthorized pid:{} uid:{}", creds.pid(), creds.uid()) - } - println!("Connection from pid:{}", creds.pid()); - } else { - bail!("No SCM credentials provided"); - } - let hello = String::from_utf8_lossy(&buf[0..msg.bytes]); - if hello != BOOTUPD_HELLO_MSG { - bail!("Didn't receive correct hello message, found: {:?}", &hello); - } - let r = AuthenticatedClient { fd: self.fd }; - self.fd = -1; - Ok(r) - } -} - -impl Drop for UnauthenticatedClient { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} - -pub(crate) struct AuthenticatedClient { - pub(crate) fd: RawFd, -} - -impl Drop for AuthenticatedClient { - fn drop(&mut self) { - if self.fd != -1 { - nix::unistd::close(self.fd).expect("close"); - } - } -} diff --git a/src/main.rs b/src/main.rs index 5cbb02fd8..b075bde06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,6 @@ mod bootupd; mod cli; mod component; mod coreos; -mod daemon; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; mod filesystem; @@ -33,7 +32,6 @@ mod filetree; target_arch = "powerpc64" ))] mod grubconfigs; -mod ipc; mod model; mod model_legacy; mod ostreeutil; diff --git a/systemd/bootupd.service b/systemd/bootupd.service deleted file mode 100644 index 52735bfe0..000000000 --- a/systemd/bootupd.service +++ /dev/null @@ -1,26 +0,0 @@ -[Unit] -Description=bootloader update daemon -Documentation=https://github.com/coreos/bootupd -# Because the daemon currently agressively auto-exits -# and our test suite runs many requests, let's allow -# a lot of restarts before failing. -StartLimitIntervalSec=2s -StartLimitBurst=10 - -[Service] -Type=notify -Environment=BOOTUPD_VERBOSITY="-v" -ExecStart=/usr/libexec/bootupd daemon $BOOTUPD_VERBOSITY -# This way our working directory isn't writable by default. -WorkingDirectory=/usr -# Various hardening flags just on general principle. We need -# to run as root, but let's avoid accidental damage. -ProtectHome=yes -ReadOnlyPaths=/usr -PrivateTmp=yes -PrivateNetwork=yes -ProtectHostname=yes -ProtectControlGroups=yes -RestrictSUIDSGID=yes -# So we can remount /boot writable -MountFlags=slave diff --git a/systemd/bootupd.socket b/systemd/bootupd.socket deleted file mode 100644 index c3f2269bc..000000000 --- a/systemd/bootupd.socket +++ /dev/null @@ -1,6 +0,0 @@ -[Socket] -ListenSequentialPacket=/run/bootupd.sock -SocketMode=0600 - -[Install] -WantedBy=sockets.target diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 2a3a13453..64af1afa3 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -16,7 +16,8 @@ if test -z "${COSA_DIR:-}"; then fi # Validate source directory bootupd_git=$(cd ${dn} && git rev-parse --show-toplevel) -test -f ${bootupd_git}/systemd/bootupd.service +# https://github.com/coreos/bootupd/issues/551 +! test -f ${bootupd_git}/systemd/bootupd.service testtmp=$(mktemp -d -p /var/tmp bootupd-e2e.XXXXXXX) export test_tmpdir=${testtmp} diff --git a/tests/kola/test-bootupd b/tests/kola/test-bootupd index 7402c6fb6..315656cc4 100755 --- a/tests/kola/test-bootupd +++ b/tests/kola/test-bootupd @@ -47,18 +47,13 @@ assert_file_has_content_literal out.txt 'Update: At latest version' assert_file_has_content out.txt '^CoreOS aleph version:' ok status -# Validate we auto-exited -sleep 2 -systemctl show -p ActiveState bootupd > out.txt -assert_file_has_content_literal out.txt 'ActiveState=inactive' - bootupctl validate | tee out.txt ok validate if env LANG=C.UTF-8 runuser -u bin bootupctl status 2>err.txt; then fatal "Was able to bootupctl status as non-root" fi -assert_file_has_content err.txt 'error:.*: Permission denied' +assert_file_has_content err.txt 'error: This command requires root privileges' # From here we'll fake updates test -w /usr || rpm-ostree usroverlay From 482d159c47f9b52e88f7d4761fe941cfcce54f2e Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 5 Jun 2024 15:55:59 +0800 Subject: [PATCH 576/641] efi: change `--update-firmware` to match current Anaconda logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy Timothée's comment: We want to be able to use `bootupd backend install --update-firmware` in Anaconda to setup the boot order on EFI systems. The issue is that when called with `--update-firmware`, bootupd currently removes the `BootCurrent` boot entry, and then adds a new BootEntry for the system being installed. The current Anaconda behavior is to remove all boot entries that match the product name, then create a new boot entry using the product name and set it as the first one in the boot order. To sync with Anaconda behavior, when called with `--update-firmware`, bootupd will remove all boot entries that match the product name. See https://github.com/coreos/bootupd/issues/658 --- Cargo.lock | 24 ++++++-- Cargo.toml | 1 + src/efi.rs | 174 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 163 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2f1ef244..7af52d848 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,7 @@ dependencies = [ "openat", "openat-ext", "openssl", + "os-release", "serde", "serde_json", "tempfile", @@ -387,6 +388,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.155" @@ -562,6 +569,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os-release" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f29ae2f71b53ec19cc23385f8e4f3d90975195aa3d09171ba3bef7159bec27" +dependencies = [ + "lazy_static", +] + [[package]] name = "os_str_bytes" version = "6.6.1" @@ -654,9 +670,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -666,9 +682,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index c03a04d37..4f1d4c09b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" +os-release = "0.1.0" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.10" diff --git a/src/efi.rs b/src/efi.rs index e621726a0..e89fb05b0 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -12,6 +12,7 @@ use std::process::Command; use anyhow::{bail, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; +use os_release::OsRelease; use walkdir::WalkDir; use widestring::U16CString; @@ -137,8 +138,14 @@ impl Efi { log::debug!("Not booted via EFI, skipping firmware update"); return Ok(()); } - clear_efi_current()?; - set_efi_current(device, espdir, vendordir) + // Read /etc/os-release + let release: OsRelease = OsRelease::new()?; + let product_name: &str = &release.name; + log::debug!("Get product name: {product_name}"); + assert!(product_name.len() > 0); + // clear all the boot entries that match the target name + clear_efi_target(product_name)?; + create_efi_boot_entry(device, espdir, vendordir, product_name) } } @@ -455,46 +462,71 @@ fn validate_esp(dir: &openat::Dir) -> Result<()> { Ok(()) } -#[context("Clearing current EFI boot entry")] -pub(crate) fn clear_efi_current() -> Result<()> { - const BOOTCURRENT: &str = "BootCurrent"; - if !crate::efi::is_efi_booted()? { - log::debug!("System is not booted via EFI"); - return Ok(()); +#[derive(Debug, PartialEq)] +struct BootEntry { + id: String, + name: String, +} + +/// Parse boot entries from efibootmgr output +fn parse_boot_entries(output: &str) -> Vec { + let mut entries = Vec::new(); + + for line in output.lines().filter_map(|line| line.strip_prefix("Boot")) { + // Need to consider if output only has "Boot0000* UiApp", without additional info + if line.starts_with('0') { + let parts = if let Some((parts, _)) = line.split_once('\t') { + parts + } else { + line + }; + if let Some((id, name)) = parts.split_once(' ') { + let id = id.trim_end_matches('*').to_string(); + let name = name.trim().to_string(); + entries.push(BootEntry { id, name }); + } + } } + entries +} + +#[context("Clearing EFI boot entries that match target {target}")] +pub(crate) fn clear_efi_target(target: &str) -> Result<()> { + let target = target.to_lowercase(); let output = Command::new(EFIBOOTMGR).output()?; if !output.status.success() { anyhow::bail!("Failed to invoke {EFIBOOTMGR}") } + let output = String::from_utf8(output.stdout)?; - let current = if let Some(current) = output - .lines() - .filter_map(|l| l.split_once(':')) - .filter_map(|(k, v)| (k == BOOTCURRENT).then_some(v.trim())) - .next() - { - current - } else { - log::debug!("No EFI {BOOTCURRENT} found"); - return Ok(()); - }; - log::debug!("EFI current: {current}"); - let output = Command::new(EFIBOOTMGR) - .args(["-b", current, "-B"]) - .output()?; - let st = output.status; - if !st.success() { - std::io::copy( - &mut std::io::Cursor::new(output.stderr), - &mut std::io::stderr().lock(), - )?; - anyhow::bail!("Failed to invoke {EFIBOOTMGR}: {st:?}"); + let boot_entries = parse_boot_entries(&output); + for entry in boot_entries { + if entry.name.to_lowercase() == target { + log::debug!("Deleting matched target {:?}", entry); + let output = Command::new(EFIBOOTMGR) + .args(["-b", entry.id.as_str(), "-B"]) + .output()?; + let st = output.status; + if !st.success() { + std::io::copy( + &mut std::io::Cursor::new(output.stderr), + &mut std::io::stderr().lock(), + )?; + anyhow::bail!("Failed to invoke {EFIBOOTMGR}: {st:?}"); + } + } } + anyhow::Ok(()) } #[context("Adding new EFI boot entry")] -pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &str) -> Result<()> { +pub(crate) fn create_efi_boot_entry( + device: &str, + espdir: &openat::Dir, + vendordir: &str, + target: &str, +) -> Result<()> { let fsinfo = crate::filesystem::inspect_filesystem(espdir, ".")?; let source = fsinfo.source; let devname = source @@ -509,6 +541,7 @@ pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &st anyhow::bail!("Failed to find {SHIM}"); } let loader = format!("\\EFI\\{}\\{SHIM}", vendordir); + log::debug!("Creating new EFI boot entry using '{target}'"); let st = Command::new(EFIBOOTMGR) .args([ "--create", @@ -519,7 +552,7 @@ pub(crate) fn set_efi_current(device: &str, espdir: &openat::Dir, vendordir: &st "--loader", loader.as_str(), "--label", - vendordir, + target, ]) .status()?; if !st.success() { @@ -546,3 +579,80 @@ fn find_file_recursive>(dir: P, target_file: &str) -> Result Result<()> { + let output = r" +BootCurrent: 0003 +Timeout: 0 seconds +BootOrder: 0003,0001,0000,0002 +Boot0000* UiApp FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331) +Boot0001* UEFI Misc Device PciRoot(0x0)/Pci(0x3,0x0){auto_created_boot_option} +Boot0002* EFI Internal Shell FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1) +Boot0003* Fedora HD(2,GPT,94ff4025-5276-4bec-adea-e98da271b64c,0x1000,0x3f800)/\EFI\fedora\shimx64.efi"; + let entries = parse_boot_entries(output); + assert_eq!( + entries, + [ + BootEntry { + id: "0000".to_string(), + name: "UiApp".to_string() + }, + BootEntry { + id: "0001".to_string(), + name: "UEFI Misc Device".to_string() + }, + BootEntry { + id: "0002".to_string(), + name: "EFI Internal Shell".to_string() + }, + BootEntry { + id: "0003".to_string(), + name: "Fedora".to_string() + } + ] + ); + let output = r" +BootCurrent: 0003 +Timeout: 0 seconds +BootOrder: 0003,0001,0000,0002"; + let entries = parse_boot_entries(output); + assert_eq!(entries, []); + + let output = r" +BootCurrent: 0003 +Timeout: 0 seconds +BootOrder: 0003,0001,0000,0002 +Boot0000* UiApp +Boot0001* UEFI Misc Device +Boot0002* EFI Internal Shell +Boot0003* test"; + let entries = parse_boot_entries(output); + assert_eq!( + entries, + [ + BootEntry { + id: "0000".to_string(), + name: "UiApp".to_string() + }, + BootEntry { + id: "0001".to_string(), + name: "UEFI Misc Device".to_string() + }, + BootEntry { + id: "0002".to_string(), + name: "EFI Internal Shell".to_string() + }, + BootEntry { + id: "0003".to_string(), + name: "test".to_string() + } + ] + ); + Ok(()) + } +} From 2218fac3d61f6e5a1b79dfac06633dfad3273c81 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Sun, 9 Jun 2024 16:24:23 +0800 Subject: [PATCH 577/641] bootupd.spec: remove `%{_unitdir}` Drop systemd service since https://github.com/coreos/bootupd/commit/261fb5e7f28b9bd2c6099fd2d484f158adffb221, so we do not need this. See error in ci log: ``` RPM build errors: File not found: /builddir/build/BUILD/bootupd-xxx-build/BUILDROOT/usr/lib/systemd/system/* ``` --- contrib/packaging/bootupd.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec index 91da18f10..ebe3c2d3d 100644 --- a/contrib/packaging/bootupd.spec +++ b/contrib/packaging/bootupd.spec @@ -29,8 +29,7 @@ BuildRequires: systemd-devel %license LICENSE %doc README.md %{_bindir}/bootupctl -%{_libexecdir}/bootupd -%{_unitdir}/* +%{_libexecdir}/bootupd %{_prefix}/lib/bootupd/grub2-static/ %prep From e51f0383337146afb4dad302360f9f47eac9632c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 20 Jun 2024 15:27:29 +0200 Subject: [PATCH 578/641] github/workflows: Update to ubuntu-24.04 & podman See: https://github.com/ostreedev/ostree/pull/3270 --- .github/workflows/ci.yml | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3698ff1f5..f87569d5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,26 +19,11 @@ env: jobs: c9s-bootc-e2e: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - # We use docker to build because it updates to the latest, whereas right now ubuntu-latest - # has podman and buildah from ~2021 (insane!) - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - uses: actions/checkout@v3 - - name: Cache Dependencies - uses: Swatinem/rust-cache@v2 - with: - key: "build-c9s" - - name: Build and export to Docker - uses: docker/build-push-action@v5 - with: - context: . - file: ci/Containerfile.c9s - load: true - tags: localhost/bootupd:latest - - name: Copy to podman - run: sudo skopeo copy docker-daemon:localhost/bootupd:latest containers-storage:localhost/bootupd:latest + - name: build + run: sudo podman build -t localhost/bootupd:latest -f ci/Containerfile.c9s . - name: bootc install to disk run: | set -xeuo pipefail @@ -60,7 +45,7 @@ jobs: run: | set -xeuo pipefail sudo podman run --rm -ti --privileged -v /:/target --pid=host --security-opt label=disable \ - -v /var/lib/containers:/var/lib/containers \ + -v /dev:/dev -v /var/lib/containers:/var/lib/containers \ localhost/bootupd:latest bootc install to-filesystem --skip-fetch-check \ --disable-selinux --replace=alongside /target # Verify we injected static configs From feada739335807a9432a1a7e36f5aa32a346c73b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 19 Jun 2024 20:37:27 -0400 Subject: [PATCH 579/641] Port to rustix, drop nix We already have rustix as a dependency; now that we don't use IPC anymore it's trivial to port to rustix. I prefer its API and maintainer. Signed-off-by: Colin Walters --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- src/cli/bootupctl.rs | 2 +- src/efi.rs | 18 +++++++++++------- src/filesystem.rs | 5 +++-- src/filetree.rs | 22 ++++++---------------- src/util.rs | 5 ++--- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7af52d848..d35ba3239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,11 +83,11 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.23.2", "openat", "openat-ext", "openssl", "os-release", + "rustix", "serde", "serde_json", "tempfile", @@ -699,9 +699,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index 4f1d4c09b..47f9eb080 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,11 +30,11 @@ hex = "0.4.3" libc = "^0.2" libsystemd = ">= 0.3, < 0.8" log = "^0.4" -nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" +rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.10" diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index e8150b1e4..123d42bda 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -142,7 +142,7 @@ fn running_in_systemd() -> bool { /// Require root permission fn require_root_permission() -> Result<()> { - if !nix::unistd::Uid::effective().is_root() { + if !rustix::process::getuid().is_root() { anyhow::bail!("This command requires root privileges") } Ok(()) diff --git a/src/efi.rs b/src/efi.rs index e89fb05b0..060eedd9c 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -13,6 +13,7 @@ use anyhow::{bail, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; use os_release::OsRelease; +use rustix::fd::BorrowedFd; use walkdir::WalkDir; use widestring::U16CString; @@ -82,9 +83,9 @@ impl Efi { if !mnt.exists() { continue; } - let st = nix::sys::statfs::statfs(&mnt) - .with_context(|| format!("statfs failed for {mnt:?}"))?; - if st.filesystem_type() != nix::sys::statfs::MSDOS_SUPER_MAGIC { + let st = + rustix::fs::statfs(&mnt).with_context(|| format!("statfs failed for {mnt:?}"))?; + if st.f_type != libc::MSDOS_SUPER_MAGIC { continue; } log::debug!("Reusing existing {mnt:?}"); @@ -454,10 +455,13 @@ impl Drop for Efi { } fn validate_esp(dir: &openat::Dir) -> Result<()> { - let stat = nix::sys::statfs::fstatfs(dir)?; - let fstype = stat.filesystem_type(); - if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { - bail!("EFI mount is not a msdos filesystem, but is {:?}", fstype); + let dir = unsafe { BorrowedFd::borrow_raw(dir.as_raw_fd()) }; + let stat = rustix::fs::fstatfs(&dir)?; + if stat.f_type != libc::MSDOS_SUPER_MAGIC { + bail!( + "EFI mount is not a msdos filesystem, but is {:?}", + stat.f_type + ); }; Ok(()) } diff --git a/src/filesystem.rs b/src/filesystem.rs index c9060a700..80b942b34 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -5,6 +5,7 @@ use std::process::Command; use anyhow::{Context, Result}; use fn_error_context::context; +use rustix::fd::BorrowedFd; use serde::Deserialize; #[derive(Deserialize, Debug)] @@ -24,12 +25,12 @@ pub(crate) struct Findmnt { #[context("Inspecting filesystem {path:?}")] pub(crate) fn inspect_filesystem(root: &openat::Dir, path: &str) -> Result { - let rootfd = root.as_raw_fd(); + let rootfd = unsafe { BorrowedFd::borrow_raw(root.as_raw_fd()) }; // SAFETY: This is unsafe just for the pre_exec, when we port to cap-std we can use cap-std-ext let o = unsafe { Command::new("findmnt") .args(["-J", "-v", "--output=SOURCE,FSTYPE,OPTIONS,UUID", path]) - .pre_exec(move || nix::unistd::fchdir(rootfd).map_err(Into::into)) + .pre_exec(move || rustix::process::fchdir(rootfd).map_err(Into::into)) .output()? }; let st = o.status; diff --git a/src/filetree.rs b/src/filetree.rs index c1e58a882..1fff67ae3 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -17,8 +17,6 @@ use std::fmt::Display; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::os::unix::io::AsRawFd; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -use std::os::unix::process::CommandExt; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::path::Path; /// The prefix we apply to our temporary files. @@ -274,20 +272,12 @@ pub(crate) struct ApplyUpdateOptions { // Let's just fork off a helper process for now. #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { - let d = d.sub_dir(".").expect("subdir"); - let mut c = std::process::Command::new("sync"); - let c = c.args(["-f", "."]); - unsafe { - c.pre_exec(move || { - nix::unistd::fchdir(d.as_raw_fd()).expect("fchdir"); - Ok(()) - }) - }; - let r = c.status().context("syncfs failed")?; - if !r.success() { - bail!("syncfs failed"); - } - Ok(()) + use rustix::fd::BorrowedFd; + use rustix::fs::{Mode, OFlags}; + let d = unsafe { BorrowedFd::borrow_raw(d.as_raw_fd()) }; + let oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::DIRECTORY; + let d = rustix::fs::openat(d, ".", oflags, Mode::empty())?; + rustix::fs::syncfs(d).map_err(Into::into) } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] diff --git a/src/util.rs b/src/util.rs index c88d173e8..d52a745e8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -67,10 +67,9 @@ pub(crate) fn filenames(dir: &openat::Dir) -> Result> { } pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { - use nix::sys::statvfs; let p = p.as_ref(); - let stat = statvfs::statvfs(p)?; - if !stat.flags().contains(statvfs::FsFlags::ST_RDONLY) { + let stat = rustix::fs::statvfs(p)?; + if !stat.f_flag.contains(rustix::fs::StatVfsMountFlags::RDONLY) { return Ok(()); } let status = std::process::Command::new("mount") From 63a9802d6323eca330e5934512d673bfead718c6 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Fri, 21 Jun 2024 11:19:48 +0000 Subject: [PATCH 580/641] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@7237451c763782c0a5e0f58ff48aa20dadf9700c. --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 495635a4f..4a559fb30 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,7 +18,7 @@ concurrency: env: CARGO_TERM_COLOR: always # Pinned toolchain for linting - ACTIONS_LINTS_TOOLCHAIN: 1.71.0 + ACTIONS_LINTS_TOOLCHAIN: 1.75.0 jobs: tests-stable: From bc2642566f082fa12f4f29d9588682939734d71a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 28 Jun 2024 10:51:10 -0400 Subject: [PATCH 581/641] ci: Add cross-arch builds Because we have a lot of arch conditionals that would be easy to break. Signed-off-by: Colin Walters --- .github/workflows/cross.yml | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/cross.yml diff --git a/.github/workflows/cross.yml b/.github/workflows/cross.yml new file mode 100644 index 000000000..6cdad1726 --- /dev/null +++ b/.github/workflows/cross.yml @@ -0,0 +1,41 @@ +name: Cross build + +on: [push, pull_request] + +permissions: + actions: read + +jobs: + crossarch-check: + runs-on: ubuntu-latest + name: Build on ${{ matrix.arch }} + + strategy: + matrix: + include: + - arch: aarch64 + distro: ubuntu_latest + - arch: s390x + distro: ubuntu_latest + - arch: ppc64le + distro: ubuntu_latest + steps: + - uses: actions/checkout@v3.0.2 + with: + submodules: true + set-safe-directory: true + + - uses: uraimo/run-on-arch-action@v2.2.0 + name: Build + id: build + with: + arch: ${{ matrix.arch }} + distro: ${{ matrix.distro }} + + githubToken: ${{ github.token }} + + run: | + set -xeu + apt update -y + apt install -y gcc make cargo libssl-dev pkg-config + cargo check From d5437e830b57b210e2fb0e0b4c5949c69c86f481 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:34:52 +0000 Subject: [PATCH 582/641] build(deps): bump serde_json from 1.0.117 to 1.0.119 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.117 to 1.0.119. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.117...v1.0.119) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d35ba3239..24621b75d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,9 +747,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0" dependencies = [ "itoa", "ryu", From 35643fb7f51cb9b9098cea0dd16fcfd3fd77dd18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:35:00 +0000 Subject: [PATCH 583/641] build(deps): bump log from 0.4.21 to 0.4.22 Bumps [log](https://github.com/rust-lang/log) from 0.4.21 to 0.4.22. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.21...0.4.22) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d35ba3239..b295661fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,9 +426,9 @@ checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" From 34c124889ff2ae4cefce179b9fdfa134cd42031b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Mon, 1 Jul 2024 15:51:51 +0200 Subject: [PATCH 584/641] README: Update now that it is no longer a daemon See: https://github.com/coreos/bootupd/pull/663 --- README.md | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c566d01ca..22a483c4e 100644 --- a/README.md +++ b/README.md @@ -118,28 +118,25 @@ But out of conservatism currently today for e.g. Fedora CoreOS, bootupd is disab by default. On the other hand, if your OS update mechanism isn't transactional, then you may want to enable bootupd by default. -- Why is bootupd a daemon? - -It's not, really. The name was intended to be "bootloader-upDater" -not "bootloader-updater-Daemon"; the choice of a "d" suffix is -in retrospect probably too confusing. - -At a technical level, yes there is a socket-activated systemd service -which will spawn a `bootupd.service`. However - the service will -*very quickly* auto exit. There's nothing long-running, so it's -not really a daemon. - -The rationale behind this design is: - -- Using a systemd service provides a robust natural "locking" - mechanism. -- Using a systemd service ensures that critical logging metadata - always consistently ends up in the systemd journal, not e.g. - a transient client SSH connection. -- systemd services can easily have sandboxing applied, and - while bootupd is obviously privileged we can still make use - of some of this. -- Ultimately, we do probably want a non-CLI API (whether that's - DBus or Cap'n Proto or varlink or something else). Having - a socket (without a defined stable API) is preparatory work for that. +- Is bootupd a daemon? + +It was never a daemon. The name was intended to be "bootloader-upDater" not +"bootloader-updater-Daemon". The choice of a "d" suffix is in retrospect +probably too confusing. + +bootupd used to have an internally-facing `bootupd.service` and +`bootupd.socket` systemd units that acted as a locking mechanism. The service +would *very quickly* auto exit. There was nothing long-running, so it was not +really a daemon. + +bootupd now uses `systemd-run` instead to guarantee the following: + +- It provides a robust natural "locking" mechanism. +- It ensures that critical logging metadata always consistently ends up in the + systemd journal, not e.g. a transient client SSH connection. +- It benefits from the sandboxing options available for systemd units, and + while bootupd is obviously privileged we can still make use of some of this. +- If we want a non-CLI API (whether that's DBus or Cap'n Proto or varlink or + something else), we will create an independent daemon with a stable API for + this specific need. From 3be390d16689be199156f680ee9f4b0f8f0f7303 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:11:54 +0000 Subject: [PATCH 585/641] build(deps): bump serde from 1.0.203 to 1.0.204 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.203 to 1.0.204. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.203...v1.0.204) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 550e23cd9..a728ccc36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -727,18 +727,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", From 078df4ace7ff85d6380946d52e864f7429d09415 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:12:06 +0000 Subject: [PATCH 586/641] build(deps): bump serde_json from 1.0.119 to 1.0.120 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.119 to 1.0.120. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.119...v1.0.120) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 550e23cd9..51adf0ce9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,9 +747,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.119" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", From d26845a6f09499aff113d98f5067370e11435954 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 10 Jul 2024 16:40:05 +0800 Subject: [PATCH 587/641] ci: minor updates - Remove fast track for `virtiofsd` as higher version is installed - Update `grub2` to newer version in ci testing --- .cci.jenkinsfile | 2 -- tests/e2e-update/e2e-update.sh | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.cci.jenkinsfile b/.cci.jenkinsfile index d8b92c986..a13a827b5 100644 --- a/.cci.jenkinsfile +++ b/.cci.jenkinsfile @@ -41,8 +41,6 @@ cosaPod(runAsUser: 0, memory: "4608Mi", cpu: "4") { stage("Build FCOS") { checkout scm unstash 'build' - // Fast track https://bodhi.fedoraproject.org/updates/FEDORA-2023-5041615f94 - shwrap("sudo dnf -y update https://kojipkgs.fedoraproject.org//packages/virtiofsd/1.7.0/5.fc38/x86_64/virtiofsd-1.7.0-5.fc38.x86_64.rpm") // Note that like {rpm-,}ostree we want to install to both / and overrides/rootfs // because bootupd is used both during the `rpm-ostree compose tree` as well as // inside the target operating system. diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index 64af1afa3..e45623f78 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -80,15 +80,15 @@ undo_manifest_fork() { if test -z "${e2e_skip_build:-}"; then echo "Building starting image" rm -f ${overrides}/rpm/*.rpm - # Version from F37 GA - add_override grub2-2.06-89.fc38 + # Version from F39 GA + add_override grub2-2.06-100.fc39 runv cosa build prev_image=$(runv cosa meta --image-path qemu) create_manifest_fork rm -f ${overrides}/rpm/*.rpm echo "Building update ostree" # Version queued in current updates - add_override grub2-2.06-102.fc38 + add_override grub2-2.06-123.fc40 mv ${test_tmpdir}/yumrepo/packages/$(arch)/*.rpm ${overrides}/rpm/ # Only build ostree update runv cosa build ostree From d060d28d8e498080186c8b927a76502ac56615f9 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 10 Jul 2024 18:51:22 +0800 Subject: [PATCH 588/641] Release 0.2.20 Fixes https://github.com/coreos/bootupd/issues/682 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81d8ece3f..d2d66b199 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.19" +version = "0.2.20" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 47f9eb080..9fe422aa6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.19" +version = "0.2.20" authors = ["Colin Walters "] edition = "2021" rust-version = "1.70.0" From 47557c356cafeb311ede3cdfa2a553a6b8abc59b Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Tue, 16 Jul 2024 16:15:37 +0800 Subject: [PATCH 589/641] efi: sync bootentry label with Anaconda Read `/etc/system-release` if exists, else get `NAME` from `/etc/os-release` See https://bugzilla.redhat.com/show_bug.cgi?id=2268505#c24 --- Cargo.lock | 1 + Cargo.toml | 1 + src/efi.rs | 27 ++++++++++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2d66b199..af5cb7a90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,7 @@ dependencies = [ "openat-ext", "openssl", "os-release", + "regex", "rustix", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 9fe422aa6..00611cdab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" +regex = "1.10.4" rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" diff --git a/src/efi.rs b/src/efi.rs index 060eedd9c..a3c2d57d3 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -139,17 +139,28 @@ impl Efi { log::debug!("Not booted via EFI, skipping firmware update"); return Ok(()); } - // Read /etc/os-release - let release: OsRelease = OsRelease::new()?; - let product_name: &str = &release.name; + let product_name = get_product_name()?; log::debug!("Get product name: {product_name}"); assert!(product_name.len() > 0); // clear all the boot entries that match the target name - clear_efi_target(product_name)?; - create_efi_boot_entry(device, espdir, vendordir, product_name) + clear_efi_target(&product_name)?; + create_efi_boot_entry(device, espdir, vendordir, &product_name) } } +#[context("Get product name")] +fn get_product_name() -> Result { + let file_path = Path::new("/etc/system-release"); + if file_path.exists() { + let content = std::fs::read_to_string(file_path)?; + let re = regex::Regex::new(r" *release.*").unwrap(); + return Ok(re.replace_all(&content, "").to_string()); + } + // Read /etc/os-release + let release: OsRelease = OsRelease::new()?; + Ok(release.name) +} + /// Convert a nul-terminated UTF-16 byte array to a String. fn string_from_utf16_bytes(slice: &[u8]) -> String { // For some reason, systemd appends 3 nul bytes after the string. @@ -659,4 +670,10 @@ Boot0003* test"; ); Ok(()) } + #[test] + fn test_get_product_name() -> Result<()> { + let name = get_product_name()?; + assert!(name.len() > 0); + Ok(()) + } } From 9b1b696aa7376d0dc6ae250ca9145d1f77ad692a Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 17 Jul 2024 16:31:39 +0800 Subject: [PATCH 590/641] efi: avoid reading global state for `get_product_name()` Inspired by https://github.com/coreos/bootupd/pull/685#discussion_r1679742803 --- Cargo.lock | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/efi.rs | 47 +++++++++++++++++++---- 3 files changed, 152 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af5cb7a90..2892398a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -74,6 +80,7 @@ version = "0.2.20" dependencies = [ "anyhow", "bincode", + "cap-std-ext", "chrono", "clap", "env_logger", @@ -102,6 +109,58 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "cap-primitives" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d00bd8d26c4270d950eaaa837387964a2089a1c3c349a690a1fa03221d29531" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "cap-std" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19eb8e3d71996828751c1ed3908a439639752ac6bdc874e41469ef7fc15fbd7f" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "rustix", +] + +[[package]] +name = "cap-std-ext" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0279cf1f7b6cbeeb98e6946e8fea58136f691d4d0aa8c775f4439a05030a481" +dependencies = [ + "cap-primitives", + "cap-tempfile", + "rustix", +] + +[[package]] +name = "cap-tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53880047c3f37cd64947775f0526795498d614182603a718c792616b762ce777" +dependencies = [ + "cap-std", + "rand", + "rustix", + "uuid", +] + [[package]] name = "cc" version = "1.0.83" @@ -260,6 +319,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fs-set-times" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +dependencies = [ + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "fs2" version = "0.4.3" @@ -363,6 +433,28 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "io-extras" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" +dependencies = [ + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.9" @@ -431,6 +523,12 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + [[package]] name = "memchr" version = "2.6.4" @@ -706,8 +804,10 @@ checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.4.1", "errno", + "itoa", "libc", "linux-raw-sys", + "once_cell", "windows-sys 0.52.0", ] @@ -867,6 +967,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ + "getrandom", "serde", ] @@ -1129,3 +1230,13 @@ name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winx" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +dependencies = [ + "bitflags 2.4.1", + "windows-sys 0.52.0", +] diff --git a/Cargo.toml b/Cargo.toml index 00611cdab..45ab6a9ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" +cap-std-ext = "4.0.0" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } env_logger = "0.10" diff --git a/src/efi.rs b/src/efi.rs index a3c2d57d3..ecaee8224 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -10,6 +10,8 @@ use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::{bail, Context, Result}; +use cap_std::fs::Dir; +use cap_std_ext::cap_std; use fn_error_context::context; use openat_ext::OpenatDirExt; use os_release::OsRelease; @@ -139,7 +141,8 @@ impl Efi { log::debug!("Not booted via EFI, skipping firmware update"); return Ok(()); } - let product_name = get_product_name()?; + let sysroot = Dir::open_ambient_dir(&Path::new("/"), cap_std::ambient_authority())?; + let product_name = get_product_name(&sysroot)?; log::debug!("Get product name: {product_name}"); assert!(product_name.len() > 0); // clear all the boot entries that match the target name @@ -149,10 +152,10 @@ impl Efi { } #[context("Get product name")] -fn get_product_name() -> Result { - let file_path = Path::new("/etc/system-release"); - if file_path.exists() { - let content = std::fs::read_to_string(file_path)?; +fn get_product_name(sysroot: &Dir) -> Result { + let release_path = "etc/system-release"; + if sysroot.exists(release_path) { + let content = sysroot.read_to_string(release_path)?; let re = regex::Regex::new(r" *release.*").unwrap(); return Ok(re.replace_all(&content, "").to_string()); } @@ -597,6 +600,8 @@ fn find_file_recursive>(dir: P, target_file: &str) -> Result Result { + let tempdir = cap_std_ext::cap_tempfile::tempdir(cap_std::ambient_authority())?; + tempdir.create_dir("etc")?; + Ok(tempdir) + } #[test] fn test_get_product_name() -> Result<()> { - let name = get_product_name()?; - assert!(name.len() > 0); + let tmpd = fixture()?; + { + tmpd.atomic_write("etc/system-release", "Fedora release 40 (Forty)")?; + let name = get_product_name(&tmpd)?; + assert_eq!("Fedora", name); + } + { + tmpd.atomic_write("etc/system-release", "CentOS Stream release 9")?; + let name = get_product_name(&tmpd)?; + assert_eq!("CentOS Stream", name); + } + { + tmpd.atomic_write( + "etc/system-release", + "Red Hat Enterprise Linux CoreOS release 4", + )?; + let name = get_product_name(&tmpd)?; + assert_eq!("Red Hat Enterprise Linux CoreOS", name); + } + { + tmpd.remove_file("etc/system-release")?; + let name = get_product_name(&tmpd)?; + assert!(name.len() > 0); + } Ok(()) } } From 2190e5562f0018ebcdd7d701e59cde6996f94b34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 01:02:57 +0000 Subject: [PATCH 591/641] build(deps): bump regex from 1.10.4 to 1.10.5 Bumps [regex](https://github.com/rust-lang/regex) from 1.10.4 to 1.10.5. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.10.4...1.10.5) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2892398a8..7f651d958 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -769,9 +769,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 45ab6a9ff..3862bed57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" -regex = "1.10.4" +regex = "1.10.5" rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 5784dbaad9b26ce51e36a95a6cd5316de43b10bb Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Fri, 26 Jul 2024 17:48:10 +0800 Subject: [PATCH 592/641] Cargo.toml: bump MSRV to 1.75.0 Sync what we did in https://github.com/coreos/coreos-installer/commit/d974fed3c2ebb176278ae861dd00aaa50e7cc19c --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 45ab6a9ff..3ee571146 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ license = "Apache-2.0" version = "0.2.20" authors = ["Colin Walters "] edition = "2021" -rust-version = "1.70.0" +rust-version = "1.75.0" include = ["src", "LICENSE", "Makefile", "systemd"] From 4e2f402848de99e13ed5f484298bbd2202765495 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Fri, 26 Jul 2024 18:10:34 +0800 Subject: [PATCH 593/641] deps: bump clap from 3.2.25 to 4.5 --- Cargo.lock | 121 ++++++++++++++----------------------------------- Cargo.toml | 2 +- src/cli/mod.rs | 5 +- 3 files changed, 36 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2892398a8..180331a68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + [[package]] name = "anyhow" version = "1.0.86" @@ -193,40 +199,42 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ - "bitflags 1.3.2", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +dependencies = [ + "anstyle", "clap_lex", - "indexmap", - "once_cell", "strsim", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.25" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "core-foundation-sys" @@ -301,7 +309,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -361,17 +369,11 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -423,16 +425,6 @@ dependencies = [ "cc", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "io-extras" version = "0.18.2" @@ -653,7 +645,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -677,12 +669,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "pkg-config" version = "0.3.27" @@ -695,30 +681,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.76" @@ -843,7 +805,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -870,9 +832,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -880,17 +842,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.48" @@ -923,12 +874,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.51" @@ -946,7 +891,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -1020,7 +965,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-shared", ] @@ -1042,7 +987,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 3ee571146..1a9256bbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ anyhow = "1.0" bincode = "1.3.2" cap-std-ext = "4.0.0" chrono = { version = "0.4.38", features = ["serde"] } -clap = { version = "3.2", default-features = false, features = ["cargo", "derive", "std", "suggestions"] } +clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } env_logger = "0.10" fn-error-context = "0.2.1" fs2 = "0.4.3" diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 98d45c0c6..285e1ea54 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,14 +1,13 @@ //! Command-line interface (CLI) logic. use anyhow::Result; -use clap::StructOpt; +use clap::Parser; use log::LevelFilter; - mod bootupctl; mod bootupd; /// Top-level multicall CLI. -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] pub enum MultiCall { Ctl(bootupctl::CtlCommand), D(bootupd::DCommand), From 3868deb11933cc3c13ea2780de248805b65d9dab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:33:01 +0000 Subject: [PATCH 594/641] build(deps): bump openssl from 0.10.64 to 0.10.66 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.64 to 0.10.66. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.64...openssl-v0.10.66) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f651d958..55d22cf14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -632,9 +632,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -658,9 +658,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", From 34aa9e72f3d55c9d7778b3ac0e6d461658fd55a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 01:39:05 +0000 Subject: [PATCH 595/641] build(deps): bump serde_json from 1.0.120 to 1.0.121 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.120 to 1.0.121. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.120...v1.0.121) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55d22cf14..de6b0792b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -848,11 +848,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] From fa0d509b6e21dd3e6a54d796bd0bdfc379633695 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:12:15 +0000 Subject: [PATCH 596/641] build(deps): bump env_logger from 0.10.1 to 0.11.5 Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.10.1 to 0.11.5. - [Release notes](https://github.com/rust-cli/env_logger/releases) - [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-cli/env_logger/compare/v0.10.1...v0.11.5) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 124 ++++++++++++++++++++++++++++++++++------------------- Cargo.toml | 2 +- 2 files changed, 81 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56b8f12d9..80f7b0d80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,12 +32,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -128,7 +171,7 @@ dependencies = [ "ipnet", "maybe-owned", "rustix", - "windows-sys 0.52.0", + "windows-sys", "winx", ] @@ -236,6 +279,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -272,17 +321,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.1" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -292,7 +351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -335,7 +394,7 @@ checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" dependencies = [ "io-lifetimes", "rustix", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -375,12 +434,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - [[package]] name = "hex" version = "0.4.3" @@ -432,7 +485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" dependencies = [ "io-lifetimes", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -448,15 +501,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "is-terminal" -version = "0.4.9" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" @@ -770,7 +818,7 @@ dependencies = [ "libc", "linux-raw-sys", "once_cell", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -863,16 +911,7 @@ dependencies = [ "cfg-if", "fastrand", "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", + "windows-sys", ] [[package]] @@ -907,6 +946,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.6.1" @@ -1045,15 +1090,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -1184,5 +1220,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" dependencies = [ "bitflags 2.4.1", - "windows-sys 0.52.0", + "windows-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 1441a95d4..27d869150 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ bincode = "1.3.2" cap-std-ext = "4.0.0" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } -env_logger = "0.10" +env_logger = "0.11" fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" From db179da71582395c4542383e93779ef376a99a11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:11:09 +0000 Subject: [PATCH 597/641] build(deps): bump clap from 4.5.11 to 4.5.13 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.11 to 4.5.13. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.11...v4.5.13) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80f7b0d80..7a36aded3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,9 +242,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -252,9 +252,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstyle", "clap_lex", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", From 868f40d5aadb0c69097b07dad63d65a4e7dadf2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:11:15 +0000 Subject: [PATCH 598/641] build(deps): bump tempfile from 3.10.1 to 3.11.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.10.1 to 3.11.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.10.1...v3.11.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80f7b0d80..4390089e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -904,12 +904,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", "windows-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 27d869150..04dae5934 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ regex = "1.10.5" rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.10" +tempfile = "^3.11" widestring = "1.1.0" walkdir = "2.3.2" From 736360c36277667e016ad8bdf483bb60dbbb5cec Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 19 Jun 2024 18:51:27 +0800 Subject: [PATCH 599/641] efi: update the ESP by creating a tmpdir and RENAME_EXCHANGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See Timothée's comment https://github.com/coreos/bootupd/issues/454#issuecomment-2178227050 Reuse `TMP_PREFIX`, logic is like this: - `cp -a fedora .btmp.fedora` - We start with a copy to make sure to keep all other files that we do not explicitly track in bootupd - Update the content of `.btmp.fedora` with the new binaries - Exchange `.btmp.fedora` -> `fedora` - Remove now "old" `.btmp.fedora` If we have a file not in a directory in `EFI`, then we can copy it to `.btmp.foo` and then act on it and finally rename it. No need to copy the entire `EFI`. And use `insert()` instead of `push()` to match `starts_with()` when scanning temp files & dirs. Fixes https://github.com/coreos/bootupd/issues/454 --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/filetree.rs | 268 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 242 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80f7b0d80..71a8d808f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,7 @@ version = "0.2.20" dependencies = [ "anyhow", "bincode", + "camino", "cap-std-ext", "chrono", "clap", @@ -158,6 +159,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" + [[package]] name = "cap-primitives" version = "3.2.0" diff --git a/Cargo.toml b/Cargo.toml index 27d869150..a3f44aad1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" cap-std-ext = "4.0.0" +camino = "1.1.7" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } env_logger = "0.11" diff --git a/src/filetree.rs b/src/filetree.rs index 1fff67ae3..047ca384c 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -7,17 +7,20 @@ #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use anyhow::{bail, Context, Result}; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +use camino::{Utf8Path, Utf8PathBuf}; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use openat_ext::OpenatDirExt; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use openssl::hash::{Hasher, MessageDigest}; +use rustix::fd::BorrowedFd; use serde::{Deserialize, Serialize}; #[allow(unused_imports)] use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Display; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::os::unix::io::AsRawFd; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -use std::path::Path; +use std::os::unix::process::CommandExt; +use std::process::Command; /// The prefix we apply to our temporary files. #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] @@ -231,7 +234,7 @@ impl FileTree { } } -// Recursively remove all files in the directory that start with our TMP_PREFIX +// Recursively remove all files/dirs in the directory that start with our TMP_PREFIX #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { for entry in dir.list_dir(".")? { @@ -245,8 +248,13 @@ fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { match dir.get_file_type(&entry)? { openat::SimpleType::Dir => { - let child = dir.sub_dir(name)?; - cleanup_tmp(&child)?; + if name.starts_with(TMP_PREFIX) { + dir.remove_all(name)?; + continue; + } else { + let child = dir.sub_dir(name)?; + cleanup_tmp(&child)?; + } } openat::SimpleType::File => { if name.starts_with(TMP_PREFIX) { @@ -272,7 +280,6 @@ pub(crate) struct ApplyUpdateOptions { // Let's just fork off a helper process for now. #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { - use rustix::fd::BorrowedFd; use rustix::fs::{Mode, OFlags}; let d = unsafe { BorrowedFd::borrow_raw(d.as_raw_fd()) }; let oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::DIRECTORY; @@ -280,12 +287,37 @@ pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { rustix::fs::syncfs(d).map_err(Into::into) } +/// Copy from src to dst at root dir +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +fn copy_dir(root: &openat::Dir, src: &str, dst: &str) -> Result<()> { + let rootfd = unsafe { BorrowedFd::borrow_raw(root.as_raw_fd()) }; + let r = unsafe { + Command::new("cp") + .args(["-a"]) + .arg(src) + .arg(dst) + .pre_exec(move || rustix::process::fchdir(rootfd).map_err(Into::into)) + .status()? + }; + if !r.success() { + anyhow::bail!("Failed to copy {src} to {dst}"); + } + log::debug!("Copy {src} to {dst}"); + Ok(()) +} + +/// Get first sub dir and tmp sub dir for the path +/// "fedora/foo/bar" -> ("fedora", ".btmp.fedora") +/// "foo" -> ("foo", ".btmp.foo") #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -fn tmpname_for_path>(path: P) -> std::path::PathBuf { - let path = path.as_ref(); - let mut buf = path.file_name().expect("filename").to_os_string(); - buf.push(TMP_PREFIX); - path.with_file_name(buf) +fn get_first_dir(path: &Utf8Path) -> Result<(&Utf8Path, String)> { + let first = path + .iter() + .next() + .ok_or_else(|| anyhow::anyhow!("Invalid path: {path}"))?; + let mut tmp = first.to_owned(); + tmp.insert_str(0, TMP_PREFIX); + Ok((first.into(), tmp)) } /// Given two directories, apply a diff generated from srcdir to destdir @@ -302,41 +334,83 @@ pub(crate) fn apply_diff( let opts = opts.unwrap_or(&default_opts); cleanup_tmp(destdir).context("cleaning up temporary files")?; - // Write new and changed files - for pathstr in diff.additions.iter().chain(diff.changes.iter()) { - let path = Path::new(pathstr); - if let Some(parent) = path.parent() { - destdir.ensure_dir_all(parent, DEFAULT_FILE_MODE)?; + let mut updates = HashMap::new(); + // Handle removals in temp dir, or remove directly if file not in dir + if !opts.skip_removals { + for pathstr in diff.removals.iter() { + let path = Utf8Path::new(pathstr); + let (first_dir, first_dir_tmp) = get_first_dir(path)?; + let path_tmp; + if first_dir != path { + path_tmp = Utf8Path::new(&first_dir_tmp).join(path.strip_prefix(&first_dir)?); + // copy to temp dir and remember + if !destdir.exists(&first_dir_tmp)? { + copy_dir(destdir, first_dir.as_str(), &first_dir_tmp)?; + updates.insert(first_dir, first_dir_tmp); + } + } else { + path_tmp = path.to_path_buf(); + } + destdir + .remove_file(path_tmp.as_std_path()) + .with_context(|| format!("removing {:?}", path_tmp))?; + } + } + // Write changed or new files to temp dir or temp file + for pathstr in diff.changes.iter().chain(diff.additions.iter()) { + let path = Utf8Path::new(pathstr); + let (first_dir, first_dir_tmp) = get_first_dir(path)?; + let mut path_tmp = Utf8PathBuf::from(&first_dir_tmp); + if first_dir != path { + if !destdir.exists(&first_dir_tmp)? && destdir.exists(first_dir.as_std_path())? { + // copy to temp dir if not exists + copy_dir(destdir, first_dir.as_str(), &first_dir_tmp)?; + } + path_tmp = path_tmp.join(path.strip_prefix(&first_dir)?); + // ensure new additions dir exists + if let Some(parent) = path_tmp.parent() { + destdir.ensure_dir_all(parent.as_std_path(), DEFAULT_FILE_MODE)?; + } + // remove changed file before copying + destdir + .remove_file_optional(path_tmp.as_std_path()) + .with_context(|| format!("removing {path_tmp} before copying"))?; } - let destp = tmpname_for_path(path); + updates.insert(first_dir, first_dir_tmp); srcdir - .copy_file_at(path, destdir, destp.as_path()) - .with_context(|| format!("writing {}", &pathstr))?; + .copy_file_at(path.as_std_path(), destdir, path_tmp.as_std_path()) + .with_context(|| format!("copying {:?} to {:?}", path, path_tmp))?; + } + + // do local exchange or rename + for (dst, tmp) in updates.iter() { + let dst = dst.as_std_path(); + log::trace!("doing local exchange for {} and {:?}", tmp, dst); + if destdir.exists(dst)? { + destdir + .local_exchange(tmp, dst) + .with_context(|| format!("exchange for {} and {:?}", tmp, dst))?; + } else { + destdir + .local_rename(tmp, dst) + .with_context(|| format!("rename for {} and {:?}", tmp, dst))?; + } } - // Ensure all of the new files are written persistently to disk + // Ensure all of the updates & changes are written persistently to disk if !opts.skip_sync { syncfs(destdir)?; } - // Now move them all into place (TODO track interruption) - for path in diff.additions.iter().chain(diff.changes.iter()) { - let pathtmp = tmpname_for_path(path); - destdir - .local_rename(&pathtmp, path) - .with_context(|| format!("renaming {path}"))?; - } - if !opts.skip_removals { - for path in diff.removals.iter() { - destdir - .remove_file_optional(path) - .with_context(|| format!("removing {path}"))?; - } + + // finally remove the temp dir + for (_, tmp) in updates.iter() { + log::trace!("cleanup: {}", tmp); + destdir.remove_all(tmp).context("clean up temp")?; } // A second full filesystem sync to narrow any races rather than // waiting for writeback to kick in. if !opts.skip_sync { syncfs(destdir)?; } - Ok(()) } @@ -345,6 +419,7 @@ mod tests { use super::*; use std::fs; use std::io::Write; + use std::path::Path; fn run_diff(a: &openat::Dir, b: &openat::Dir) -> Result { let ta = FileTree::new_from_dir(a)?; @@ -508,4 +583,129 @@ mod tests { assert!(!a.join(relp).join("shim.x64").exists()); Ok(()) } + #[test] + fn test_get_first_dir() -> Result<()> { + // test path + let path = Utf8Path::new("foo/subdir/bar"); + let (tp, tp_tmp) = get_first_dir(path)?; + assert_eq!(tp, Utf8Path::new("foo")); + assert_eq!(tp_tmp, ".btmp.foo"); + // test file + let path = Utf8Path::new("testfile"); + let (tp, tp_tmp) = get_first_dir(path)?; + assert_eq!(tp, Utf8Path::new("testfile")); + assert_eq!(tp_tmp, ".btmp.testfile"); + Ok(()) + } + #[test] + fn test_cleanup_tmp() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let p = tmpd.path(); + let pa = p.join("a/.btmp.a"); + let pb = p.join(".btmp.b/b"); + std::fs::create_dir_all(&pa)?; + std::fs::create_dir_all(&pb)?; + let dp = openat::Dir::open(p)?; + { + let mut buf = dp.write_file("a/foo", 0o644)?; + buf.write_all("foocontents".as_bytes())?; + let mut buf = dp.write_file("a/.btmp.foo", 0o644)?; + buf.write_all("foocontents".as_bytes())?; + let mut buf = dp.write_file(".btmp.b/foo", 0o644)?; + buf.write_all("foocontents".as_bytes())?; + } + assert!(dp.exists("a/.btmp.a")?); + assert!(dp.exists("a/foo")?); + assert!(dp.exists("a/.btmp.foo")?); + assert!(dp.exists("a/.btmp.a")?); + assert!(dp.exists(".btmp.b/b")?); + assert!(dp.exists(".btmp.b/foo")?); + cleanup_tmp(&dp)?; + assert!(!dp.exists("a/.btmp.a")?); + assert!(dp.exists("a/foo")?); + assert!(!dp.exists("a/.btmp.foo")?); + assert!(!dp.exists(".btmp.b")?); + Ok(()) + } + #[test] + fn test_apply_with_file() -> Result<()> { + let tmpd = tempfile::tempdir()?; + let p = tmpd.path(); + let pa = p.join("a"); + let pb = p.join("b"); + std::fs::create_dir(&pa)?; + std::fs::create_dir(&pb)?; + let a = openat::Dir::open(&pa)?; + let b = openat::Dir::open(&pb)?; + a.create_dir("foo", 0o755)?; + a.create_dir("bar", 0o755)?; + let foo = Path::new("foo/bar"); + let bar = Path::new("bar/foo"); + let testfile = "testfile"; + { + let mut buf = a.write_file(foo, 0o644)?; + buf.write_all("foocontents".as_bytes())?; + let mut buf = a.write_file(bar, 0o644)?; + buf.write_all("barcontents".as_bytes())?; + let mut buf = a.write_file(testfile, 0o644)?; + buf.write_all("testfilecontents".as_bytes())?; + } + + let diff = run_diff(&a, &b)?; + assert_eq!(diff.count(), 3); + b.create_dir("foo", 0o755)?; + { + let mut buf = b.write_file(foo, 0o644)?; + buf.write_all("foocontents".as_bytes())?; + } + let b_btime_foo = fs::metadata(pb.join(foo))?.created()?; + + { + let diff = run_diff(&b, &a)?; + assert_eq!(diff.count(), 2); + apply_diff(&a, &b, &diff, None).context("test additional files")?; + assert_eq!( + String::from_utf8(std::fs::read(pb.join(testfile))?)?, + "testfilecontents" + ); + assert_eq!( + String::from_utf8(std::fs::read(pb.join(bar))?)?, + "barcontents" + ); + // creation time is not changed for unchanged file + let b_btime_foo_new = fs::metadata(pb.join(foo))?.created()?; + assert_eq!(b_btime_foo_new, b_btime_foo); + } + { + fs::write(pa.join(testfile), "newtestfile")?; + fs::write(pa.join(bar), "newbar")?; + let diff = run_diff(&b, &a)?; + assert_eq!(diff.count(), 2); + apply_diff(&a, &b, &diff, None).context("test changed files")?; + assert_eq!( + String::from_utf8(std::fs::read(pb.join(testfile))?)?, + "newtestfile" + ); + assert_eq!(String::from_utf8(std::fs::read(pb.join(bar))?)?, "newbar"); + // creation time is not changed for unchanged file + let b_btime_foo_new = fs::metadata(pb.join(foo))?.created()?; + assert_eq!(b_btime_foo_new, b_btime_foo); + } + { + a.remove_file(testfile)?; + a.remove_file(bar)?; + let diff = run_diff(&b, &a)?; + assert_eq!(diff.count(), 2); + apply_diff(&a, &b, &diff, None).context("test removed files")?; + assert_eq!(b.exists(testfile)?, false); + assert_eq!(b.exists(bar)?, false); + let diff = run_diff(&b, &a)?; + assert_eq!(diff.count(), 0); + // creation time is not changed for unchanged file + let b_btime_foo_new = fs::metadata(pb.join(foo))?.created()?; + assert_eq!(b_btime_foo_new, b_btime_foo); + } + + Ok(()) + } } From e08bc297845398f2010ff535669513792c296a07 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 18 Jul 2024 09:12:31 +0800 Subject: [PATCH 600/641] filetree: add failpoint when doing exchange Inspired by https://github.com/coreos/bootupd/pull/669#issuecomment-2220760948 --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 1 + src/bootupd.rs | 15 +++++++++++++++ src/efi.rs | 2 +- src/failpoints.rs | 21 +++++++++++++++++++++ src/filetree.rs | 2 +- src/main.rs | 2 ++ tests/e2e-update/e2e-update-in-vm.sh | 7 ++++++- tests/e2e-update/e2e-update.sh | 8 ++++++-- 9 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 src/failpoints.rs diff --git a/Cargo.lock b/Cargo.lock index 71a8d808f..9c5ad3ecd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,6 +134,7 @@ dependencies = [ "chrono", "clap", "env_logger", + "fail", "fn-error-context", "fs2", "hex", @@ -361,6 +362,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "fail" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c" +dependencies = [ + "log", + "once_cell", + "rand", +] + [[package]] name = "fastrand" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index a3f44aad1..155159bab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ camino = "1.1.7" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } env_logger = "0.11" +fail = { version = "0.5", features = ["failpoints"] } fn-error-context = "0.2.1" fs2 = "0.4.3" hex = "0.4.3" diff --git a/src/bootupd.rs b/src/bootupd.rs index 72d025d03..4f029e83c 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -396,6 +396,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { } pub(crate) fn client_run_update() -> Result<()> { + crate::try_fail_point!("update"); let status: Status = status()?; if status.components.is_empty() && status.adoptable.is_empty() { println!("No components installed."); @@ -489,3 +490,17 @@ pub(crate) fn client_run_validate() -> Result<()> { } Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_failpoint_update() { + let guard = fail::FailScenario::setup(); + fail::cfg("update", "return").unwrap(); + let r = client_run_update(); + assert_eq!(r.is_err(), true); + guard.teardown(); + } +} diff --git a/src/efi.rs b/src/efi.rs index ecaee8224..ed53e854e 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -141,7 +141,7 @@ impl Efi { log::debug!("Not booted via EFI, skipping firmware update"); return Ok(()); } - let sysroot = Dir::open_ambient_dir(&Path::new("/"), cap_std::ambient_authority())?; + let sysroot = Dir::open_ambient_dir("/", cap_std::ambient_authority())?; let product_name = get_product_name(&sysroot)?; log::debug!("Get product name: {product_name}"); assert!(product_name.len() > 0); diff --git a/src/failpoints.rs b/src/failpoints.rs new file mode 100644 index 000000000..78dce44fe --- /dev/null +++ b/src/failpoints.rs @@ -0,0 +1,21 @@ +//! Wrappers and utilities on top of the `fail` crate. +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/// TODO: Use https://github.com/tikv/fail-rs/pull/68 once it merges +/// copy from https://github.com/coreos/rpm-ostree/commit/aa8d7fb0ceaabfaf10252180e2ddee049d07aae3#diff-adcc419e139605fae34d17b31418dbaf515af2fe9fb766fcbdb2eaad862b3daa +#[macro_export] +macro_rules! try_fail_point { + ($name:expr) => {{ + if let Some(e) = fail::eval($name, |msg| { + let msg = msg.unwrap_or_else(|| "synthetic failpoint".to_string()); + anyhow::Error::msg(msg) + }) { + return Err(From::from(e)); + } + }}; + ($name:expr, $cond:expr) => {{ + if $cond { + $crate::try_fail_point!($name); + } + }}; +} diff --git a/src/filetree.rs b/src/filetree.rs index 047ca384c..8234dcbac 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -395,6 +395,7 @@ pub(crate) fn apply_diff( .local_rename(tmp, dst) .with_context(|| format!("rename for {} and {:?}", tmp, dst))?; } + crate::try_fail_point!("update::exchange"); } // Ensure all of the updates & changes are written persistently to disk if !opts.skip_sync { @@ -705,7 +706,6 @@ mod tests { let b_btime_foo_new = fs::metadata(pb.join(foo))?.created()?; assert_eq!(b_btime_foo_new, b_btime_foo); } - Ok(()) } } diff --git a/src/main.rs b/src/main.rs index b075bde06..7c7cb40c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ mod component; mod coreos; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] mod efi; +mod failpoints; mod filesystem; mod filetree; #[cfg(any( @@ -43,6 +44,7 @@ use clap::crate_name; /// Binary entrypoint, for both daemon and client logic. fn main() { + let _scenario = fail::FailScenario::setup(); let exit_code = run_cli(); std::process::exit(exit_code); } diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index fd969cad7..0956bdfac 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -67,7 +67,12 @@ tmpefimount=$(mount_tmp_efi) assert_not_has_file ${tmpefimount}/EFI/fedora/test-bootupd.efi -bootupctl update | tee out.txt +if env FAILPOINTS='update::exchange=return' bootupctl update -vvv 2>err.txt; then + fatal "should have errored" +fi +assert_file_has_content err.txt "error: .*synthetic failpoint" + +bootupctl update -vvv | tee out.txt assert_file_has_content out.txt "Previous EFI: .*" assert_file_has_content out.txt "Updated EFI: ${TARGET_GRUB_PKG}.*,test-bootupd-payload-1.0" diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh index e45623f78..5fc19e878 100755 --- a/tests/e2e-update/e2e-update.sh +++ b/tests/e2e-update/e2e-update.sh @@ -24,10 +24,14 @@ export test_tmpdir=${testtmp} # This is new content for our update test_bootupd_payload_file=/boot/efi/EFI/fedora/test-bootupd.efi +test_bootupd_payload_file1=/boot/efi/EFI/BOOT/test-bootupd1.efi build_rpm test-bootupd-payload \ - files ${test_bootupd_payload_file} \ + files "${test_bootupd_payload_file} + ${test_bootupd_payload_file1}" \ install "mkdir -p %{buildroot}/$(dirname ${test_bootupd_payload_file}) - echo test-payload > %{buildroot}/${test_bootupd_payload_file}" + echo test-payload > %{buildroot}/${test_bootupd_payload_file} + mkdir -p %{buildroot}/$(dirname ${test_bootupd_payload_file1}) + echo test-payload1 > %{buildroot}/${test_bootupd_payload_file1}" # Start in cosa dir cd ${COSA_DIR} From d1425fe254dcdaf2419813d2797c49818a24abeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:50:18 +0000 Subject: [PATCH 601/641] build(deps): bump serde_json from 1.0.121 to 1.0.122 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.121 to 1.0.122. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.121...v1.0.122) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c38cd442..73b6fbff2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -858,9 +858,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", "memchr", From b5b8cd95329c6da19b67d89d92125761cc17a9b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:50:19 +0000 Subject: [PATCH 602/641] build(deps): bump regex from 1.10.5 to 1.10.6 Bumps [regex](https://github.com/rust-lang/regex) from 1.10.5 to 1.10.6. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.10.5...1.10.6) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c38cd442..e01be6dac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -779,9 +779,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 04dae5934..7da39c40e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" -regex = "1.10.5" +regex = "1.10.6" rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 9454a61b9cff161ff3e7820ef135e9cf67c81350 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 01:49:59 +0000 Subject: [PATCH 603/641] build(deps): bump tempfile from 3.11.0 to 3.12.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.11.0 to 3.12.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/commits) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 88 ++++++++++++++++++++++++++++++++---------------------- Cargo.toml | 2 +- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1613d2e66..d6380f91d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -171,7 +171,7 @@ dependencies = [ "ipnet", "maybe-owned", "rustix", - "windows-sys", + "windows-sys 0.52.0", "winx", ] @@ -237,7 +237,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -351,7 +351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -394,7 +394,7 @@ checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" dependencies = [ "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -485,7 +485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" dependencies = [ "io-lifetimes", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -818,7 +818,7 @@ dependencies = [ "libc", "linux-raw-sys", "once_cell", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -904,15 +904,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1097,7 +1097,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1117,17 +1126,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1138,9 +1148,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -1150,9 +1160,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -1162,9 +1172,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -1174,9 +1190,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -1186,9 +1202,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -1198,9 +1214,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -1210,9 +1226,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winx" @@ -1221,5 +1237,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" dependencies = [ "bitflags 2.4.1", - "windows-sys", + "windows-sys 0.52.0", ] diff --git a/Cargo.toml b/Cargo.toml index 7da39c40e..7c4617bbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ regex = "1.10.6" rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.11" +tempfile = "^3.12" widestring = "1.1.0" walkdir = "2.3.2" From 84c091ad377b5bb6e066bd967091be1931066ba7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 21:15:02 +0000 Subject: [PATCH 604/641] build(deps): bump clap from 4.5.13 to 4.5.16 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.13 to 4.5.16. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.13...clap_complete-v4.5.16) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d30c11d84..96757d753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,9 +250,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.13" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstyle", "clap_lex", From 0918b1a106d9cecc8be71543196f6f629fa632d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:19:59 +0000 Subject: [PATCH 605/641] build(deps): bump camino from 1.1.7 to 1.1.9 Bumps [camino](https://github.com/camino-rs/camino) from 1.1.7 to 1.1.9. - [Release notes](https://github.com/camino-rs/camino/releases) - [Changelog](https://github.com/camino-rs/camino/blob/main/CHANGELOG.md) - [Commits](https://github.com/camino-rs/camino/compare/camino-1.1.7...camino-1.1.9) --- updated-dependencies: - dependency-name: camino dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96757d753..0f92bf744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,9 +162,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" [[package]] name = "cap-primitives" diff --git a/Cargo.toml b/Cargo.toml index 272f404e6..2b3e8f5ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ path = "src/main.rs" anyhow = "1.0" bincode = "1.3.2" cap-std-ext = "4.0.0" -camino = "1.1.7" +camino = "1.1.9" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } env_logger = "0.11" From c547c82435e08129ef494a32e7fadc25611c505a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:20:06 +0000 Subject: [PATCH 606/641] build(deps): bump serde_json from 1.0.122 to 1.0.127 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.122 to 1.0.127. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.122...1.0.127) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96757d753..feb64083f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,9 +877,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "itoa", "memchr", From 5b5bc6f63bd52d0ff1d76012da2d589f4c8586dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:20:12 +0000 Subject: [PATCH 607/641] build(deps): bump libc from 0.2.155 to 0.2.158 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.155 to 0.2.158. - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.158/CHANGELOG.md) - [Commits](https://github.com/rust-lang/libc/compare/0.2.155...0.2.158) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96757d753..954488c9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -548,9 +548,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libsystemd" From a842e47866190856cc71b404954e47098b5f3b01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:20:22 +0000 Subject: [PATCH 608/641] build(deps): bump serde from 1.0.204 to 1.0.209 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.204 to 1.0.209. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.204...v1.0.209) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96757d753..9028c8f3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -857,18 +857,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", From 2ca0d3067562cb713b53757d2ba42e6d546817f0 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Tue, 27 Aug 2024 09:41:47 +0800 Subject: [PATCH 609/641] Release 0.2.21 See https://github.com/coreos/bootupd/issues/712 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e887ee834..b627181e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.20" +version = "0.2.21" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 2b3e8f5ce..302bea361 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.20" +version = "0.2.21" authors = ["Colin Walters "] edition = "2021" rust-version = "1.75.0" From c5e7115f1a14bbd926a7c297b15f3e80e823c1a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 01:27:36 +0000 Subject: [PATCH 610/641] build(deps): bump rustix from 0.38.34 to 0.38.35 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.34 to 0.38.35. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.34...v0.38.35) --- updated-dependencies: - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b627181e5..0b36c89b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -572,9 +572,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" @@ -827,9 +827,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index 302bea361..ea2b37020 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" regex = "1.10.6" -rustix = { version = "0.38.34", features = ["process", "fs"] } +rustix = { version = "0.38.35", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.12" From 6fcc010ce084741313610ff64824c2384dcc29e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Mon, 2 Sep 2024 16:58:27 +0200 Subject: [PATCH 611/641] bootupctl: Clear failure status from previous runs If for whatever reason a bootupd command fails, it will leave the systemd service unit in a failed state and systemd will then refuse to run a unit under the same name with `systemd-run` again until the failure is cleared. Thus systematically call `systemctl reset-failed` before calling `systemd-run` to clear any potential failures from previous calls. Do not check the return code of the systemctl command on purpose as it may fail if the unit does not exists yet, i.e. if no bootupctl command has been run yet. Also ignore stdout/stderr to avoid showing unexpected errors messages to users. See: https://github.com/coreos/bootupd/issues/707 See: https://github.com/coreos/bootupd/pull/663 --- src/cli/bootupctl.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 123d42bda..ab86f9f8b 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -4,7 +4,7 @@ use clap::Parser; use log::LevelFilter; use std::os::unix::process::CommandExt; -use std::process::Command; +use std::process::{Command, Stdio}; static SYSTEMD_ARGS_BOOTUPD: &[&str] = &[ "--unit", @@ -154,6 +154,14 @@ fn ensure_running_in_systemd() -> Result<()> { require_root_permission()?; let running_in_systemd = running_in_systemd(); if !running_in_systemd { + // Clear any failure status that may have happened previously + let _r = Command::new("systemctl") + .arg("reset-failed") + .arg("bootupd.service") + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()? + .wait()?; let r = Command::new("systemd-run") .args(SYSTEMD_ARGS_BOOTUPD) .args(std::env::args()) From 14954a8accd660dc7f697951d3bb0b8d6ee4e287 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:16:52 +0000 Subject: [PATCH 612/641] build(deps): bump anyhow from 1.0.86 to 1.0.87 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.86 to 1.0.87. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.86...1.0.87) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b36c89b2..4256a1b39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "autocfg" From 5f7e34ffe1cc740d3e2908035a8d871fc69d766c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:16:59 +0000 Subject: [PATCH 613/641] build(deps): bump rustix from 0.38.35 to 0.38.36 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.35 to 0.38.36. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.35...v0.38.36) --- updated-dependencies: - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b36c89b2..fad25598c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,9 +827,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.35" +version = "0.38.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" +checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index ea2b37020..74c3a49bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" regex = "1.10.6" -rustix = { version = "0.38.35", features = ["process", "fs"] } +rustix = { version = "0.38.36", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.12" From faef64db882c7105a91f22bb569c7b5cbefb4a80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:17:09 +0000 Subject: [PATCH 614/641] build(deps): bump clap from 4.5.16 to 4.5.17 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.16 to 4.5.17. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.16...clap_complete-v4.5.17) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b36c89b2..116ecf30a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,9 +250,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstyle", "clap_lex", From ca234b1ef97a6b8bb62da0528220e20bcd8c8385 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:17:17 +0000 Subject: [PATCH 615/641] build(deps): bump serde_json from 1.0.127 to 1.0.128 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.127 to 1.0.128. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.127...1.0.128) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b36c89b2..4af8c6b8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,9 +877,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", From 56c5a16763e123178fc4d96cf6a7ce432f5dd380 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 06:53:29 +0000 Subject: [PATCH 616/641] build(deps): bump serde from 1.0.209 to 1.0.210 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.209 to 1.0.210. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.209...v1.0.210) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cc1f50ff..c271a17e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -857,18 +857,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", From 0aebbc5b424099abc64ab7c0d49a88cbfbf83e47 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Sat, 14 Sep 2024 15:04:16 +0800 Subject: [PATCH 617/641] spec: sync upstream to build all archs and drop i686 --- contrib/packaging/bootupd.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/packaging/bootupd.spec b/contrib/packaging/bootupd.spec index ebe3c2d3d..53c8fdd32 100644 --- a/contrib/packaging/bootupd.spec +++ b/contrib/packaging/bootupd.spec @@ -14,7 +14,10 @@ Source0: https://github.com/coreos/bootupd/releases/download/v%{version}/ Source1: https://github.com/coreos/bootupd/releases/download/v%{version}/bootupd-%{version}-vendor.tar.zstd # For now, see upstream -ExclusiveArch: x86_64 aarch64 +# See https://github.com/coreos/fedora-coreos-tracker/issues/1716 +%if 0%{?fedora} || 0%{?rhel} >= 10 +ExcludeArch: %{ix86} +%endif BuildRequires: make BuildRequires: cargo # For autosetup -Sgit From 12b5d5d8bad5cb2b906caadd76ef75565c07b08d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:08:14 +0000 Subject: [PATCH 618/641] build(deps): bump anyhow from 1.0.87 to 1.0.89 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.87 to 1.0.89. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.87...1.0.89) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd0d9dc5e..3fd03a632 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "autocfg" From f2035126a70bb591a9c2531b3648335faf8c4d28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:08:23 +0000 Subject: [PATCH 619/641] build(deps): bump rustix from 0.38.36 to 0.38.37 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.36 to 0.38.37. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGELOG.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.36...v0.38.37) --- updated-dependencies: - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd0d9dc5e..d75211001 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,9 +827,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.36" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index 74c3a49bb..594e08e32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" regex = "1.10.6" -rustix = { version = "0.38.36", features = ["process", "fs"] } +rustix = { version = "0.38.37", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.12" From 7cc055f7710929af5666704dd1cd0627ee84015f Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 12 Sep 2024 17:02:51 +0800 Subject: [PATCH 620/641] bios.rs: add `adopt-and-update` Fixes https://github.com/coreos/bootupd/issues/717 --- src/bios.rs | 22 ++++++++++------ src/component.rs | 32 +++++++++++++++++++++++ src/efi.rs | 38 ++++------------------------ tests/e2e-update/e2e-update-in-vm.sh | 7 +++++ 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index a3fb23fc1..481fff16a 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -122,16 +122,22 @@ impl Component for Bios { } fn query_adopt(&self) -> Result> { - Ok(None) + crate::component::query_adopt_state() } - #[allow(unused_variables)] - fn adopt_update( - &self, - sysroot: &openat::Dir, - update: &ContentMetadata, - ) -> Result { - todo!(); + fn adopt_update(&self, _: &openat::Dir, update: &ContentMetadata) -> Result { + let Some(meta) = self.query_adopt()? else { + anyhow::bail!("Failed to find adoptable system") + }; + + let device = self.get_device()?; + let device = device.trim(); + self.run_grub_install("/", device)?; + Ok(InstalledContent { + meta: update.clone(), + filetree: None, + adopted_from: Some(meta.version), + }) } fn query_update(&self, sysroot: &openat::Dir) -> Result> { diff --git a/src/component.rs b/src/component.rs index 65be68d15..dfff20d5e 100644 --- a/src/component.rs +++ b/src/component.rs @@ -144,6 +144,38 @@ pub(crate) fn get_component_update( } } +#[context("Querying adoptable state")] +pub(crate) fn query_adopt_state() -> Result> { + // This would be extended with support for other operating systems later + if let Some(coreos_aleph) = crate::coreos::get_aleph_version(Path::new("/"))? { + let meta = ContentMetadata { + timestamp: coreos_aleph.ts, + version: coreos_aleph.aleph.version, + }; + log::trace!("Adoptable: {:?}", &meta); + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); + } else { + log::trace!("No CoreOS aleph detected"); + } + let ostree_deploy_dir = Path::new("/ostree/deploy"); + if ostree_deploy_dir.exists() { + let btime = ostree_deploy_dir.metadata()?.created()?; + let timestamp = chrono::DateTime::from(btime); + let meta = ContentMetadata { + timestamp, + version: "unknown".to_string(), + }; + return Ok(Some(Adoptable { + version: meta, + confident: true, + })); + } + Ok(None) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/efi.rs b/src/efi.rs index ed53e854e..75c34f4c9 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -179,7 +179,7 @@ fn string_from_utf16_bytes(slice: &[u8]) -> String { fn read_efi_var_utf16_string(name: &str) -> Option { let efivars = Path::new("/sys/firmware/efi/efivars"); if !efivars.exists() { - log::warn!("No efivars mount at {:?}", efivars); + log::trace!("No efivars mount at {:?}", efivars); return None; } let path = efivars.join(name); @@ -239,39 +239,13 @@ impl Component for Efi { log::trace!("No ESP detected"); return Ok(None); }; - // This would be extended with support for other operating systems later - if let Some(coreos_aleph) = crate::coreos::get_aleph_version(Path::new("/"))? { - let meta = ContentMetadata { - timestamp: coreos_aleph.ts, - version: coreos_aleph.aleph.version, - }; - log::trace!("EFI adoptable: {:?}", &meta); - return Ok(Some(Adoptable { - version: meta, - confident: true, - })); - } else { - log::trace!("No CoreOS aleph detected"); - } + // Don't adopt if the system is booted with systemd-boot or // systemd-stub since those will be managed with bootctl. if skip_systemd_bootloaders() { return Ok(None); } - let ostree_deploy_dir = Path::new("/ostree/deploy"); - if ostree_deploy_dir.exists() { - let btime = ostree_deploy_dir.metadata()?.created()?; - let timestamp = chrono::DateTime::from(btime); - let meta = ContentMetadata { - timestamp, - version: "unknown".to_string(), - }; - return Ok(Some(Adoptable { - version: meta, - confident: true, - })); - } - Ok(None) + crate::component::query_adopt_state() } /// Given an adoptable system and an update, perform the update. @@ -280,10 +254,8 @@ impl Component for Efi { sysroot: &openat::Dir, updatemeta: &ContentMetadata, ) -> Result { - let meta = if let Some(meta) = self.query_adopt()? { - meta - } else { - anyhow::bail!("Failed to find adoptable system"); + let Some(meta) = self.query_adopt()? else { + anyhow::bail!("Failed to find adoptable system") }; let esp = self.open_esp()?; diff --git a/tests/e2e-update/e2e-update-in-vm.sh b/tests/e2e-update/e2e-update-in-vm.sh index 0956bdfac..a35775334 100755 --- a/tests/e2e-update/e2e-update-in-vm.sh +++ b/tests/e2e-update/e2e-update-in-vm.sh @@ -84,6 +84,13 @@ if test -s out.txt; then fi ok update not avail +mount -o remount,rw /boot +rm -f /boot/bootupd-state.json +bootupctl adopt-and-update | tee out.txt +assert_file_has_content out.txt "Adopted and updated: BIOS: .*" +assert_file_has_content out.txt "Adopted and updated: EFI: .*" +ok adopt-and-update + tap_finish touch /run/testtmp/success sync From 7e2fbc4600f843a49029dfe5952b53488e3c7a7f Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 18 Sep 2024 22:12:40 +0800 Subject: [PATCH 621/641] Release 0.2.22 See https://github.com/coreos/bootupd/issues/727 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f44e58a4a..f7f0aa13d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.21" +version = "0.2.22" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 594e08e32..cc1dfd7b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.21" +version = "0.2.22" authors = ["Colin Walters "] edition = "2021" rust-version = "1.75.0" From 68ec4a82a90ef16a3fe0a770e9fdb7679da861b1 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Fri, 20 Sep 2024 16:35:10 +0800 Subject: [PATCH 622/641] Convert to `let-else` syntax Convert to [let else](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html) where possible. Inspired by https://github.com/coreos/bootupd/pull/723#discussion_r1757480310 --- src/bios.rs | 4 +--- src/bootupd.rs | 10 +++------- src/efi.rs | 4 +--- src/filetree.rs | 8 ++------ src/util.rs | 4 +--- 5 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index 481fff16a..fbe128562 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -95,9 +95,7 @@ impl Component for Bios { device: &str, _update_firmware: bool, ) -> Result { - let meta = if let Some(meta) = get_component_update(src_root, self)? { - meta - } else { + let Some(meta) = get_component_update(src_root, self)? else { anyhow::bail!("No update metadata for component {} found", self.name()); }; diff --git a/src/bootupd.rs b/src/bootupd.rs index 4f029e83c..dd441096b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -249,9 +249,7 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { ensure_writable_boot()?; - let update = if let Some(update) = component.query_update(&sysroot)? { - update - } else { + let Some(update) = component.query_update(&sysroot)? else { anyhow::bail!("Component {} has no available update", name); }; let mut state_guard = @@ -270,12 +268,10 @@ pub(crate) fn adopt_and_update(name: &str) -> Result { pub(crate) fn validate(name: &str) -> Result { let state = SavedState::load_from_disk("/")?.unwrap_or_default(); let component = component::new_from_name(name)?; - let inst = if let Some(inst) = state.installed.get(name) { - inst.clone() - } else { + let Some(inst) = state.installed.get(name) else { anyhow::bail!("Component {} is not installed", name); }; - component.validate(&inst) + component.validate(inst) } pub(crate) fn status() -> Result { diff --git a/src/efi.rs b/src/efi.rs index 75c34f4c9..2ab46c247 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -283,9 +283,7 @@ impl Component for Efi { device: &str, update_firmware: bool, ) -> Result { - let meta = if let Some(meta) = get_component_update(src_root, self)? { - meta - } else { + let Some(meta) = get_component_update(src_root, self)? else { anyhow::bail!("No update metadata for component {} found", self.name()); }; log::debug!("Found metadata {}", meta.version); diff --git a/src/filetree.rs b/src/filetree.rs index 8234dcbac..cf10f8c3c 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -104,9 +104,7 @@ impl FileTree { let mut ret = HashMap::new(); for entry in dir.list_dir(".")? { let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { + let Some(name) = entry.file_name().to_str() else { bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) }; if name.starts_with(TMP_PREFIX) { @@ -239,9 +237,7 @@ impl FileTree { fn cleanup_tmp(dir: &openat::Dir) -> Result<()> { for entry in dir.list_dir(".")? { let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { + let Some(name) = entry.file_name().to_str() else { // Skip invalid UTF-8 for now, we will barf on it later though. continue; }; diff --git a/src/util.rs b/src/util.rs index d52a745e8..0635ef41e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -37,9 +37,7 @@ pub(crate) fn filenames(dir: &openat::Dir) -> Result> { let mut ret = HashSet::new(); for entry in dir.list_dir(".")? { let entry = entry?; - let name = if let Some(name) = entry.file_name().to_str() { - name - } else { + let Some(name) = entry.file_name().to_str() else { bail!("Invalid UTF-8 filename: {:?}", entry.file_name()) }; match dir.get_file_type(&entry)? { From b1ca7671ddade1a7079b3cb31af9cdc6c6f47f7c Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Fri, 20 Sep 2024 10:58:31 +0800 Subject: [PATCH 623/641] Skip `UEFI` or `BIOS` on none hybrid partition layout - When booting with `BIOS` and no `ESP` device detected, skip `UEFI` checking - When booting with `UEFI` and no `bios_boot` partition found, skip `BIOS` checking Fixes https://github.com/coreos/bootupd/issues/717 --- src/bios.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/bootupd.rs | 6 +----- src/efi.rs | 35 ++++++++++++++++++++++----------- 3 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/bios.rs b/src/bios.rs index fbe128562..11609d284 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -8,10 +8,23 @@ use crate::packagesystem; use anyhow::{bail, Result}; use crate::util; +use serde::{Deserialize, Serialize}; // grub2-install file path pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; +#[derive(Serialize, Deserialize, Debug)] +struct BlockDevice { + path: String, + pttype: String, + parttypename: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Devices { + blockdevices: Vec, +} + #[derive(Default)] pub(crate) struct Bios {} @@ -22,12 +35,11 @@ impl Bios { #[cfg(target_arch = "x86_64")] { // find /boot partition - let boot_dir = Path::new("/").join("boot"); cmd = Command::new("findmnt"); cmd.arg("--noheadings") .arg("--output") .arg("SOURCE") - .arg(boot_dir); + .arg("/boot"); let partition = util::cmd_output(&mut cmd)?; // lsblk to find parent device @@ -81,6 +93,38 @@ impl Bios { } Ok(()) } + + // check bios_boot partition on gpt type disk + fn get_bios_boot_partition(&self) -> Result> { + let target = self.get_device()?; + // lsblk to list children with bios_boot + let output = Command::new("lsblk") + .args([ + "--json", + "--output", + "PATH,PTTYPE,PARTTYPENAME", + target.trim(), + ]) + .output()?; + if !output.status.success() { + std::io::stderr().write_all(&output.stderr)?; + bail!("Failed to run lsblk"); + } + + let output = String::from_utf8(output.stdout)?; + // Parse the JSON string into the `Devices` struct + let devices: Devices = serde_json::from_str(&output).expect("JSON was not well-formatted"); + + // Find the device with the parttypename "BIOS boot" + for device in devices.blockdevices { + if let Some(parttypename) = &device.parttypename { + if parttypename == "BIOS boot" && device.pttype == "gpt" { + return Ok(Some(device.path)); + } + } + } + Ok(None) + } } impl Component for Bios { @@ -120,6 +164,11 @@ impl Component for Bios { } fn query_adopt(&self) -> Result> { + #[cfg(target_arch = "x86_64")] + if crate::efi::is_efi_booted()? && self.get_bios_boot_partition()?.is_none() { + log::debug!("Skip BIOS adopt"); + return Ok(None); + } crate::component::query_adopt_state() } diff --git a/src/bootupd.rs b/src/bootupd.rs index dd441096b..2bf2c6b4f 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -380,11 +380,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> { #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] { - let boot_method = if Path::new("/sys/firmware/efi").exists() { - "EFI" - } else { - "BIOS" - }; + let boot_method = if efi::is_efi_booted()? { "EFI" } else { "BIOS" }; println!("Boot method: {}", boot_method); } diff --git a/src/efi.rs b/src/efi.rs index 2ab46c247..389de5811 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -63,6 +63,10 @@ impl Efi { } fn open_esp_optional(&self) -> Result> { + if !is_efi_booted()? && self.get_esp_device().is_none() { + log::debug!("Skip EFI"); + return Ok(None); + } let sysroot = openat::Dir::open("/")?; let esp = sysroot.sub_dir_optional(&self.esp_path()?)?; Ok(esp) @@ -75,6 +79,20 @@ impl Efi { Ok(esp) } + fn get_esp_device(&self) -> Option { + let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL] + .into_iter() + .map(|p| Path::new("/dev/disk/by-partlabel/").join(p)); + let mut esp_device = None; + for path in esp_devices { + if path.exists() { + esp_device = Some(path); + break; + } + } + return esp_device; + } + pub(crate) fn ensure_mounted_esp(&self, root: &Path) -> Result { let mut mountpoint = self.mountpoint.borrow_mut(); if let Some(mountpoint) = mountpoint.as_deref() { @@ -94,17 +112,9 @@ impl Efi { return Ok(mnt); } - let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL] - .into_iter() - .map(|p| Path::new("/dev/disk/by-partlabel/").join(p)); - let mut esp_device = None; - for path in esp_devices { - if path.exists() { - esp_device = Some(path); - break; - } - } - let esp_device = esp_device.ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?; + let esp_device = self + .get_esp_device() + .ok_or_else(|| anyhow::anyhow!("Failed to find ESP device"))?; for &mnt in ESP_MOUNTS.iter() { let mnt = root.join(mnt); if !mnt.exists() { @@ -386,6 +396,9 @@ impl Component for Efi { } fn validate(&self, current: &InstalledContent) -> Result { + if !is_efi_booted()? && self.get_esp_device().is_none() { + return Ok(ValidationResult::Skip); + } let currentf = current .filetree .as_ref() From ed100c118d8d1c90084871a6b752313c11e951d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:25:07 +0000 Subject: [PATCH 624/641] build(deps): bump clap from 4.5.17 to 4.5.18 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.17 to 4.5.18. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.17...clap_complete-v4.5.18) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7f0aa13d..ffb0a4167 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,9 +250,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstyle", "clap_lex", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", From c91c97bcad59b66ab6ff50055bc6d1879f85a9d5 Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Wed, 25 Sep 2024 01:46:59 +0000 Subject: [PATCH 625/641] Release 0.2.23 See https://github.com/coreos/bootupd/issues/733 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffb0a4167..c37355d23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.22" +version = "0.2.23" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index cc1dfd7b1..7d7f9e30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.22" +version = "0.2.23" authors = ["Colin Walters "] edition = "2021" rust-version = "1.75.0" From 1c378bfc86f2de58f2e6f3776746754dd88b9d9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:08:16 +0000 Subject: [PATCH 626/641] build(deps): bump regex from 1.10.6 to 1.11.0 Bumps [regex](https://github.com/rust-lang/regex) from 1.10.6 to 1.11.0. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.10.6...1.11.0) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c37355d23..c633cf388 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -798,9 +798,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -810,9 +810,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -821,9 +821,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" diff --git a/Cargo.toml b/Cargo.toml index 7d7f9e30d..60df4ac3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" -regex = "1.10.6" +regex = "1.11.0" rustix = { version = "0.38.37", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From be3fb22a6775fed0ca469071a3b6397d89266f28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:16:34 +0000 Subject: [PATCH 627/641] build(deps): bump tempfile from 3.12.0 to 3.13.0 Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.12.0 to 3.13.0. - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.12.0...v3.13.0) --- updated-dependencies: - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c37355d23..13ecd6e76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -375,9 +375,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fn-error-context" @@ -923,9 +923,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", diff --git a/Cargo.toml b/Cargo.toml index 7d7f9e30d..9eda2901c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ regex = "1.10.6" rustix = { version = "0.38.37", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" -tempfile = "^3.12" +tempfile = "^3.13" widestring = "1.1.0" walkdir = "2.3.2" From 5f359ee5eb3803a143fc826f68817e86e94810d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:16:36 +0000 Subject: [PATCH 628/641] build(deps): bump libc from 0.2.158 to 0.2.159 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.158 to 0.2.159. - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.159/CHANGELOG.md) - [Commits](https://github.com/rust-lang/libc/compare/0.2.158...0.2.159) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c37355d23..ceefdb497 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -548,9 +548,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libsystemd" From f8504baad9b985a53537472716acf1f53c161383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Wed, 2 Oct 2024 16:12:17 +0200 Subject: [PATCH 629/641] bios: Handle empty pttype from lsblk output zram, sr0 (CD/DVD) and LUKS devices generally don't use partitions, thus don't have a partition table and thus don't have a partition table type so this field may be null. Fixes: https://github.com/coreos/bootupd/issues/739 Signed-off-by: Colin Walters --- src/bios.rs | 23 ++++++++++++++--- tests/fixtures/example-lsblk-output.json | 33 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/example-lsblk-output.json diff --git a/src/bios.rs b/src/bios.rs index 11609d284..96d007416 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -16,7 +16,7 @@ pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; #[derive(Serialize, Deserialize, Debug)] struct BlockDevice { path: String, - pttype: String, + pttype: Option, parttypename: Option, } @@ -113,12 +113,14 @@ impl Bios { let output = String::from_utf8(output.stdout)?; // Parse the JSON string into the `Devices` struct - let devices: Devices = serde_json::from_str(&output).expect("JSON was not well-formatted"); + let Ok(devices) = serde_json::from_str::(&output) else { + bail!("Could not deserialize JSON output from lsblk"); + }; // Find the device with the parttypename "BIOS boot" for device in devices.blockdevices { if let Some(parttypename) = &device.parttypename { - if parttypename == "BIOS boot" && device.pttype == "gpt" { + if parttypename == "BIOS boot" && device.pttype.as_deref() == Some("gpt") { return Ok(Some(device.path)); } } @@ -213,3 +215,18 @@ impl Component for Bios { Ok(None) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_lsblk_output() { + let data = include_str!("../tests/fixtures/example-lsblk-output.json"); + let devices: Devices = serde_json::from_str(&data).expect("JSON was not well-formatted"); + assert_eq!(devices.blockdevices.len(), 7); + assert_eq!(devices.blockdevices[0].path, "/dev/sr0"); + assert!(devices.blockdevices[0].pttype.is_none()); + assert!(devices.blockdevices[0].parttypename.is_none()); + } +} diff --git a/tests/fixtures/example-lsblk-output.json b/tests/fixtures/example-lsblk-output.json new file mode 100644 index 000000000..f0aac3e0d --- /dev/null +++ b/tests/fixtures/example-lsblk-output.json @@ -0,0 +1,33 @@ +{ + "blockdevices": [ + { + "path": "/dev/sr0", + "pttype": null, + "parttypename": null + },{ + "path": "/dev/zram0", + "pttype": null, + "parttypename": null + },{ + "path": "/dev/vda", + "pttype": "gpt", + "parttypename": null + },{ + "path": "/dev/vda1", + "pttype": "gpt", + "parttypename": "EFI System" + },{ + "path": "/dev/vda2", + "pttype": "gpt", + "parttypename": "Linux extended boot" + },{ + "path": "/dev/vda3", + "pttype": "gpt", + "parttypename": "Linux filesystem" + },{ + "path": "/dev/mapper/luks-df2d5f95-5725-44dd-83e1-81bc4cdc49b8", + "pttype": null, + "parttypename": null + } + ] +} From f13d561f20a3c1d4bf475f8ae80517017e9c4463 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 01:51:43 +0000 Subject: [PATCH 630/641] build(deps): bump clap from 4.5.18 to 4.5.19 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.18 to 4.5.19. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.18...clap_complete-v4.5.19) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29b26b55f..e6b5c3794 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,9 +250,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.18" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" dependencies = [ "clap_builder", "clap_derive", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" dependencies = [ "anstyle", "clap_lex", From 4ed8134ce04f6e67aa0a8224881d868c1796094e Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Thu, 10 Oct 2024 13:19:08 +0000 Subject: [PATCH 631/641] Release 0.2.24 This is to include https://github.com/coreos/bootupd/pull/740. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6b5c3794..1243a03b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "bootupd" -version = "0.2.23" +version = "0.2.24" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 2768207bd..3f0176405 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bootupd" description = "Bootloader updater" license = "Apache-2.0" -version = "0.2.23" +version = "0.2.24" authors = ["Colin Walters "] edition = "2021" rust-version = "1.75.0" From a72a41f7babef47fa3ffcdb3e80430175daa6cbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 02:51:15 +0000 Subject: [PATCH 632/641] build(deps): bump cap-std-ext from 4.0.2 to 4.0.3 Bumps [cap-std-ext](https://github.com/coreos/cap-std-ext) from 4.0.2 to 4.0.3. - [Commits](https://github.com/coreos/cap-std-ext/compare/v4.0.2...v4.0.3) --- updated-dependencies: - dependency-name: cap-std-ext dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1243a03b9..a4e78d8f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,12 +197,13 @@ dependencies = [ [[package]] name = "cap-std-ext" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0279cf1f7b6cbeeb98e6946e8fea58136f691d4d0aa8c775f4439a05030a481" +checksum = "ef94280e28b736a40311060c9aa8a88e961dd6b05914bfcfc10a8d9ab0ad43d4" dependencies = [ "cap-primitives", "cap-tempfile", + "libc", "rustix", ] diff --git a/Cargo.toml b/Cargo.toml index 3f0176405..5280a5d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0" bincode = "1.3.2" -cap-std-ext = "4.0.0" +cap-std-ext = "4.0.3" camino = "1.1.9" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5", default-features = false, features = ["cargo", "derive", "std", "help", "usage", "suggestions"] } From 22ba1b9a7a8d1f20ea9548b9fabea673beca46e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 08:51:49 +0000 Subject: [PATCH 633/641] build(deps): bump clap from 4.5.19 to 4.5.20 Bumps [clap](https://github.com/clap-rs/clap) from 4.5.19 to 4.5.20. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.19...clap_complete-v4.5.20) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a4e78d8f7..ed7669eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -261,9 +261,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstyle", "clap_lex", From 94bee2ec7b9c051b9535ebd0ced531c2485a6798 Mon Sep 17 00:00:00 2001 From: Renata Ravanelli Date: Thu, 17 Oct 2024 10:54:55 -0300 Subject: [PATCH 634/641] grub-static-pre.cfg: Update link to preserve coreos-assembler history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - grub.cfg was removed from the main branch in https://github.com/coreos/coreos-assembler/pull/3900 - Updated the link to maintain reference to the file’s origin and history. Signed-off-by: Renata Ravanelli --- src/grub2/grub-static-pre.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grub2/grub-static-pre.cfg b/src/grub2/grub-static-pre.cfg index 9717cfb9d..d4a81d883 100644 --- a/src/grub2/grub-static-pre.cfg +++ b/src/grub2/grub-static-pre.cfg @@ -1,4 +1,4 @@ -# This file is copied from https://github.com/coreos/coreos-assembler/blob/main/src/grub.cfg +# This file is copied from https://github.com/coreos/coreos-assembler/blob/0eb25d1c718c88414c0b9aedd19dc56c09afbda8/src/grub.cfg # Changes: # - Dropped Ignition glue, that can be injected into platform.cfg # petitboot doesn't support -e and doesn't support an empty path part From caa344c8d44e3e3301bfe6e80e078014694a67fe Mon Sep 17 00:00:00 2001 From: HuijingHei Date: Mon, 28 Oct 2024 08:38:40 +0000 Subject: [PATCH 635/641] ci: update `uraimo/run-on-arch-action` to v2.8.1 See https://github.com/uraimo/run-on-arch-action/issues/155 --- .github/workflows/cross.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cross.yml b/.github/workflows/cross.yml index 6cdad1726..12ddcd5a4 100644 --- a/.github/workflows/cross.yml +++ b/.github/workflows/cross.yml @@ -25,7 +25,7 @@ jobs: submodules: true set-safe-directory: true - - uses: uraimo/run-on-arch-action@v2.2.0 + - uses: uraimo/run-on-arch-action@v2.8.1 name: Build id: build with: From 0608bfeca30e3221fba22d667a5d2e7c0fae8566 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:04:38 +0000 Subject: [PATCH 636/641] build(deps): bump regex from 1.11.0 to 1.11.1 Bumps [regex](https://github.com/rust-lang/regex) from 1.11.0 to 1.11.1. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.11.0...1.11.1) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed7669eb1..0562aa17f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -799,9 +799,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 5280a5d35..c6d45104d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" -regex = "1.11.0" +regex = "1.11.1" rustix = { version = "0.38.37", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" From 3def9b0cdd7c1608f7eb6f54583b70193b900a8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:05:51 +0000 Subject: [PATCH 637/641] build(deps): bump anyhow from 1.0.89 to 1.0.91 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.89 to 1.0.91. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.89...1.0.91) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed7669eb1..ec1c5e25a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "autocfg" From 230a84026672746081cc2d11bd337125d4598a0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:47:43 +0000 Subject: [PATCH 638/641] build(deps): bump rustix from 0.38.37 to 0.38.38 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.37 to 0.38.38. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGELOG.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.37...v0.38.38) --- updated-dependencies: - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0562aa17f..b94398c84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,9 +549,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libsystemd" @@ -828,9 +828,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index c6d45104d..9034ab1b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" regex = "1.11.1" -rustix = { version = "0.38.37", features = ["process", "fs"] } +rustix = { version = "0.38.38", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.13" From 912766d773d87dbbbedbe88e87c7e4ea78208c57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:47:47 +0000 Subject: [PATCH 639/641] build(deps): bump serde_json from 1.0.128 to 1.0.132 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.128 to 1.0.132. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.128...1.0.132) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0562aa17f..0b8d71fd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -878,9 +878,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", From d60bd2d2435a888d104435c2efd47896b6d27591 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:47:53 +0000 Subject: [PATCH 640/641] build(deps): bump openssl from 0.10.66 to 0.10.68 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.66 to 0.10.68. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...openssl-v0.10.68) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0562aa17f..26b500dbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -692,9 +692,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", From 308da3d5c5f694c137cfdb4a7e7b2336695854c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:52:31 +0000 Subject: [PATCH 641/641] build(deps): bump serde from 1.0.210 to 1.0.213 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.210 to 1.0.213. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.210...v1.0.213) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccce82e53..77b82f6aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -751,9 +751,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -858,18 +858,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", @@ -913,9 +913,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote",