From f0f496838971cc0e7f33f579e3bffb733f37b7d2 Mon Sep 17 00:00:00 2001 From: Esteban Borai Date: Wed, 1 Nov 2023 15:04:54 +0000 Subject: [PATCH] feat: deprecate `fluvio install` in place of `fvm` (#3647) Removes `fluvio install` to stick with `fvm` solution. ## Example ``` Fluvio Command Line Interface fluvio-cli [OPTIONS] Commands: consume Read messages from a topic/partition produce Write messages to a topic/partition topic Manage and view Topics partition Manage and view Partitions smartmodule Create and manage SmartModules [aliases: sm] table-format Create a TableFormat display specification [aliases: tf] hub Work with the SmartModule Hub profile Manage Profiles, which describe linked clusters cluster Install or uninstall Fluvio cluster version Print Fluvio version information completions Generate command-line completions for Fluvio Options: -c, --cluster Address of cluster --tls Enable TLS --enable-client-cert TLS: use client cert --domain Required if client cert is used --ca-cert Path to TLS ca cert, required when client cert is enabled --client-cert Path to TLS client certificate --client-key Path to TLS client private key -P, --profile -h, --help Print help ``` --- crates/fluvio-cli/src/error.rs | 2 - crates/fluvio-cli/src/install/mod.rs | 1 - crates/fluvio-cli/src/install/plugins.rs | 266 ----------------------- crates/fluvio-cli/src/lib.rs | 36 +-- 4 files changed, 9 insertions(+), 296 deletions(-) delete mode 100644 crates/fluvio-cli/src/install/mod.rs delete mode 100644 crates/fluvio-cli/src/install/plugins.rs diff --git a/crates/fluvio-cli/src/error.rs b/crates/fluvio-cli/src/error.rs index a7b8d592bb..428311c627 100644 --- a/crates/fluvio-cli/src/error.rs +++ b/crates/fluvio-cli/src/error.rs @@ -47,8 +47,6 @@ pub enum CliError { #[error("Invalid argument: {0}")] InvalidArg(String), - #[error("Unknown error: {0}")] - Other(String), #[error("{0}")] CollectedError(String), #[error("Unexpected Infallible error")] diff --git a/crates/fluvio-cli/src/install/mod.rs b/crates/fluvio-cli/src/install/mod.rs deleted file mode 100644 index 25a06164e5..0000000000 --- a/crates/fluvio-cli/src/install/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod plugins; diff --git a/crates/fluvio-cli/src/install/plugins.rs b/crates/fluvio-cli/src/install/plugins.rs deleted file mode 100644 index 3fa2824207..0000000000 --- a/crates/fluvio-cli/src/install/plugins.rs +++ /dev/null @@ -1,266 +0,0 @@ -use std::str::FromStr; -use clap::Parser; -use tracing::debug; -use anyhow::Result; -use current_platform::CURRENT_PLATFORM; - -use fluvio_cli_common::error::{HttpError, PackageNotFound}; -use fluvio_cli_common::install::{ - fetch_latest_version, fetch_package_file, fluvio_extensions_dir, install_bin, install_println, - fluvio_bin_dir, -}; - -use fluvio_index::{PackageId, HttpAgent, MaybeVersion}; -use fluvio_channel::{LATEST_CHANNEL_NAME, FLUVIO_RELEASE_CHANNEL}; -use fluvio_hub_util as hubutil; -use hubutil::{HubAccess, HUB_API_BPKG_AUTH, INFINYON_HUB_REMOTE, FLUVIO_HUB_PROFILE_ENV}; -use hubutil::http::{self, StatusCode}; - -use crate::error::CliError; - -#[derive(Parser, Debug)] -pub struct InstallOpt { - /// The ID of a package to install, e.g. "fluvio/fluvio-cloud". - package: Option>, - /// Used for testing. Specifies alternate package location, e.g. "test/" - #[arg(hide = true, long)] - prefix: Option, - /// Install the latest prerelease rather than the latest release - /// - /// If the package ID contains a version (e.g. `fluvio/fluvio:0.6.0`), this is ignored - #[arg(long)] - pub develop: bool, - - /// When this flag is provided, use the hub. Dev-only - #[arg(long, hide_short_help = true)] - pub hub: bool, - - /// Use local hub defaults. - /// Implied if INFINYON_HUB_REMOTE or FLUVIO_CLOUD_PROFILE env vars are set - /// - Dev-only - #[arg(long, hide_short_help = true)] - pub use_hub_defaults: bool, - - /// When this flag is provided, use the hub. Dev-only - #[arg(long, hide_short_help = true)] - pub channel: Option, - - /// override default target arch determination - #[arg(long, hide_short_help = true)] - pub target: Option, -} - -impl InstallOpt { - pub async fn process(self) -> Result<()> { - if self.hub { - debug!("Using the hub to install"); - - let mut homedir_path = fluvio_bin_dir()?; - let package_name; - //let binpath = "sample-bin-script"; - let bin_install_path = if let Some(ref p) = self.package { - let package = p; - package_name = package.name().to_string(); - homedir_path.push(package_name.clone()); - homedir_path.to_str().ok_or(crate::CliError::Other( - "Unable to render path to fluvio bin dir".to_string(), - ))? - } else { - return Err(crate::CliError::Other("No package name provided".to_string()).into()); - }; - debug!(?bin_install_path, "Install path"); - - let access_remote = if std::env::var(INFINYON_HUB_REMOTE).is_ok() - || std::env::var(FLUVIO_HUB_PROFILE_ENV).is_ok() - || self.use_hub_defaults - { - None - } else { - Some("https://hub.infinyon.cloud".to_string()) - }; - - let access = HubAccess::default_load(&access_remote).map_err(|_| { - crate::CliError::Other("Something happened getting hub dev info".to_string()) - })?; - let data = self.get_binary(&package_name, &access).await?; - - debug!(?bin_install_path, "Writing binary to fs"); - install_bin(bin_install_path, data)?; - } else { - let agent = match &self.prefix { - Some(prefix) => HttpAgent::with_prefix(prefix)?, - None => HttpAgent::default(), - }; - - let result = self.install_plugin(&agent).await; - match result { - Ok(_) => (), - Err(err) => match err.downcast_ref::() { - Some(crate::CliError::IndexError(fluvio_index::Error::MissingTarget( - target, - ))) => { - install_println(format!( - "❕ Package '{}' is not available for target {}, skipping", - self.package - .ok_or(crate::CliError::Other( - "Package name not provided".to_string(), - ))? - .name(), - target - )); - install_println("❕ Consider filing an issue to add support for this platform using the link below! 👇"); - install_println(format!( - "❕ https://github.com/infinyon/fluvio/issues/new?title=Support+fluvio-cloud+on+target+{target}" - )); - return Ok(()); - } - _ => return Err(err), - }, - } - } - - Ok(()) - } - - async fn install_plugin(&self, agent: &HttpAgent) -> Result<()> { - let target = if let Some(user_override) = &self.target { - fluvio_index::Target::from_str(&user_override.to_string())? - } else { - // need to analyze to if we can make CURRENT_PLATFORM - // the default instead of PACKAGE_TARGET, keep - // each use the same for now - fluvio_index::package_target()? - }; - - // If a version is given in the package ID, use it. Otherwise, use latest - let id = match self - .package - .clone() - .ok_or(crate::CliError::Other( - "Package name not provided".to_string(), - ))? - .maybe_version() - { - Some(version) => { - install_println(format!( - "⏳ Downloading package with provided version: {}...", - &self.package.clone().ok_or(crate::CliError::Other( - "Package name not provided".to_string(), - ))? - )); - let version = version.clone(); - self.package - .clone() - .ok_or(crate::CliError::Other( - "Package name not provided".to_string(), - ))? - .into_versioned(version) - } - None => { - let id = &self.package.clone().ok_or(crate::CliError::Other( - "Package name not provided".to_string(), - ))?; - install_println(format!("🎣 Fetching latest version for package: {id}...")); - let version = fetch_latest_version(agent, id, &target, self.develop).await?; - let id = id.clone().into_versioned(version.into()); - install_println(format!( - "⏳ Downloading package with latest version: {id}..." - )); - id - } - }; - - // Download the package file from the package registry - let package_result = fetch_package_file(agent, &id, &target).await; - let package_file = match package_result { - Ok(pf) => pf, - Err(err) => match err.downcast_ref::() { - Some(PackageNotFound { - package, - version, - target, - }) => { - install_println(format!( - "❕ Package {package} is not published at {version} for {target}, skipping" - )); - return Ok(()); - } - None => return Err(err), - }, - }; - install_println("🔑 Downloaded and verified package file"); - - // Install the package to the ~/.fluvio/bin/ dir - // If the plugin name doesn't start with `fluvio-`, then install it to the bin dir - let fluvio_dir = if id.name().to_string().starts_with("fluvio-") { - fluvio_extensions_dir()? - } else { - fluvio_bin_dir()? - }; - debug!("{fluvio_dir:#?}"); - - let package_filename = if target.to_string().contains("windows") { - format!("{}.exe", id.name().as_str()) - } else { - id.name().to_string() - }; - let package_path = fluvio_dir.join(package_filename); - install_bin(package_path, package_file)?; - - Ok(()) - } - - fn get_channel(&self) -> String { - if let Some(user_override) = &self.channel { - user_override.to_string() - } else if let Ok(channel_name) = std::env::var(FLUVIO_RELEASE_CHANNEL) { - channel_name - } else { - LATEST_CHANNEL_NAME.to_string() - } - } - - fn get_target(&self) -> String { - if let Some(user_override) = &self.target { - user_override.to_string() - } else { - CURRENT_PLATFORM.to_string() - } - } - - async fn get_binary(&self, bin_name: &str, access: &HubAccess) -> Result> { - let actiontoken = access - .get_bpkg_get_token() - .await - .map_err(|_| HttpError::InvalidInput("authorization error".into()))?; - - let binurl = format!( - "{}/{HUB_API_BPKG_AUTH}/{channel}/{systuple}/{bin_name}", - access.remote, - channel = self.get_channel(), - systuple = self.get_target(), - ); - debug!("Downloading binary from hub: {binurl}"); - let mut resp = http::get(binurl) - .header("Authorization", actiontoken) - .await - .map_err(|_| HttpError::InvalidInput("authorization error".into()))?; - - match resp.status() { - StatusCode::Ok => {} - code => { - let body_err_message = resp - .body_string() - .await - .unwrap_or_else(|_err| "couldn't fetch error message".to_string()); - let msg = format!("Status({code}) {body_err_message}"); - return Err(crate::CliError::HubError(msg).into()); - } - } - let data = resp - .body_bytes() - .await - .map_err(|_| crate::CliError::HubError("Data unpack failure".into()))?; - Ok(data) - } -} diff --git a/crates/fluvio-cli/src/lib.rs b/crates/fluvio-cli/src/lib.rs index 75b41841b3..930b7921bd 100644 --- a/crates/fluvio-cli/src/lib.rs +++ b/crates/fluvio-cli/src/lib.rs @@ -3,16 +3,20 @@ //! CLI configurations at the top of the tree mod error; -pub mod client; -pub mod install; -mod profile; -mod version; mod metadata; +mod profile; mod render; +mod version; + +pub mod client; + pub(crate) mod monitoring; +// Re-exported pub(crate) use error::CliError; + use fluvio_extension_common as common; + pub(crate) const VERSION: &str = include_str!("../../../VERSION"); // list of public export @@ -52,10 +56,9 @@ mod root { #[cfg(feature = "k8s")] use fluvio_cluster::cli::ClusterCmd; use fluvio_cli_common::install::fluvio_extensions_dir; - use fluvio_channel::{FLUVIO_RELEASE_CHANNEL, LATEST_CHANNEL_NAME}; + use fluvio_channel::FLUVIO_RELEASE_CHANNEL; use crate::profile::ProfileOpt; - use crate::install::plugins::InstallOpt; use crate::client::FluvioCmd; use crate::metadata::{MetadataOpt, subcommand_metadata}; use crate::version::VersionOpt; @@ -118,16 +121,6 @@ mod root { #[command(subcommand, name = "cluster")] Cluster(Box), - /// Install Fluvio plugins - /// - /// The Fluvio CLI considers any executable with the prefix `fluvio-` to be a - /// CLI plugin. For example, an executable named `fluvio-foo` in your PATH may - /// be invoked by running `fluvio foo`. - /// - /// This command allows you to install plugins from Fluvio's package registry. - #[command(name = "install")] - Install(InstallOpt), - /// Print Fluvio version information #[command(name = "version")] Version(VersionOpt), @@ -171,17 +164,6 @@ mod root { let version = semver::Version::parse(crate::VERSION).unwrap(); cluster.process(out, version, root.target).await?; } - Self::Install(mut install) => { - if let Ok(channel_name) = std::env::var(FLUVIO_RELEASE_CHANNEL) { - println!("Current channel: {}", &channel_name); - - if channel_name == LATEST_CHANNEL_NAME { - install.develop = true; - } - }; - - install.process().await?; - } Self::Version(version) => { version.process(root.target).await?; }