Skip to content

Commit

Permalink
Check cli vs server versions
Browse files Browse the repository at this point in the history
  • Loading branch information
jupposessho committed Mar 30, 2024
1 parent 37d9eb5 commit eca51f9
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 3 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions golem-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ tracing-subscriber = "0.3.18"
tungstenite = "0.20.1"
url = { workspace = true }
uuid = { workspace = true }
version-compare = "=0.0.11"

[dev-dependencies]
async-recursion = "1.0.5"
Expand Down
1 change: 1 addition & 0 deletions golem-cli/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
// limitations under the License.

pub mod errors;
pub mod health_check;
pub mod template;
pub mod worker;
8 changes: 7 additions & 1 deletion golem-cli/src/clients/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use golem_client::api::{TemplateError, WorkerError};
use golem_client::api::{HealthCheckError, TemplateError, WorkerError};
use golem_client::model::{
GolemError, GolemErrorFailedToResumeWorker, GolemErrorGetLatestVersionOfTemplateFailed,
GolemErrorInterrupted, GolemErrorInvalidRequest, GolemErrorInvalidShardId,
Expand Down Expand Up @@ -54,6 +54,12 @@ impl ResponseContentErrorMapper for WorkerError {
}
}

impl ResponseContentErrorMapper for HealthCheckError {
fn map(self) -> String {
"Invalid request".to_string()
}
}

fn display_golem_error(error: golem_client::model::GolemError) -> String {
match error {
GolemError::InvalidRequest(GolemErrorInvalidRequest { details }) => {
Expand Down
40 changes: 40 additions & 0 deletions golem-cli/src/clients/health_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2024 Golem Cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use async_trait::async_trait;
use golem_client::model::VersionInfo;
use tracing::debug;

use crate::model::GolemError;

#[async_trait]
pub trait HealthCheckClient {
async fn version(&self) -> Result<VersionInfo, GolemError>;
}

#[derive(Clone)]
pub struct HealthCheckClientLive<C: golem_client::api::HealthCheckClient + Sync + Send> {
pub client: C,
}

#[async_trait]
impl<C: golem_client::api::HealthCheckClient + Sync + Send> HealthCheckClient
for HealthCheckClientLive<C>
{
async fn version(&self) -> Result<VersionInfo, GolemError> {
debug!("Getting server version");

Ok(self.client.version().await?)
}
}
2 changes: 1 addition & 1 deletion golem-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub mod clients;
pub mod examples;
pub mod model;
pub mod template;
pub mod version;
pub mod worker;

pub fn parse_key_val(
s: &str,
) -> Result<(String, String), Box<dyn std::error::Error + Send + Sync + 'static>> {
Expand Down
30 changes: 29 additions & 1 deletion golem-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ use golem_examples::model::{ExampleName, GuestLanguage, GuestLanguageTier, Packa
use reqwest::Url;
use tracing_subscriber::FmtSubscriber;

use golem_cli::clients::health_check::HealthCheckClientLive;
use golem_cli::clients::template::TemplateClientLive;
use golem_cli::clients::worker::WorkerClientLive;
use golem_cli::examples;
use golem_cli::template::{TemplateHandler, TemplateHandlerLive, TemplateSubcommand};
use golem_cli::version::{VersionHandler, VersionHandlerLive};
use golem_cli::worker::{WorkerHandler, WorkerHandlerLive, WorkerSubcommand};

#[derive(Subcommand, Debug)]
Expand Down Expand Up @@ -169,7 +171,7 @@ async fn async_main(cmd: GolemCommand) -> Result<(), Box<dyn std::error::Error>>

let template_client = TemplateClientLive {
client: golem_client::api::TemplateClientLive {
context: template_context,
context: template_context.clone(),
},
};
let template_srv = TemplateHandlerLive {
Expand All @@ -187,6 +189,32 @@ async fn async_main(cmd: GolemCommand) -> Result<(), Box<dyn std::error::Error>>
templates: &template_srv,
};

let health_check_client_for_template = HealthCheckClientLive {
client: golem_client::api::HealthCheckClientLive {
context: template_context.clone(),
},
};

let health_check_client_for_worker = HealthCheckClientLive {
client: golem_client::api::HealthCheckClientLive {
context: worker_context.clone(),
},
};

let update_srv = VersionHandlerLive {
template_client: health_check_client_for_template,
worker_client: health_check_client_for_worker,
};

let yellow = "\x1b[33m";
let reset_color = "\x1b[0m";

let version_check = update_srv.check().await;

if let Err(err) = version_check {
eprintln!("{}{}{}", yellow, err.0, reset_color)
}

let res = match cmd.command {
Command::Template { subcommand } => template_srv.handle(subcommand).await,
Command::Worker { subcommand } => worker_srv.handle(subcommand).await,
Expand Down
66 changes: 66 additions & 0 deletions golem-cli/src/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 Golem Cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use async_trait::async_trait;
use version_compare::Version;

use crate::clients::health_check::HealthCheckClient;
use crate::model::{GolemError, GolemResult};

const VERSION: &str = env!("CARGO_PKG_VERSION");

#[async_trait]
pub trait VersionHandler {
async fn check(&self) -> Result<GolemResult, GolemError>;
}

pub struct VersionHandlerLive<
T: HealthCheckClient + Send + Sync + Send + Sync,
W: HealthCheckClient + Send + Sync + Send + Sync,
> {
pub template_client: T,
pub worker_client: W,
}

#[async_trait]
impl<T: HealthCheckClient + Send + Sync, W: HealthCheckClient + Send + Sync> VersionHandler
for VersionHandlerLive<T, W>
{
async fn check(&self) -> Result<GolemResult, GolemError> {
let template_version_info = self.template_client.version().await?;
let worker_version_info = self.worker_client.version().await?;

let cli_version = Version::from(VERSION).unwrap();
let template_version = Version::from(template_version_info.version.as_str()).unwrap();
let worker_version = Version::from(worker_version_info.version.as_str()).unwrap();

let warning = |cli_version: Version, server_version: Version| -> String {
format!("Warning: golem-cli {} is older than the targeted Golem servers ({})\nInstall the matching version with:\ncargo install golem-cli@{}\n", cli_version.as_str(), server_version.as_str(), server_version.as_str()).to_string()
};

if cli_version < template_version || cli_version < worker_version {
if template_version > worker_version {
Err(GolemError(warning(cli_version, template_version)))
} else {
Err(GolemError(warning(cli_version, worker_version)))
}
} else if cli_version < template_version {
Err(GolemError(warning(cli_version, template_version)))
} else if cli_version < worker_version {
Err(GolemError(warning(cli_version, worker_version)))
} else {
Ok(GolemResult::Str("No updates found".to_string()))
}
}
}

0 comments on commit eca51f9

Please sign in to comment.