Empezar
This commit is contained in:
commit
6a50670238
8 changed files with 645 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
root/
|
||||
v00001/
|
||||
boot/
|
||||
image.squashfs
|
120
alpine.lua
Normal file
120
alpine.lua
Normal file
|
@ -0,0 +1,120 @@
|
|||
local alpine = {}
|
||||
|
||||
local utils = require("utils")
|
||||
local t = require("utils/templater")
|
||||
|
||||
-- Returns nil when no failure, otherwise apk's status code
|
||||
function alpine.init_rootfs(path, alpine_base_version, alpine_version)
|
||||
local status = os.execute(t("doas rm -rf {{path}} && mkdir -p {{path}}", {path = path}))
|
||||
if not (status == 0) then return status end
|
||||
local url = t("https://dl-cdn.alpinelinux.org/alpine/v{{base_version}}/releases/x86_64/alpine-minirootfs-{{version}}-x86_64.tar.gz", {
|
||||
base_version = alpine_base_version,
|
||||
version = alpine_version
|
||||
})
|
||||
local status = os.execute(t("cd {{path}} && wget --no-verbose -O- {{url}} | tar zx", { path = path, url = url }))
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
function alpine.move_boot(path)
|
||||
local status = os.execute(t("doas rm -rf {{path}}/../boot && doas mv {{path}}/boot {{path}}/../ && doas mkdir {{path}}/boot", {
|
||||
path = path,
|
||||
}))
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
function alpine.make_squashfs(path, output_path)
|
||||
local status = os.execute(t("mksquashfs {{path}} {{output_path}} -comp zstd -noappend -quiet", {
|
||||
path = path,
|
||||
output_path = output_path,
|
||||
}))
|
||||
if not (status == 0) then return status end
|
||||
-- status = os.execute(t("qemu-img convert {{output_path}} {{output_path}}.qcow2 -O qcow2", {
|
||||
-- output_path = output_path,
|
||||
-- }))
|
||||
-- if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
function alpine.mkdir(rootfs_path, path)
|
||||
local real_path = rootfs_path..path
|
||||
|
||||
local cmd = t("mkdir -p {{real_path}}", {
|
||||
real_path = real_path,
|
||||
})
|
||||
|
||||
-- XXX: Usar lua-posix
|
||||
local status = os.execute(cmd)
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
function alpine.write_file(rootfs_path, path, content)
|
||||
local real_path = rootfs_path..path
|
||||
|
||||
local cmd = t("mkdir -p {{real_dirname}} && test -f {{real_path}} || exit 0 && doas chown $(id -u) {{real_path}}", {
|
||||
real_path = real_path,
|
||||
real_dirname = utils.dirname(real_path),
|
||||
})
|
||||
|
||||
-- XXX: Usar lua-posix
|
||||
local status = os.execute(cmd)
|
||||
if not (status == 0) then return status end
|
||||
|
||||
local file, err = io.open(real_path, "w+")
|
||||
if not file then return err end
|
||||
|
||||
file:write(content)
|
||||
file:close()
|
||||
end
|
||||
|
||||
function alpine.symlink(rootfs_path, path, target)
|
||||
local real_path = rootfs_path..path
|
||||
|
||||
local cmd = t("mkdir -p {{real_dirname}} && ln -s {{target}} {{real_path}}", {
|
||||
real_path = real_path,
|
||||
target = target,
|
||||
real_dirname = utils.dirname(real_path),
|
||||
})
|
||||
|
||||
-- XXX: Usar lua-posix
|
||||
local status = os.execute(cmd)
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
function alpine.chmod(rootfs_path, path, perms)
|
||||
local real_path = rootfs_path..path
|
||||
|
||||
local cmd = t("chmod {{perms}} {{real_path}}", {
|
||||
real_path = real_path,
|
||||
perms = perms,
|
||||
})
|
||||
|
||||
-- XXX: Usar lua-posix
|
||||
local status = os.execute(cmd)
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
-- Returns nil when no failure, otherwise string error or apk's status code
|
||||
function alpine.make_world(rootfs_path, packages)
|
||||
local world = alpine.write_file(rootfs_path,
|
||||
"/etc/apk/world",
|
||||
utils.join_table(packages, "\n"))
|
||||
if err then return err end
|
||||
|
||||
local status = os.execute("doas apk update --no-cache --root "..rootfs_path)
|
||||
if not (status == 0) then return status end
|
||||
local status = os.execute("doas apk upgrade --no-cache --root "..rootfs_path)
|
||||
if not (status == 0) then return status end
|
||||
local status = os.execute("doas apk add --no-cache --root "..rootfs_path)
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
-- Returns nil when no failure, otherwise status code
|
||||
function alpine.set_password(rootfs_path, user, password)
|
||||
local status = os.execute(t("echo '{{password}}\n{{password}}' | doas chroot {{rootfs_path}} passwd {{user}}", {
|
||||
password = password,
|
||||
rootfs_path = rootfs_path,
|
||||
user = user,
|
||||
}))
|
||||
if not (status == 0) then return status end
|
||||
end
|
||||
|
||||
return alpine
|
31
modules/kernel.lua
Normal file
31
modules/kernel.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
print("=> Module: kernel")
|
||||
modules.kernel = {}
|
||||
|
||||
add_packages({ "linux-virt", "syslinux" })
|
||||
add_file("/etc/update-extlinux.conf", [[# configuration for extlinux config builder
|
||||
|
||||
# Overwrite current /boot/extlinux.conf.
|
||||
overwrite=1
|
||||
|
||||
# vesa_menu
|
||||
# use fancy vesa menu (vesamenu.c32) menus, won't work with serial
|
||||
vesa_menu=1
|
||||
|
||||
#default_kernel_opts=quiet
|
||||
default_kernel_opts=
|
||||
modules=loop,squashfs,sd-mod,usb-storage,ext4,vfat
|
||||
|
||||
# root device - if not specified, will be guessed using
|
||||
# blkid -o export /dev/root
|
||||
root=/dev/sda
|
||||
|
||||
# if set to non-zero, update-extlinux will be a lot more verbose.
|
||||
verbose=0
|
||||
|
||||
hidden=0
|
||||
timeout=3
|
||||
default=lts
|
||||
]])
|
||||
|
||||
add_file("/etc/mkinitfs/mkinitfs.conf",
|
||||
'features="squashfs ata base cdrom ext4 keymap kms mmc nvme scsi usb virtio"')
|
369
modules/runit.lua
Normal file
369
modules/runit.lua
Normal file
|
@ -0,0 +1,369 @@
|
|||
print("=> Module: runit")
|
||||
|
||||
mkdir("/etc/runit/runsvdir/default")
|
||||
add_symlink("/etc/runit/runsvdir/current", "/etc/runit/runsvdir/default")
|
||||
add_symlink("/etc/service", "/etc/runit/runsvdir/current")
|
||||
|
||||
local t = require "../utils/templater"
|
||||
local function add_executable(path, script)
|
||||
add_file(path, script)
|
||||
chmod(path, "700")
|
||||
end
|
||||
local function add_service(name, script)
|
||||
local params = {name = name}
|
||||
local run_script_path = t("/etc/sv/{{name}}/run", params)
|
||||
add_executable(run_script_path, script)
|
||||
add_symlink("/etc/runit/runsvdir/default/"..name, "/etc/sv/"..name)
|
||||
add_symlink(
|
||||
t("/etc/sv/{{name}}/supervise", params),
|
||||
t("/run/runit/supervise.{{name}}", params)
|
||||
)
|
||||
end
|
||||
|
||||
modules.runit = {
|
||||
add_service = add_service,
|
||||
}
|
||||
|
||||
add_mount("tmpfs /var/log tmpfs defaults 0 0")
|
||||
|
||||
-- Estos scripts fueron robados de Void Linux
|
||||
add_executable("/etc/runit/functions", [[
|
||||
msg() {
|
||||
# bold
|
||||
printf "\\033[1m=> $@\\033[m\\n"
|
||||
}
|
||||
|
||||
msg_ok() {
|
||||
# bold/green
|
||||
printf "\\033[1m\\033[32m OK\\033[m\\n"
|
||||
}
|
||||
|
||||
msg_error() {
|
||||
# bold/red
|
||||
printf "\\033[1m\\033[31mERROR: $@\\033[m\\n"
|
||||
}
|
||||
|
||||
msg_warn() {
|
||||
# bold/yellow
|
||||
printf "\\033[1m\\033[33mWARNING: $@\\033[m\\n"
|
||||
}
|
||||
|
||||
emergency_shell() {
|
||||
echo
|
||||
echo "Cannot continue due to errors above, starting emergency shell."
|
||||
echo "When ready type exit to continue booting."
|
||||
/bin/sh -l
|
||||
}
|
||||
|
||||
detect_virt() {
|
||||
# Detect LXC (and other) containers
|
||||
[ -z "${container+x}" ] || export VIRTUALIZATION=1
|
||||
}
|
||||
|
||||
deactivate_vgs() {
|
||||
_group=${1:-All}
|
||||
if [ -x /sbin/vgchange -o -x /bin/vgchange ]; then
|
||||
vgs=$(vgs|wc -l)
|
||||
if [ $vgs -gt 0 ]; then
|
||||
msg "Deactivating $_group LVM Volume Groups..."
|
||||
vgchange -an
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
deactivate_crypt() {
|
||||
if [ -x /sbin/dmsetup -o -x /bin/dmsetup ]; then
|
||||
msg "Deactivating Crypt Volumes"
|
||||
for v in $(dmsetup ls --target crypt --exec "dmsetup info -c --noheadings -o open,name"); do
|
||||
[ ${v%%:*} = "0" ] && cryptsetup close ${v##*:}
|
||||
done
|
||||
deactivate_vgs "Crypt"
|
||||
fi
|
||||
}
|
||||
]])
|
||||
|
||||
add_executable("/etc/runit/core-services/00-pseudofs.sh", [[
|
||||
msg "Mounting pseudo-filesystems..."
|
||||
mountpoint -q /proc || mount -o nosuid,noexec,nodev -t proc proc /proc
|
||||
mountpoint -q /sys || mount -o nosuid,noexec,nodev -t sysfs sys /sys
|
||||
mountpoint -q /run || mount -o mode=0755,nosuid,nodev -t tmpfs run /run
|
||||
mountpoint -q /dev || mount -o mode=0755,nosuid -t devtmpfs dev /dev
|
||||
mkdir -p -m0755 /run/runit /run/lvm /run/user /run/lock /run/log /dev/pts /dev/shm
|
||||
mountpoint -q /dev/pts || mount -o mode=0620,gid=5,nosuid,noexec -n -t devpts devpts /dev/pts
|
||||
mountpoint -q /dev/shm || mount -o mode=1777,nosuid,nodev -n -t tmpfs shm /dev/shm
|
||||
mountpoint -q /sys/kernel/security || mount -n -t securityfs securityfs /sys/kernel/security
|
||||
|
||||
if [ -d /sys/firmware/efi/efivars ]; then
|
||||
mountpoint -q /sys/firmware/efi/efivars || mount -o nosuid,noexec,nodev -t efivarfs efivarfs /sys/firmware/efi/efivars
|
||||
fi
|
||||
|
||||
if [ -z "$VIRTUALIZATION" ]; then
|
||||
_cgroupv1=""
|
||||
_cgroupv2=""
|
||||
|
||||
case "${CGROUP_MODE:-hybrid}" in
|
||||
legacy)
|
||||
_cgroupv1="/sys/fs/cgroup"
|
||||
;;
|
||||
hybrid)
|
||||
_cgroupv1="/sys/fs/cgroup"
|
||||
_cgroupv2="${_cgroupv1}/unified"
|
||||
;;
|
||||
unified)
|
||||
_cgroupv2="/sys/fs/cgroup"
|
||||
;;
|
||||
esac
|
||||
|
||||
# cgroup v1
|
||||
if [ -n "$_cgroupv1" ]; then
|
||||
mountpoint -q "$_cgroupv1" || mount -o mode=0755 -t tmpfs cgroup "$_cgroupv1"
|
||||
while read -r _subsys_name _hierarchy _num_cgroups _enabled; do
|
||||
[ "$_enabled" = "1" ] || continue
|
||||
_controller="${_cgroupv1}/${_subsys_name}"
|
||||
mkdir -p "$_controller"
|
||||
mountpoint -q "$_controller" || mount -t cgroup -o "$_subsys_name" cgroup "$_controller"
|
||||
done < /proc/cgroups
|
||||
fi
|
||||
|
||||
# cgroup v2
|
||||
if [ -n "$_cgroupv2" ]; then
|
||||
mkdir -p "$_cgroupv2"
|
||||
mountpoint -q "$_cgroupv2" || mount -t cgroup2 -o nsdelegate cgroup2 "$_cgroupv2"
|
||||
fi
|
||||
fi]])
|
||||
|
||||
add_executable("/etc/runit/core-services/01-static-devnodes.sh", [[
|
||||
# Some kernel modules must be loaded before starting udev(7).
|
||||
# Load them by looking at the output of `kmod static-nodes`.
|
||||
|
||||
for f in $(kmod static-nodes 2>/dev/null|awk '/Module/ {print $2}'); do
|
||||
modprobe -bq $f 2>/dev/null
|
||||
done
|
||||
]])
|
||||
|
||||
add_executable("/etc/runit/core-services/02-udev.sh", [[
|
||||
[ -n "$VIRTUALIZATION" ] && return 0
|
||||
|
||||
if [ -x /sbin/udevd -o -x /bin/udevd ]; then
|
||||
_udevd=udevd
|
||||
else
|
||||
msg_warn "cannot find udevd!"
|
||||
fi
|
||||
|
||||
if [ -n "${_udevd}" ]; then
|
||||
msg "Starting udev and waiting for devices to settle..."
|
||||
${_udevd} --daemon
|
||||
udevadm trigger --action=add --type=subsystems
|
||||
udevadm trigger --action=add --type=devices
|
||||
udevadm settle
|
||||
fi
|
||||
]])
|
||||
|
||||
|
||||
add_executable("/etc/runit/core-services/03-filesystems.sh", [[
|
||||
[ -n "$VIRTUALIZATION" ] && return 0
|
||||
|
||||
#msg "Remounting rootfs read-only..."
|
||||
#mount -o remount,ro / || emergency_shell
|
||||
|
||||
if [ -x /sbin/dmraid -o -x /bin/dmraid ]; then
|
||||
msg "Activating dmraid devices..."
|
||||
dmraid -i -ay
|
||||
fi
|
||||
|
||||
if [ -x /bin/mdadm ]; then
|
||||
msg "Activating software RAID arrays..."
|
||||
mdadm -As
|
||||
fi
|
||||
|
||||
if [ -x /bin/btrfs ]; then
|
||||
msg "Activating btrfs devices..."
|
||||
btrfs device scan || emergency_shell
|
||||
fi
|
||||
|
||||
if [ -x /sbin/vgchange -o -x /bin/vgchange ]; then
|
||||
msg "Activating LVM devices..."
|
||||
vgchange --sysinit -a ay || emergency_shell
|
||||
fi
|
||||
|
||||
if [ -e /etc/crypttab ]; then
|
||||
msg "Activating encrypted devices..."
|
||||
awk -f /etc/runit/crypt.awk /etc/crypttab
|
||||
|
||||
if [ -x /sbin/vgchange -o -x /bin/vgchange ]; then
|
||||
msg "Activating LVM devices for dm-crypt..."
|
||||
vgchange --sysinit -a ay || emergency_shell
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -x /usr/bin/zpool -a -x /usr/bin/zfs ]; then
|
||||
if [ -e /etc/zfs/zpool.cache ]; then
|
||||
msg "Importing cached ZFS pools..."
|
||||
zpool import -N -a -c /etc/zfs/zpool.cache
|
||||
else
|
||||
msg "Scanning for and importing ZFS pools..."
|
||||
zpool import -N -a -o cachefile=none
|
||||
fi
|
||||
|
||||
msg "Mounting ZFS file systems..."
|
||||
zfs mount -a -l
|
||||
|
||||
msg "Sharing ZFS file systems..."
|
||||
zfs share -a
|
||||
|
||||
# NOTE(dh): ZFS has ZVOLs, block devices on top of storage pools.
|
||||
# In theory, it would be possible to use these as devices in
|
||||
# dmraid, btrfs, LVM and so on. In practice it's unlikely that
|
||||
# anybody is doing that, so we aren't supporting it for now.
|
||||
fi
|
||||
|
||||
[ -f /fastboot ] && FASTBOOT=1
|
||||
[ -f /forcefsck ] && FORCEFSCK="-f"
|
||||
for arg in $(cat /proc/cmdline); do
|
||||
case $arg in
|
||||
fastboot) FASTBOOT=1;;
|
||||
forcefsck) FORCEFSCK="-f";;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$FASTBOOT" ]; then
|
||||
msg "Checking filesystems:"
|
||||
fsck -A -T -a -t noopts=_netdev $FORCEFSCK
|
||||
if [ $? -gt 1 ]; then
|
||||
s emergency_shell
|
||||
fi
|
||||
fi
|
||||
|
||||
msg "Mounting all non-network filesystems..."
|
||||
mount -a -t "nosysfs,nonfs,nonfs4,nosmbfs,nocifs" -O no_netdev || emergency_shell
|
||||
]])
|
||||
|
||||
add_executable("/etc/runit/core-services/04-swap.sh", [[
|
||||
[ -n "$VIRTUALIZATION" ] && return 0
|
||||
|
||||
msg "Initializing swap..."
|
||||
swapon -a || emergency_shell
|
||||
]])
|
||||
|
||||
add_executable("/etc/runit/core-services/05-misc.sh", [[
|
||||
install -m0664 -o root -g utmp /dev/null /run/utmp
|
||||
#halt -B # for wtmp
|
||||
|
||||
msg "Setting up loopback interface..."
|
||||
ip link set up dev lo
|
||||
|
||||
loadkeys -q -u us
|
||||
]])
|
||||
|
||||
-- Initial boot
|
||||
add_executable("/etc/runit/1", [[#!/bin/sh
|
||||
|
||||
PATH=/bin:/usr/bin:/usr/sbin:/sbin
|
||||
|
||||
. /etc/runit/functions
|
||||
|
||||
msg "Welcome to Nulo!"
|
||||
|
||||
[ -r /etc/rc.conf ] && . /etc/rc.conf
|
||||
|
||||
# Start core services: one-time system tasks.
|
||||
detect_virt
|
||||
for f in /etc/runit/core-services/*.sh; do
|
||||
[ -r $f ] && . $f
|
||||
done
|
||||
|
||||
dmesg >/var/log/dmesg.log
|
||||
if [ $(sysctl -n kernel.dmesg_restrict 2>/dev/null) -eq 1 ]; then
|
||||
chmod 0600 /var/log/dmesg.log
|
||||
else
|
||||
chmod 0644 /var/log/dmesg.log
|
||||
fi
|
||||
|
||||
# create files for controlling runit
|
||||
mkdir -p /run/runit
|
||||
install -m000 /dev/null /run/runit/stopit
|
||||
install -m000 /dev/null /run/runit/reboot
|
||||
|
||||
msg "Initialization complete, running stage 2..."
|
||||
]])
|
||||
add_executable("/etc/runit/2", [[#!/bin/sh
|
||||
PATH=/bin:/usr/bin:/usr/sbin:/sbin
|
||||
|
||||
runlevel=default
|
||||
for arg in $(cat /proc/cmdline); do
|
||||
if [ -d /etc/runit/runsvdir/"$arg" ]; then
|
||||
echo "Runlevel detected: '$arg' (via kernel cmdline)"
|
||||
runlevel="$arg"
|
||||
fi
|
||||
done
|
||||
|
||||
[ -x /etc/rc.local ] && /etc/rc.local
|
||||
|
||||
runsvchdir "${runlevel}"
|
||||
mkdir -p /run/runit/runsvdir
|
||||
ln -s /etc/runit/runsvdir/current /run/runit/runsvdir/current
|
||||
|
||||
ls -la /run/runit/runsvdir/current/
|
||||
|
||||
exec env - PATH=$PATH \
|
||||
runsvdir -P /run/runit/runsvdir/current 'log: ................................'
|
||||
]])
|
||||
|
||||
-- Shutdown
|
||||
add_executable("/etc/runit/3", [[#!/bin/sh
|
||||
PATH=/bin:/usr/bin:/usr/sbin:/sbin
|
||||
|
||||
. /etc/runit/functions
|
||||
detect_virt
|
||||
[ -r /etc/rc.conf ] && . /etc/rc.conf
|
||||
|
||||
echo
|
||||
msg "Waiting for services to stop..."
|
||||
sv force-stop /etc/service/*
|
||||
sv exit /etc/service/*
|
||||
|
||||
[ -x /etc/rc.shutdown ] && /etc/rc.shutdown
|
||||
|
||||
if [ -z "$VIRTUALIZATION" -a -n "$HARDWARECLOCK" ]; then
|
||||
hwclock --systohc ${HARDWARECLOCK:+--$(echo $HARDWARECLOCK |tr A-Z a-z)}
|
||||
fi
|
||||
|
||||
halt -w # for wtmp
|
||||
|
||||
if [ -z "$VIRTUALIZATION" ]; then
|
||||
msg "Stopping udev..."
|
||||
udevadm control --exit
|
||||
fi
|
||||
|
||||
msg "Sending TERM signal to processes..."
|
||||
pkill --inverse -s0,1 -TERM
|
||||
sleep 1
|
||||
msg "Sending KILL signal to processes..."
|
||||
pkill --inverse -s0,1 -KILL
|
||||
|
||||
if [ -z "$VIRTUALIZATION" ]; then
|
||||
msg "Unmounting filesystems, disabling swap..."
|
||||
swapoff -a
|
||||
umount -r -a -t nosysfs,noproc,nodevtmpfs,notmpfs
|
||||
msg "Remounting rootfs read-only..."
|
||||
mount -o remount,ro /
|
||||
fi
|
||||
|
||||
sync
|
||||
|
||||
if [ -z "$VIRTUALIZATION" ]; then
|
||||
deactivate_vgs
|
||||
deactivate_crypt
|
||||
if [ -e /run/runit/reboot ] && command -v kexec >/dev/null; then
|
||||
msg "Triggering kexec..."
|
||||
kexec -e 2>/dev/null
|
||||
# not reached when kexec was successful.
|
||||
fi
|
||||
fi
|
||||
]])
|
||||
|
||||
add_packages({ "runit", "procps", "eudev" })
|
||||
modules.runit.add_service("getty-tty1", [[#!/bin/sh
|
||||
exec chpst -P getty 38400 tty1 linux]])
|
||||
modules.runit.add_service("getty-tty2", [[#!/bin/sh
|
||||
exec chpst -P getty 38400 tty2 linux]])
|
12
qemu.sh
Executable file
12
qemu.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
if test "$NOGRAPHIC" = true; then
|
||||
append="console=ttyS0"
|
||||
qemuappend="-nographic"
|
||||
fi
|
||||
|
||||
doas chown root:$(id -u) -R boot/ && doas chmod g+rw -R boot/
|
||||
qemu-system-x86_64 -enable-kvm -m 2048 \
|
||||
-drive file=image.squashfs,media=disk \
|
||||
-kernel boot/vmlinuz-virt -initrd boot/initramfs-virt \
|
||||
-append "root=/dev/sda rootfstype=squashfs init=/sbin/runit-init $append" $qemuappend
|
55
setup.lua
Normal file
55
setup.lua
Normal file
|
@ -0,0 +1,55 @@
|
|||
local utils = require("utils")
|
||||
local alpine = require("alpine")
|
||||
|
||||
local alpine_base_version = "3.15"
|
||||
local alpine_version = alpine_base_version..".0"
|
||||
local packages = {
|
||||
"alpine-baselayout",
|
||||
-- "alpine-conf",
|
||||
"apk-tools",
|
||||
"busybox",
|
||||
"libc-utils",
|
||||
"alpine-keys",
|
||||
}
|
||||
local mounts = {
|
||||
"tmpfs /tmp tmpfs defaults 0 0",
|
||||
}
|
||||
modules = {}
|
||||
|
||||
local root = "./root"
|
||||
|
||||
function add_packages(new_packages)
|
||||
utils.table_concat(packages, new_packages)
|
||||
end
|
||||
function add_mount(new_mount)
|
||||
table.insert(mounts, new_mount)
|
||||
end
|
||||
function add_file(path, content)
|
||||
utils.expect_nil(alpine.write_file(root, path, content))
|
||||
end
|
||||
function add_symlink(path, target)
|
||||
utils.expect_nil(alpine.symlink(root, path, target))
|
||||
end
|
||||
function chmod(path, perms)
|
||||
utils.expect_nil(alpine.chmod(root, path, perms))
|
||||
end
|
||||
function mkdir(path)
|
||||
utils.expect_nil(alpine.mkdir(root, path))
|
||||
end
|
||||
|
||||
print("=> Initializing rootfs...")
|
||||
utils.expect_nil(alpine.init_rootfs(root, alpine_base_version, alpine_version))
|
||||
|
||||
require("modules/kernel")
|
||||
require("modules/runit")
|
||||
|
||||
print("=> Writing fstab...")
|
||||
add_file("/etc/fstab", utils.join_table(mounts, "\n"))
|
||||
print("=> Installing and upgrading packages...")
|
||||
utils.expect_nil(alpine.make_world(root, packages))
|
||||
print("=> Setting password...")
|
||||
utils.expect_nil(alpine.set_password(root, "root", "12345678"))
|
||||
print("=> Moving boot...")
|
||||
utils.expect_nil(alpine.move_boot(root))
|
||||
print("=> Making image...")
|
||||
utils.expect_nil(alpine.make_squashfs(root, "image.squashfs"))
|
38
utils.lua
Normal file
38
utils.lua
Normal file
|
@ -0,0 +1,38 @@
|
|||
local utils = {}
|
||||
|
||||
function utils.expect_nil(result)
|
||||
if result then
|
||||
print("Error: "..result)
|
||||
os.exit(1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- https://stackoverflow.com/a/15278426
|
||||
function utils.table_concat(t1, t2)
|
||||
for i=1,#t2 do
|
||||
t1[#t1+1] = t2[i]
|
||||
end
|
||||
return t1
|
||||
end
|
||||
|
||||
-- Turns a table of strings into a string separated by separator.
|
||||
function utils.join_table(table, separator)
|
||||
local string = ""
|
||||
for i=1,#table do
|
||||
string = string .. table[i] .. separator
|
||||
end
|
||||
return string
|
||||
end
|
||||
|
||||
-- https://github.com/Donearm/scripts/blob/ad3429dc4b69e6108f538bf1656216c7a192c9fd/lib/basename.lua
|
||||
function utils.basename(str)
|
||||
return string.gsub(str, "(.*/)(.*)", "%2")
|
||||
end
|
||||
|
||||
-- https://gist.github.com/AndrewHazelden/a7b6551915a71a44770e
|
||||
function utils.dirname(str)
|
||||
return str:match("(.*/)")
|
||||
end
|
||||
|
||||
return utils
|
16
utils/templater.lua
Normal file
16
utils/templater.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
local utils = require "../utils"
|
||||
return function (template, params, pattern)
|
||||
local content = string.gsub(template, pattern or "{{([%w_]+)}}", function (s)
|
||||
if params[s] == nil then
|
||||
utils.expect_nil("No variable "..s)
|
||||
end
|
||||
if params[s] == true then
|
||||
return "true"
|
||||
end
|
||||
if params[s] == false then
|
||||
return "false"
|
||||
end
|
||||
return params[s]
|
||||
end)
|
||||
return content
|
||||
end
|
Loading…
Reference in a new issue