Extend VM Service Linux Support
Nucleic-Session: 44D29355-D1D8-4327-97B6-B1AEBD5EDE57 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Write a newc-format cpio archive of a directory tree to stdout.
|
||||
|
||||
Used by scripts/build-linux-bootstrap.sh to pack the Nucleic Linux bootstrap initramfs without a
|
||||
`cpio` binary (which macOS lacks by default). Emits the SVR4/newc format the Linux kernel's initramfs
|
||||
loader expects; handles regular files, directories, and symlinks. Byte-identical on Linux and macOS.
|
||||
"""
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
|
||||
def field(n: int) -> bytes:
|
||||
return b"%08X" % (n & 0xFFFFFFFF)
|
||||
|
||||
|
||||
def emit(out, name: bytes, st, data: bytes):
|
||||
# newc header: magic + 13 eight-hex fields, then name (NUL-terminated, 4-byte padded), then data
|
||||
# (4-byte padded).
|
||||
hdr = b"070701"
|
||||
hdr += field(st.st_ino if st else 0)
|
||||
hdr += field(st.st_mode if st else 0)
|
||||
hdr += field(0) # uid — normalize to root so the initramfs is reproducible
|
||||
hdr += field(0) # gid
|
||||
hdr += field(st.st_nlink if st else 1)
|
||||
hdr += field(0) # mtime — normalize for reproducibility
|
||||
hdr += field(len(data))
|
||||
hdr += field(0) * 4 # devmajor/minor, rdevmajor/minor
|
||||
namebytes = name + b"\x00"
|
||||
hdr += field(len(namebytes))
|
||||
hdr += field(0) # check (unused for newc)
|
||||
out.write(hdr)
|
||||
out.write(namebytes)
|
||||
pad = (-(len(hdr) + len(namebytes))) % 4
|
||||
out.write(b"\x00" * pad)
|
||||
out.write(data)
|
||||
out.write(b"\x00" * ((-len(data)) % 4))
|
||||
|
||||
|
||||
def main():
|
||||
rootdir = sys.argv[1]
|
||||
out = sys.stdout.buffer
|
||||
entries = []
|
||||
for dirpath, dirnames, filenames in os.walk(rootdir):
|
||||
for d in sorted(dirnames):
|
||||
entries.append(os.path.join(dirpath, d))
|
||||
for f in sorted(filenames):
|
||||
entries.append(os.path.join(dirpath, f))
|
||||
for path in entries:
|
||||
rel = os.path.relpath(path, rootdir).encode()
|
||||
st = os.lstat(path)
|
||||
if stat.S_ISLNK(st.st_mode):
|
||||
data = os.readlink(path).encode()
|
||||
elif stat.S_ISDIR(st.st_mode):
|
||||
data = b""
|
||||
else:
|
||||
with open(path, "rb") as fh:
|
||||
data = fh.read()
|
||||
emit(out, rel, st, data)
|
||||
# Trailer.
|
||||
class Z:
|
||||
st_ino = 0
|
||||
st_mode = 0
|
||||
st_nlink = 1
|
||||
emit(out, b"TRAILER!!!", Z(), b"")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user