diff --git a/Dockerfile b/Dockerfile index de800b3..67f31fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN apk add --no-cache \ rustup \ upx \ git \ + openssh-client \ wget \ curl \ tar \ diff --git a/README.md b/README.md index 39393ed..569fa7b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A comprehensive build system for creating custom Alpine Linux 3.22 x86_64 initra - **Alpine Linux 3.22** miniroot as base system - **zinit** process manager (complete OpenRC replacement) - **Rootless containers** (Docker/Podman compatible) -- **Rust components** with musl targeting (zinit, rfs, mycelium) +- **Rust components** with musl targeting (zinit, rfs, mycelium, zosstorage) - **Aggressive optimization** (strip + UPX compression) - **2-stage module loading** for hardware support - **GitHub Actions** compatible build pipeline @@ -222,6 +222,7 @@ Services are migrated from existing `configs/zinit/` directory with proper initi - **zinit**: Standard cargo build - **rfs**: Standard cargo build - **mycelium**: Build in `myceliumd/` subdirectory + - **zosstorage**: Build from the storage orchestration component for Zero-OS 4. Install binaries to initramfs ### Phase 4: System Configuration diff --git a/config/kernel.config b/config/kernel.config index bfb1a16..2c277c7 100644 --- a/config/kernel.config +++ b/config/kernel.config @@ -1,18 +1,18 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 6.12.44 Kernel Configuration +# Linux/x86 6.12.49 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="gcc (Alpine 14.2.0) 14.2.0" +CONFIG_CC_VERSION_TEXT="gcc (GCC) 15.2.1 20250813" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=140200 +CONFIG_GCC_VERSION=150201 CONFIG_CLANG_VERSION=0 CONFIG_AS_IS_GNU=y -CONFIG_AS_VERSION=24400 +CONFIG_AS_VERSION=24500 CONFIG_LD_IS_BFD=y -CONFIG_LD_VERSION=24400 +CONFIG_LD_VERSION=24500 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=109000 -CONFIG_RUSTC_LLVM_VERSION=200108 +CONFIG_RUSTC_VERSION=108900 +CONFIG_RUSTC_LLVM_VERSION=200107 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y @@ -20,6 +20,7 @@ CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_CC_HAS_COUNTED_BY=y CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES=y CONFIG_PAHOLE_VERSION=130 @@ -368,23 +369,10 @@ CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y -CONFIG_PARAVIRT_XXL=y # CONFIG_PARAVIRT_DEBUG is not set CONFIG_PARAVIRT_SPINLOCKS=y CONFIG_X86_HV_CALLBACK_VECTOR=y -CONFIG_XEN=y -CONFIG_XEN_PV=y -CONFIG_XEN_512GB=y -CONFIG_XEN_PV_SMP=y -CONFIG_XEN_PV_DOM0=y -CONFIG_XEN_PVHVM=y -CONFIG_XEN_PVHVM_SMP=y -CONFIG_XEN_PVHVM_GUEST=y -CONFIG_XEN_SAVE_RESTORE=y -# CONFIG_XEN_DEBUG_FS is not set -CONFIG_XEN_PVH=y -CONFIG_XEN_DOM0=y -CONFIG_XEN_PV_MSR_SAFE=y +# CONFIG_XEN is not set CONFIG_KVM_GUEST=y CONFIG_ARCH_CPUIDLE_HALTPOLL=y CONFIG_PVH=y @@ -528,7 +516,7 @@ CONFIG_HOTPLUG_CPU=y CONFIG_LEGACY_VSYSCALL_XONLY=y # CONFIG_LEGACY_VSYSCALL_NONE is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="intel_iommu=on kvm-intel.nested=1 console=ttyS1,115200n8 console=tty1 consoleblank=0 earlyprintk=serial,ttyS1,115200n8 loglevel=7" +CONFIG_CMDLINE="consoleblank=0 earlyprintk=serial loglevel=7" # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_MODIFY_LDT_SYSCALL=y # CONFIG_STRICT_SIGALTSTACK_SIZE is not set @@ -573,6 +561,7 @@ CONFIG_MITIGATION_SRBDS=y CONFIG_MITIGATION_SSB=y CONFIG_MITIGATION_ITS=y CONFIG_MITIGATION_TSA=y +CONFIG_MITIGATION_VMSCAPE=y CONFIG_ARCH_HAS_ADD_PAGES=y # @@ -737,7 +726,6 @@ CONFIG_INTEL_IDLE=y # CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y -CONFIG_PCI_XEN=y CONFIG_MMCONF_FAM10H=y # CONFIG_PCI_CNB20LE_QUIRK is not set # CONFIG_ISA_BUS is not set @@ -1959,7 +1947,6 @@ CONFIG_FIB_RULES=y CONFIG_NET_9P=m CONFIG_NET_9P_FD=m CONFIG_NET_9P_VIRTIO=m -CONFIG_NET_9P_XEN=m # CONFIG_NET_9P_RDMA is not set # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set @@ -2009,7 +1996,6 @@ CONFIG_PCI_QUIRKS=y CONFIG_PCI_REALLOC_ENABLE_AUTO=y CONFIG_PCI_STUB=m # CONFIG_PCI_PF_STUB is not set -CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_PCI_ATS=y CONFIG_PCI_LOCKLESS_CONFIG=y CONFIG_PCI_IOV=y @@ -2127,7 +2113,6 @@ CONFIG_ALLOW_DEV_COREDUMP=y # CONFIG_DEBUG_DEVRES is not set # CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -CONFIG_SYS_HYPERVISOR=y CONFIG_GENERIC_CPU_DEVICES=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y @@ -2397,8 +2382,6 @@ CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set CONFIG_ATA_OVER_ETH=m -CONFIG_XEN_BLKDEV_FRONTEND=m -CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_RBD=m # CONFIG_BLK_DEV_UBLK is not set @@ -2602,7 +2585,6 @@ CONFIG_SCSI_FLASHPOINT=y # CONFIG_SCSI_MYRB is not set # CONFIG_SCSI_MYRS is not set CONFIG_VMWARE_PVSCSI=m -CONFIG_XEN_SCSI_FRONTEND=m CONFIG_HYPERV_STORAGE=m CONFIG_LIBFC=m CONFIG_LIBFCOE=m @@ -3408,8 +3390,6 @@ CONFIG_IEEE802154_ATUSB=m # CONFIG_WWAN is not set # end of Wireless WAN -CONFIG_XEN_NETDEV_FRONTEND=m -CONFIG_XEN_NETDEV_BACKEND=m CONFIG_VMXNET3=m CONFIG_FUJITSU_ES=m CONFIG_HYPERV_NET=m @@ -3583,9 +3563,6 @@ CONFIG_N_GSM=m CONFIG_NOZOMI=m # CONFIG_NULL_TTY is not set CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -CONFIG_HVC_XEN_FRONTEND=y CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y # CONFIG_TTY_PRINTK is not set @@ -3636,7 +3613,6 @@ CONFIG_TCG_TIS_I2C_NUVOTON=m CONFIG_TCG_NSC=m CONFIG_TCG_ATMEL=m CONFIG_TCG_INFINEON=m -CONFIG_TCG_XEN=m CONFIG_TCG_CRB=m # CONFIG_TCG_VTPM_PROXY is not set # CONFIG_TCG_TIS_ST33ZP24_I2C is not set @@ -4412,7 +4388,6 @@ CONFIG_INTEL_MEI_WDT=m CONFIG_NI903X_WDT=m CONFIG_NIC7018_WDT=m CONFIG_MEN_A21_WDT=m -CONFIG_XEN_WDT=m # # PCI-based Watchdog Cards @@ -4868,7 +4843,6 @@ CONFIG_DRM_CIRRUS_QEMU=m # CONFIG_TINYDRM_REPAPER is not set # CONFIG_TINYDRM_ST7586 is not set # CONFIG_TINYDRM_ST7735R is not set -# CONFIG_DRM_XEN_FRONTEND is not set CONFIG_DRM_VBOXVIDEO=m # CONFIG_DRM_GUD is not set # CONFIG_DRM_SSD130X is not set @@ -4920,7 +4894,6 @@ CONFIG_FB_EFI=y # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set # CONFIG_FB_VIRTUAL is not set -CONFIG_XEN_FBDEV_FRONTEND=m # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set CONFIG_FB_HYPERV=m @@ -5132,7 +5105,6 @@ CONFIG_SND_PCMCIA=y # CONFIG_SND_SOC is not set CONFIG_SND_X86=y # CONFIG_HDMI_LPE_AUDIO is not set -# CONFIG_SND_XEN_FRONTEND is not set CONFIG_SND_VIRTIO=m CONFIG_HID_SUPPORT=y CONFIG_HID=m @@ -5349,7 +5321,6 @@ CONFIG_USB_R8A66597_HCD=m # CONFIG_USB_HCD_BCMA is not set # CONFIG_USB_HCD_SSB is not set # CONFIG_USB_HCD_TEST_MODE is not set -# CONFIG_USB_XEN_HCD is not set # # USB Device Class drivers @@ -6024,41 +5995,6 @@ CONFIG_HYPERV_UTILS=m CONFIG_HYPERV_BALLOON=m # end of Microsoft Hyper-V guest support -# -# Xen driver support -# -CONFIG_XEN_BALLOON=y -CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y -CONFIG_XEN_MEMORY_HOTPLUG_LIMIT=512 -CONFIG_XEN_SCRUB_PAGES_DEFAULT=y -CONFIG_XEN_DEV_EVTCHN=m -CONFIG_XEN_BACKEND=y -CONFIG_XENFS=m -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_SYS_HYPERVISOR=y -CONFIG_XEN_XENBUS_FRONTEND=y -CONFIG_XEN_GNTDEV=m -CONFIG_XEN_GRANT_DEV_ALLOC=m -# CONFIG_XEN_GRANT_DMA_ALLOC is not set -CONFIG_SWIOTLB_XEN=y -CONFIG_XEN_PCI_STUB=y -CONFIG_XEN_PCIDEV_BACKEND=m -# CONFIG_XEN_PVCALLS_FRONTEND is not set -# CONFIG_XEN_PVCALLS_BACKEND is not set -CONFIG_XEN_SCSI_BACKEND=m -CONFIG_XEN_PRIVCMD=m -CONFIG_XEN_ACPI_PROCESSOR=m -CONFIG_XEN_MCE_LOG=y -CONFIG_XEN_HAVE_PVMMU=y -CONFIG_XEN_EFI=y -CONFIG_XEN_AUTO_XLATE=y -CONFIG_XEN_ACPI=y -CONFIG_XEN_SYMS=y -CONFIG_XEN_HAVE_VPMU=y -CONFIG_XEN_UNPOPULATED_ALLOC=y -# CONFIG_XEN_VIRTIO is not set -# end of Xen driver support - # CONFIG_GREYBUS is not set # CONFIG_COMEDI is not set CONFIG_STAGING=y diff --git a/config/modules.conf b/config/modules.conf index 95c94a0..100b613 100644 --- a/config/modules.conf +++ b/config/modules.conf @@ -70,5 +70,8 @@ stage1:evdev stage1:serio_raw stage1:serio +# zos core networking is with openvswitch vxlan over mycelium +openvswitch + # Keep stage2 empty; we only use stage1 in this build # stage2: (intentionally unused) diff --git a/config/sources.conf b/config/sources.conf index effd9b7..501970d 100644 --- a/config/sources.conf +++ b/config/sources.conf @@ -4,7 +4,8 @@ # Git repositories to clone and build git zinit https://github.com/threefoldtech/zinit master build_zinit git mycelium https://github.com/threefoldtech/mycelium v0.6.1 build_mycelium - +git zosstorage git@git.ourworld.tf:delandtj/zosstorage main build_zosstorage +git rfs https://github.com/threefoldtech/rfs development build_rfs # Pre-built releases to download -release rfs https://github.com/threefoldtech/rfs/releases/download/v2.0.6/rfs v2.0.6 install_rfs +# release rfs https://github.com/threefoldtech/rfs/releases/download/v2.0.6/rfs v2.0.6 install_rfs release corex https://github.com/threefoldtech/corex/releases/download/2.1.4/corex-2.1.4-amd64-linux-static 2.1.4 install_corex rename=corex \ No newline at end of file diff --git a/config/zinit/init/ovs-dbserver.sh b/config/zinit/init/ovs-dbserver.sh new file mode 100644 index 0000000..3063e34 --- /dev/null +++ b/config/zinit/init/ovs-dbserver.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Simple script to create OVS database and start ovsdb-server + +# Configuration +DATABASE=${DATABASE:-"/etc/openvswitch/conf.db"} +DBSCHEMA="/usr/share/openvswitch/vswitch.ovsschema" +DB_SOCKET=${DB_SOCKET:-"/var/run/openvswitch/db.sock"} +RUNDIR="/var/run/openvswitch" + +# Create run directory +mkdir -p "$RUNDIR" + +# Create database if it doesn't exist +if [ ! -e "$DATABASE" ]; then + echo "Creating database: $DATABASE" + ovsdb-tool create "$DATABASE" "$DBSCHEMA" +fi + +# Check if database needs conversion +if [ "$(ovsdb-tool needs-conversion "$DATABASE" "$DBSCHEMA")" = "yes" ]; then + echo "Converting database: $DATABASE" + ovsdb-tool convert "$DATABASE" "$DBSCHEMA" +fi + +# Start ovsdb-server +echo "Starting ovsdb-server..." +exec ovsdb-server \ + --remote=punix:"$DB_SOCKET" \ + --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ + --pidfile \ + --detach \ + "$DATABASE" diff --git a/config/zinit/mycelium.yaml b/config/zinit/mycelium.yaml index 595b8c0..2038885 100644 --- a/config/zinit/mycelium.yaml +++ b/config/zinit/mycelium.yaml @@ -1,7 +1,8 @@ -exec: /usr/bin/mycelium --key-file /tmp/mycelium_priv_key.bin +exec: /usr/bin/mycelium --key-file /var/cache/etc/mycelium_priv_key.bin --tun-name my0 --silent --peers tcp://188.40.132.242:9651 tcp://136.243.47.186:9651 tcp://185.69.166.7:9651 tcp://185.69.166.8:9651 tcp://65.21.231.58:9651 tcp://65.109.18.113:9651 tcp://209.159.146.190:9651 tcp://5.78.122.16:9651 tcp://5.223.43.251:9651 tcp://142.93.217.194:9651 after: - network - - udev-rfs \ No newline at end of file + - udev-rfs + - zosstorage \ No newline at end of file diff --git a/config/zinit/network.yaml b/config/zinit/network.yaml index ab294c7..da847df 100644 --- a/config/zinit/network.yaml +++ b/config/zinit/network.yaml @@ -3,4 +3,4 @@ after: - depmod - udevd - udev-trigger -test: ping www.google.com +test: ping -c1 www.google.com diff --git a/config/zinit/ovs-dbserver.yaml b/config/zinit/ovs-dbserver.yaml new file mode 100644 index 0000000..4e9ca46 --- /dev/null +++ b/config/zinit/ovs-dbserver.yaml @@ -0,0 +1,4 @@ +exec: /etc/zinit/init/ovsdb-server.sh +oneshot: true +after: + - zossstorage \ No newline at end of file diff --git a/config/zinit/zosstorage.yaml b/config/zinit/zosstorage.yaml new file mode 100644 index 0000000..cd5abd6 --- /dev/null +++ b/config/zinit/zosstorage.yaml @@ -0,0 +1,4 @@ +exec: /usr/bin/zosstorage -l debug +oneshot: true +after: + - rfs-modules \ No newline at end of file diff --git a/docs/NOTES.md b/docs/NOTES.md index e142dcb..59c71e9 100644 --- a/docs/NOTES.md +++ b/docs/NOTES.md @@ -84,7 +84,7 @@ Initramfs Assembly – Key Functions - Install init script: [bash.initramfs_install_init_script()](scripts/lib/initramfs.sh:74) - Installs [config/init](config/init) as /init in initramfs root. - Components copy: [bash.initramfs_copy_components()](scripts/lib/initramfs.sh:101) - - Installs built components (zinit/rfs/mycelium/corex) into proper locations, strips/UPX where applicable. +- Installs built components (zinit/rfs/mycelium/corex/zosstorage) into proper locations, strips/UPX where applicable. - Modules setup: [bash.initramfs_setup_modules()](scripts/lib/initramfs.sh:229) - Reads [config/modules.conf](config/modules.conf), resolves deps via [bash.initramfs_resolve_module_dependencies()](scripts/lib/initramfs.sh:318), generates stage1 list (firmware hints in modules.conf are ignored; firmware.conf is authoritative). - Create module scripts: [bash.initramfs_create_module_scripts()](scripts/lib/initramfs.sh:427) @@ -204,6 +204,8 @@ Change Log - Normalize INSTALL_DIR/COMPONENTS_DIR/KERNEL_DIR/DIST_DIR to absolute paths post-config load. - Add validation diagnostics prints (input/PWD/PROJECT_ROOT/INSTALL_DIR/resolved). - Ensure shadow package in container for passwd/chpasswd; keep openssl and openssl-dev; remove perl earlier. +- 2025-10-10: + - Record zosstorage as a standard component installed during [bash.initramfs_copy_components()](scripts/lib/initramfs.sh:101) and sync component documentation references. Updates 2025-10-01 - Function index regenerated: see [scripts/functionlist.md](scripts/functionlist.md) for an authoritative map of all functions with current line numbers. Use it alongside the quick links below to jump into code fast. diff --git a/runit.sh b/runit.sh new file mode 100755 index 0000000..16e7fb2 --- /dev/null +++ b/runit.sh @@ -0,0 +1,263 @@ +#!/bin/bash + +set -e + +# Default configuration +HYPERVISOR="${HYPERVISOR:-qemu}" # qemu or ch (cloud-hypervisor) +NUM_DISKS="${NUM_DISKS:-3}" +DISK_SIZE="${DISK_SIZE:-10G}" +DISK_PREFIX="zosvol" +KERNEL="dist/vmlinuz.efi" +MEMORY="2048" +BRIDGE="${BRIDGE:-zosbr}" +TAP_INTERFACE="${TAP_INTERFACE:-zos-tap0}" + +# Parse command line arguments +RESET_VOLUMES=false + +usage() { + cat < Choose hypervisor (default: qemu) + -d, --disks Number of disks to create (default: 3) + -s, --disk-size Size of each disk (default: 10G) + -r, --reset Delete and recreate all volumes + -m, --memory Memory in MB (default: 2048) + -b, --bridge Network bridge name (default: zosbr) + -h, --help Show this help message + +Environment variables: + HYPERVISOR Same as --hypervisor + NUM_DISKS Same as --disks + DISK_SIZE Same as --disk-size + BRIDGE Same as --bridge + +Examples: + $0 -H qemu -d 5 + $0 --hypervisor ch --reset + $0 -d 4 -r + HYPERVISOR=ch NUM_DISKS=4 $0 +EOF + exit 0 +} + +# Parse arguments using getopt +TEMP=$(getopt -o 'H:d:s:rm:b:h' --long 'hypervisor:,disks:,disk-size:,reset,memory:,bridge:,help' -n "$0" -- "$@") + +if [ $? -ne 0 ]; then + echo "Error parsing arguments. Try '$0 --help' for more information." + exit 1 +fi + +eval set -- "$TEMP" +unset TEMP + +while true; do + case "$1" in + '-H' | '--hypervisor') + HYPERVISOR="$2" + shift 2 + ;; + '-d' | '--disks') + NUM_DISKS="$2" + shift 2 + ;; + '-s' | '--disk-size') + DISK_SIZE="$2" + shift 2 + ;; + '-r' | '--reset') + RESET_VOLUMES=true + shift + ;; + '-m' | '--memory') + MEMORY="$2" + shift 2 + ;; + '-b' | '--bridge') + BRIDGE="$2" + shift 2 + ;; + '-h' | '--help') + usage + ;; + '--') + shift + break + ;; + *) + echo "Internal error!" + exit 1 + ;; + esac +done + +# Validate hypervisor choice +if [[ "$HYPERVISOR" != "qemu" && "$HYPERVISOR" != "ch" ]]; then + echo "Error: Invalid hypervisor '$HYPERVISOR'. Must be 'qemu' or 'ch'" + exit 1 +fi + +if [[ "$HYPERVISOR" == "qemu" ]]; then + DISK_SUFFIX="qcow" + DISK_FORMAT="qcow2" +else + DISK_SUFFIX="raw" + DISK_FORMAT="raw" +fi + +# Validate kernel exists +if [[ ! -f "$KERNEL" ]]; then + echo "Error: Kernel not found at $KERNEL" + echo "Run the build first: ./scripts/build.sh" + exit 1 +fi + +# Setup TAP interface for cloud-hypervisor +setup_tap_interface() { + local tap="$1" + local bridge="$2" + + echo "Setting up TAP interface $tap for cloud-hypervisor..." + if [[ -z "${CH_TAP_IP:-}" && -z "${CH_TAP_MASK:-}" ]]; then + echo " Reminder: set CH_TAP_IP and CH_TAP_MASK to configure $tap and silence cloud-hypervisor IP warnings." + fi + + # Check if bridge exists + if ! ip link show "$bridge" &>/dev/null; then + echo "Warning: Bridge $bridge does not exist. Create it with:" + echo " sudo ip link add name $bridge type bridge" + echo " sudo ip link set $bridge up" + echo "" + read -p "Continue anyway? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + fi + + # Check if TAP already exists + if ip link show "$tap" &>/dev/null; then + echo " TAP interface $tap already exists" + # Check if it's already attached to bridge + if bridge link show | grep -q "$tap"; then + echo " $tap is already attached to bridge" + return 0 + else + echo " Attaching $tap to bridge $bridge" + sudo ip link set dev "$tap" master "$bridge" 2>/dev/null || true + return 0 + fi + fi + + # Create new TAP interface + echo " Creating TAP interface $tap" + sudo ip tuntap add "$tap" mode tap user "$(whoami)" + + # Bring it up + echo " Bringing up $tap" + sudo ip link set "$tap" up + + # Attach to bridge + echo " Attaching $tap to bridge $bridge" + sudo ip link set dev "$tap" master "$bridge" + + echo " TAP interface setup complete" +} + +# Cleanup TAP interface on exit (for cloud-hypervisor) +cleanup_tap_interface() { + local tap="$1" + if [[ -n "$tap" ]] && ip link show "$tap" &>/dev/null; then + echo "Cleaning up TAP interface $tap" + sudo ip link delete "$tap" 2>/dev/null || true + fi +} + +# Reset volumes if requested +if [[ "$RESET_VOLUMES" == "true" ]]; then + echo "Resetting volumes..." + for i in $(seq 0 $((NUM_DISKS - 1))); do + for suffix in qcow raw; do + vol="${DISK_PREFIX}${i}.${suffix}" + if [[ -f "$vol" ]]; then + echo " Removing $vol" + rm -f "$vol" + fi + done + done +fi + +# Create disk volumes if they don't exist +echo "Ensuring $NUM_DISKS disk volume(s) exist..." +for i in $(seq 0 $((NUM_DISKS - 1))); do + vol="${DISK_PREFIX}${i}.${DISK_SUFFIX}" + if [[ ! -f "$vol" ]]; then + echo " Creating $vol (size: $DISK_SIZE, format: $DISK_FORMAT)" + qemu-img create -f "$DISK_FORMAT" "$vol" "$DISK_SIZE" >/dev/null + else + echo " $vol already exists" + fi +done + +# Build disk arguments based on hypervisor +DISK_ARGS=() +if [[ "$HYPERVISOR" == "qemu" ]]; then + for i in $(seq 0 $((NUM_DISKS - 1))); do + vol="${DISK_PREFIX}${i}.${DISK_SUFFIX}" + DISK_ARGS+=("-drive" "file=$vol,format=$DISK_FORMAT,if=virtio") + done +elif [[ "$HYPERVISOR" == "ch" ]]; then + # cloud-hypervisor requires comma-separated disk list in single --disk argument + # Use raw format (no compression) + CH_DISKS="" + for i in $(seq 0 $((NUM_DISKS - 1))); do + vol="${DISK_PREFIX}${i}.${DISK_SUFFIX}" + if [[ -z "$CH_DISKS" ]]; then + CH_DISKS="path=$vol,iommu=on" + else + CH_DISKS="${CH_DISKS},path=$vol,iommu=on" + fi + done + if [[ -n "$CH_DISKS" ]]; then + DISK_ARGS+=("--disk" "$CH_DISKS") + fi +fi + +# Launch the appropriate hypervisor +echo "Launching with $HYPERVISOR hypervisor..." +echo "" + +if [[ "$HYPERVISOR" == "qemu" ]]; then + exec qemu-system-x86_64 \ + -kernel "$KERNEL" \ + -m "$MEMORY" \ + -enable-kvm \ + -cpu host \ + -net nic,model=virtio \ + -net bridge,br="$BRIDGE" \ + "${DISK_ARGS[@]}" \ + -chardev stdio,id=char0,mux=on,logfile=serial.log \ + -serial chardev:char0 \ + -mon chardev=char0 \ + -append "console=ttyS0,115200n8 console=tty" + +elif [[ "$HYPERVISOR" == "ch" ]]; then + # Setup TAP interface for cloud-hypervisor + setup_tap_interface "$TAP_INTERFACE" "$BRIDGE" + + # Cleanup on exit + trap "cleanup_tap_interface '$TAP_INTERFACE'" EXIT + + exec cloud-hypervisor \ + --kernel "$KERNEL" \ + --memory size="${MEMORY}M" \ + --cpus boot=2 \ + --net "tap=$TAP_INTERFACE" \ + "${DISK_ARGS[@]}" \ + --console off \ + --serial tty \ + --cmdline "console=ttyS0,115200n8" +fi diff --git a/scripts/dev-container.sh b/scripts/dev-container.sh index b4cd508..7209a24 100755 --- a/scripts/dev-container.sh +++ b/scripts/dev-container.sh @@ -9,6 +9,7 @@ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Container configuration CONTAINER_NAME="zero-os-dev" BUILDER_IMAGE="zero-os-builder:latest" +HOST_SSH_DIR="${SSH_MOUNT_DIR:-${HOME}/.ssh}" # Default to verbose, streaming logs for dev flows unless explicitly disabled export DEBUG="${DEBUG:-1}" @@ -88,18 +89,32 @@ function dev_container_start() { log_info "Creating new development container: ${CONTAINER_NAME}" # Create persistent container with all necessary mounts and environment - safe_execute podman run -d \ - --name "$CONTAINER_NAME" \ - --privileged \ - -v "${PROJECT_ROOT}:/workspace" \ - -w /workspace \ - -e DEBUG=1 \ - -e ALPINE_VERSION=3.22 \ - -e KERNEL_VERSION=6.12.44 \ - -e RUST_TARGET=x86_64-unknown-linux-musl \ - -e OPTIMIZATION_LEVEL=max \ - "$BUILDER_IMAGE" \ + local podman_args=( + run -d + --name "$CONTAINER_NAME" + --privileged + -v "${PROJECT_ROOT}:/workspace" + -w /workspace + -e DEBUG=1 + -e ALPINE_VERSION=3.22 + -e KERNEL_VERSION=6.12.44 + -e RUST_TARGET=x86_64-unknown-linux-musl + -e OPTIMIZATION_LEVEL=max + ) + + if [[ -d "$HOST_SSH_DIR" ]]; then + log_info "Mounting SSH directory: ${HOST_SSH_DIR} -> /root/.ssh (read-only)" + podman_args+=(-v "${HOST_SSH_DIR}:/root/.ssh:ro") + else + log_warn "SSH directory not found at ${HOST_SSH_DIR}; skipping SSH mount" + fi + + podman_args+=( + "$BUILDER_IMAGE" sleep infinity + ) + + safe_execute podman "${podman_args[@]}" log_info "Development container started successfully" log_info "Container name: ${CONTAINER_NAME}" diff --git a/scripts/lib/components.sh b/scripts/lib/components.sh index e4d41e0..76dbab3 100644 --- a/scripts/lib/components.sh +++ b/scripts/lib/components.sh @@ -421,6 +421,50 @@ function build_rfs() { log_info "Built rfs binary (${binary_size}) at: ${binary_path}" } +# Build function for zosstorage (standard Rust build) +function build_zosstorage() { + local name="$1" + local component_dir="$2" + + section_header "Building zosstorage with musl target" + + components_setup_rust_env + + log_info "Building zosstorage from: ${component_dir}" + + if [[ ! -d "$component_dir" ]]; then + log_error "Component directory not found: ${component_dir}" + return 1 + fi + + log_info "Executing: cd $component_dir" + cd "$component_dir" || { + log_error "Failed to change to directory: $component_dir" + return 1 + } + + local current_dir + current_dir=$(pwd) + log_info "Current directory: ${current_dir}" + + if [[ ! -f "Cargo.toml" ]]; then + log_error "Cargo.toml not found in: ${current_dir}" + return 1 + fi + + safe_execute cargo build --release --target "$RUST_TARGET" + + local binary_path="target/${RUST_TARGET}/release/zosstorage" + if [[ ! -f "$binary_path" ]]; then + log_error "zosstorage binary not found at: ${binary_path}" + return 1 + fi + + local binary_size + binary_size=$(get_file_size "$binary_path") + log_info "Built zosstorage binary (${binary_size}) at: ${binary_path}" +} + # Build function for mycelium (special subdirectory build) function build_mycelium() { local name="$1" @@ -554,6 +598,16 @@ function components_verify_installation() { ((missing_count++)) fi + # zosstorage + local zosstorage_bin="${components_dir}/zosstorage/target/x86_64-unknown-linux-musl/release/zosstorage" + if [[ -x "$zosstorage_bin" ]]; then + log_info "✓ zosstorage ($(get_file_size "$zosstorage_bin")) at: ${zosstorage_bin#${components_dir}/}" + ((ok_count++)) + else + log_error "✗ zosstorage missing: ${zosstorage_bin#${components_dir}/}" + ((missing_count++)) + fi + # corex local corex_bin="${components_dir}/corex/corex" if [[ -x "$corex_bin" ]]; then @@ -599,7 +653,7 @@ function components_cleanup() { export -f components_parse_sources_conf export -f components_download_git components_download_release components_process_extra_options export -f components_build_component components_setup_rust_env -export -f build_zinit build_rfs build_mycelium install_corex +export -f build_zinit build_rfs build_zosstorage build_mycelium install_corex export -f components_verify_installation components_cleanup # Export functions for install_rfs export -f install_rfs diff --git a/scripts/lib/initramfs.sh b/scripts/lib/initramfs.sh index d765477..88707ff 100644 --- a/scripts/lib/initramfs.sh +++ b/scripts/lib/initramfs.sh @@ -186,6 +186,34 @@ function initramfs_copy_components() { log_error "✗ mycelium binary not found: ${mycelium_binary}" ((missing_count++)) fi + + # Copy zosstorage to /usr/bin + local zosstorage_binary="${components_dir}/zosstorage/target/x86_64-unknown-linux-musl/release/zosstorage" + if [[ -f "$zosstorage_binary" ]]; then + safe_mkdir "${initramfs_dir}/usr/bin" + safe_execute cp "$zosstorage_binary" "${initramfs_dir}/usr/bin/zosstorage" + safe_execute chmod +x "${initramfs_dir}/usr/bin/zosstorage" + + local original_size=$(get_file_size "${initramfs_dir}/usr/bin/zosstorage") + if strip "${initramfs_dir}/usr/bin/zosstorage" 2>/dev/null || true; then + log_debug "Stripped zosstorage" + else + log_debug "zosstorage already stripped or strip failed" + fi + + if command_exists "upx" && upx --best --force "${initramfs_dir}/usr/bin/zosstorage" >/dev/null 2>&1 || true; then + log_debug "UPX compressed zosstorage" + else + log_debug "UPX failed or already compressed" + fi + + local final_size=$(get_file_size "${initramfs_dir}/usr/bin/zosstorage") + log_info "✓ Copied zosstorage ${original_size} → ${final_size} to /usr/bin/zosstorage" + ((copied_count++)) + else + log_error "✗ zosstorage binary not found: ${zosstorage_binary}" + ((missing_count++)) + fi # Copy corex to /usr/bin local corex_binary="${components_dir}/corex/corex" @@ -929,6 +957,7 @@ function initramfs_validate() { local component_binaries=( "usr/bin/rfs" "usr/bin/mycelium" + "usr/bin/zosstorage" "usr/bin/corex" ) diff --git a/scripts/rfs/pack-tree.sh b/scripts/rfs/pack-tree.sh index 6d48ee7..a22cd35 100755 --- a/scripts/rfs/pack-tree.sh +++ b/scripts/rfs/pack-tree.sh @@ -109,7 +109,7 @@ section "Packing directory to flist" log_info "Source path: ${SRC_PATH}" log_info "Manifest: ${MANIFEST_PATH}" log_info "Store: ${RFS_S3_STORE_URI}" -safe_execute "${RFS_BIN}" pack --debug -m "${MANIFEST_PATH}" -s "${RFS_S3_STORE_URI}" "${SRC_PATH}" +safe_execute "${RFS_BIN}" --debug pack -m "${MANIFEST_PATH}" -s "${RFS_S3_STORE_URI}" "${SRC_PATH}" section "Patching route.url in manifest to S3 read-only endpoint" rfs_common_build_route_url