164 lines
5.6 KiB
Plaintext
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
|
|
}
|