taskcluster.rs (3161B)
1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0. If a copy of the MPL was not distributed with this 3 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 use anyhow::{Context, Result}; 6 7 pub struct TaskCluster { 8 root_url: url::Url, 9 client: reqwest::blocking::Client, 10 } 11 12 impl TaskCluster { 13 pub fn from_env() -> Result<Self> { 14 let root_url = if let Ok(proxy_url) = std::env::var("TASKCLUSTER_PROXY_URL") { 15 proxy_url 16 .parse() 17 .context("Couldn't parse TASKCLUSTER_PROXY_URL.")? 18 } else { 19 std::env::var("TASKCLUSTER_ROOT_URL") 20 .context("TASKCLUSTER_ROOT_URL not set.") 21 .and_then(|var| var.parse().context("Couldn't parse TASKCLUSTER_ROOT_URL."))? 22 }; 23 24 Ok(TaskCluster { 25 root_url, 26 client: reqwest::blocking::Client::new(), 27 }) 28 } 29 30 /// Return the root URL as suitable for passing to other processes. 31 /// 32 /// In particular, any trailing slashes are removed. 33 pub fn root_url(&self) -> String { 34 self.root_url.as_str().trim_end_matches("/").to_string() 35 } 36 37 pub fn task_artifact_url(&self, task_id: &str, path: &str) -> url::Url { 38 let mut url = self.root_url.clone(); 39 url.set_path(&format!("api/queue/v1/task/{}/artifacts/{}", task_id, path)); 40 url 41 } 42 43 pub fn stream_artifact(&self, task_id: &str, path: &str) -> Result<impl std::io::Read> { 44 let url = self.task_artifact_url(task_id, path); 45 Ok(self.client.get(url).send()?.error_for_status()?) 46 } 47 } 48 49 #[cfg(test)] 50 mod test { 51 use std::env; 52 53 #[test] 54 fn test_url() { 55 let cluster = super::TaskCluster { 56 root_url: url::Url::parse("http://taskcluster.example").unwrap(), 57 client: reqwest::blocking::Client::new(), 58 }; 59 assert_eq!( 60 cluster.task_artifact_url("QzDLgP4YRwanIvgPt6ClfA","public/docker-contexts/decision.tar.gz"), 61 url::Url::parse("http://taskcluster.example/api/queue/v1/task/QzDLgP4YRwanIvgPt6ClfA/artifacts/public/docker-contexts/decision.tar.gz").unwrap(), 62 ); 63 } 64 65 #[test] 66 fn test_from_env_proxy_url() { 67 env::set_var("TASKCLUSTER_PROXY_URL", "http://taskcluster"); 68 env::set_var( 69 "TASKCLUSTER_ROOT_URL", 70 "https://firefox-ci-tc.services.mozilla.com", 71 ); 72 73 let cluster = super::TaskCluster::from_env().unwrap(); 74 assert_eq!(cluster.root_url.as_str(), "http://taskcluster/"); 75 76 env::remove_var("TASKCLUSTER_PROXY_URL"); 77 env::remove_var("TASKCLUSTER_ROOT_URL"); 78 } 79 80 #[test] 81 fn test_from_env_fallback_to_root_url() { 82 env::remove_var("TASKCLUSTER_PROXY_URL"); 83 env::set_var( 84 "TASKCLUSTER_ROOT_URL", 85 "https://firefox-ci-tc.services.mozilla.com", 86 ); 87 88 let cluster = super::TaskCluster::from_env().unwrap(); 89 assert_eq!( 90 cluster.root_url.as_str(), 91 "https://firefox-ci-tc.services.mozilla.com/" 92 ); 93 94 env::remove_var("TASKCLUSTER_ROOT_URL"); 95 } 96 }