- Add internal/phases/ with complete phase management system - Add internal/types/ with core data structures - Add internal/treefile/ for OSTree treefile generation - Update examples with YAML configurations - Update .gitignore to properly exclude test artifacts and build outputs - Update dependencies and configuration files
203 lines
6.2 KiB
Go
203 lines
6.2 KiB
Go
package phases
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"deb-bootc-compose/internal/types"
|
|
)
|
|
|
|
// OSTreePhase handles OSTree commit creation and repository management
|
|
type OSTreePhase struct {
|
|
PhaseBase
|
|
}
|
|
|
|
// NewOSTreePhase creates a new OSTreePhase
|
|
func NewOSTreePhase() *OSTreePhase {
|
|
return &OSTreePhase{
|
|
PhaseBase: NewPhaseBase("ostree", []string{"build"}),
|
|
}
|
|
}
|
|
|
|
// Run executes the OSTree phase
|
|
func (p *OSTreePhase) Run(engine types.Engine) error {
|
|
logger := engine.GetLogger()
|
|
logger.Printf("Starting OSTree phase...")
|
|
|
|
// Get package information from treefile
|
|
treefile := engine.GetTreefile()
|
|
|
|
// Process each variant and architecture
|
|
for _, variant := range treefile.Variants {
|
|
for _, arch := range variant.Architectures {
|
|
logger.Printf("Processing variant %s for architecture %s", variant.Name, arch)
|
|
|
|
// Get packages for this variant/architecture combination
|
|
packages := treefile.GetPackagesForVariant(variant.Name, arch)
|
|
|
|
// Create OSTree commit using apt-ostree
|
|
ref := treefile.GetOSTreeRef(variant.Name, arch)
|
|
subject := fmt.Sprintf("Debian %s %s variant for %s", treefile.Release, variant.Name, arch)
|
|
body := fmt.Sprintf("Debian %s %s variant for %s architecture\nGenerated by deb-bootc-compose", treefile.Release, variant.Name, arch)
|
|
|
|
// Collect all package names
|
|
allPackages := make([]string, 0)
|
|
allPackages = append(allPackages, packages.Required...)
|
|
allPackages = append(allPackages, packages.Optional...)
|
|
allPackages = append(allPackages, packages.Recommended...)
|
|
allPackages = append(allPackages, packages.Development...)
|
|
allPackages = append(allPackages, packages.Kernel...)
|
|
allPackages = append(allPackages, packages.Bootloader...)
|
|
|
|
commitID, err := engine.GetOSTreeTool().CreateCommit(ref, subject, body, allPackages)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create OSTree commit for variant %s/%s: %w", variant.Name, arch, err)
|
|
}
|
|
|
|
// Create variant-specific work directory
|
|
variantWorkDir := filepath.Join(engine.GetWorkDir(), "variants", variant.Name, arch)
|
|
if err := os.MkdirAll(variantWorkDir, 0755); err != nil {
|
|
return fmt.Errorf("failed to create variant work directory: %w", err)
|
|
}
|
|
|
|
// Write commit information
|
|
if err := p.writeCommitInfo(variantWorkDir, ref, commitID, subject, body, allPackages); err != nil {
|
|
return fmt.Errorf("failed to write commit info for variant %s/%s: %w", variant.Name, arch, err)
|
|
}
|
|
|
|
logger.Printf("Completed OSTree commit for variant %s/%s: %s", variant.Name, arch, commitID)
|
|
}
|
|
}
|
|
|
|
logger.Printf("OSTree phase completed successfully")
|
|
return nil
|
|
}
|
|
|
|
// createOSTreeCommit creates an OSTree commit for a specific variant and architecture
|
|
func (p *OSTreePhase) createOSTreeCommit(engine types.Engine, workDir string, variant types.Variant, arch string) error {
|
|
logger := engine.GetLogger()
|
|
ostreeTool := engine.GetOSTreeTool()
|
|
|
|
// Get packages for this variant
|
|
packages := engine.GetTreefile().GetPackagesForVariant(variant.Name, arch)
|
|
|
|
// Generate OSTree reference
|
|
ref := engine.GetTreefile().GetOSTreeRef(variant.Name, arch)
|
|
|
|
// Generate commit subject and body
|
|
subject := fmt.Sprintf("Debian %s %s variant for %s",
|
|
engine.GetTreefile().Release,
|
|
variant.Name,
|
|
arch)
|
|
|
|
body := fmt.Sprintf(`Debian %s %s variant for %s architecture
|
|
Generated by deb-bootc-compose
|
|
Timestamp: %s
|
|
Variant: %s
|
|
Architecture: %s
|
|
|
|
Packages included:
|
|
- Required: %d
|
|
- Optional: %d
|
|
- Recommended: %d
|
|
- Development: %d
|
|
- Kernel: %d
|
|
- Bootloader: %d`,
|
|
engine.GetTreefile().Release,
|
|
variant.Name,
|
|
arch,
|
|
time.Now().Format(time.RFC3339),
|
|
variant.Name,
|
|
arch,
|
|
len(packages.Required),
|
|
len(packages.Optional),
|
|
len(packages.Recommended),
|
|
len(packages.Development),
|
|
len(packages.Kernel),
|
|
len(packages.Bootloader))
|
|
|
|
// Collect all package names
|
|
allPackages := make([]string, 0)
|
|
allPackages = append(allPackages, packages.Required...)
|
|
allPackages = append(allPackages, packages.Optional...)
|
|
allPackages = append(allPackages, packages.Recommended...)
|
|
allPackages = append(allPackages, packages.Development...)
|
|
allPackages = append(allPackages, packages.Kernel...)
|
|
allPackages = append(allPackages, packages.Bootloader...)
|
|
|
|
// Remove duplicates
|
|
uniquePackages := make(map[string]bool)
|
|
for _, pkg := range allPackages {
|
|
uniquePackages[pkg] = true
|
|
}
|
|
|
|
uniqueList := make([]string, 0, len(uniquePackages))
|
|
for pkg := range uniquePackages {
|
|
uniqueList = append(uniqueList, pkg)
|
|
}
|
|
|
|
// Create OSTree commit
|
|
logger.Printf("Creating OSTree commit for reference: %s", ref)
|
|
commitID, err := ostreeTool.CreateCommit(ref, subject, body, uniqueList)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create OSTree commit: %w", err)
|
|
}
|
|
|
|
// Update the reference to point to the new commit
|
|
if err := ostreeTool.UpdateRef(ref, commitID); err != nil {
|
|
return fmt.Errorf("failed to update OSTree reference: %w", err)
|
|
}
|
|
|
|
// Validate the commit
|
|
if err := ostreeTool.ValidateCommit(commitID); err != nil {
|
|
return fmt.Errorf("failed to validate OSTree commit: %w", err)
|
|
}
|
|
|
|
// Write commit information
|
|
if err := p.writeCommitInfo(workDir, ref, commitID, subject, body, uniqueList); err != nil {
|
|
return fmt.Errorf("failed to write commit information: %w", err)
|
|
}
|
|
|
|
logger.Printf("Successfully created OSTree commit %s for reference %s", commitID, ref)
|
|
return nil
|
|
}
|
|
|
|
// writeCommitInfo writes commit information to files
|
|
func (p *OSTreePhase) writeCommitInfo(workDir string, ref, commitID, subject, body string, packages []string) error {
|
|
// Write commit details
|
|
commitFile := filepath.Join(workDir, "commit-info.txt")
|
|
content := fmt.Sprintf(`OSTree Commit Information
|
|
Reference: %s
|
|
Commit ID: %s
|
|
Subject: %s
|
|
Timestamp: %s
|
|
|
|
Body:
|
|
%s
|
|
|
|
Packages (%d):
|
|
`, ref, commitID, subject, time.Now().Format(time.RFC3339), body, len(packages))
|
|
|
|
for _, pkg := range packages {
|
|
content += fmt.Sprintf(" - %s\n", pkg)
|
|
}
|
|
|
|
if err := os.WriteFile(commitFile, []byte(content), 0644); err != nil {
|
|
return fmt.Errorf("failed to write commit info: %w", err)
|
|
}
|
|
|
|
// Write package list
|
|
packagesFile := filepath.Join(workDir, "packages.txt")
|
|
pkgContent := ""
|
|
for _, pkg := range packages {
|
|
pkgContent += pkg + "\n"
|
|
}
|
|
|
|
if err := os.WriteFile(packagesFile, []byte(pkgContent), 0644); err != nil {
|
|
return fmt.Errorf("failed to write packages list: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|