Better Linux distribution detection (fix #146)

This commit is contained in:
Roey Darwish Dror
2019-05-07 16:21:51 +03:00
parent 6186eadb70
commit 9f054308c8
3 changed files with 63 additions and 44 deletions

18
Cargo.lock generated
View File

@@ -1060,6 +1060,11 @@ dependencies = [
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "result"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.13" version = "0.1.13"
@@ -1174,6 +1179,16 @@ dependencies = [
"syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "serde_ini"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.39" version = "1.0.39"
@@ -1499,6 +1514,7 @@ dependencies = [
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"self_update 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "self_update 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1830,6 +1846,7 @@ dependencies = [
"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" "checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum reqwest 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3c4ef83e0beb14bfe38b9f01330a5bc8e965a9f9628690aa28383746dac1e925" "checksum reqwest 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3c4ef83e0beb14bfe38b9f01330a5bc8e965a9f9628690aa28383746dac1e925"
"checksum result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560"
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
@@ -1844,6 +1861,7 @@ dependencies = [
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" "checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4"
"checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79" "checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79"
"checksum serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139"
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" "checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2"
"checksum shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de7a5b5a9142fd278a10e0209b021a1b85849352e6951f4f914735c976737564" "checksum shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de7a5b5a9142fd278a10e0209b021a1b85849352e6951f4f914735c976737564"

View File

@@ -25,6 +25,7 @@ walkdir = "2.2.7"
console = "0.7.5" console = "0.7.5"
self_update_crate = { version = "0.5.1", optional = true, package = "self_update" } self_update_crate = { version = "0.5.1", optional = true, package = "self_update" }
lazy_static = "1.2.0" lazy_static = "1.2.0"
serde_ini = "0.2.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
nix = "0.13.0" nix = "0.13.0"

View File

@@ -3,62 +3,64 @@ use crate::executor::RunType;
use crate::terminal::{print_separator, print_warning}; use crate::terminal::{print_separator, print_warning};
use crate::utils::{require, require_option, which}; use crate::utils::{require, require_option, which};
use failure::ResultExt; use failure::ResultExt;
use serde::Deserialize;
use serde_ini;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use walkdir::WalkDir; use walkdir::WalkDir;
static OS_RELEASE_PATH: &str = "/etc/os-release";
#[derive(Debug, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
struct OsRelease {
id_like: Option<String>,
id: String,
}
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum Distribution { pub enum Distribution {
Arch, Arch,
CentOS, CentOS,
Fedora, Fedora,
Debian, Debian,
Ubuntu,
Gentoo, Gentoo,
OpenSuse, Suse,
Void, Void,
Solus, Solus,
Mint,
} }
impl Distribution { impl Distribution {
pub fn detect() -> Result<Self, Error> { fn parse_os_release() -> Result<Self, Error> {
let content = fs::read_to_string("/etc/os-release").context(ErrorKind::UnknownLinuxDistribution)?; let os_release: OsRelease =
serde_ini::de::from_read(fs::File::open(OS_RELEASE_PATH).context(ErrorKind::UnknownLinuxDistribution)?)
.context(ErrorKind::UnknownLinuxDistribution)?;
if content.contains("Arch") | content.contains("Manjaro") | content.contains("Antergos") { match os_release.id_like.as_ref().map(String::as_str) {
return Ok(Distribution::Arch); Some("debian") => {
}
if content.contains("CentOS") || content.contains("Oracle Linux") {
return Ok(Distribution::CentOS);
}
if content.contains("Fedora") {
return Ok(Distribution::Fedora);
}
if content.contains("Ubuntu") {
return Ok(Distribution::Ubuntu);
}
if content.contains("Debian") {
return Ok(Distribution::Debian); return Ok(Distribution::Debian);
} }
Some("\"suse\"") => {
if content.contains("openSUSE") { return Ok(Distribution::Suse);
return Ok(Distribution::OpenSuse); }
_ => (),
} }
if content.contains("void") { if let Some("debian") = os_release.id_like.as_ref().map(String::as_str) {}
return Ok(Distribution::Void);
Ok(match os_release.id.as_ref() {
"arch" => Distribution::Arch,
"centos" => Distribution::CentOS,
"fedora" => Distribution::Fedora,
"void" => Distribution::Void,
"solus" => Distribution::Solus,
_ => Err(ErrorKind::UnknownLinuxDistribution)?,
})
} }
if content.contains("Solus") { pub fn detect() -> Result<Self, Error> {
return Ok(Distribution::Solus); if PathBuf::from(OS_RELEASE_PATH).exists() {
} return Self::parse_os_release();
if content.contains("Mint") {
return Ok(Distribution::Mint);
} }
if PathBuf::from("/etc/gentoo-release").exists() { if PathBuf::from("/etc/gentoo-release").exists() {
@@ -76,11 +78,9 @@ impl Distribution {
Distribution::Arch => upgrade_arch_linux(&sudo, cleanup, run_type), Distribution::Arch => upgrade_arch_linux(&sudo, cleanup, run_type),
Distribution::CentOS => upgrade_redhat(&sudo, run_type), Distribution::CentOS => upgrade_redhat(&sudo, run_type),
Distribution::Fedora => upgrade_fedora(&sudo, run_type), Distribution::Fedora => upgrade_fedora(&sudo, run_type),
Distribution::Ubuntu | Distribution::Debian | Distribution::Mint => { Distribution::Debian => upgrade_debian(&sudo, cleanup, run_type),
upgrade_debian(&sudo, cleanup, run_type)
}
Distribution::Gentoo => upgrade_gentoo(&sudo, run_type), Distribution::Gentoo => upgrade_gentoo(&sudo, run_type),
Distribution::OpenSuse => upgrade_opensuse(&sudo, run_type), Distribution::Suse => upgrade_suse(&sudo, run_type),
Distribution::Void => upgrade_void(&sudo, run_type), Distribution::Void => upgrade_void(&sudo, run_type),
Distribution::Solus => upgrade_solus(&sudo, run_type), Distribution::Solus => upgrade_solus(&sudo, run_type),
} }
@@ -152,7 +152,7 @@ fn upgrade_redhat(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error
Ok(()) Ok(())
} }
fn upgrade_opensuse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> { fn upgrade_suse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
if let Some(sudo) = &sudo { if let Some(sudo) = &sudo {
run_type run_type
.execute(&sudo) .execute(&sudo)