~humaid/diss_y4_impl

1cb6875ec0ab67129f1fe3c2b2f8c68e792b578f — Humaid AlQassimi 2 years ago c55883e
Add new changes
M .gitignore => .gitignore +3 -0
@@ 1,5 1,8 @@
*.iso
*.img
*.pub
*.sec
builds/
metadata.json
temp/
linux-gen

A assets/04081_lagoonnebula_1920x1080-attrib.txt => assets/04081_lagoonnebula_1920x1080-attrib.txt +21 -0
@@ 0,0 1,21 @@
https://interfacelift.com/wallpaper/details/4081/lagoon_nebula.html


Lagoon Nebula
By Dominic Kamp
October 25th, 2016

Taken from Gornergrad, a rocky ridge of the Pennine Alps, overlooking the
Gorner Glacier south-east of Zermatt in Switzerland.

I was like standing there and then like woah, all of a sudden there was this
cloud reaching out and then it was like lit from below and I was like SNAP boom
into my camera.

Moon for lighting, Photoshop, Manfrotto tripod, gloves.

Nikon D800, Nikon AF-S NIKKOR 14-24mm f/2.8G ED.

Photo Settings: 19mm, f/2, 25 seconds, ISO 100.

Map: 45.9833, 7.7847

A assets/04081_lagoonnebula_1920x1080.png => assets/04081_lagoonnebula_1920x1080.png +0 -0
A assets/lubuntu-calamares.desktop => assets/lubuntu-calamares.desktop +11 -0
@@ 0,0 1,11 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Install To Disk
Exec=bash -c "export BROWSER='sudo -H -u lubuntu firefox'; sudo -E calamares"
Comment=Calamares — System Installer
Icon=calamares
Terminal=false
StartupNotify=true
Categories=Qt;System;
Keywords=installer;calamares;system;

A assets/splash.pcx => assets/splash.pcx +0 -0
A assets/splash.png => assets/splash.png +0 -0
M builder/build.go => builder/build.go +6 -1
@@ 26,6 26,7 @@ func build(sess *buildSession) error {
		return errors.Wrap(err, "chmod filesystem manifest")
	}

	setProgress(sess, "Building: Creating filesystem manifest", 10)
	{ // write filesystem.manifest
		output, err := execc(sess.tempDir, "chroot", sess.chrootDir, "dpkg-query",
			"-W", "--showformat='${Package} ${Version}\\n'")


@@ 59,6 60,7 @@ func build(sess *buildSession) error {
	// TODO remove from the manifest (desktop) the calamares and casper
	// packages

	setProgress(sess, "Building: Making squashfs file", 11)
	config.Logger.Debug("build: mksquashfs")
	o, err := execc("", "mksquashfs",
		sess.chrootDir, sess.extractDir+"/casper/filesystem.squashfs",


@@ 67,6 69,7 @@ func build(sess *buildSession) error {
		return errors.Wrap(err, "mksquashfs "+string(o))
	}

	setProgress(sess, "Building: Calculating system size", 12)
	{ // write filesystem.size
		size, err := exec.Command("du", "-sx", "--block-size=1", sess.chrootDir).Output()
		if err != nil {


@@ 95,6 98,7 @@ func build(sess *buildSession) error {

	config.Logger.Debug("build: hashes")
	var hashes strings.Builder
	setProgress(sess, "Building: Calculating file hashes", 13)

	err = filepath.Walk(sess.extractDir,
		func(path string, info os.FileInfo, err error) error {


@@ 108,7 112,7 @@ func build(sess *buildSession) error {
					return err
				}

				hashes.WriteString(strings.Replace(string(hash), sess.extractDir, "", -1))
				hashes.WriteString("." + strings.Replace(string(hash), sess.extractDir, "", -1))
			}
			return nil
		})


@@ 130,6 134,7 @@ func build(sess *buildSession) error {
		}
	}

	setProgress(sess, "Building: Creating .iso file", 14)
	config.Logger.Debug("build: xorriso")
	xorriso := exec.Command("xorriso", "-as", "mkisofs",
		"-r", "-V", sess.cust.DistName+" "+sess.cust.DistVer+" amd64",

M builder/builder.go => builder/builder.go +25 -2
@@ 6,6 6,7 @@ import (
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"git.sr.ht/~humaid/linux-gen/config"


@@ 51,6 52,19 @@ type SystemMetadata struct {
	Timezones []string
}

var maxProg int = 16

func setProgress(sess *buildSession, status string, prog int) {
	mkdir("./builds")
	mkdir("./builds/" + sess.cust.AuthorID)
	if maxProg == prog || maxProg == -1 {
		writeToFile("./builds/"+sess.cust.AuthorID+"/prog", "Complete")
	} else {
		tot := int((float64(prog) / float64(maxProg)) * 100)
		writeToFile("./builds/"+sess.cust.AuthorID+"/prog", status+" ("+strconv.Itoa(tot)+"%)")
	}
}

func GetMetadata() (SystemMetadata, error) {
	var err error



@@ 202,6 216,7 @@ func Start(cust Customisation) (string, error) {
		cust:       cust,
	}

	setProgress(&sess, "Preparing...", 1)
	if _, err := os.Stat(dir); err == nil {
		cleanup(&sess)
	}


@@ 218,6 233,7 @@ func Start(cust Customisation) (string, error) {
		cleanup(&sess)
		return "", err
	}
	setProgress(&sess, "Customising", 5)

	config.Logger.Debug("start customise")
	err = customise(&sess)


@@ 230,7 246,10 @@ func Start(cust Customisation) (string, error) {
		cleanup(&sess)
		return "", err
	}
	config.Logger.Debug("Will build after press enter")
	fmt.Scanln()

	setProgress(&sess, "Building", 9)
	config.Logger.Debug("start build")
	err = build(&sess)
	if err != nil {


@@ 243,12 262,16 @@ func Start(cust Customisation) (string, error) {
		return "", err
	}

	setProgress(&sess, "Finalising...", 15)
	mkdir("./builds")
	mkdir("./builds/" + cust.AuthorID)
	os.Remove("./builds/final.iso")
	_, err = exec.Command("cp", sess.tempDir+"/output.iso", "./builds/"+cust.AuthorID+"/final.iso").Output()
	o, _ := execc("./builds/"+cust.AuthorID+"/final.iso", "sha256sum", "final.iso")
	writeToFile("./builds/"+cust.AuthorID+"/sha256sum.txt", o)

	cleanup(&sess)
	setProgress(&sess, "Complete", 16)

	return "", nil
}


@@ 274,8 297,8 @@ func cleanup(sess *buildSession) {
		}
	}

	//config.Logger.Debug("Will remove all when press enter")
	//fmt.Scanln()
	config.Logger.Debug("Will remove all when press enter")
	fmt.Scanln()
	os.RemoveAll(sess.tempDir)
}


M builder/customise.go => builder/customise.go +15 -0
@@ 22,6 22,8 @@ func sedFile(file string, pattern string) error {
func customise(sess *buildSession) error {
	var date = time.Now().Format(DATE)

	setProgress(sess, "Customising: Applying Branding", 6)

	sedFile(sess.extractDir+"/isolinux/txt.cfg", "s/Lubuntu/"+sess.cust.DistName+"/g")
	sedFile(sess.extractDir+"/boot/grub/grub.cfg", "s/Lubuntu/"+sess.cust.DistName+"/g")
	sedFile(sess.extractDir+"/boot/grub/loopback.cfg", "s/Lubuntu/"+sess.cust.DistName+"/g")


@@ 59,6 61,7 @@ UBUNTU_CODENAME=focal`)
		"s/lubuntu\\.me/humaidq\\.ae/g")

	// Install packages
	setProgress(sess, "Customising: Creating build script", 7)
	if err := buildCustomiseScript(sess); err != nil {
		return errors.Wrap(err, "build customise script")
	}


@@ 67,6 70,7 @@ UBUNTU_CODENAME=focal`)
	os.Remove(sess.chrootDir + "/etc/resolv.conf")
	os.Remove(sess.chrootDir + "/var/lib/dpkg/statoverride")
	writeToFile(sess.chrootDir+"/etc/resolv.conf", "nameserver 8.8.8.8")
	setProgress(sess, "Customising: Mouting partitions", 7)

	// mount /dev
	_, err := execc(sess.tempDir, "mount", "--bind", "/dev/", sess.chrootDir+"/dev")


@@ 74,10 78,19 @@ UBUNTU_CODENAME=focal`)
		return errors.Wrap(err, "mount /dev for chroot")
	}

	setProgress(sess, "Customising: Installing packages and applying customisations", 8)
	if _, err := execc(sess.tempDir, "chroot", sess.chrootDir, "/bin/bash", "/root/cust.sh"); err != nil {
		return errors.Wrap(err, "chroot customise script")
	}

	// copy over pictures
	wd, _ := os.Getwd()
	execc(wd, "cp", "-f", "./assets/splash.pcx", sess.extractDir+"/isolinux/")
	execc(wd, "cp", "-f", "./assets/splash.png", sess.extractDir+"/isolinux/")
	execc(wd, "cp", "-f", "./assets/lubuntu-calamares.desktop", sess.chrootDir+"/usr/share/applications/lubuntu-calamares.desktop")
	execc(wd, "chmod", "+x", sess.chrootDir+"/usr/share/applications/lubuntu-calamares.desktop")
	execc(wd, "cp", "-f", "./assets/04081_lagoonnebula_1920x1080.png", sess.chrootDir+"/usr/share/lubuntu/wallpapers/lubuntu-default-wallpaper.png")

	umount(sess.chrootDir + "/dev")

	return nil


@@ 110,6 123,8 @@ apt update

	sh.WriteString("apt autoremove --purge -y\n")

	sh.WriteString(sess.cust.Script + "\n")

	sh.WriteString(`umount /proc
umount /sys
umount /dev/pts

M builder/extract.go => builder/extract.go +4 -0
@@ 40,6 40,7 @@ func extract(sess *buildSession) error {
	mkdir(sess.mountDir)
	mkdir(sess.extractDir)

	setProgress(sess, "Extracting: mounting ISO", 2)
	config.Logger.Debug("extract: mount ISO")
	// mount the ISO file
	_, err = exec.Command("mount", "-o", "loop", config.Config.OrigISOFile,


@@ 50,6 51,7 @@ func extract(sess *buildSession) error {

	config.Logger.Debug(sess.mountDir, sess.extractDir)
	config.Logger.Debug("extract: rsync")
	setProgress(sess, "Extracting: rsync", 3)

	// copy contents to extract folder
	o, err := execc("", "rsync", "--exclude=/casper/filesystem.squashfs",


@@ 59,12 61,14 @@ func extract(sess *buildSession) error {
		//return errors.Wrap(err, "copy contents (rsync) "+o)
	}

	setProgress(sess, "Extracting: unsquashfs", 3)
	config.Logger.Debug("extract: unsquashfs")
	o, err = execc(sess.tempDir, "unsquashfs",
		sess.mountDir+"/casper/filesystem.squashfs")
	if err != nil {
		return errors.Wrap(err, "unsquashfs: "+o)
	}
	setProgress(sess, "Extracting: unmounting and cleaning up", 4)

	os.Rename(sess.tempDir+"/squashfs-root", sess.chrootDir)


A builds/web/prog => builds/web/prog +1 -0
@@ 0,0 1,1 @@
Complete
\ No newline at end of file

M cmd/start.go => cmd/start.go +1 -1
@@ 62,7 62,7 @@ func start(clx *cli.Context) (err error) {
	m.Get("/pkgs/sel", routes.SelectPackageHandler)
	m.Get("/build", routes.BuildHandler)
	m.Post("/build", routes.BuildHandler)
	m.Get("/download/:name.iso", routes.DownloadHandler)
	m.Get("/download/:name", routes.DownloadHandler)

	log.Printf("Starting web server on port %s\n", config.Config.SitePort)
	log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%s", config.Config.SitePort), m))

A key.txt => key.txt +1 -0
@@ 0,0 1,1 @@
ieje2ieWash8Yohd

M routes/home.go => routes/home.go +16 -1
@@ 39,7 39,16 @@ func DownloadHandler(ctx *macaron.Context, sess session.Store) {
		sessData = s.(sessionData)
	}
	ctx.Data["sess"] = sessData
	ctx.ServeFile("./builds/web/final.iso")
	name := ctx.Params("name")
	switch name {
	case "final.iso":
		ctx.ServeFile("./builds/web/final.iso")
	case "sha256sum.txt":
		ctx.ServeFile("./builds/web/sha256sum.txt")
	case "sha256sum.sig":
		ctx.ServeFile("./builds/web/sha256sum.sig")
	}
	ctx.PlainText(400, []byte("invalid file"))
}

type packageAction int


@@ 378,6 387,12 @@ func BuildHandler(ctx *macaron.Context, sess session.Store) {
		return
	}

	if a, err := ioutil.ReadFile("./builds/web/prog"); err == nil {
		if string(a) != "Complete" {
			ctx.Data["Progress"] = string(a)
		}
	}

	if stat, err := os.Stat("./builds/web/final.iso"); err == nil && !stat.IsDir() {
		ctx.Data["HasBuild"] = true
		ctx.Data["BuildTime"] = stat.ModTime().Format("2 January 2006 3:04pm")

M templates/build.html => templates/build.html +12 -1
@@ 1,5 1,8 @@
{{ template "partials/header" .}}
{{ template "partials/configbar" . }}
{{if .Progress}}
<meta http-equiv="refresh" content="1">
{{end}}
<h2>Build</h2>
<p>Once you have completed customising your system above, you may build your
system.</p>


@@ 7,7 10,11 @@ system.</p>
<p>Ready to build {{.sess.Name}} {{.sess.Version}}. Visit configuration page to
adjust version.</p>
<form method="post">
  {{if .Progress}}
  <p><b>Build in progress:</b> {{.Progress}}</p>
  {{else}}
<p><button type="submit" class="btn">Build ISO</button></p>
  {{end}}
</form>

<h3>Builds</h3>


@@ 25,7 32,11 @@ adjust version.</p>
    <td>{{.sess.Name}} build</td>
    <td>{{.BuildTime}}</td>
    <td>{{.BuildSize}} GB</td>
    <td><a href="/download/final.iso" class="btn">Download</a></td>
    <td>
      <a href="/download/final.iso" class="btn">Download</a>
      <a href="/download/sha256sum.txt" class="btn">Hash</a>
      <a href="/download/sha256sum.sig" class="btn">Sig</a>
    </td>
  </tr>
  {{else}}
  <tr>

M templates/partials/footer.html => templates/partials/footer.html +1 -2
@@ 2,8 2,7 @@
    </div>
    <div class="footer">
      <p><a rel="noopener noreferrer" href="/">CSLDG</a> is part of a research
      project by Humaid AlQassimi at Heriot-Watt University. This is a
      prototype.</p>
      project by Humaid AlQassimi at Heriot-Watt University.</p>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js" integrity="sha512-RXf+QSDCUQs5uwRKaDoXt55jygZZm2V++WUZduaU/Ui/9EGp3f/2KZVahFZBKGH0s774sd3HmrhUy+SgOFQLVQ==" crossorigin="anonymous"></script>
  </body>