Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Remove old kernel versions, by keeping only the active one and the latest one
#!/usr/bin/php
<?php
try {
$doEcho = true;
$action = 'view';
if(isset($argv) && is_array($argv) && (count($argv) == 2)) {
$action = strtolower($argv[1]);
switch($action) {
case 'view':
case 'simulate':
case 'batch':
break;
case 'get-command':
$doEcho = false;
break;
case 'h':
case '-h':
case 'help':
case '--help':
echo "{$argv[0]} [view|simulate|get-command|batch]\n";
die(0);
default:
throw new Exception("Unknown option: $action\nSyntax:\n{$argv[0]} [view|simulate|get-command|batch]");
}
}
$rxVersion = '(\\d[\\d\\-\\.]+\\d)(-[a-z][a-z0-9]*)?';
$currentVersion = launch('uname -r 2>&1');
if(!preg_match('/^' . $rxVersion . '$/i', $currentVersion)) {
throw new Exception("Currently active kernel version not recognized: $currentVersion");
}
if($doEcho) {
echo "Current version : $currentVersion\n";
}
$installedVersions = array();
$files = @scandir('/boot');
if((!is_array($files)) || empty($files)) {
throw new Exception("Unable to retrieve the contents of the /boot folder");
}
$prefixes = array('System.map-', 'config-', 'initrd.img-', 'vmlinuz-');
foreach($files as $file) {
if(!is_file("/boot/$file")) {
continue;
}
$ok = false;
foreach($prefixes as $p) {
if(strpos($file, $p) === 0) {
$v = substr($file, strlen($p));
if(!preg_match('/^' . $rxVersion . '$/i', $v)) {
throw new Exception("Installed active kernel version not recognized: $v (file: $file)");
}
if(!in_array($v, $installedVersions, true)) {
$installedVersions[] = $v;
}
break;
}
}
}
if(empty($installedVersions)) {
throw new Exception('No installed kernel versions found');
}
usort($installedVersions, 'version_compare');
if($doEcho) {
echo "Installed versions: ", implode(', ', $installedVersions), "\n";
}
if(!in_array($currentVersion, $installedVersions, true)) {
throw new Exception('The current version is not in the installed versions found');
}
$latestVersion = $installedVersions[count($installedVersions) - 1];
if($doEcho) {
echo "Latest version : $latestVersion\n";
}
$versionsToRemove = array();
foreach($installedVersions as $installedVersion) {
switch($installedVersion) {
case $currentVersion:
case $latestVersion:
break;
default:
$versionsToRemove[] = $installedVersion;
break;
}
}
if($doEcho) {
echo "Versions to remove: ", empty($versionsToRemove) ? 'none' :implode(', ', $versionsToRemove) , "\n";
}
if(($action === 'view') || empty($versionsToRemove)) {
return;
}
$cmd = 'remove --purge ';
foreach($versionsToRemove as $versionToRemove) {
foreach(array('linux-headers-', 'linux-image-') as $prefix) {
if(preg_match('/(\\d[\\d\\-\\.]+\\d)-[a-z]+[a-z][0-9]*$/', $versionToRemove, $match)) {
$cmd .= " $prefix{$match[1]} $prefix{$match[1]}-*";
}
else {
$cmd .= " $prefix$versionToRemove";
}
}
}
switch($action) {
case 'simulate':
$cmd = "apt-get --simulate $cmd";
$rc = null;
system($cmd, $rc);
if($rc !== 0) {
throw new Exception("Command failed:\n$cmd");
}
break;
case 'get-command':
$cmd = "apt-get $cmd";
echo $cmd, "\n";
break;
case 'batch':
$cmd = "apt-get --quiet --assume-yes --force-yes $cmd";
echo "Executing command:\n$cmd\n";
system($cmd, $rc);
if($rc !== 0) {
throw new Exception("Command failed!");
}
break;
}
die(0);
}
catch(Exception $x) {
$msg = trim($x->getMessage()) . "\n";
$hStdErr = @fopen('php://stderr', 'w');
if($hStdErr === false) {
echo $msg;
}
else {
fwrite($hStdErr, $msg);
fclose($hStdErr);
}
$rc = $x->getCode();
die($rc ? $rc : 1);
}
function launch($command) {
$output = array();
$rc = null;
@exec($command, $output, $rc);
$output = is_array($output) ? implode("\n", $output) : '';
if($rc !== 0) {
throw new Exception("Command failed with return code $rc:\n$command" . (strlen($output) ? "\n$output" : ''));
}
return $output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment