Last active
August 29, 2015 14:03
-
-
Save mlocati/2eb1663f1d16f22c1715 to your computer and use it in GitHub Desktop.
Remove old kernel versions, by keeping only the active one and the latest one
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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