Skip to content

Commit cafe60d

Browse files
committed
feat(macos): initial borken implementation
Add more stuff
1 parent 723667c commit cafe60d

File tree

4 files changed

+120
-28
lines changed

4 files changed

+120
-28
lines changed

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
VERS?= 11
44
PKGVERS?= 11.0_2025Q3
55
UNAME_M!= uname -m
6+
UNAME_S!= uname -s
67
# for an obscure reason, packages path use uname -m...
78
DIST?= https://nycdn.netbsd.org/pub/NetBSD-daily/netbsd-${VERS}/latest/${ARCH}/binary
89
.if !defined(ARCH)
@@ -31,9 +32,14 @@ EXTRAS+= -o
3132

3233
ENVVARS= SERVICE=${SERVICE} ARCH=${ARCH} PKGVERS=${PKGVERS} MOUNTRO=${MOUNTRO}
3334
.if ${WHOAMI} != "root"
35+
# macOS doesn't need sudo anymore (uses staging approach)
36+
. if ${UNAME_S} == "Darwin"
37+
SUDO= ${ENVVARS}
38+
. else
3439
SUDO!= command -v doas >/dev/null && \
3540
echo '${ENVVARS} doas' || \
3641
echo 'sudo -E ${ENVVARS}'
42+
. endif
3743
.else
3844
SUDO= ${ENVVARS}
3945
.endif
@@ -133,21 +139,28 @@ pkgfetch:
133139
rescue:
134140
${MAKE} setfetch SETS="${RESCUE}"
135141
${SUDO} ./mkimg.sh -m 20 -x "${RESCUE}" ${EXTRAS}
142+
.if ${UNAME_S} != "Darwin"
136143
${SUDO} chown ${USER}:${GROUP} ${.TARGET}-${ARCH}.img
144+
.endif
137145

138146
base:
139147
$Q${MAKE} setfetch SETS="${BASE}"
140148
$Qecho "${ARROW} creating root filesystem (${IMGSIZE}M)"
141149
$Q${SUDO} ./mkimg.sh -i ${SERVICE}-${ARCH}.img -s ${SERVICE} \
142150
-m ${IMGSIZE} -x "${BASE}" ${EXTRAS}
151+
.if ${UNAME_S} != "Darwin"
143152
$Q${SUDO} chown ${USER}:${GROUP} ${SERVICE}-${ARCH}.img
153+
@${SUDO} chown ${USER}:${GROUP} ${SERVICE}-${ARCH}.img
154+
.endif
144155
$Qecho "${CHECK} image ready: ${SERVICE}-${ARCH}.img"
145156

146157
prof:
147158
${MAKE} setfetch SETS="${PROF}"
148159
${SUDO} ./mkimg.sh -i ${.TARGET}-${ARCH}.img -s ${.TARGET} -m 1024 -k kernels/${KERNEL} \
149160
-x "${PROF}" ${EXTRAS}
161+
.if ${UNAME_S} != "Darwin"
150162
${SUDO} chown ${WHOAMI} ${.TARGET}-${ARCH}.img
163+
.endif
151164

152165
# for use with sailor, needs rework
153166
#imgbuilder:
@@ -198,4 +211,6 @@ build: kernfetch
198211
$Qwhile [ -f tmp/build-${SERVICE} ]; do sleep 0.2; done
199212
$Qecho "${ARROW} killing the builder microvm"
200213
$Qkill $$(cat qemu-${.TARGET}.pid)
214+
.if ${UNAME_S} != "Darwin"
201215
$Q${SUDO} chown ${USER}:${GROUP} ${SERVICE}-${ARCH}.img
216+
.endif

flake.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
devShells.default = pkgs.mkShell {
1616
buildInputs = with pkgs; [
1717
bmake
18+
qemu_full
1819
];
1920
};
2021
});
21-
}
22+
}

mkimg.sh

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ usage()
88
{
99
cat 1>&2 << _USAGE_
1010
Usage: $progname [-s service] [-m megabytes] [-i image] [-x set]
11-
[-k kernel] [-o] [-c URL]
11+
[-k kernel] [-o] [-c URL] [-d]
1212
Create a root image
1313
-s service service name, default "rescue"
1414
-r rootdir hand crafted root directory to use
@@ -18,6 +18,7 @@ Usage: $progname [-s service] [-m megabytes] [-i image] [-x set]
1818
-k kernel kernel to copy in the image
1919
-c URL URL to a script to execute as finalizer
2020
-o read-only root filesystem
21+
-d enable debug mode (verbose output)
2122
_USAGE_
2223
exit 1
2324
}
@@ -28,7 +29,7 @@ rsynclite()
2829
(cd $1 && tar cfp - .)|(cd $2 && tar xfp -)
2930
}
3031

31-
options="s:m:i:r:x:k:c:oh"
32+
options="s:m:i:r:x:k:c:odh"
3233

3334
while getopts "$options" opt
3435
do
@@ -41,11 +42,18 @@ do
4142
k) kernel="$OPTARG";;
4243
c) curlsh="$OPTARG";;
4344
o) rofs=y;;
45+
d) debug=y;;
4446
h) usage;;
4547
*) usage;;
4648
esac
4749
done
4850

51+
# Enable debug mode if requested
52+
if [ -n "$debug" ]; then
53+
set -x # Print commands as they execute
54+
set -v # Print shell input lines as they are read
55+
fi
56+
4957
export ARCH PKGVERS
5058

5159
arch=${ARCH:-"amd64"}
@@ -110,20 +118,21 @@ if [ -z "$is_netbsd" -a -f "service/${svc}/NETBSD_ONLY" ]; then
110118
exit 1
111119
fi
112120

113-
[ -n "$is_darwin" -o -n "$is_unknown" ] && \
121+
[ -n "$is_unknown" ] && \
114122
echo "${progname}: OS is not supported" && exit 1
115123

116-
if [ -n "$is_linux" ]; then
117-
u=M
124+
if [ -n "$is_darwin" ]; then
125+
# Use temporary directory to stage files
126+
stagedir=$(mktemp -d)
127+
mnt=$stagedir
118128
else
119-
u=m
129+
# Use platform-independent dd syntax that works with both GNU and BSD dd
130+
# bs=1048576 (1MB in bytes) works on all platforms
131+
dd if=/dev/zero of=./${img} bs=1048576 count=${megs}
132+
mkdir -p mnt
133+
mnt=$(pwd)/mnt
120134
fi
121135

122-
dd if=/dev/zero of=./${img} bs=1${u} count=${megs}
123-
124-
mkdir -p mnt
125-
mnt=$(pwd)/mnt
126-
127136
if [ -n "$is_linux" ]; then
128137
mke2fs -O none $img
129138
mount -o loop $img $mnt
@@ -133,6 +142,8 @@ elif [ -n "$is_freebsd" ]; then
133142
newfs -o time -O2 /dev/${vnd}
134143
mount -o noatime /dev/${vnd} $mnt
135144
mountfs="ffs"
145+
elif [ -n "$is_darwin" ]; then
146+
mountfs="staged" # Special flag for macOS staging mode
136147
else # NetBSD (and probably OpenBSD)
137148
vnd=$(vndconfig -l|grep -m1 'not'|cut -f1 -d:)
138149
vndconfig $vnd $img
@@ -155,7 +166,7 @@ else
155166
do
156167
# don't prepend sets path if this is a full path
157168
case $s in */*) ;; *) s="sets/${arch}/${s}" ;; esac
158-
echo -n "extracting ${s}.. "
169+
printf "extracting ${s}.. "
159170
$TAR xfp ${s} -C ${mnt}/ || exit 1
160171
echo done
161172
done
@@ -164,7 +175,7 @@ fi
164175
# additional packages
165176
[ -n "$ADDPKGS" ] && for pkg in ${ADDPKGS}; do
166177
eval $($TAR xfp $pkg -O +BUILD_INFO|grep ^LOCALBASE)
167-
echo -n "extracting $pkg to ${LOCALBASE}.. "
178+
printf "extracting $pkg to ${LOCALBASE}.. "
168179
mkdir -p ${mnt}/${LOCALBASE}
169180
$TAR xfp ${pkg} -C ${mnt}/${LOCALBASE} || exit 1
170181
echo done
@@ -181,6 +192,7 @@ rsynclite service/common/ ${mnt}/etc/include/
181192

182193
[ -n "$kernel" ] && cp -f $kernel ${mnt}/
183194

195+
BACK=$PWD
184196
cd $mnt
185197

186198
if [ "$svc" = "rescue" ]; then
@@ -207,20 +219,37 @@ fi
207219

208220
# newer NetBSD versions use tmpfs for /dev, sailor copies MAKEDEV from /dev
209221
# backup MAKEDEV so imgbuilder rc can copy it
210-
cp dev/MAKEDEV etc/
211-
# unionfs with ext2 leads to i/o error
212-
sed -ie 's/-o union//g' dev/MAKEDEV
222+
if [ -f dev/MAKEDEV ]; then
223+
cp -f dev/MAKEDEV etc/
224+
# unionfs with ext2 leads to i/o error
225+
# Use portable sed approach that works with both GNU and BSD sed
226+
sed 's/-o union//g' dev/MAKEDEV > dev/MAKEDEV.tmp && rm -f dev/MAKEDEV && mv dev/MAKEDEV.tmp dev/MAKEDEV
227+
fi
213228
# record wanted pkgsrc version
214229
echo "PKGVERS=$PKGVERS" > etc/pkgvers
215230

216231
# proceed with caution
217232
[ -n "$curlsh" ] && curl -sSL "$CURLSH" | /bin/sh
218233

219-
cd ..
234+
cd $BACK
235+
236+
if [ -n "$is_darwin" ]; then
237+
# macOS: Convert staged files to qemu image
238+
(cd $mnt && $TAR cf - .) > ${img}.tar
239+
echo "Created ${img}.tar"
220240

221-
umount $mnt
241+
# Clean up staging directory
242+
rm -rf $mnt
222243

223-
[ -n "$is_freebsd" ] && mdconfig -d -u $vnd
224-
[ -z "$is_linux" ] && [ -z "$is_freebsd" ] && vndconfig -u $vnd
244+
echo "macOS build complete!"
245+
if [ -f "$qcow_img" ]; then
246+
echo "Created qemu image: $qcow_img"
247+
fi
248+
else
249+
umount $mnt
250+
[ -z "$is_linux" ] && vndconfig -u $vnd
251+
[ -n "$is_freebsd" ] && mdconfig -d -u $vnd
252+
[ -z "$is_linux" ] && [ -z "$is_freebsd" ] && vndconfig -u $vnd
253+
fi
225254

226255
exit 0

startnb.sh

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,39 @@ if [ -z "$kernel" -o -z "$img" ]; then
8383
usage
8484
fi
8585

86+
# Handle tar files created by macOS staging approach
87+
# Check if img ends with .tar or if a .tar file exists for the specified .img
88+
tarfile=""
89+
tar_extracted_dir=""
90+
if [ "${img%.tar}" != "$img" ]; then
91+
# User specified a .tar file directly
92+
tarfile="$img"
93+
img="${img%.tar}"
94+
elif [ -f "${img%.img}.tar" -a ! -f "$img" ]; then
95+
# Found corresponding .tar file for .img
96+
tarfile="${img%.img}.tar"
97+
fi
98+
99+
if [ -n "$tarfile" -a -f "$tarfile" ]; then
100+
echo "* Found tar archive $tarfile, extracting to directory..."
101+
102+
# Create extraction directory based on image name
103+
tar_extracted_dir="${img%.img}.d"
104+
105+
# Extract if not already extracted
106+
if [ ! -d "$tar_extracted_dir" ]; then
107+
mkdir -p "$tar_extracted_dir"
108+
tar -xf "$tarfile" -C "$tar_extracted_dir"
109+
echo "* Extracted to: $tar_extracted_dir"
110+
else
111+
echo "* Using existing directory: $tar_extracted_dir"
112+
fi
113+
114+
# Use the directory path as the root filesystem via 9p
115+
img="$tar_extracted_dir"
116+
use_9p_root=yes
117+
fi
118+
86119
[ -n "$hostfwd" ] && network="\
87120
-device virtio-net-device,netdev=net${uuid}0 \
88121
-netdev user,id=net${uuid}0,ipv6=off,$(echo "$hostfwd"|sed -E 's/(udp|tcp)?::/hostfwd=\1::/g')"
@@ -209,13 +242,27 @@ fi
209242
# QMP is available
210243
[ -n "${qmp_port}" ] && extra="$extra -qmp tcp:localhost:${qmp_port},server,wait=off"
211244

212-
cmd="${QEMU} -smp $cores \
213-
$mflags -m $mem $cpuflags \
214-
-kernel $kernel -append \"console=${console} root=${root} ${append}\" \
215-
-global virtio-mmio.force-legacy=false ${share} \
216-
-device virtio-blk-device,drive=hd${uuid}0${sharerw} \
217-
-drive if=none,file=${img},format=raw,id=hd${uuid}0 \
218-
${drive2} ${network} ${d} ${viosock} ${extra}"
245+
# Build the command differently if using 9p root from tar extraction
246+
if [ -n "$use_9p_root" ]; then
247+
echo "* Using 9p filesystem for root from directory: $img"
248+
# Use 9p virtio filesystem as root
249+
cmd="${QEMU} -smp $cores \
250+
$mflags -m $mem $cpuflags \
251+
-kernel $kernel -append \"console=${console} root=9p:root ${append}\" \
252+
-global virtio-mmio.force-legacy=false \
253+
-fsdev local,path=${img},security_model=none,id=root \
254+
-device virtio-9p-device,fsdev=root,mount_tag=root \
255+
${share} ${drive2} ${network} ${d} ${viosock} ${extra}"
256+
else
257+
# Normal block device root
258+
cmd="${QEMU} -smp $cores \
259+
$mflags -m $mem $cpuflags \
260+
-kernel $kernel -append \"console=${console} root=${root} ${append}\" \
261+
-global virtio-mmio.force-legacy=false ${share} \
262+
-device virtio-blk-device,drive=hd${uuid}0${sharerw} \
263+
-drive if=none,file=${img},format=raw,id=hd${uuid}0 \
264+
${drive2} ${network} ${d} ${viosock} ${extra}"
265+
fi
219266

220267
[ -n "$VERBOSE" ] && echo "$cmd" && exit
221268

0 commit comments

Comments
 (0)