use crate::command::status::status_postgres;
use crate::manifest::{get_package_manifest, pg_config_and_version};
use crate::CommandExecute;
use eyre::eyre;
use owo_colors::OwoColorize;
use pgx_pg_config::{PgConfig, PgConfigSelector, Pgx};
use std::path::PathBuf;
use std::process::Stdio;
#[derive(clap::Args, Debug, Clone)]
#[clap(author)]
pub(crate) struct Stop {
#[clap(env = "PG_VERSION")]
pg_version: Option<String>,
#[clap(from_global, action = ArgAction::Count)]
verbose: u8,
#[clap(long, short)]
package: Option<String>,
#[clap(long, value_parser)]
manifest_path: Option<PathBuf>,
}
impl CommandExecute for Stop {
#[tracing::instrument(level = "error", skip(self))]
fn execute(self) -> eyre::Result<()> {
fn perform(me: Stop, pgx: &Pgx) -> eyre::Result<()> {
let (package_manifest, _) = get_package_manifest(
&clap_cargo::Features::default(),
me.package.as_ref(),
me.manifest_path,
)?;
let (pg_config, _) =
pg_config_and_version(&pgx, &package_manifest, me.pg_version, None, false)?;
stop_postgres(pg_config)
}
let pgx = Pgx::from_config()?;
if self.pg_version == Some("all".into()) {
for v in pgx.iter(PgConfigSelector::All) {
let mut versioned_start = self.clone();
versioned_start.pg_version = Some(v?.label()?);
perform(versioned_start, &pgx)?;
}
Ok(())
} else {
perform(self, &pgx)
}
}
}
#[tracing::instrument(level = "error", skip_all, fields(pg_version = %pg_config.version()?))]
pub(crate) fn stop_postgres(pg_config: &PgConfig) -> eyre::Result<()> {
Pgx::home()?;
let datadir = pg_config.data_dir()?;
let bindir = pg_config.bin_dir()?;
if status_postgres(pg_config)? == false {
tracing::debug!("Already stopped");
return Ok(());
}
println!("{} Postgres v{}", " Stopping".bold().green(), pg_config.major_version()?);
let mut command = std::process::Command::new(format!("{}/pg_ctl", bindir.display()));
command
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("stop")
.arg("-m")
.arg("fast")
.arg("-D")
.arg(&datadir);
let output = command.output()?;
if !output.status.success() {
Err(eyre!("{}", String::from_utf8(output.stderr)?,))
} else {
Ok(())
}
}