17 KiB
Bootstrap System API Documentation
Overview
This document describes the internal API of the NIP Bootstrap System. This is intended for developers who want to understand or extend the bootstrap functionality.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Bootstrap Coordinator │
│ (bootstrap.nim) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────┼────────────┬──────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Recipe │ │Download │ │Install │ │ Tool │
│ Manager │ │ Manager │ │ Manager │ │ Adapters │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
Module: recipe_parser.nim
Parses and validates KDL recipe files.
Types
PlatformArch
type PlatformArch* = enum
paX86_64 = "x86_64"
paAarch64 = "aarch64"
paArmv7 = "armv7"
Supported CPU architectures.
RecipeBinary
type RecipeBinary* = object
name*: string
url*: string
checksum*: string # Format: "blake2b-<hash>"
size*: int64 # bytes
executable*: bool
Represents a standalone binary file.
RecipeArchive
type RecipeArchive* = object
name*: string
url*: string
checksum*: string
size*: int64
extractTo*: string
Represents a compressed archive.
RecipePlatform
type RecipePlatform* = object
arch*: PlatformArch
os*: string # "linux", "bsd", etc.
binaries*: seq[RecipeBinary]
archives*: seq[RecipeArchive]
Platform-specific binaries and archives.
RecipeDependency
type RecipeDependency* = object
name*: string
kind*: string # "system", "nip", "optional"
version*: string # Optional version requirement
required*: bool
System or package dependency.
RecipeInstall
type RecipeInstall* = object
script*: string # Path to installation script
verifyScript*: string # Path to verification script
postInstall*: string # Optional post-install script
Installation script configuration.
RecipeMetadata
type RecipeMetadata* = object
author*: string
license*: string
updated*: string # ISO date
homepage*: string
issues*: string
Recipe metadata.
Recipe
type Recipe* = object
name*: string
version*: string
description*: string
toolType*: string # "nix", "pkgsrc", "gentoo"
platforms*: seq[RecipePlatform]
dependencies*: seq[RecipeDependency]
install*: RecipeInstall
metadata*: RecipeMetadata
Complete recipe definition.
Procedures
parseRecipe
proc parseRecipe*(kdlContent: string): Option[Recipe]
Parse a recipe from KDL string content.
Parameters:
kdlContent- KDL recipe content as string
Returns:
Option[Recipe]- Parsed recipe or none if parsing fails
Example:
let content = readFile("minimal-nix.kdl")
let recipeOpt = parseRecipe(content)
if recipeOpt.isSome():
let recipe = recipeOpt.get()
echo recipe.name
parseRecipeFile
proc parseRecipeFile*(filePath: string): Option[Recipe]
Parse a recipe from a file.
Parameters:
filePath- Path to recipe file
Returns:
Option[Recipe]- Parsed recipe or none if parsing fails
Example:
let recipeOpt = parseRecipeFile("recipes/nix/minimal-nix.kdl")
validateRecipe
proc validateRecipe*(recipe: Recipe): tuple[valid: bool, errors: seq[string]]
Validate a recipe structure.
Parameters:
recipe- Recipe to validate
Returns:
- Tuple of (valid, errors) where valid is true if recipe is valid
Example:
let (valid, errors) = validateRecipe(recipe)
if not valid:
for error in errors:
echo "Error: ", error
selectPlatform
proc selectPlatform*(recipe: Recipe, targetArch: PlatformArch,
targetOs: string = "linux"): Option[RecipePlatform]
Select appropriate platform from recipe.
Parameters:
recipe- Recipe to select fromtargetArch- Target architecturetargetOs- Target OS (default: "linux")
Returns:
Option[RecipePlatform]- Selected platform or none
Example:
let platformOpt = selectPlatform(recipe, paX86_64, "linux")
getCurrentPlatform
proc getCurrentPlatform*(): tuple[arch: PlatformArch, os: string]
Detect current system platform.
Returns:
- Tuple of (arch, os)
Example:
let (arch, os) = getCurrentPlatform()
echo "Running on: ", arch, "/", os
Module: recipe_manager.nim
Manages recipe fetching, caching, and loading.
Types
RecipeManager
type RecipeManager* = ref object
repoUrl*: string
localCache*: string
recipes*: Table[string, Recipe]
lastUpdate*: Time
Manages recipe repository and caching.
RecipeFetchResult
type RecipeFetchResult* = object
success*: bool
message*: string
recipesUpdated*: int
Result of recipe fetch operation.
Procedures
newRecipeManager
proc newRecipeManager*(repoUrl: string = DefaultRepoUrl,
cacheDir: string = ""): RecipeManager
Create a new RecipeManager.
Parameters:
repoUrl- Git repository URL (default: NexusToolKit repo)cacheDir- Cache directory (default: XDG cache)
Returns:
RecipeManagerinstance
Example:
let manager = newRecipeManager()
fetchRecipes
proc fetchRecipes*(rm: RecipeManager): RecipeFetchResult
Fetch or update recipes from Git repository.
Parameters:
rm- RecipeManager instance
Returns:
RecipeFetchResultwith status and message
Example:
let result = manager.fetchRecipes()
if result.success:
echo "Updated ", result.recipesUpdated, " recipes"
loadRecipe
proc loadRecipe*(rm: RecipeManager, toolType: string): Option[Recipe]
Load and parse recipe for a tool type.
Parameters:
rm- RecipeManager instancetoolType- Tool type ("nix", "pkgsrc", "gentoo")
Returns:
Option[Recipe]- Loaded recipe or none
Example:
let recipeOpt = manager.loadRecipe("nix")
if recipeOpt.isSome():
let recipe = recipeOpt.get()
echo "Loaded: ", recipe.name
hasRecipe
proc hasRecipe*(rm: RecipeManager, toolType: string): bool
Check if recipe exists for a tool type.
Parameters:
rm- RecipeManager instancetoolType- Tool type to check
Returns:
bool- True if recipe exists
Example:
if manager.hasRecipe("nix"):
echo "Nix recipe available"
listAvailableRecipes
proc listAvailableRecipes*(rm: RecipeManager): seq[string]
List all available recipe tool types.
Parameters:
rm- RecipeManager instance
Returns:
- Sequence of tool type strings
Example:
for toolType in manager.listAvailableRecipes():
echo "Available: ", toolType
Module: download_manager.nim
Manages file downloads with verification.
Types
DownloadResult
type DownloadResult* = object
success*: bool
filePath*: string
message*: string
bytesDownloaded*: int64
duration*: Duration
Result of download operation.
DownloadManager
type DownloadManager* = ref object
cacheDir*: string
maxRetries*: int
timeout*: Duration
client*: HttpClient
Manages file downloads.
Procedures
newDownloadManager
proc newDownloadManager*(cacheDir: string = ""): DownloadManager
Create a new DownloadManager.
Parameters:
cacheDir- Cache directory (default: XDG cache)
Returns:
DownloadManagerinstance
Example:
let manager = newDownloadManager()
defer: manager.close()
close
proc close*(dm: DownloadManager)
Close the download manager and cleanup resources.
Parameters:
dm- DownloadManager instance
Example:
manager.close()
downloadFile
proc downloadFile*(dm: DownloadManager, url: string, destPath: string,
expectedChecksum: string = ""): DownloadResult
Download a file with checksum verification.
Parameters:
dm- DownloadManager instanceurl- Download URL (HTTPS)destPath- Destination file pathexpectedChecksum- Expected Blake2b checksum (optional)
Returns:
DownloadResultwith status and details
Example:
let result = manager.downloadFile(
"https://example.com/file",
"/tmp/file",
"blake2b-abc123..."
)
if result.success:
echo "Downloaded: ", result.bytesDownloaded, " bytes"
verifyChecksum
proc verifyChecksum*(filePath: string, expectedChecksum: string): bool
Verify file checksum using Blake2b.
Parameters:
filePath- Path to fileexpectedChecksum- Expected checksum in format "blake2b-"
Returns:
bool- True if checksum matches
Example:
if verifyChecksum("/tmp/file", "blake2b-abc123..."):
echo "Checksum verified"
getCachedFile
proc getCachedFile*(dm: DownloadManager, filename: string): string
Get path to cached file.
Parameters:
dm- DownloadManager instancefilename- Filename
Returns:
- Full path to cached file
Example:
let path = manager.getCachedFile("nix-build")
Module: installation_manager.nim
Manages tool installation and rollback.
Types
InstallState
type InstallState* = enum
isNotStarted = "not_started"
isFetching = "fetching"
isDownloading = "downloading"
isVerifying = "verifying"
isExtracting = "extracting"
isInstalling = "installing"
isVerifyingInstall = "verifying_install"
isComplete = "complete"
isFailed = "failed"
Installation state.
InstallResult
type InstallResult* = object
success*: bool
toolPath*: string
version*: string
message*: string
errors*: seq[string]
warnings*: seq[string]
installTime*: Duration
Result of installation operation.
InstallationManager
type InstallationManager* = ref object
toolsDir*: string
tempDir*: string
backupDir*: string
Manages tool installation.
Procedures
newInstallationManager
proc newInstallationManager*(toolsDir: string = ""): InstallationManager
Create a new InstallationManager.
Parameters:
toolsDir- Tools directory (default: XDG data)
Returns:
InstallationManagerinstance
Example:
let manager = newInstallationManager()
extractArchive
proc extractArchive*(im: InstallationManager, archivePath: string,
destDir: string): tuple[success: bool, message: string]
Extract archive to destination directory.
Parameters:
im- InstallationManager instancearchivePath- Path to archive filedestDir- Destination directory
Returns:
- Tuple of (success, message)
Example:
let (success, msg) = manager.extractArchive(
"/tmp/archive.tar.xz",
"/opt/tool"
)
executeScript
proc executeScript*(im: InstallationManager, scriptPath: string,
workDir: string, env: Table[string, string] = initTable[string, string]()):
tuple[success: bool, output: string]
Execute installation script.
Parameters:
im- InstallationManager instancescriptPath- Path to scriptworkDir- Working directoryenv- Environment variables
Returns:
- Tuple of (success, output)
Example:
let env = {"INSTALL_DIR": "/opt/tool"}.toTable
let (success, output) = manager.executeScript(
"install.sh",
"/opt/tool",
env
)
verifyInstallation
proc verifyInstallation*(im: InstallationManager, toolType: string,
verifyScript: string, toolPath: string):
tuple[success: bool, message: string]
Verify tool installation.
Parameters:
im- InstallationManager instancetoolType- Tool typeverifyScript- Path to verification scripttoolPath- Tool installation path
Returns:
- Tuple of (success, message)
Example:
let (success, msg) = manager.verifyInstallation(
"nix",
"verify.sh",
"/opt/nix"
)
backupTool
proc backupTool*(im: InstallationManager, toolType: string): bool
Backup existing tool installation.
Parameters:
im- InstallationManager instancetoolType- Tool type
Returns:
bool- True if backup succeeded
Example:
if manager.backupTool("nix"):
echo "Backup created"
rollback
proc rollback*(im: InstallationManager, toolType: string): bool
Rollback failed installation.
Parameters:
im- InstallationManager instancetoolType- Tool type
Returns:
bool- True if rollback succeeded
Example:
if not installSuccess:
discard manager.rollback("nix")
Module: bootstrap.nim
Main bootstrap coordinator.
Types
BuildToolType
type BuildToolType* = enum
bttNix = "nix"
bttPkgsrc = "pkgsrc"
bttGentoo = "gentoo"
Supported build tool types.
BootstrapResult
type BootstrapResult* = object
success*: bool
toolPath*: string
message*: string
errors*: seq[string]
warnings*: seq[string]
Result of bootstrap operation.
Procedures
isToolInstalled
proc isToolInstalled*(toolType: BuildToolType): bool
Check if a build tool is installed in NIP's directory.
Parameters:
toolType- Tool type to check
Returns:
bool- True if installed
Example:
if isToolInstalled(bttNix):
echo "Nix is installed"
isSystemToolAvailable
proc isSystemToolAvailable*(toolType: BuildToolType): bool
Check if tool is available on the system.
Parameters:
toolType- Tool type to check
Returns:
bool- True if available
Example:
if isSystemToolAvailable(bttNix):
echo "Nix is available on system"
handleMissingTool
proc handleMissingTool*(toolType: BuildToolType, autoBootstrap: bool = false): bool
Handle missing build tool - prompt user or auto-bootstrap.
Parameters:
toolType- Tool typeautoBootstrap- Auto-install without prompting
Returns:
bool- True if tool is now available
Example:
if not isToolInstalled(bttNix):
if handleMissingTool(bttNix, autoBootstrap = true):
echo "Nix installed successfully"
installMinimalTools
proc installMinimalTools*(toolType: BuildToolType): BootstrapResult
Install minimal build tools for the specified type.
Parameters:
toolType- Tool type to install
Returns:
BootstrapResultwith status and details
Example:
let result = installMinimalTools(bttNix)
if result.success:
echo "Installed to: ", result.toolPath
Usage Examples
Complete Installation Flow
import nimpak/build/[bootstrap, recipe_manager, download_manager, installation_manager]
# Initialize managers
let recipeManager = newRecipeManager()
let downloadManager = newDownloadManager()
let installManager = newInstallationManager()
defer: downloadManager.close()
# Fetch recipes
let fetchResult = recipeManager.fetchRecipes()
if not fetchResult.success:
echo "Failed to fetch recipes"
quit(1)
# Load recipe
let recipeOpt = recipeManager.loadRecipe("nix")
if recipeOpt.isNone():
echo "Recipe not found"
quit(1)
let recipe = recipeOpt.get()
# Select platform
let (arch, os) = getCurrentPlatform()
let platformOpt = selectPlatform(recipe, arch, os)
if platformOpt.isNone():
echo "Platform not supported"
quit(1)
let platform = platformOpt.get()
# Download binaries
for binary in platform.binaries:
let destPath = downloadManager.getCachedFile(binary.name)
let result = downloadManager.downloadFile(binary.url, destPath, binary.checksum)
if not result.success:
echo "Download failed: ", result.message
quit(1)
# Install
let toolDir = "/opt/nix"
let env = {"INSTALL_DIR": toolDir}.toTable
let (success, output) = installManager.executeScript(
recipe.install.script,
toolDir,
env
)
if success:
echo "Installation successful"
else:
echo "Installation failed: ", output
Error Handling
All procedures that can fail return either:
Option[T]- UseisSome()andget()to check and extracttuple[success: bool, ...]- ChecksuccessfieldResultobject withsuccessfield
Always check return values and handle errors appropriately.
Thread Safety
The bootstrap system is not thread-safe. Do not use the same manager instances from multiple threads.
See Also
- Bootstrap Guide - User documentation
- Recipe Authoring Guide - Creating recipes
- Source Build Guide - Building from source