Files
tononixOS_application_krnlu…/RoboFile.php
2021-11-12 00:13:45 -05:00

250 lines
14 KiB
PHP

<?php
require_once(__DIR__."/vendor/autoload.php"); // Pull in Composer Autoload
define("APPNAME", "tononixOS Kernel Update Client"); // Define the application name so our universal application stub can find it.
/**
* Application Name: tononixOS Kernel Update Client
* Application Desc: Allows tononixOS devices to update their kernel via source with no user intervention, similar to Gentoo's Genkernel
* Application Ver: v1.0.2
*/
/**
* TODO: Device detection
* TODO: Use of device-configs for cloning kernel repositories
* TODO: Build own tononixOS self-update mechanism
*/
class RoboFile extends \Robo\Tasks
{
public $dir;
public $device_name;
public $device_manufacturer;
public function __construct()
{
\Robo\Robo::loadConfiguration([__DIR__."/config.yml",getenv("HOME")."/.local/system/etc/tononixOS/config.yml","/etc/tononixOS/config.yml"]);
$this->dir = array("kernel-source" => \Robo\Robo::Config()->get("tononix.directories.kernel-source"),
"kernel-source-symlink" => \Robo\Robo::Config()->get("tononix.directories.kernel-source-symlink"),
"kernel-install" => \Robo\Robo::Config()->get("tononix.directories.kernel-install"),
"kernel-device" => \Robo\Robo::Config()->get("tononix.device.boot-partiton"));
if(!empty(\Robo\Robo::Config()->get("tononix.debug"))) define("DEBUG", true);
$device_info = \AndroidDevice::__getDeviceInfo();
if($device_info == false) {
$this->device_name = \Robo\Robo::Config()->get("tononix.device.name");
$this->device_manufacturer = \Robo\Robo::Config()->get("tononix.device.manufacturer");
} else {
$this->device_name = $device_info['device_name'];
$this->device_manufacturer = $device_info['device_manufacturer'];
}
}
public function kernelSourceRetrieve($opts = ['branch' => "flo", 'repository' => "https://tonoxisisle.services/git/tononixOS/ubports_kernel_google_msm", 'kernel-name' => '3.4.y-tononixOS-flo'])
{
$genkernel = true;
if (!file_exists(getenv("HOME")."/.local/system/etc/genkernel.conf")) {
$this->say("Gentoo Prefix not detected, not using Genkernel to build kernel...");
$genkernel = false;
}
if($genkernel == false)
{
if(!file_exists($this->dir['kernel-source']."/".$opts['kernel-name'])) {
$this->say("Retrieving kernel sources from: ".$opts['repository']." using branch ".$opts['branch']."...");
$this->taskGitStack()
->stopOnFail()
->cloneRepo($opts['repository'], $this->dir['kernel-source'].$opts['kernel-name'], $opts['branch'])
->run();
} else {
$this->say("Updating kernel sources from: ".$opts['repository']." using branch ".$opts['branch']."...");
$this->taskGitStack()
->stopOnFail()
->dir($this->dir['kernel-source']."/".$opts['kernel-name'])
->pull("origin", $opts['branch'])
->run();
}
$this->_symlink($this->dir['kernel-source'].$opts['kernel-name'], $this->dir['kernel-source-symlink']);
} else {
if(!file_exists(getenv("HOME")."/.local/system/usr/src/".$opts['kernel-name'])) {
$this->say("Retrieving kernel sources from: ".$opts['repository']." using branch ".$opts['branch']."...");
$this->taskGitStack()
->stopOnFail()
->cloneRepo($opts['repository'], getenv("HOME")."/.local/system/usr/src/".$opts['kernel-name'], $opts['branch'])
->run();
} else {
$this->say("Updating kernel sources from: ".$opts['repository']." using branch ".$opts['branch']."...");
$this->taskGitStack()
->stopOnFail()
->dir(getenv("HOME")."/.local/system/usr/src/".$opts['kernel-name'])
->pull("origin", $opts['branch'])
->run();
}
$this->_symlink(getenv("HOME")."/.local/system/usr/src/".$opts['kernel-name'], $this->dir['kernel-source-symlink']);
}
}
public function kernelSourceBuild()
{
$genkernel = true;
if(!file_exists($this->dir['kernel-source-symlink'])) {
$this->say("Kernel source was not found in ".$this->dir['kernel-source-symlink'].", pulling down kernel sources for device...");
$this->kernelSourceRetrieve();
}
if(!file_exists(getenv("HOME")."/.local/system/etc/genkernel.conf"))
{
$this->say("Gentoo Prefix not detected, not using Genkernel to build kernel...");
$genkernel = false;
}
$this->say("Building kernel....");
if($genkernel == true) {
$this->_exec("genkernel --config=".getenv("HOME")."/.local/system/etc/genkernel.conf bzImage");
} else {
if(!$this->device_name)
{
$this->_copy($this->dir['kernel-source-symlink']."/arch/arm/configs/tononixos_defconfig", $this->dir['kernel-source-symlink']."/.config");
} else {
$this->_copy($this->dir['kernel-source-symlink']."/arch/arm/configs/tononixos_".$this->device_name."_defconfig", $this->dir['kernel-source-symlink']."/.config");
}
putenv("ARCH=arm");
putenv("SUBARCH=arm");
$this->taskExec("make -j4")->dir($this->dir['kernel-source-symlink'])->run();
$this->_copy($this->dir['kernel-source-symlink']."/arch/arm/boot/zImage", $this->dir['kernel-install']."/kernel");
}
}
public function kernelInstall($opts = ['flash_kernel' => false, 'keep-image-after-flash' => true])
{
$genkernel = true;
if(!file_exists(getenv("HOME")."/.local/system/etc/genkernel.conf"))
{
$genkernel = false;
$this->say("Gentoo Prefix not detected, ignoring prefix assumptions...");
} else {
$bootdir = getenv("HOME")."/.local/system/boot";
}
\Robo\Robo::loadConfiguration([getenv("HOME")."/.config/tononix/device-configs/".$this->device_manufacturer."/".$this->device_name."yml",getenv("HOME")."/.local/system/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml","/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml",__DIR__."/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml"]);
$kernelBootPartiton = \Robo\Robo::Config()->get("device.partition_info.boot").\AndroidDevice::__getBootSlot();
if(\AndroidDevice::__getBootSlot())
{
$this->say("Extracting inital ramdisk from current boot image in boot-slot: ".\AndroidDevice::__getBootSlot()."...");
if($genkernel == false)
{
$this->_exec("dd if=".$kernelBootPartition." of=".$this->dir['kernel-install']."/boot_current-krnlupdate.img");
$this->taskExec("abootimg -x boot_current-krnlupdate.img")->dir($this->dir['kernel-install'])->run();
$this->_remove([$this->dir['kernel-install']."/zImage"]);
if(!file_exists($this->dir['kernel-install']."/kernel")) {
$this->yell("No kernel has been build yet.. Kicking off kernel build...");
$this->kernelSourceBuild();
}
$this->say("Creating new boot.img with new kernel image...");
$this->taskExec("abootimg --create newboot.img -f ./bootimg.cfg -k ./kernel -r ./initrd.img")->dir($this->dir['kernel-install'])->run();
if($opts['flash-kernel'] == true)
{
$this->kernelFlash(array("boot-image"=>$this->dir['kernel-install']."/newboot.img"));
$this->_move($this->dir['kernel-install']."/newboot.img", $this->dir['kernel-install']."/boot.img");
}
} else {
$this->_exec("dd if=".$kernelBootPartition." of=".getenv("HOME")."/.local/system/boot/boot_current-krnlupdate.img");
$this->taskExec("abootimg -x boot_current-krnlupdate.img")->dir($this->dir['kernel-install'])->run();
$this->_remove([getenv("HOME")."/.local/system/boot/zImage"]);
if(!file_exists(getenv("HOME")."/.local/system/boot/kernel")) {
$this->yell("No kernel has been built yet... Kicking off kernel build using GenKernel...");
$this->kernelSourceBuild();
}
$this->say("Creating new boot.img with new kernel image...");
$this->taskExec("abootimg --create newboot.img -f ./bootimg.cfg -k ./kernel -r ./initrd.img")->dir(getenv("HOME")."/.local/system/boot")->run();
if($opts['flash-kernel'] == true)
{
$this->kernelFlash(array("boot-image"=>getenv("HOME")."/.local/system/boot/newboot.img"));
$this->_move(getenv("HOME")."/.local/system/boot/newboot.img",getenv("HOME")."/.local/system/boot/boot.img");
}
}
}
}
public function kernelFlash($opts = ['boot-image' => "", 'boot-partition' => ""])
{
\Robo\Robo::loadConfiguration([getenv("HOME")."/.config/tononix/device-configs/".$this->device_manufacturer."/".$this->device_name."yml",getenv("HOME")."/.local/system/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml","/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml",__DIR__."/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml"]);
$kernelBootPartition = \Robo\Robo::Config()->get("device.partition_info.boot").\AndroidDevices::__getBootSlot();
$genkernel = true;
if (!file_exists(getenv("HOME")."/.local/system/etc/genkernel.conf")) {
$genkernel = false;
$this->say("Gentoo Prefix not detected, ignoring prefix assumptions...");
}
if($genkernel == false)
{
$bootImage = $this->dir['kernel-install']."/boot.img";
} else {
$bootImage = getenv("HOME")."/.local/system/boot/boot.img";
}
if(!empty($opts['boot-image'])) $bootImage = $opts['boot-image'];
if(!empty($opts['boot-partition'])) $kernelBootPartition = $opts['boot-partition'];
$this->say("Writing kernel boot image: ".$bootImage." to: ".$kernelBootPartition);
$this->taskExec("dd if=".$bootImage." of=".$kernelBootPartition);
}
public function kernelBackup($opts = ['boot-partition' => ""])
{
$genkernel = true;
if (!file_exists(getenv("HOME")."/.local/system/etc/genkernel.conf")) {
$genkernel = false;
$this->say("Gentoo Prefix not detected, ignoring prefix assumptions...");
}
if($genkernel == false)
{
$bootImage = $this->dir['kernel-install']."/boot.img";
} else {
$bootImage = getenv("HOME")."/.local/system/boot/boot.img";
}
\Robo\Robo::loadConfiguration([getenv("HOME")."/.config/tononix/device-configs/".$this->device_manufacturer."/".$this->device_name."yml",getenv("HOME")."/.local/system/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml","/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml",__DIR__."/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml"]);
$kernelBootPartition = \Robo\Robo::Config()->get("device.partition_info.boot").\AndroidDevice::__getBootSlot();
if(!empty($opts['boot-partition'])) $kernelBootPartition = $opts['boot-partition'];
$this->say("Creating backup of currently working kernel and configuration (if available)....");
if($genkernel == false)
{
if(!file_exists($this->dir['kernel-install']."/backups")) $this->_mkdir($this->dir['kernel-install']."/backups");
} else {
if(!file_exists(getenv("HOME")."/.local/system/boot/backups")) $this->_mkdir(getenv("HOME")."/.local/system/boot/backups");
}
$collection = $this->collectionBuilder();
$tmpDir = $collection->tmpDir()->getPath();
$collection->say("Making a copy of working kernel configuration...");
$collection->taskFilesystemStack()->copy("/proc/config.gz", "$tmpDir/config.gz");
$collection->say("Copying the current boot image...");
$collection->taskExec("dd if=".$kernelBootPartition." of=$tmpDir/boot.img");
if ($genkernel == false) {
$collection->say("Packaging kernel backup in ".$this->dir['kernel-install']."/backups/...");
$collection->taskPack($this->dir['kernel-install']."/backups/boot.img-".date("mdY-gha").".tar.gz")
->add("$tmpDir/config.gz")
->add("$tmpDir/boot.img");
} else {
$collection->say("Packaging kernel backup in ".getenv("HOME")."/.local/system/boot/backups/...");
$collection->taskPack(getenv("HOME")."/.local/system/boot/backups/boot.img-".date("mdY-gha").".tar.gz")
->add("$tmpDir/config.gz")
->add("$tmpDir/boot.img");
}
$collection->run();
}
public function kernelRestore($opts = ['backup-package' => "", 'boot-partition' => ""])
{
\Robo\Robo::loadConfiguration([getenv("HOME")."/.config/tononix/device-configs/".$this->device_manufacturer."/".$this->device_name."yml",getenv("HOME")."/.local/system/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml","/etc/tononixOS/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml",__DIR__."/device-configs/".$this->device_manufacturer."/".$this->device_name.".yml"]);
$kernelBootPartition = \Robo\Robo::Config()->get("device.partition_info.boot").\AndroidDevice::__getBootSlot();
if(!empty($opts['boot-partition'])) $kernelBootPartition = $opts['boot-partition'];
if(!empty($opts['backup-package'])) {
$this->yell("No package specified, cannot proceed.");
die();
}
die("TODO: This function has not been implemented yet...");
}
}