#!/bin/sh # functions.sh — Shared utility functions for KubeSolo OS init # Sourced by /sbin/init before running stages # POSIX sh only — must work with BusyBox ash # Wait for a block device to appear wait_for_device() { dev="$1" timeout="${2:-30}" i=0 while [ "$i" -lt "$timeout" ]; do [ -b "$dev" ] && return 0 sleep 1 i=$((i + 1)) done return 1 } # Wait for a file to appear wait_for_file() { path="$1" timeout="${2:-30}" i=0 while [ "$i" -lt "$timeout" ]; do [ -f "$path" ] && return 0 sleep 1 i=$((i + 1)) done return 1 } # Get IP address of an interface (POSIX-safe, no grep -P) get_iface_ip() { iface="$1" ip -4 addr show "$iface" 2>/dev/null | \ sed -n 's/.*inet \([0-9.]*\).*/\1/p' | head -1 } # Check if running in a VM (useful for adjusting timeouts) is_virtual() { [ -d /sys/class/dmi/id ] && \ grep -qi -e 'qemu' -e 'kvm' -e 'vmware' -e 'virtualbox' -e 'xen' -e 'hyperv' \ /sys/class/dmi/id/sys_vendor 2>/dev/null } # Resolve a LABEL= or UUID= device spec to a block device path resolve_device() { spec="$1" case "$spec" in LABEL=*) blkid -L "${spec#LABEL=}" 2>/dev/null ;; UUID=*) blkid -U "${spec#UUID=}" 2>/dev/null ;; *) echo "$spec" ;; esac } # Write a key=value pair to a simple config file config_set() { file="$1" key="$2" value="$3" if grep -q "^${key}=" "$file" 2>/dev/null; then sed -i "s|^${key}=.*|${key}=${value}|" "$file" else echo "${key}=${value}" >> "$file" fi } # Read a value from a simple key=value config file config_get() { file="$1" key="$2" default="${3:-}" if [ -f "$file" ]; then value=$(sed -n "s/^${key}=//p" "$file" | tail -1) echo "${value:-$default}" else echo "$default" fi }