Skip to content

Instantly share code, notes, and snippets.

@albancrommer
Created July 19, 2016 13:33
Show Gist options
  • Save albancrommer/f91cea51381b84390c2c662020286b7a to your computer and use it in GitHub Desktop.
Save albancrommer/f91cea51381b84390c2c662020286b7a to your computer and use it in GitHub Desktop.
<?php
/**
*
* This script extracts the most recent packages updates from a debian server
* by parsing the /var/log/apt/history.log file.
* It creates a new log file whose location can be provided as a shell parameter
*
*/
#### ####
## UTILITIES #
#### ####
/**
* Simple version number extractor
* @param $version_string string
* @return array
**/
function versionStruct( $version_string ){
preg_match("/(\d+)\.(\d+)\.(.*)/",$version_string,$matches);
$return = array();
$return["major"] = $matches[1];
$return["minor"] = $matches[2];
$return["details"] = $matches[3];
return $return;
}
/**
* Simple panic function
*/
function panic( $message ){
echo $message;
exit(1);
}
#### #####
# BUSINESS LOGIC #
#### #####
// It should attempt to read the history file
$logFile= file("/var/log/apt/history.log");
if( ! $logFile ) {
panic( "No result" );
}
// It should attempt to find a valid upgrade log line
$line_count = count( $logFile ) ;
for( $i = $line_count - 1; $i > $line_count - 5 ; $i-- ){
$res = strpos( $logFile[$i], "Upgrade:" );
if( strpos( $logFile[$i], "Upgrade:" ) !== FALSE ){
$line= $logFile[$i];
break;
}
}
if( ! isset($line) ){
panic ("Broken file, could not find an upgrade line");
}
$result = array();
// It should read package name, old, new version occurences
preg_match_all("/ (\S+) \((\S+), (\S+)\),/",$line,$matches);
// It should store packages infos
foreach( $matches[1] as $index => $package ){
$before = $matches[2][$index];
$after = $matches[3][$index];
// It should detect important version changes
$beforeStruct = versionStruct( $before );
$afterStruct = versionStruct( $after );
$packageInfo = array( "before" => $before, "after" => $after );
if( $beforeStruct["major"] != $afterStruct["major"]
|| $beforeStruct["minor"] != $afterStruct["minor"]
){
$packageInfo["notify"] = true;
}
$result[ $package ] = $packageInfo;
}
$output_file = count( $argv ) > 1 ? $argv[1] : "/infra/data/packages/".gethostname()."/".date("Ymd-His").".json";
$output_dir = dirname( $output_file);
if( ! is_dir( $output_dir ) ) {
if( ! mkdir( $output_dir, true ) ) {
panic( "failed to create $output_dir");
}
}
if( ! touch ( $output_file ) ){
panic ( "failed to create $output_file");
}
if( ! file_put_contents( $output_file, json_encode($result)) ){
panic ( "failed to copy content to $output_file");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment