mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
fix(workspace): stabilise the development stack (#2024)
This commit is contained in:
1 parent
cf1a7d7a8a
commit
5d2e5932a4
55 files changed
+1848
-3396
No files matched your search
+107
-7
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result, bail};
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use fluxer_dev::cassandra::{
|
||||
apply_schema, compute_diff, render_target_schema, verify_schema, write_diff_file,
|
||||
@@ -11,9 +11,19 @@ use fluxer_dev::desktop::{
|
||||
};
|
||||
use fluxer_dev::env::merge_default_env_with_current;
|
||||
use fluxer_dev::manifest::{DEV_PROXY_PORT, LOCAL_APP_URL};
|
||||
use fluxer_dev::paths::{DEV_ENV_FILE, DEV_LOCAL_ENV_FILE, ROOT_LOCAL_ENV_FILE};
|
||||
use fluxer_dev::paths::{DEV_ENV_FILE, DEV_LOCAL_ENV_FILE, ROOT, ROOT_LOCAL_ENV_FILE};
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command as ProcessCommand;
|
||||
|
||||
const DEV_INFRA_SERVICES: &[&str] = &[
|
||||
"postgres",
|
||||
"valkey",
|
||||
"nats",
|
||||
"livekit",
|
||||
"meilisearch",
|
||||
"mailpit",
|
||||
];
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "fluxer-dev")]
|
||||
@@ -34,6 +44,7 @@ enum Command {
|
||||
Proxy(ProxyArgs),
|
||||
Dev(DevArgs),
|
||||
RustServices(RustServicesArgs),
|
||||
Infra(InfraArgs),
|
||||
Cassandra(CassandraArgs),
|
||||
Desktop(DesktopArgs),
|
||||
MediaProxy(MediaProxyArgs),
|
||||
@@ -44,8 +55,6 @@ enum Command {
|
||||
struct BootstrapArgs {
|
||||
#[arg(long)]
|
||||
skip_install: bool,
|
||||
#[arg(long)]
|
||||
skip_desktop_install: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -76,6 +85,19 @@ struct RustServicesArgs {
|
||||
services: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
struct InfraArgs {
|
||||
#[command(subcommand)]
|
||||
command: InfraCommand,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
enum InfraCommand {
|
||||
Start,
|
||||
Stop,
|
||||
Status,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
struct CassandraArgs {
|
||||
#[command(subcommand)]
|
||||
@@ -193,10 +215,12 @@ async fn main() -> Result<()> {
|
||||
|
||||
match cli.command {
|
||||
Command::Bootstrap(args) => {
|
||||
fluxer_dev::bootstrap::bootstrap(args.skip_install, args.skip_desktop_install).await?;
|
||||
fluxer_dev::bootstrap::bootstrap(args.skip_install).await?;
|
||||
}
|
||||
Command::PostStart => fluxer_dev::bootstrap::post_start().await?,
|
||||
Command::Gateway(args) if args.mode == "single" => fluxer_dev::gateway::run_gateway()?,
|
||||
Command::Gateway(args) if args.mode == "single" => {
|
||||
std::process::exit(fluxer_dev::gateway::run_gateway().await?)
|
||||
}
|
||||
Command::Gateway(_) => {
|
||||
std::process::exit(fluxer_dev::gateway::run_gateway_cluster().await?)
|
||||
}
|
||||
@@ -216,6 +240,7 @@ async fn main() -> Result<()> {
|
||||
Command::RustServices(args) => {
|
||||
std::process::exit(fluxer_dev::rust_services::run_rust_services(&args.services).await?)
|
||||
}
|
||||
Command::Infra(args) => run_infra(args.command)?,
|
||||
Command::Cassandra(args) => match args.command {
|
||||
CassandraCommand::Diff { output } => {
|
||||
let diff = compute_diff(None).await?;
|
||||
@@ -315,3 +340,78 @@ fn apply_default_env() -> Result<()> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_infra(command: InfraCommand) -> Result<()> {
|
||||
let project = compose_project_name()?;
|
||||
let compose_file = ROOT.join(".devcontainer/docker-compose.yml");
|
||||
let mut args = vec![
|
||||
"compose".to_owned(),
|
||||
"--project-name".to_owned(),
|
||||
project,
|
||||
"-f".to_owned(),
|
||||
compose_file.display().to_string(),
|
||||
];
|
||||
match command {
|
||||
InfraCommand::Start => args.push("start".to_owned()),
|
||||
InfraCommand::Stop => args.push("stop".to_owned()),
|
||||
InfraCommand::Status => {
|
||||
args.push("ps".to_owned());
|
||||
args.push("--all".to_owned());
|
||||
}
|
||||
}
|
||||
args.extend(
|
||||
DEV_INFRA_SERVICES
|
||||
.iter()
|
||||
.map(|service| (*service).to_owned()),
|
||||
);
|
||||
let status = ProcessCommand::new("docker")
|
||||
.args(&args)
|
||||
.status()
|
||||
.context("failed to run Docker Compose for the dev infrastructure")?;
|
||||
if !status.success() {
|
||||
bail!("Docker Compose dev infrastructure command failed with {status}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compose_project_name() -> Result<String> {
|
||||
if Path::new("/.dockerenv").exists() {
|
||||
let container = std::fs::read_to_string("/etc/hostname")
|
||||
.context("failed to read the current devcontainer hostname")?;
|
||||
let container = container.trim();
|
||||
if container.is_empty()
|
||||
|| !container
|
||||
.bytes()
|
||||
.all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'.' | b'-'))
|
||||
{
|
||||
bail!("Current devcontainer hostname is invalid");
|
||||
}
|
||||
let output = ProcessCommand::new("docker")
|
||||
.args([
|
||||
"inspect",
|
||||
"--format",
|
||||
"{{ index .Config.Labels \"com.docker.compose.project\" }}",
|
||||
container,
|
||||
])
|
||||
.output()
|
||||
.context("failed to inspect the current devcontainer Compose project")?;
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"Could not discover the current devcontainer Compose project: {}",
|
||||
String::from_utf8_lossy(&output.stderr).trim()
|
||||
);
|
||||
}
|
||||
let project = String::from_utf8(output.stdout)
|
||||
.context("devcontainer Compose project label is not valid UTF-8")?
|
||||
.trim()
|
||||
.to_owned();
|
||||
if project.is_empty() || project == "<no value>" {
|
||||
bail!("Current container has no com.docker.compose.project label");
|
||||
}
|
||||
return Ok(project);
|
||||
}
|
||||
std::env::var("COMPOSE_PROJECT_NAME")
|
||||
.ok()
|
||||
.filter(|project| !project.trim().is_empty())
|
||||
.context("COMPOSE_PROJECT_NAME must be set when managing dev infrastructure from the host")
|
||||
}
|
||||
Reference in new issue
Block a user