-
Notifications
You must be signed in to change notification settings - Fork 6
chore: added ods version compatibility check #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
5fc7a00
5d5aa99
1ad8ff7
8801416
e336899
150380a
c2a7c85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| use crate::common::{config_path, validate_password, validate_token_and_claims}; | ||
| use crate::common::{config_path, validate_password, validate_token_and_claims, VERSION_CHECK}; | ||
| use crate::middleware::TOKEN_EXPIRE_HOURS; | ||
| use crate::socket_client::*; | ||
| use actix_files::NamedFile; | ||
|
|
@@ -113,7 +113,16 @@ impl Api { | |
|
|
||
| pub async fn healthcheck() -> impl Responder { | ||
| debug!("healthcheck() called"); | ||
| HttpResponse::Ok().finish() | ||
|
|
||
| if let Some(result) = VERSION_CHECK.get() { | ||
| if result.version_mismatch { | ||
| HttpResponse::ServiceUnavailable().json(result) | ||
| } else { | ||
| HttpResponse::Ok().json(result) | ||
| } | ||
| } else { | ||
| HttpResponse::Ok().body("No version check performed yet") | ||
| } | ||
JanZachmann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| pub async fn factory_reset( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,22 @@ | ||
| 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}; | ||
| use std::{fs, io::Write, path::Path, sync::OnceLock}; | ||
|
|
||
| pub static VERSION_CHECK: OnceLock<VersionCheckResult> = OnceLock::new(); | ||
|
||
|
|
||
| #[derive(Clone, Debug, Serialize)] | ||
| pub struct VersionCheckResult { | ||
| pub req_ods_version: String, | ||
| pub cur_ods_version: String, | ||
| pub version_mismatch: bool, | ||
| } | ||
|
|
||
| #[derive(Deserialize)] | ||
| pub struct RealmInfo { | ||
|
|
@@ -30,6 +41,7 @@ pub struct StatusResponse { | |
| #[derive(Deserialize)] | ||
| pub struct SystemInfo { | ||
| pub fleet_id: Option<String>, | ||
| omnect_device_service_version: String, | ||
| } | ||
|
|
||
| #[derive(Deserialize)] | ||
|
|
@@ -199,3 +211,27 @@ pub fn create_frontend_config_file(keycloak_url: &str) -> Result<()> { | |
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| pub async fn check_and_store_ods_version(ods_socket_path: &str) -> Result<()> { | ||
| 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(¤t_version); | ||
|
|
||
| VERSION_CHECK.get_or_init(|| VersionCheckResult { | ||
| req_ods_version: REQ_ODS_VERSION.to_string(), | ||
| cur_ods_version: status_response | ||
| .system_info | ||
| .omnect_device_service_version | ||
| .clone(), | ||
| version_mismatch, | ||
| }); | ||
|
|
||
| Ok(()) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
||
|
|
@@ -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"); | ||
ronny-standtke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 :)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @empwilli what do you mean by "...attempt to create a file..."? |
||
| 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")); | ||
|
|
@@ -166,19 +179,11 @@ async fn main() { | |
| ¢rifugo_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!())); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
healthcheck must be called in another PR during startup and handle the result