Fix branch name conversion bug with regex-based solution
- Replace broken sequential replace() logic with robust regex pattern - Fix architecture name preservation (x86_64, aarch64, arm64) - Use regex pattern ^([^_]+)_([^_]+)_(.*)$ for proper parsing - Add lazy_static for efficient regex compilation - Resolve compose command branch matching issues - Test: ubuntu_24.04_x86_64 now correctly converts to ubuntu/24.04/x86_64
This commit is contained in:
parent
5777c11f85
commit
c39d6c03b5
4 changed files with 55 additions and 15 deletions
|
|
@ -60,6 +60,9 @@ jsonpath-rust = "0.1"
|
||||||
# Regular expressions
|
# Regular expressions
|
||||||
regex = "1.0"
|
regex = "1.0"
|
||||||
|
|
||||||
|
# Lazy static initialization
|
||||||
|
lazy_static = "1.4"
|
||||||
|
|
||||||
# UUID generation
|
# UUID generation
|
||||||
uuid = { version = "1.0", features = ["v4"] }
|
uuid = { version = "1.0", features = ["v4"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use crate::error::AptOstreeResult;
|
use crate::error::AptOstreeResult;
|
||||||
use crate::system::AptOstreeSystem;
|
use crate::ostree::OstreeManager;
|
||||||
|
|
||||||
/// Base image reference (e.g., "ubuntu:24.04")
|
/// Base image reference (e.g., "ubuntu:24.04")
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -32,15 +31,18 @@ pub struct ComposeOptions {
|
||||||
/// Compose manager for handling base image resolution and compose operations
|
/// Compose manager for handling base image resolution and compose operations
|
||||||
pub struct ComposeManager {
|
pub struct ComposeManager {
|
||||||
branch: String,
|
branch: String,
|
||||||
|
ostree_manager: OstreeManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComposeManager {
|
impl ComposeManager {
|
||||||
/// Create a new compose manager
|
/// Create a new compose manager
|
||||||
pub async fn new(branch: &str) -> AptOstreeResult<Self> {
|
pub async fn new(branch: &str) -> AptOstreeResult<Self> {
|
||||||
// For now, don't initialize the full system to avoid OSTree validation
|
// Initialize OSTree manager for real branch operations
|
||||||
// TODO: Add proper system initialization when OSTree integration is complete
|
let ostree_manager = OstreeManager::new("/var/lib/apt-ostree/repo")?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
branch: branch.to_string(),
|
branch: branch.to_string(),
|
||||||
|
ostree_manager,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +53,7 @@ impl ComposeManager {
|
||||||
let base_image = self.parse_base_image_ref(base_ref)?;
|
let base_image = self.parse_base_image_ref(base_ref)?;
|
||||||
let ostree_branch = self.map_to_ostree_branch(&base_image)?;
|
let ostree_branch = self.map_to_ostree_branch(&base_image)?;
|
||||||
|
|
||||||
// Check if the branch exists locally
|
// Check if the branch exists locally using real OSTree manager
|
||||||
let exists_locally = self.check_branch_exists(&ostree_branch).await?;
|
let exists_locally = self.check_branch_exists(&ostree_branch).await?;
|
||||||
|
|
||||||
let resolved = ResolvedBaseImage {
|
let resolved = ResolvedBaseImage {
|
||||||
|
|
@ -127,13 +129,25 @@ impl ComposeManager {
|
||||||
Ok(branch)
|
Ok(branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if an OSTree branch exists locally
|
/// Check if an OSTree branch exists locally using real OSTree manager
|
||||||
async fn check_branch_exists(&self, _branch: &str) -> AptOstreeResult<bool> {
|
async fn check_branch_exists(&self, branch: &str) -> AptOstreeResult<bool> {
|
||||||
// TODO: Implement real OSTree branch checking
|
info!("Checking if OSTree branch exists: {}", branch);
|
||||||
// For now, return false to indicate we need to pull from registry
|
|
||||||
warn!("OSTree branch existence checking not yet implemented");
|
// Use the existing OSTree manager to check branch existence
|
||||||
|
match self.ostree_manager.list_branches() {
|
||||||
|
Ok(branches) => {
|
||||||
|
info!("Available branches: {:?}", branches);
|
||||||
|
let exists = branches.contains(&branch.to_string());
|
||||||
|
info!("Branch {} exists locally: {}", branch, exists);
|
||||||
|
Ok(exists)
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to check branch existence: {}", e);
|
||||||
|
// If we can't check, assume it doesn't exist
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new deployment from a base image
|
/// Create a new deployment from a base image
|
||||||
pub async fn create_deployment(&self, options: &ComposeOptions) -> AptOstreeResult<String> {
|
pub async fn create_deployment(&self, options: &ComposeOptions) -> AptOstreeResult<String> {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,19 @@
|
||||||
//! Simplified OSTree-like repository manager for apt-ostree
|
//! Simplified OSTree-like repository manager for apt-ostree
|
||||||
use tracing::{info};
|
use tracing::{info, warn};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
use regex::Regex;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::error::{AptOstreeError, AptOstreeResult};
|
use crate::error::{AptOstreeError, AptOstreeResult};
|
||||||
|
|
||||||
|
// Lazily initialize the regex to compile it only once
|
||||||
|
lazy_static! {
|
||||||
|
static ref BRANCH_NAME_RE: Regex = Regex::new(r"^([^_]+)_([^_]+)_(.*)$").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/// Simplified OSTree-like repository manager
|
/// Simplified OSTree-like repository manager
|
||||||
pub struct OstreeManager {
|
pub struct OstreeManager {
|
||||||
repo_path: PathBuf,
|
repo_path: PathBuf,
|
||||||
|
|
@ -198,8 +205,24 @@ impl OstreeManager {
|
||||||
for entry in fs::read_dir(&refs_dir)? {
|
for entry in fs::read_dir(&refs_dir)? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
if entry.file_type()?.is_file() {
|
if entry.file_type()?.is_file() {
|
||||||
let name = entry.file_name().to_string_lossy().replace("_", "/");
|
let name = entry.file_name().to_string_lossy().to_string();
|
||||||
branches.push(name);
|
info!("DEBUG: Original name: '{}'", name);
|
||||||
|
|
||||||
|
// Use regex to properly parse distribution_version_architecture pattern
|
||||||
|
let converted_name = if let Some(captures) = BRANCH_NAME_RE.captures(&name) {
|
||||||
|
let distribution = captures.get(1).unwrap().as_str();
|
||||||
|
let version = captures.get(2).unwrap().as_str();
|
||||||
|
let architecture = captures.get(3).unwrap().as_str(); // This correctly preserves "x86_64"
|
||||||
|
|
||||||
|
format!("{}/{}/{}", distribution, version, architecture)
|
||||||
|
} else {
|
||||||
|
// Handle cases where the branch name doesn't match the expected pattern
|
||||||
|
warn!("Branch name '{}' does not match expected pattern, returning as-is", name);
|
||||||
|
name
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("DEBUG: Final converted name: '{}'", converted_name);
|
||||||
|
branches.push(converted_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue