Major refactor: Remove debos integration, add particle-os CLI system, implement OSTree stages, and create comprehensive build pipeline
Some checks failed
particle-os CI / Test particle-os (push) Failing after 1s
particle-os CI / Integration Test (push) Has been skipped
particle-os CI / Security & Quality (push) Failing after 1s
Test particle-os Basic Functionality / test-basic (push) Failing after 1s
Tests / test (1.21.x) (push) Failing after 2s
Tests / test (1.22.x) (push) Failing after 1s
particle-os CI / Build and Release (push) Has been skipped
Some checks failed
particle-os CI / Test particle-os (push) Failing after 1s
particle-os CI / Integration Test (push) Has been skipped
particle-os CI / Security & Quality (push) Failing after 1s
Test particle-os Basic Functionality / test-basic (push) Failing after 1s
Tests / test (1.21.x) (push) Failing after 2s
Tests / test (1.22.x) (push) Failing after 1s
particle-os CI / Build and Release (push) Has been skipped
This commit is contained in:
parent
c7e335d60f
commit
d2d4c2e4e7
101 changed files with 13234 additions and 6342 deletions
246
bib/create-working-bootable.go
Normal file
246
bib/create-working-bootable.go
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Usage: go run create-working-bootable.go <rootfs-path> [output-path]")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
rootfsPath := os.Args[1]
|
||||
outputPath := "debian-working-bootable.img"
|
||||
if len(os.Args) > 2 {
|
||||
outputPath = os.Args[2]
|
||||
}
|
||||
|
||||
fmt.Printf("Creating working bootable image from rootfs: %s\n", rootfsPath)
|
||||
fmt.Printf("Output: %s\n", outputPath)
|
||||
|
||||
// Check if rootfs exists
|
||||
if _, err := os.Stat(rootfsPath); os.IsNotExist(err) {
|
||||
fmt.Printf("Error: rootfs path does not exist: %s\n", rootfsPath)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create a 5GB raw disk image
|
||||
imageSize := "5G"
|
||||
fmt.Printf("Creating %s raw disk image...\n", imageSize)
|
||||
|
||||
// Use qemu-img to create the image
|
||||
cmd := exec.Command("qemu-img", "create", "-f", "raw", outputPath, imageSize)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error creating image: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create a loop device
|
||||
fmt.Println("Setting up loop device...")
|
||||
cmd = exec.Command("sudo", "losetup", "--find", "--show", outputPath)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting up loop device: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
loopDevice := strings.TrimSpace(string(output))
|
||||
fmt.Printf("Loop device: %s\n", loopDevice)
|
||||
|
||||
// Clean up loop device on exit
|
||||
defer func() {
|
||||
fmt.Printf("Cleaning up loop device: %s\n", loopDevice)
|
||||
exec.Command("sudo", "losetup", "-d", loopDevice).Run()
|
||||
}()
|
||||
|
||||
// Create partition table (GPT)
|
||||
fmt.Println("Creating GPT partition table...")
|
||||
cmd = exec.Command("sudo", "parted", loopDevice, "mklabel", "gpt")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error creating partition table: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create a single partition
|
||||
fmt.Println("Creating partition...")
|
||||
cmd = exec.Command("sudo", "parted", loopDevice, "mkpart", "primary", "ext4", "1MiB", "100%")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error creating partition: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Get the partition device
|
||||
partitionDevice := loopDevice + "p1"
|
||||
fmt.Printf("Partition device: %s\n", partitionDevice)
|
||||
|
||||
// Format the partition with ext4
|
||||
fmt.Println("Formatting partition with ext4...")
|
||||
cmd = exec.Command("sudo", "mkfs.ext4", partitionDevice)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error formatting partition: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create mount point
|
||||
mountPoint := "/tmp/particle-os-mount"
|
||||
if err := os.MkdirAll(mountPoint, 0755); err != nil {
|
||||
fmt.Printf("Error creating mount point: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Mount the partition
|
||||
fmt.Printf("Mounting partition to %s...\n", mountPoint)
|
||||
cmd = exec.Command("sudo", "mount", partitionDevice, mountPoint)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error mounting partition: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Clean up mount on exit
|
||||
defer func() {
|
||||
fmt.Printf("Unmounting %s...\n", mountPoint)
|
||||
exec.Command("sudo", "umount", mountPoint).Run()
|
||||
}()
|
||||
|
||||
// Copy rootfs content
|
||||
fmt.Printf("Copying rootfs content from %s to %s...\n", rootfsPath, mountPoint)
|
||||
cmd = exec.Command("sudo", "cp", "-a", rootfsPath+"/.", mountPoint+"/")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Error copying rootfs: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Fix permissions after copy
|
||||
fmt.Println("Fixing permissions...")
|
||||
cmd = exec.Command("sudo", "chown", "-R", "root:root", mountPoint)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: could not fix ownership: %v\n", err)
|
||||
}
|
||||
|
||||
// Install a kernel using debootstrap or apt
|
||||
fmt.Println("Installing kernel and bootloader...")
|
||||
|
||||
// Bind mount necessary directories for package installation
|
||||
bindDirs := []string{"/dev", "/proc", "/sys"}
|
||||
for _, dir := range bindDirs {
|
||||
bindMount := filepath.Join(mountPoint, dir)
|
||||
if err := exec.Command("sudo", "mount", "--bind", dir, bindMount).Run(); err != nil {
|
||||
fmt.Printf("Warning: could not bind mount %s: %v\n", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Update package lists
|
||||
fmt.Println("Updating package lists...")
|
||||
cmd = exec.Command("sudo", "chroot", mountPoint, "apt", "update")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: apt update failed: %v\n", err)
|
||||
}
|
||||
|
||||
// Install kernel and essential packages
|
||||
fmt.Println("Installing kernel and essential packages...")
|
||||
kernelPackages := []string{
|
||||
"linux-image-amd64", // Main kernel
|
||||
"linux-headers-amd64", // Kernel headers
|
||||
"grub-pc", // GRUB bootloader
|
||||
"grub-pc-bin", // GRUB binaries
|
||||
"os-prober", // OS detection
|
||||
"initramfs-tools", // Initial RAM disk
|
||||
"systemd-sysv", // Systemd
|
||||
"systemd", // Systemd
|
||||
"udev", // Device management
|
||||
"console-setup", // Console setup
|
||||
"keyboard-configuration", // Keyboard config
|
||||
"locales", // Locales
|
||||
"tzdata", // Timezone data
|
||||
}
|
||||
|
||||
for _, pkg := range kernelPackages {
|
||||
fmt.Printf("Installing %s...\n", pkg)
|
||||
cmd = exec.Command("sudo", "chroot", mountPoint, "apt", "install", "-y", "--no-install-recommends", pkg)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: failed to install %s: %v\n", pkg, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate initramfs
|
||||
fmt.Println("Generating initramfs...")
|
||||
cmd = exec.Command("sudo", "chroot", mountPoint, "update-initramfs", "-u", "-k", "all")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: initramfs generation failed: %v\n", err)
|
||||
}
|
||||
|
||||
// Install GRUB bootloader
|
||||
fmt.Println("Installing GRUB bootloader...")
|
||||
cmd = exec.Command("sudo", "chroot", mountPoint, "grub-install", "--target=i386-pc", loopDevice)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: GRUB installation failed: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("GRUB installed successfully")
|
||||
}
|
||||
|
||||
// Generate GRUB config
|
||||
fmt.Println("Generating GRUB configuration...")
|
||||
cmd = exec.Command("sudo", "chroot", mountPoint, "update-grub")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: GRUB config generation failed: %v\n", err)
|
||||
}
|
||||
|
||||
// Create a simple fstab
|
||||
fmt.Println("Creating fstab...")
|
||||
fstabContent := `# /etc/fstab for particle-os
|
||||
/dev/sda1 / ext4 rw,errors=remount-ro 0 1
|
||||
proc /proc proc defaults 0 0
|
||||
sysfs /sys sysfs defaults 0 0
|
||||
devpts /dev/pts devpts gid=5,mode=620 0 0
|
||||
tmpfs /run tmpfs defaults 0 0
|
||||
`
|
||||
fstabFile := filepath.Join(mountPoint, "etc", "fstab")
|
||||
cmd = exec.Command("sudo", "sh", "-c", fmt.Sprintf("cat > %s << 'EOF'\n%sEOF", fstabFile, fstabContent))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Printf("Warning: could not create fstab: %v\n", err)
|
||||
}
|
||||
|
||||
// Unbind mount directories
|
||||
for _, dir := range bindDirs {
|
||||
bindMount := filepath.Join(mountPoint, dir)
|
||||
exec.Command("sudo", "umount", bindMount).Run()
|
||||
}
|
||||
|
||||
fmt.Printf("\n✅ Working bootable image created successfully: %s\n", outputPath)
|
||||
fmt.Printf("Image size: %s\n", imageSize)
|
||||
fmt.Printf("Filesystem: ext4\n")
|
||||
fmt.Printf("Bootloader: GRUB with kernel\n")
|
||||
fmt.Printf("\nTo test the image:\n")
|
||||
fmt.Printf("qemu-system-x86_64 -m 2G -drive file=%s,format=raw -nographic -serial stdio\n", outputPath)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue