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:
robojerk 2025-07-18 20:25:07 +00:00
parent 5777c11f85
commit c39d6c03b5
4 changed files with 55 additions and 15 deletions

View file

@ -2,7 +2,7 @@
## Overview
Fedora Atomic Desktops, including spins like Silverblue, Kinoite (KDE Plasma), Bazzite, and Bluefin, leverage rpm-ostree to provide a unique approach to operating system management built around an immutable core filesystem. This differs significantly from traditional Linux distributions and introduces some nuances in how the filesystem is structured and interact with applications.
Fedora Atomic Desktops, including spins like Silverblue, Kinoite (KDE Plasma), Bazzite, and Bluefin, leverage rpm-ostree to provide a unique approach to operating system management built around an immutable core filesystem. This differs significantly from traditional Linux distributions and introduces some nuances in how the filesystem is structured and interact with applications.
**NEW: apt-ostree Integration**
The apt-ostree project brings similar atomic filesystem concepts to Ubuntu/Debian systems, adapting OSTree's immutable filesystem model for APT package management.

View file

@ -60,6 +60,9 @@ jsonpath-rust = "0.1"
# Regular expressions
regex = "1.0"
# Lazy static initialization
lazy_static = "1.4"
# UUID generation
uuid = { version = "1.0", features = ["v4"] }

View file

@ -1,7 +1,6 @@
use std::path::PathBuf;
use tracing::{info, warn};
use crate::error::AptOstreeResult;
use crate::system::AptOstreeSystem;
use crate::ostree::OstreeManager;
/// Base image reference (e.g., "ubuntu:24.04")
#[derive(Debug, Clone)]
@ -32,15 +31,18 @@ pub struct ComposeOptions {
/// Compose manager for handling base image resolution and compose operations
pub struct ComposeManager {
branch: String,
ostree_manager: OstreeManager,
}
impl ComposeManager {
/// Create a new compose manager
pub async fn new(branch: &str) -> AptOstreeResult<Self> {
// For now, don't initialize the full system to avoid OSTree validation
// TODO: Add proper system initialization when OSTree integration is complete
// Initialize OSTree manager for real branch operations
let ostree_manager = OstreeManager::new("/var/lib/apt-ostree/repo")?;
Ok(Self {
branch: branch.to_string(),
ostree_manager,
})
}
@ -51,7 +53,7 @@ impl ComposeManager {
let base_image = self.parse_base_image_ref(base_ref)?;
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 resolved = ResolvedBaseImage {
@ -127,12 +129,24 @@ impl ComposeManager {
Ok(branch)
}
/// Check if an OSTree branch exists locally
async fn check_branch_exists(&self, _branch: &str) -> AptOstreeResult<bool> {
// TODO: Implement real OSTree branch checking
// For now, return false to indicate we need to pull from registry
warn!("OSTree branch existence checking not yet implemented");
Ok(false)
/// Check if an OSTree branch exists locally using real OSTree manager
async fn check_branch_exists(&self, branch: &str) -> AptOstreeResult<bool> {
info!("Checking if OSTree branch exists: {}", branch);
// 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)
}
}
}
/// Create a new deployment from a base image

View file

@ -1,12 +1,19 @@
//! Simplified OSTree-like repository manager for apt-ostree
use tracing::{info};
use tracing::{info, warn};
use std::path::{Path, PathBuf};
use std::fs;
use serde::{Serialize, Deserialize};
use tokio::process::Command;
use regex::Regex;
use lazy_static::lazy_static;
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
pub struct OstreeManager {
repo_path: PathBuf,
@ -198,8 +205,24 @@ impl OstreeManager {
for entry in fs::read_dir(&refs_dir)? {
let entry = entry?;
if entry.file_type()?.is_file() {
let name = entry.file_name().to_string_lossy().replace("_", "/");
branches.push(name);
let name = entry.file_name().to_string_lossy().to_string();
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);
}
}