From f53a3bede0c47a03570ac342252680af2c9d787e Mon Sep 17 00:00:00 2001 From: PradeepKiruvale Date: Fri, 19 Aug 2022 12:00:27 +0530 Subject: Enhance the tedge_apt_plugin error message to be more verbose (#1341) * Enhance the error message to be more precise Signed-off-by: Pradeep Kumar K J --- plugins/tedge_apt_plugin/src/error.rs | 15 ++++--- plugins/tedge_apt_plugin/src/main.rs | 7 +-- plugins/tedge_apt_plugin/src/module_check.rs | 64 +++++++++++++++++----------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/plugins/tedge_apt_plugin/src/error.rs b/plugins/tedge_apt_plugin/src/error.rs index 07c8399a..c9332cf3 100644 --- a/plugins/tedge_apt_plugin/src/error.rs +++ b/plugins/tedge_apt_plugin/src/error.rs @@ -9,17 +9,18 @@ pub enum InternalError { #[error(transparent)] FromUtf8(#[from] std::string::FromUtf8Error), - #[error("Parsing Debian package failed for `{file}`")] - ParsingError { file: String }, - #[error(transparent)] FromCsv(#[from] csv::Error), - #[error("Validation of {package} failed with version mismatch. Installed version: {installed}, Expected version: {expected}")] - VersionMismatch { + #[error("Parsing Debian package failed for `{file}`, Error: {error}")] + ParsingError { file: String, error: String }, + + #[error("Validation of {package} metadata failed, expected value for the {expected_key} is {expected_value}, but provided {provided_value}")] + MetaDataMismatch { package: String, - installed: String, - expected: String, + expected_key: String, + expected_value: String, + provided_value: String, }, } diff --git a/plugins/tedge_apt_plugin/src/main.rs b/plugins/tedge_apt_plugin/src/main.rs index 5d503aeb..8fada405 100644 --- a/plugins/tedge_apt_plugin/src/main.rs +++ b/plugins/tedge_apt_plugin/src/main.rs @@ -207,10 +207,11 @@ fn validate_version(module_name: &str, module_version: &str) -> Result<(), Inter // Value at index 0 is the package name { if installed_version != module_version { - return Err(InternalError::VersionMismatch { + return Err(InternalError::MetaDataMismatch { package: module_name.into(), - installed: installed_version.into(), - expected: module_version.into(), + expected_key: "Version".into(), + expected_value: installed_version.into(), + provided_value: module_version.into(), }); } } diff --git a/plugins/tedge_apt_plugin/src/module_check.rs b/plugins/tedge_apt_plugin/src/module_check.rs index ecb20497..69ccb84e 100644 --- a/plugins/tedge_apt_plugin/src/module_check.rs +++ b/plugins/tedge_apt_plugin/src/module_check.rs @@ -1,5 +1,5 @@ use crate::error::InternalError; -use std::process::{Command, Stdio}; +use std::process::Command; use std::{ ffi::OsStr, path::{Path, PathBuf}, @@ -22,41 +22,55 @@ impl PackageMetadata { }) } - fn metadata_contains_all(&self, patterns: &[&str]) -> bool { + fn metadata_contains_all(&self, patterns: &[&str]) -> Result<(), InternalError> { for pattern in patterns { if !&self.metadata.contains(pattern) { - return false; - }; + let given_metadata_split: Vec<&str> = pattern.split(':').collect(); + // Extract the expected meta data value for the given key + // For example Package name, Version etc. + let expected_metadata_split: Vec<&str> = self + .metadata + .split(&given_metadata_split[0]) + .collect::>()[1] + .split('\n') + .collect::>()[0] + .split(':') + .collect(); + + return Err(InternalError::MetaDataMismatch { + package: self.file_path().to_string_lossy().to_string(), + expected_key: given_metadata_split[0].to_string(), + expected_value: expected_metadata_split[1].to_string(), + provided_value: given_metadata_split[1].to_string(), + }); + } } - true + Ok(()) } fn get_module_metadata(file_path: &str) -> Result, InternalError> { - Ok(Command::new("dpkg") - .arg("-I") - .arg(file_path) - .stdout(Stdio::piped()) - .output()? - .stdout) + let res = Command::new("dpkg").arg("-I").arg(file_path).output()?; + match res.status.success() { + true => Ok(res.stdout), + false => Err(InternalError::ParsingError { + file: file_path.to_string(), + error: String::from_utf8_lossy(&res.stderr).to_string(), + }), + } } pub fn validate_package(&mut self, contain_args: &[&str]) -> Result<(), InternalError> { - if self.metadata_contains_all(contain_args) { - // In the current implementation using `apt-get` it is required that the file has '.deb' extension (if we use dpkg extension doesn't matter). - if self.file_path.extension() != Some(OsStr::new("deb")) { - let new_path = PathBuf::from(format!("{}.deb", self.file_path().to_string_lossy())); + self.metadata_contains_all(contain_args)?; + // In the current implementation using `apt-get` it is required that the file has '.deb' extension (if we use dpkg extension doesn't matter). + if self.file_path.extension() != Some(OsStr::new("deb")) { + let new_path = PathBuf::from(format!("{}.deb", self.file_path().to_string_lossy())); - let _res = std::os::unix::fs::symlink(self.file_path(), &new_path); - self.file_path = new_path; - self.remove_modified = true; - } - - Ok(()) - } else { - Err(InternalError::ParsingError { - file: self.file_path().to_string_lossy().to_string(), - }) + let _res = std::os::unix::fs::symlink(self.file_path(), &new_path); + self.file_path = new_path; + self.remove_modified = true; } + + Ok(()) } pub fn file_path(&self) -> &Path { -- cgit v1.2.3