First commit

This commit is contained in:
Fierelier 2022-02-20 18:36:34 +01:00
parent 1071933500
commit 4784383153
5 changed files with 342 additions and 2 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2022
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,3 +1,7 @@
# mdevuan
a devuan image maker
A Devuan image maker
Commands required:
Syntax: `python3 mdevuan.py <image name> <tmp folder>`
Example: `python3 mdevuan.py devuan.img /tmp/devuan`

210
mdevuan.py Normal file
View File

@ -0,0 +1,210 @@
#!/usr/bin/env python3
import sys
import os
import shutil
diskSize = "1536M"
swapSize = "256M"
outputImage = os.path.abspath(sys.argv[1])
mountPoint = os.path.abspath(sys.argv[2].rstrip("/"))
mountPoints = [ # List of mount points to dismount when quitting
os.path.join(mountPoint,"proc"),
os.path.join(mountPoint,"sys"),
os.path.join(mountPoint,"dev"),
mountPoint
]
preReqs = [ # List of required commands to check for
"fallocate",
"losetup",
"fdisk",
"losetup",
"mkswap",
"mkfs.ext4",
"mount",
"blkid",
"debootstrap",
"chmod",
"chroot",
"umount"
]
loopName = False
class processError(Exception): pass
import subprocess
def procWait(proc):
rtn = proc.wait()
if rtn != 0: raise processError
def call(*args,**kwargs):
proc = subprocess.Popen(*args,**kwargs)
procWait(proc)
def callo(*args,**kwargs):
data = b""
proc = subprocess.Popen(*args,**kwargs,stdout=subprocess.PIPE)
while True:
b = proc.stdout.read()
if b == b"": break
data += b
procWait(proc)
return data.decode("utf-8")
def cleanUp():
global diskSize
global swapSize
global outputImage
global mountPoint
global loopName
for mp in mountPoints:
print("Dismounting " +mp+ " ...")
try:
call(["umount",mp])
except: pass
try:
os.rmdir(mountPoint)
except Exception as e:
print(e)
print("Detaching loop device ...")
try:
call(["losetup","-d",loopName])
except:
pass
def main():
global diskSize
global swapSize
global outputImage
global mountPoint
global loopName
print("Checking prerequisites ...")
call(["sh","-c","command"])
for req in preReqs:
try:
call(["sh","-c","command -v " + req],stdout=subprocess.DEVNULL)
except:
print("Missing command: " +req)
raise
print("Creating disk image ...")
if os.path.isfile(outputImage): os.remove(outputImage)
call(["fallocate","-l",diskSize,outputImage])
print("Creating loop device ...")
call(["losetup","-fP",outputImage])
print("Setting up loop device ...")
table = callo(["losetup","--list"]).replace("\r","").split("\n")
length = len(table)
index = 0
while index < length:
while " " in table[index]:
table[index] = table[index].replace(" "," ")
if table[index] == "":
del table[index]
length -= 1
continue
table[index] = table[index].split(" ")
index += 1
nameIndex = table[0].index("NAME")
backfileIndex = table[0].index("BACK-FILE")
index = 1
while index < length:
if table[index][backfileIndex] == outputImage:
loopName = table[index][nameIndex]
break
index += 1
if loopName == False:
print("Loop device not found.")
raise processError
print("Partitioning ...")
proc = subprocess.Popen(["fdisk",loopName],stdin=subprocess.PIPE)
proc.communicate(("""\
n
e
+""" +swapSize+ """
t
swap
n
p
t
linux
w
\
""").encode("utf-8"))
procWait(proc)
print("Making swap ...")
call(["mkswap",loopName + "p1"])
print("Formatting / (ext4) ...")
call(["mkfs.ext4",loopName+ "p2"])
print("Mounting / ...")
if not os.path.isdir(mountPoint): os.makedirs(mountPoint)
call(["mount",loopName + "p2",mountPoint])
print("Installing Devuan Chimaera ...")
tries = 0
while tries < 10:
try:
call(["debootstrap","--arch=i386","chimaera",mountPoint,"http://deb.devuan.org/merged"])
break
except:
tries += 1
continue
if tries >= 10:
raise processError
print("Setting up chroot ...")
call(["mount","-o","bind","/dev",os.path.join(mountPoint,"dev")])
call(["mount","-o","bind","/sys",os.path.join(mountPoint,"sys")])
call(["mount","-t","proc","/proc",os.path.join(mountPoint,"proc")])
shutil.copyfile("/proc/mounts",os.path.join(mountPoint,"etc","mtab"))
with open("setup","r",encoding="utf-8") as fhIn:
with open(os.path.join(mountPoint,"setup"),"w",encoding="utf-8") as fhOut:
for line in fhIn:
fhOut.write(line.replace("$LOOPNAME",loopName))
call(["chmod","+x",os.path.join(mountPoint,"setup")])
print("Adding devices to fstab ...")
idSwap = callo(["blkid","-o","value","-s","UUID",loopName+ "p1"]).strip(" \t\r\n")
idRoot = callo(["blkid","-o","value","-s","UUID",loopName+ "p2"]).strip(" \t\r\n")
with open(os.path.join(mountPoint,"etc","fstab"),"a+",encoding="utf-8") as fh:
fh.write("\nUUID=" +idSwap+ " none swap sw 0 0")
fh.write("\nUUID=" +idRoot+ " / ext4 errors=remount-ro 0 1")
print("Running setup ...")
call(["chroot",mountPoint,"/setup"])
print("Injecting OOBE ...")
os.rename(os.path.join(mountPoint,"bin","login"),os.path.join(mountPoint,"bin","login.bak"))
shutil.copyfile("oobe",os.path.join(mountPoint,"bin","login"))
call(["chmod","+x",os.path.join(mountPoint,"bin","login")])
cleanUp()
try:
main()
except:
print("\n --- AN ERROR OCCURED, CLEANING UP ... --- ")
cleanUp()
print("")
raise

108
oobe Normal file
View File

@ -0,0 +1,108 @@
#!/usr/bin/env python3
# This script is ran when booting into the OS, and the setup isn't finished
import os
import traceback
import subprocess
debug = False
os.environ["PATH"] = "/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
def procWait(proc):
rtn = proc.wait()
if debug: print(rtn)
if rtn != 0: raise processError
def call(*args,**kwargs):
if debug: print(str(args[0]))
proc = subprocess.Popen(*args,**kwargs)
procWait(proc)
def mchoice(choices):
while True:
choice = input("Choice: ").lower()
if not choice in choices: continue
return choice
def main():
while True:
print("Welcome to Devuan Linux.")
print("1: Finish installation")
print("2: Clone to other device")
print("3: Open bash")
print("4: Shut down")
choice = mchoice(["1","2","3","4"])
if choice == "1":
call(["apt","install","keyboard-configuration","console-setup","locales","tzdata","--yes"])
#call(["dpkg-reconfigure","keyboard-configuration"])
#call(["setupcon"])
#call(["dpkg-reconfigure","console-setup"])
#call(["setupcon"])
call(["dpkg-reconfigure","locales"])
call(["dpkg-reconfigure","tzdata"])
print("")
hostname = input("Hostname: ")
with open("/etc/hosts","w",encoding="utf-8") as fh:
fh.write("""\
127.0.0.1 localhost
127.0.1.1 $HOSTNAME
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters\
""".replace("$HOSTNAME",hostname)
)
with open("/etc/hostname","w",encoding="utf-8") as fh:
fh.write(hostname)
os.environ["HOSTNAME"] = hostname
print("")
print("Configure your network now, using nmtui? (y/n)")
if mchoice(["y","n"]) == "y": call(["nmtui"])
print("")
call(["groupadd","-f","sudo"])
username = False
while True:
username = input("First user (Administrator): ").lower().strip(" ")
if username == "root": continue
try:
call(["id","-u",username])
except:
try:
call(["adduser",username])
except:
try:
call(["deluser","--remove-home",username])
except:
continue
try:
call(["usermod","-a","-G","sudo",username])
except:
print("Warning: Couldn't add user to sudo group!")
break
print("")
print("Booting into new environment ...")
os.remove("/bin/login")
os.rename("/bin/login.bak","/bin/login")
return
if choice == "2":
print("Not implemented.")
continue
if choice == "3":
call(["bash"])
return
if choice == "4":
call(["poweroff"])
return
try:
main()
except:
print(traceback.format_exc())
input("Press RETURN to quit.")

18
setup Normal file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# This script is ran within in the chroot
set -e
echo 'APT::Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retry
apt autoclean --yes
apt install linux-image-686 grub2 sudo network-manager python3 --yes
apt autoclean --yes
apt install --download-only console-setup keyboard-configuration locales tzdata --yes
rm /etc/apt/apt.conf.d/80-retry
grub-install --boot-directory="/boot" --modules=part_msdos "$LOOPNAME"
update-grub
update-initramfs -u -k all
echo ""
echo "Do any manual changes now, enter 'exit' to finish setup."
bash
if [[ -f "$HOME/.bash_history" ]]; then
rm "$HOME/.bash_history"
fi