provisioning/tools/distribution/installer_metadata.nu

164 lines
5.6 KiB
Plaintext

# Module: Installer Metadata Analysis
# Purpose: Analyzes distribution structure, components, versions, and installation requirements
# Dependencies: None (standalone utilities)
# Extract distribution archive for analysis
export def extract_distribution_for_analysis [dist_path: string, installer_config: record] {
let temp_dir = ($installer_config.output_dir | path join "tmp" "analysis")
mkdir $temp_dir
let dist_name = ($dist_path | path basename)
if ($dist_name | str ends-with ".tar.gz") or ($dist_name | str ends-with ".tgz") {
cd $temp_dir
tar -xzf $dist_path
} else if ($dist_name | str ends-with ".zip") {
cd $temp_dir
unzip $dist_path
} else {
return { status: "error", reason: $"Unsupported archive format: ($dist_name)" }
}
# Find the extracted directory (usually a single top-level directory)
let extracted_contents = (ls $temp_dir)
if ($extracted_contents | length) == 1 and (($extracted_contents | get 0.type) == "dir") {
return ($extracted_contents | get 0.name)
} else {
return $temp_dir
}
}
# Analyze distribution components
export def analyze_distribution_components [analysis_path: string] {
let components = {
has_platform: (($analysis_path | path join "platform") | path exists)
has_core: (($analysis_path | path join "core") | path exists)
has_config: (($analysis_path | path join "config") | path exists)
has_docs: (($analysis_path | path join "docs") | path exists)
has_services: (($analysis_path | path join "services") | path exists)
}
# Find executables
let executables = if $components.has_platform {
ls ($analysis_path | path join "platform") | where type == file | get name
} else if $components.has_core and (($analysis_path | path join "core" "bin") | path exists) {
ls ($analysis_path | path join "core" "bin") | where type == file | get name
} else {
[]
}
# Find configuration files
let config_files = if $components.has_config {
ls -la ($analysis_path | path join "config")
| where name =~ "\\.(toml|yaml|json)$"
| get name
} else {
[]
}
# Find service definitions
let service_files = if $components.has_services {
ls -la ($analysis_path | path join "services")
| where name =~ "\\.(service|yml|yaml)$"
| get name
} else {
[]
}
let components = ($components
| insert executables $executables
| insert config_files $config_files
| insert service_files $service_files
| insert total_size (get_directory_size $analysis_path))
return $components
}
# Detect distribution version
export def detect_distribution_version [analysis_path: string] {
# Try to find version from metadata
let metadata_files = [
($analysis_path | path join "core-metadata.json")
($analysis_path | path join "platform-metadata.json")
($analysis_path | path join "metadata.json")
($analysis_path | path join "VERSION")
]
for metadata_file in $metadata_files {
if ($metadata_file | path exists) {
let version = if ($metadata_file | str ends-with ".json") {
let data = (open $metadata_file)
$data.version? | default "unknown"
} else {
open $metadata_file --raw | str trim
}
if $version != "unknown" {
return { version: $version, source: ($metadata_file | path basename) }
}
}
}
# Fallback: try to extract from directory name
let dir_name = ($analysis_path | path basename)
let version_match = ($dir_name | parse --regex ".*-([0-9]+\\.[0-9]+\\.[0-9]+)")
if ($version_match | length) > 0 {
return { version: ($version_match | get 0.capture0), source: "directory_name" }
}
return { version: "unknown", source: "none" }
}
# Analyze installation requirements
export def analyze_installation_requirements [analysis_path: string, components: record] {
mut requirements = {
system_user: "provisioning"
system_group: "provisioning"
install_dirs: []
config_dirs: []
data_dirs: []
log_dirs: []
service_dependencies: []
port_requirements: []
}
# Standard installation directories
if $components.has_platform or ($components.executables | length) > 0 {
$requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/bin")
}
if $components.has_core {
$requirements.install_dirs = ($requirements.install_dirs | append "/usr/local/lib/provisioning")
}
if $components.has_config {
$requirements.config_dirs = ($requirements.config_dirs | append "/etc/provisioning")
}
# Data and log directories
$requirements.data_dirs = ($requirements.data_dirs | append "/var/lib/provisioning")
$requirements.log_dirs = ($requirements.log_dirs | append "/var/log/provisioning")
# Service dependencies (would analyze service files to determine)
if $components.has_services {
$requirements.service_dependencies = ($requirements.service_dependencies | append "network.target")
}
# Port requirements (would analyze configuration to determine)
$requirements.port_requirements = ($requirements.port_requirements | append { port: 8080, description: "Main API" })
return $requirements
}
# Get directory size helper
def get_directory_size [dir: string] {
if not ($dir | path exists) {
return 0
}
glob $"($dir)/**/*"
| each {|file| stat $file | get size }
| math sum
}