config.rs (4614B)
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::Result; 6 use serde::de::Error; 7 use serde::Deserialize; 8 use std::collections::HashMap; 9 10 fn default_image_name() -> String { 11 "mozilla.org/taskgraph/default-image:latest".into() 12 } 13 fn default_zstd_level() -> i32 { 14 3 15 } 16 17 fn from_json<'de, D, T>(deserializer: D) -> Result<T, D::Error> 18 where 19 D: serde::de::Deserializer<'de>, 20 T: serde::de::DeserializeOwned, 21 { 22 let value: String = serde::Deserialize::deserialize(deserializer)?; 23 serde_json::from_str(&value).map_err(|err| { 24 D::Error::invalid_value(serde::de::Unexpected::Str(&value), &&*err.to_string()) 25 }) 26 } 27 28 #[derive(Deserialize, Debug, PartialEq, Eq)] 29 pub struct Config { 30 pub context_task_id: String, 31 pub context_path: String, 32 pub parent_task_id: Option<String>, 33 #[serde(default = "default_image_name")] 34 pub image_name: String, 35 #[serde(default = "default_zstd_level")] 36 pub docker_image_zstd_level: i32, 37 #[serde(default)] 38 pub debug: bool, 39 #[serde(default, deserialize_with = "from_json")] 40 pub docker_build_args: HashMap<String, String>, 41 pub chown_output: Option<String>, 42 } 43 44 impl Config { 45 pub fn from_env() -> Result<Config> { 46 Ok(envy::from_env()?) 47 } 48 } 49 50 #[cfg(test)] 51 mod test { 52 use anyhow::Result; 53 54 #[test] 55 fn test() -> Result<()> { 56 let env: Vec<(String, String)> = vec![ 57 ("CONTEXT_TASK_ID".into(), "xGRRgzG6QlCCwsFsyuqm0Q".into()), 58 ( 59 "CONTEXT_PATH".into(), 60 "public/docker-contexts/image.tar.gz".into(), 61 ), 62 ]; 63 let config: super::Config = envy::from_iter(env.into_iter())?; 64 assert_eq!( 65 config, 66 super::Config { 67 context_task_id: "xGRRgzG6QlCCwsFsyuqm0Q".into(), 68 context_path: "public/docker-contexts/image.tar.gz".into(), 69 parent_task_id: None, 70 image_name: "mozilla.org/taskgraph/default-image:latest".into(), 71 docker_image_zstd_level: 3, 72 debug: false, 73 docker_build_args: Default::default(), 74 chown_output: None, 75 } 76 ); 77 Ok(()) 78 } 79 80 #[test] 81 fn test_docker_build_args() -> Result<()> { 82 let env: Vec<(String, String)> = vec![ 83 ("CONTEXT_TASK_ID".into(), "xGRRgzG6QlCCwsFsyuqm0Q".into()), 84 ( 85 "CONTEXT_PATH".into(), 86 "public/docker-contexts/image.tar.gz".into(), 87 ), 88 ( 89 "DOCKER_BUILD_ARGS".into(), 90 serde_json::json! ({ 91 "test": "Value", 92 }) 93 .to_string(), 94 ), 95 ]; 96 let config: super::Config = envy::from_iter(env.into_iter())?; 97 assert_eq!( 98 config, 99 super::Config { 100 context_task_id: "xGRRgzG6QlCCwsFsyuqm0Q".into(), 101 context_path: "public/docker-contexts/image.tar.gz".into(), 102 parent_task_id: None, 103 image_name: "mozilla.org/taskgraph/default-image:latest".into(), 104 docker_image_zstd_level: 3, 105 debug: false, 106 docker_build_args: [("test".to_string(), "Value".to_string())] 107 .iter() 108 .cloned() 109 .collect(), 110 chown_output: None, 111 } 112 ); 113 Ok(()) 114 } 115 116 #[test] 117 fn test_user_config() -> Result<()> { 118 let env: Vec<(String, String)> = vec![ 119 ("CONTEXT_TASK_ID".into(), "xGRRgzG6QlCCwsFsyuqm0Q".into()), 120 ( 121 "CONTEXT_PATH".into(), 122 "public/docker-contexts/image.tar.gz".into(), 123 ), 124 ("USER".into(), "1000:1000".into()), 125 ]; 126 let config: super::Config = envy::from_iter(env.into_iter())?; 127 assert_eq!( 128 config, 129 super::Config { 130 context_task_id: "xGRRgzG6QlCCwsFsyuqm0Q".into(), 131 context_path: "public/docker-contexts/image.tar.gz".into(), 132 parent_task_id: None, 133 image_name: "mozilla.org/taskgraph/default-image:latest".into(), 134 docker_image_zstd_level: 3, 135 debug: false, 136 docker_build_args: Default::default(), 137 chown_output: Some("1000:1000".into()), 138 } 139 ); 140 Ok(()) 141 } 142 }