1mod arch;
2mod linux;
3#[allow(dead_code)]
4mod macos;
5#[allow(dead_code)]
6mod windows;
7
8use std::{collections::HashMap, env::consts};
9
10use lazy_static::lazy_static;
11use semver::Version;
12
13pub use self::{arch::Architecture, linux::LinuxType, macos::MacOsType, windows::WindowsType};
14use crate::{
15 error::{Error, Result},
16 url::{Url, UrlBuilder},
17 util::FileExtension,
18};
19
20lazy_static! {
21 pub static ref OS_MAP: HashMap<&'static str, OperatingSystem> = {
22 let mut map = HashMap::new();
23
24 map.insert("amazon", OperatingSystem::Linux(LinuxType::Amazon));
25 map.insert("debian71", OperatingSystem::Linux(LinuxType::Debian7));
26 map.insert("debian81", OperatingSystem::Linux(LinuxType::Debian8));
27 map.insert("legacy", OperatingSystem::Linux(LinuxType::Legacy));
28 map.insert("osx", OperatingSystem::MacOs(MacOsType::Ssl));
29 map.insert("osx-nossl", OperatingSystem::MacOs(MacOsType::NonSsl));
30 map.insert("rhel62", OperatingSystem::Linux(LinuxType::Rhel6));
31 map.insert("rhel70", OperatingSystem::Linux(LinuxType::Rhel7));
32 map.insert("suse11", OperatingSystem::Linux(LinuxType::Suse11));
33 map.insert("suse12", OperatingSystem::Linux(LinuxType::Suse12));
34 map.insert("ubuntu1204", OperatingSystem::Linux(LinuxType::Ubuntu1204));
35 map.insert("ubuntu1404", OperatingSystem::Linux(LinuxType::Ubuntu1404));
36 map.insert(
37 "ubuntu1604",
38 OperatingSystem::Linux(LinuxType::Ubuntu1604(Architecture::X86_64)),
39 );
40 map.insert(
41 "ubuntu1604-arm",
42 OperatingSystem::Linux(LinuxType::Ubuntu1604(Architecture::Arm)),
43 );
44 map.insert("ubuntu1804", OperatingSystem::Linux(LinuxType::Ubuntu1804));
45 map
46 };
47 pub static ref OS_NAMES: Vec<&'static str> = {
48 let mut names: Vec<_> = OS_MAP.keys().cloned().collect();
49 names.sort();
50
51 names
52 };
53}
54
55#[derive(Clone, Debug)]
56pub enum OperatingSystem {
57 Linux(LinuxType),
58
59 #[allow(dead_code)]
60 MacOs(MacOsType),
61
62 #[allow(dead_code)]
63 Windows(WindowsType),
64}
65
66impl OperatingSystem {
67 pub fn get(version: &Version) -> Result<Self> {
68 match consts::OS {
69 "linux" => LinuxType::get().map(OperatingSystem::Linux),
70 "macos" => {
71 let macos_type = if version.major < 3 {
75 MacOsType::NonSsl
76 } else {
77 MacOsType::Ssl
78 };
79
80 Ok(OperatingSystem::MacOs(macos_type))
81 }
82 "windows" => Err(Error::UnsupportedOs {
83 os_name: "windows".to_string(),
84 }),
85 s => Err(Error::UnsupportedOs {
86 os_name: s.to_string(),
87 }),
88 }
89 }
90}
91
92impl OperatingSystem {
93 fn extension(&self) -> FileExtension {
94 match *self {
95 OperatingSystem::Linux(_) | OperatingSystem::MacOs(_) => FileExtension::Tgz,
96 OperatingSystem::Windows(_) => FileExtension::Msi,
97 }
98 }
99
100 fn name(&self) -> &'static str {
101 match *self {
102 OperatingSystem::Linux(_) => "linux",
103 OperatingSystem::MacOs(_) => "osx",
104 OperatingSystem::Windows(_) => "win32",
105 }
106 }
107
108 pub fn from_name(name: &str) -> Option<Self> {
109 OS_MAP.get(name).map(Clone::clone)
110 }
111
112 pub fn download_url(&self, version: &Version) -> Url {
113 let mut builder = UrlBuilder::new(self.name(), self.extension().name(), version);
114
115 builder.add_distro_path_item("mongodb".to_string());
116 builder.add_distro_path_item(self.name().to_string());
117
118 let url_path = match *self {
119 OperatingSystem::Linux(ref os_type) => os_type.url_path(version),
120 OperatingSystem::MacOs(ref os_type) => os_type.url_path(version),
121 OperatingSystem::Windows(ref os_type) => os_type.url_path(version),
122 };
123
124 for item in url_path {
125 builder.add_distro_path_item(item);
126 }
127
128 builder.build()
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use semver::Version;
135
136 use super::arch::Architecture;
137 use super::linux::LinuxType;
138 use super::macos::MacOsType;
139 use super::windows::WindowsType;
140 use super::OperatingSystem;
141
142 fn matches_url(url: &str, os: OperatingSystem, version: Version) -> String {
143 let download_url = os.download_url(&version);
144 let dirname = download_url.dirname();
145
146 assert_eq!(url, String::from(download_url));
147 dirname
148 }
149
150 #[test]
154 fn amazon_linux_url() {
155 matches_url(
156 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.4.6.tgz",
157 OperatingSystem::Linux(LinuxType::Amazon),
158 version!(3, 4, 6),
159 );
160 }
161
162 #[test]
163 fn debian7_linux_url() {
164 matches_url(
165 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian71-3.4.6.tgz",
166 OperatingSystem::Linux(LinuxType::Debian7),
167 version!(3, 4, 6),
168 );
169 }
170
171 #[test]
172 fn debian8_linux_url() {
173 matches_url(
174 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-debian81-3.4.6.tgz",
175 OperatingSystem::Linux(LinuxType::Debian8),
176 version!(3, 4, 6),
177 );
178 }
179
180 #[test]
181 fn legacy_linux_url() {
182 matches_url(
183 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.6.tgz",
184 OperatingSystem::Linux(LinuxType::Legacy),
185 version!(3, 4, 6),
186 );
187 }
188
189 #[test]
190 fn rhel6_linux_url() {
191 matches_url(
192 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.6.tgz",
193 OperatingSystem::Linux(LinuxType::Rhel6),
194 version!(3, 4, 6),
195 );
196 }
197
198 #[test]
199 fn rhel7_linux_url() {
200 matches_url(
201 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.6.tgz",
202 OperatingSystem::Linux(LinuxType::Rhel7),
203 version!(3, 4, 6),
204 );
205 }
206
207 #[test]
208 fn suse11_linux_url() {
209 matches_url(
210 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse11-3.4.6.tgz",
211 OperatingSystem::Linux(LinuxType::Suse11),
212 version!(3, 4, 6),
213 );
214 }
215
216 #[test]
217 fn suse12_linux_url() {
218 matches_url(
219 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-3.4.6.tgz",
220 OperatingSystem::Linux(LinuxType::Suse12),
221 version!(3, 4, 6),
222 );
223 }
224
225 #[test]
226 fn ubuntu1204_linux_url() {
227 matches_url(
228 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1204-3.4.6.tgz",
229 OperatingSystem::Linux(LinuxType::Ubuntu1204),
230 version!(3, 4, 6),
231 );
232 }
233
234 #[test]
235 fn ubunutu1404_linux_url() {
236 matches_url(
237 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-3.4.6.tgz",
238 OperatingSystem::Linux(LinuxType::Ubuntu1404),
239 version!(3, 4, 6),
240 );
241 }
242
243 #[test]
244 fn ubunutu1604_arm_linux_url() {
245 matches_url(
246 "https://fastdl.mongodb.org/linux/mongodb-linux-arm64-ubuntu1604-3.4.6.tgz",
247 OperatingSystem::Linux(LinuxType::Ubuntu1604(Architecture::Arm)),
248 version!(3, 4, 6),
249 );
250 }
251
252 #[test]
253 fn ubuntu1604_x86_64_linux_url() {
254 matches_url(
255 "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.4.6.tgz",
256 OperatingSystem::Linux(LinuxType::Ubuntu1604(Architecture::X86_64)),
257 version!(3, 4, 6),
258 );
259 }
260
261 #[test]
265 fn nonssl_osx_url() {
266 let dirname = matches_url(
267 "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.4.6.tgz",
268 OperatingSystem::MacOs(MacOsType::NonSsl),
269 version!(3, 4, 6),
270 );
271
272 assert_eq!(dirname, "mongodb-osx-x86_64-3.4.6");
273 }
274
275 #[test]
276 fn ssl_osx_url() {
277 let dirname = matches_url(
278 "https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.4.6.tgz",
279 OperatingSystem::MacOs(MacOsType::Ssl),
280 version!(3, 4, 6),
281 );
282
283 assert_eq!(dirname, "mongodb-osx-x86_64-3.4.6");
284 }
285
286 #[test]
287 fn ssl_macos_url() {
288 let dirname = matches_url(
289 "https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.5.4.tgz",
290 OperatingSystem::MacOs(MacOsType::Ssl),
291 version!(3, 5, 4),
292 );
293
294 assert_eq!(dirname, "mongodb-macOS-x86_64-3.5.4");
295 }
296
297 #[test]
301 fn server2008_windows_url() {
302 matches_url(
303 "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-3.4.6-signed.msi",
304 OperatingSystem::Windows(WindowsType::Server2008),
305 version!(3, 4, 6),
306 );
307 }
308
309 #[test]
310 fn server2008_r2_windows_url() {
311 matches_url(
312 "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-3.4.6-signed.msi",
313 OperatingSystem::Windows(WindowsType::Server2008R2),
314 version!(3, 4, 6),
315 );
316 }
317
318 #[test]
319 fn server2008_r2_ssl_windows_url() {
320 matches_url(
321 "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.4.6-signed.msi",
322 OperatingSystem::Windows(WindowsType::Server2008R2Ssl),
323 version!(3, 4, 6),
324 );
325 }
326}