Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
name = "omnect-ui"
readme = "README.md"
repository = "git@github.com:omnect/omnect-ui.git"
version = "0.13.3"
version = "0.14.0"
build = "src/build.rs"

[dependencies]
Expand Down Expand Up @@ -50,6 +50,7 @@ rustls = { version = "0.23", default-features = false, features = [
rustls-pemfile = { version = "2.2", default-features = false, features = [
"std",
] }
semver = { version = "1.0", default-features = false }
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = [
"raw_value",
Expand Down
17 changes: 15 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ pub enum FactoryResetMode {
Mode4 = 4,
}

#[derive(Clone, Debug, Serialize)]
pub struct VersionCheckResult {
pub req_ods_version: String,
pub cur_ods_version: String,
pub version_mismatch: bool,
}

#[derive(Clone)]
pub struct Api {
pub ods_socket_path: String,
Expand All @@ -89,6 +96,7 @@ pub struct Api {
pub index_html: PathBuf,
pub keycloak_public_key_url: String,
pub tenant: String,
pub version_check_result: VersionCheckResult,
}

impl Api {
Expand All @@ -111,9 +119,14 @@ impl Api {
Ok(NamedFile::open(config_path!("app_config.js"))?)
}

pub async fn healthcheck() -> impl Responder {
pub async fn healthcheck(config: web::Data<Api>) -> impl Responder {
debug!("healthcheck() called");
HttpResponse::Ok().finish()

if config.version_check_result.version_mismatch {
HttpResponse::ServiceUnavailable().json(&config.version_check_result)
} else {
HttpResponse::Ok().json(&config.version_check_result)
}
}

pub async fn factory_reset(
Expand Down
26 changes: 26 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::api::VersionCheckResult;
use crate::REQ_ODS_VERSION;
use actix_web::body::MessageBody;
use anyhow::{anyhow, bail, Context, Result};
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use base64::{prelude::BASE64_STANDARD, Engine};
use jwt_simple::prelude::{RS256PublicKey, RSAPublicKeyLike};
use reqwest::blocking::get;
use semver::{Version, VersionReq};
use serde::{Deserialize, Serialize};
use std::{fs, io::Write, path::Path};

Expand All @@ -30,6 +33,7 @@ pub struct StatusResponse {
#[derive(Deserialize)]
pub struct SystemInfo {
pub fleet_id: Option<String>,
omnect_device_service_version: String,
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -199,3 +203,25 @@ pub fn create_frontend_config_file(keycloak_url: &str) -> Result<()> {

Ok(())
}

pub async fn check_and_store_ods_version(ods_socket_path: &str) -> Result<VersionCheckResult> {
let status_response = get_status(ods_socket_path)
.await
.context("failed to get status from socket client")?;

let version_req = VersionReq::parse(REQ_ODS_VERSION)
.map_err(|e| anyhow!("failed to parse REQ_ODS_VERSION: {e}"))?;
let current_version =
Version::parse(&status_response.system_info.omnect_device_service_version)
.map_err(|e| anyhow!("failed to parse omnect_device_service_version: {e}"))?;
let version_mismatch = !version_req.matches(&current_version);

Ok(VersionCheckResult {
req_ods_version: REQ_ODS_VERSION.to_string(),
cur_ods_version: status_response
.system_info
.omnect_device_service_version
.clone(),
version_mismatch,
})
}
24 changes: 15 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ use tokio::{
};
use uuid::Uuid;

pub const REQ_ODS_VERSION: &str = ">=0.39.0";

const UPLOAD_LIMIT_BYTES: usize = 250 * 1024 * 1024;
const MEMORY_LIMIT_BYTES: usize = 10 * 1024 * 1024;

Expand Down Expand Up @@ -120,11 +122,22 @@ async fn main() {
.parse::<u64>()
.expect("UI_PORT format");

let ods_socket_path = std::env::var("SOCKET_PATH").expect("env SOCKET_PATH is missing");
fs::exists(&ods_socket_path).unwrap_or_else(|_| {
panic!(
"omnect device service socket file {} does not exist",
&ods_socket_path
)
});
Comment on lines +126 to +131
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO we don't need this check. There might be cases where the unix domain socket exists and is deleted later on. We should instead ensure, that the open call to the unix domain socket does not attempt to create a file if the file does not exist, and handle the error on opening.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I just saw, that this is pre-existing code. Still: just drop the check :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@empwilli what do you mean by "...attempt to create a file..."?

let version_check_result = common::check_and_store_ods_version(&ods_socket_path)
.await
.expect("failed to check and store ods version");

CryptoProvider::install_default(default_provider()).expect("failed to install crypto provider");

certificate::create_module_certificate(&cert_path!(), &key_path!())
.await
.expect("Failed to create module certificate");
.expect("failed to create module certificate");

let mut tls_certs =
std::io::BufReader::new(std::fs::File::open(cert_path!()).expect("read certs_file"));
Expand Down Expand Up @@ -166,19 +179,11 @@ async fn main() {
&centrifugo_http_server_port!(),
);

let ods_socket_path = std::env::var("SOCKET_PATH").expect("env SOCKET_PATH is missing");
let index_html =
std::fs::canonicalize("static/index.html").expect("static/index.html not found");

let tenant = std::env::var("TENANT").expect("env TENANT is missing");

fs::exists(&ods_socket_path).unwrap_or_else(|_| {
panic!(
"omnect device service socket file {} does not exist",
&ods_socket_path
)
});

fs::exists(&update_os_path!())
.unwrap_or_else(|_| panic!("path {} for os update does not exist", &update_os_path!()));

Expand All @@ -194,6 +199,7 @@ async fn main() {
index_html,
keycloak_public_key_url: keycloak_url!(),
tenant,
version_check_result,
};

let session_key = Key::generate();
Expand Down
Loading