Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updog: Add support for query parameters in TUF requests #542

Merged
merged 1 commit into from
Dec 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions workspaces/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions workspaces/updater/updog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ tough = { version = "0.1.0", features = ["http"] }
update_metadata = { path = "../update_metadata" }
structopt = "0.3"
migrator = { path = "../../api/migration/migrator" }
url = "2.1.0"

[dev-dependencies]
tempfile = "3.1.0"
6 changes: 6 additions & 0 deletions workspaces/updater/updog/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ pub(crate) enum Error {
source: std::io::Error,
},

#[snafu(display("2Borrow2Fast"))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆

TransportBorrow {
backtrace: Backtrace,
source: std::cell::BorrowMutError,
},

#[snafu(display("Failed to serialize update information: {}", source))]
UpdateSerialize {
source: serde_json::Error,
Expand Down
27 changes: 17 additions & 10 deletions workspaces/updater/updog/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#![warn(clippy::pedantic)]

mod error;
mod transport;

use crate::error::Result;
use crate::transport::{HttpQueryRepo, HttpQueryTransport};
use chrono::{DateTime, Utc};
use data_store_version::Version as DataVersion;
use semver::Version as SemVer;
Expand All @@ -17,11 +19,9 @@ use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::process;
use std::str::FromStr;
use tough::{HttpTransport, Limits, Repository, Settings};
use tough::{Limits, Repository, Settings};
use update_metadata::{Manifest, Update};

type HttpRepo<'a> = Repository<'a, HttpTransport>;

#[cfg(target_arch = "x86_64")]
const TARGET_ARCH: &str = "x86_64";
#[cfg(target_arch = "aarch64")]
Expand Down Expand Up @@ -96,7 +96,10 @@ fn load_config() -> Result<Config> {
Ok(config)
}

fn load_repository<'a>(transport: &'a HttpTransport, config: &'a Config) -> Result<HttpRepo<'a>> {
fn load_repository<'a>(
transport: &'a HttpQueryTransport,
config: &'a Config,
) -> Result<HttpQueryRepo<'a>> {
fs::create_dir_all("/var/lib/thar/updog").context(error::CreateMetadataCache)?;
Repository::load(
transport,
Expand All @@ -118,7 +121,7 @@ fn load_repository<'a>(transport: &'a HttpTransport, config: &'a Config) -> Resu
.context(error::Metadata)
}

fn load_manifest(repository: &HttpRepo<'_>) -> Result<Manifest> {
fn load_manifest(repository: &HttpQueryRepo<'_>) -> Result<Manifest> {
let target = "manifest.json";
serde_json::from_reader(
repository
Expand Down Expand Up @@ -201,7 +204,7 @@ fn update_required<'a>(
}

fn write_target_to_disk<P: AsRef<Path>>(
repository: &HttpRepo<'_>,
repository: &HttpQueryRepo<'_>,
target: &str,
disk_path: P,
) -> Result<()> {
Expand Down Expand Up @@ -261,7 +264,7 @@ fn migration_targets(
/// storage. All intermediate migrations between the current version and the
/// target version must be retrieved.
fn retrieve_migrations(
repository: &HttpRepo<'_>,
repository: &HttpQueryRepo<'_>,
manifest: &Manifest,
update: &Update,
) -> Result<()> {
Expand Down Expand Up @@ -309,7 +312,7 @@ fn retrieve_migrations(
Ok(())
}

fn update_image(update: &Update, repository: &HttpRepo<'_>) -> Result<()> {
fn update_image(update: &Update, repository: &HttpQueryRepo<'_>) -> Result<()> {
let mut gpt_state = State::load().context(error::PartitionTableRead)?;
gpt_state.clear_inactive();
// Write out the clearing of the inactive partition immediately, because we're about to
Expand Down Expand Up @@ -444,10 +447,14 @@ fn main_inner() -> Result<()> {
serde_plain::from_str::<Command>(&arguments.subcommand).unwrap_or_else(|_| usage());

let config = load_config()?;
let transport = HttpTransport::new();
let (current_version, flavor) = running_version()?;
let transport = HttpQueryTransport::new();
transport
.queries_get_mut()
.context(error::TransportBorrow)?
.push((String::from("version"), current_version.to_string()));
let repository = load_repository(&transport, &config)?;
let manifest = load_manifest(&repository)?;
let (current_version, flavor) = running_version().unwrap();

match command {
Command::CheckUpdate | Command::Whats => {
Expand Down
45 changes: 45 additions & 0 deletions workspaces/updater/updog/src/transport.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::cell::{BorrowMutError, RefCell};
use tough::{HttpTransport, Repository, Transport};
use url::Url;

#[derive(Debug)]
#[allow(clippy::module_name_repetitions)]
pub struct HttpQueryTransport {
pub inner: HttpTransport,
parameters: RefCell<Vec<(String, String)>>,
}

impl HttpQueryTransport {
pub fn new() -> Self {
Self {
inner: HttpTransport::new(),
parameters: RefCell::new(vec![]),
}
}

/// Try to borrow a mutable reference to parameters; returns an error if
/// a borrow is already active
pub fn queries_get_mut(
&self,
) -> Result<std::cell::RefMut<'_, Vec<(String, String)>>, BorrowMutError> {
self.parameters.try_borrow_mut()
}

fn set_query_string(&self, mut url: Url) -> Url {
tjkirch marked this conversation as resolved.
Show resolved Hide resolved
for (key, val) in self.parameters.borrow().iter() {
url.query_pairs_mut().append_pair(&key, &val);
}
url
}
}

pub type HttpQueryRepo<'a> = Repository<'a, HttpQueryTransport>;

impl Transport for HttpQueryTransport {
type Stream = reqwest::Response;
type Error = reqwest::Error;

fn fetch(&self, url: Url) -> Result<Self::Stream, Self::Error> {
self.inner.fetch(self.set_query_string(url))
}
}