Commit 1fdac977 authored by Fabian Kosmale's avatar Fabian Kosmale
Browse files

refactoring: use an IsoBuilder class, created a main script

parent 08387cbe
#!/usr/bin/env python3
from settings import *
import container
import iso
import os
from os.path import join as pjoin
def read_package_list(package_list):
"""Read the file :package_list and return a list of packages"""
packages = ""
with open("./config/packages.conf") as package_list:
# TODO: that can be done with a list comprehension...
for line in package_list:
line = line.strip()
if not line or line.startswith("#"):
continue
packages = " ".join((packages, line))
return packages.strip().split()
if __name__ == "__main__":
locale_archive = "./locale-archive" # FIXME
if not os.path.isfile(locale_archive):
locale_archive = None
else:
locale_archive = os.path.abspath(locale_archive)
package_list = read_package_list(pjoin(configdir, "packages.conf"))
container.create(package_list, rootfolder=pjoin(outputdir, "chakra"))
iso_builder = iso.IsoBuilder(outputdir, datadir, configdir)
iso_builder.prepare_overlay(locale_archive)
iso_builder.prepare_iso()
iso_builder.make_iso()
# vim: set syntax=python:
......@@ -13,15 +13,3 @@ def create(package_list=None, rootfolder="chakra"):
with open("log", "w") as log:
subprocess.check_call(command,
shell=False, stderr=log)
if __name__ == "__main__":
packages = ""
with open("./config/packages.conf") as package_list:
# TODO: that can be done with a list comprehension...
for line in package_list:
line = line.strip()
if not line or line.startswith("#"):
continue
packages = " ".join((packages, line))
create(packages.strip().split())
......@@ -2,6 +2,7 @@
"""Creates the actual ISO"""
import os
from os.path import join as pjoin
import glob
import re
import subprocess
......@@ -9,146 +10,166 @@ import datetime
import shutil
inform = print # TODO
iso_root = "iso_root"
squashfs_files = [] # list of squashfs image files
label='CHAKRA_{}'.format(datetime.datetime.now().strftime("%Y-%m-%d"))
overlay_packages_dir = os.path.join(".", "overlay-packages")
class IsoBuilder:
def __init__(self, outputdir, datadir, configdir):
self.iso_root = pjoin(outputdir, "iso_root")
def make_suqash(directory="chakra", name=None):
"""TODO."""
assert os.path.isdir(directory), "mksquash only works on directories!"
if name is None:
sqimg = os.path.join(os.getcwd(), "{}.img".format(directory))
else:
sqimg = name
inform("Generating SquashFS image for {}".format(directory))
# TODO: check if existing image is out of date
inform("Creating SquashFS image. This may take some time...")
command = "mksquashfs {} {} -noappend -comp xz -Xbcj x86".format(
directory,
sqimg
).split(" ")
if not os.path.isfile(sqimg):
subprocess.check_call(command)
squashfs_files.append(sqimg)
self.outputdir = outputdir
self.datadir = datadir
self.configdir = configdir
self.squashfs_files = [] # list of squashfs image files
self.label='CHAKRA_{}'.format(datetime.datetime.now().strftime("%Y-%m-%d"))
self.overlay_packages_dir = pjoin(outputdir, "overlay-packages")
def prepare_overlay(locale_archive=None):
"""
Creates missing files in the overlay.
If no locale_archive is given, a new one is created based on the locale.conf
in config. Furthermore, all packages specified in overlay_packages will be
downloaded and put into overlay-packages
:locale_archive: path to an existig locale_archive
"""
if locale_archive is None or not os.path.isfile(locale_archive):
# create locale_archive
pass
else:
# copy existing one to correct place
shutil.copy(locale_archive,
os.path.abspath("./overlay-files/usr/lib/locale/"))
# download packages
package_dir = os.path.join(overlay_packages_dir, "opt/chakra/pkgs")
package_dir = os.path.abspath(package_dir)
os.makedirs(package_dir)
command = "pacman -Swdd --noconfirm --cachedir {} {}"
with open("./config/overlay-packages.conf") as packages:
for line in packages:
line = line.strip()
if not line:
continue
subprocess.check_call(
command.format(
package_dir,
line
).split())
def make_suqash(self, directory="chakra", name=None):
"""Creates a squashfs image out of :directory:.
:directory: the directory to be compressed
:name: the name of the resulting squashfs image
"""
assert os.path.isdir(directory), "mksquash only works on directories!"
if name is None:
name = "{}.img".format(directory)
sqimg = pjoin(self.datadir, "{}.img".format(name))
inform("Generating SquashFS image for {}".format(directory))
# TODO: check if existing image is out of date
inform("Creating SquashFS image. This may take some time...")
command = "mksquashfs {} {} -noappend -comp xz -Xbcj x86".format(
directory,
sqimg
).split(" ")
# only create sqimg if it doesn't already exist to save time
# TODO: create a hash of the directory to check if it became "dirty"
if not os.path.isfile(sqimg):
subprocess.check_call(command)
self.squashfs_files.append(sqimg)
def prepare_iso():
make_suqash(os.path.abspath("chakra"), "root-image.sqfs")
make_suqash(os.path.abspath("overlay-files"), "overlay.sqfs")
make_suqash(os.path.abspath(overlay_packages_dir), "overlay-pkgs.sqfs")
inform(label)
# create root directory for iso image
os.makedirs(iso_root)
# for more information see http://www.syslinux.org/wiki/index.php/ISOLINUX
"""Copies the required files"""
# copy all isolinux files to iso_root/isolinux
isolinux_dir = os.path.join(iso_root, "isolinux")
# this will create isolinux_dir and copy everything from config/isolinux
shutil.copytree("./isolinux", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/isolinux.bin", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/ldlinux.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/libcom32.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/liblua.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/libgpl.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/libmenu.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/libutil.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/mboot.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/whichsys.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/chain.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/gfxboot.c32", isolinux_dir)
shutil.copy("/usr/lib/syslinux/bios/hdt.c32", isolinux_dir)
isolinux_cfg = os.path.join(isolinux_dir, "isolinux.cfg")
with open(isolinux_cfg) as infile:
lines = infile.readlines()
with open(isolinux_cfg, "w") as outfile:
for line in lines:
line = re.sub("%CHAKRAISO_LABEL%", label, line)
outfile.write(line)
# create the directory where the image will reside
image_dir = os.path.join(iso_root, "chakra/boot/x86_64/")
os.makedirs(image_dir)
# copy the initramfs
shutil.copy("./chakra/boot/chakraiso.img", os.path.join(image_dir, "chakraiso.img"))
# copy the kernel
shutil.copy("./chakra/boot/vmlinuz-linux", os.path.join(image_dir, "chakraiso"))
# copy the isomounts file
shutil.copy("./config/isomounts", os.path.join(iso_root, "chakra"))
# copy the squashfs images
squashfs_dir = os.path.join(iso_root, "chakra", "x86_64")
os.makedirs(squashfs_dir)
for file in squashfs_files:
shutil.copy(file, squashfs_dir)
def prepare_overlay(self, locale_archive=None):
"""
Creates missing files in the overlay.
If no locale_archive is given, a new one is created based on the locale.conf
in config. Furthermore, all packages specified in overlay_packages will be
downloaded and put into overlay-packages
:locale_archive: path to an existig locale_archive
:datadir: files are copied for there
:outputdir: the overlay files are put there
"""
# copy overlay files to outputdir
overlay_files = pjoin(self.datadir, "overlay-files")
shutil.copytree(overlay_files, pjoin(self.outputdir,"overlay-files"))
if locale_archive is None or not os.path.isfile(locale_archive):
# create locale_archive
pass
else:
# copy existing one to correct place
shutil.copy(locale_archive, pjoin(overlay_files, "/usr/lib/locale/"))
# download packages
package_dir = os.path.join(self.overlay_packages_dir, "opt/chakra/pkgs")
package_dir = os.path.abspath(package_dir)
os.makedirs(package_dir, exist_ok=True)
command = "pacman -Swdd --noconfirm --cachedir {} {}"
with open("./config/overlay-packages.conf") as packages:
for line in packages:
line = line.strip()
if not line:
continue
subprocess.check_call(
command.format(
package_dir,
line
).split())
def make_iso(publisher='Chakra_GNU/Linux_<http://www.chakraos.org>',
application='Chakra_GNU/Linux_Live/Rescue_CD',
label='CHAKRA_{}'.format(
datetime.datetime.now().strftime("%Y-%m-%d")),
imgname='output.iso'
):
inform("Building ISO")
# check if we really need the one below
command = """mkisofs
-output {imgname}
-A {application}
-publisher {publisher}
-b isolinux/isolinux.bin
-c isolinux/boot.cat
-rational-rock
-uid 0
-gid 0
--iso-level 3
-no-emul-boot
-boot-load-size 4
-boot-info-table
-l
-V {label}
-udf
iso_root
""".format(**{
"publisher": publisher,
"application": application,
"label": label,
"imgname": imgname,
})
with open("log", "w") as log:
subprocess.check_call(command.strip().split(), shell=False, stderr=log)
subprocess.check_call(["isohybrid", imgname], stderr=log)
if __name__ == "__main__":
prepare_overlay("./locale-archive")
prepare_iso()
make_iso()
def prepare_iso(self):
self.make_suqash(pjoin(self.outputdir,"chakra"), "root-image.sqfs")
self.make_suqash(pjoin(self.outputdir, "overlay-files"), "overlay.sqfs")
self.make_suqash(self.overlay_packages_dir, "overlay-pkgs.sqfs")
# create root directory for iso image
os.makedirs(self.iso_root)
# for more information see http://www.syslinux.org/wiki/index.php/ISOLINUX
"""Copies the required files"""
# copy all isolinux files to iso_root/isolinux
isolinux_dir = os.path.join(self.iso_root, "isolinux")
# this will create isolinux_dir and copy everything from <datadir>/isolinux
shutil.copytree(pjoin(self.datadir, "isolinux"), isolinux_dir)
assert os.path.isdir("/usr/lib/syslinux"), "syslinux must be installed"
syslinux_path = "/usr/lib/syslinux/bios/"
syslinux_components = (
"isolinux.bin" ,
"ldlinux.c32" ,
"libcom32.c32" ,
"liblua.c32" ,
"libgpl.c32" ,
"libmenu.c32" ,
"libutil.c32" ,
"mboot.c32" ,
"whichsys.c32" ,
"chain.c32" ,
"gfxboot.c32" ,
"hdt.c32" ,
)
for component in syslinux_components:
shutil.copy(pjoin(syslinux_path, component), isolinux_dir)
isolinux_cfg = os.path.join(isolinux_dir, "isolinux.cfg")
# adjust label
with open(isolinux_cfg) as infile:
lines = infile.readlines()
with open(isolinux_cfg, "w") as outfile:
for line in lines:
line = re.sub("%CHAKRAISO_LABEL%", self.label, line)
outfile.write(line)
# create the directory where the image will reside
image_dir = os.path.join(self.iso_root, "chakra/boot/x86_64/")
os.makedirs(image_dir)
# copy the initramfs
shutil.copy(pjoin(self.outputdir, "chakra/boot/chakraiso.img"), pjoin(image_dir, "chakraiso.img"))
# copy the kernel
shutil.copy(pjoin(self.outputdir, "chakra/boot/vmlinuz-linux"), pjoin(image_dir, "chakraiso"))
# copy the isomounts file
shutil.copy(pjoin(self.configdir, "isomounts"), pjoin(self.iso_root, "chakra"))
# TODO: add sanity check: # isomounts entries == len(self.squashfs_files)
# copy the squashfs images
squashfs_dir = pjoin(self.iso_root, "chakra", "x86_64")
os.makedirs(squashfs_dir)
for file in self.squashfs_files:
shutil.copy(file, squashfs_dir)
def make_iso(self, publisher='Chakra_GNU/Linux_<http://www.chakraos.org>',
application='Chakra_GNU/Linux_Live/Rescue_CD',
label=None,
imgname='output.iso'
):
if label is None:
label = self.label
inform("Building ISO")
command = """mkisofs
-output {imgname}
-A {application}
-publisher {publisher}
-b isolinux/isolinux.bin
-c isolinux/boot.cat
-rational-rock
-uid 0
-gid 0
--iso-level 3
-no-emul-boot
-boot-load-size 4
-boot-info-table
-l
-V {label}
-udf
{iso_root}
""".format(**{
"publisher": publisher,
"application": application,
"label": label,
"imgname": imgname,
"iso_root": self.iso_root,
})
with open("log", "w") as log:
subprocess.check_call(command.strip().split(), shell=False, stderr=log)
subprocess.check_call(["isohybrid", imgname], stderr=log)
import os
from os.path import join as pjoin
__all__ = ['datadir', "configdir", "outputdir"]
curwd = os.getcwd()
datadir = os.path.abspath("./data")
configdir = os.path.abspath("./config")
outputdir = os.path.abspath(pjoin(curwd, "./iso_build"))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment