Subversion Repositories computer_asset_manager_v1

Rev

Rev 23 | Rev 25 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
23 rodolico 1
<?php
2
 
3
/*
4
 * Requires php-pear and libyaml under Debian Wheezy
5
 *
6
 * apt-get install php-pear php5-dev libyaml-dev libyaml-0-2 libyaml-0-2-dbg
7
 * pecl install yaml
8
 * echo 'extension=yaml.so' >> /etc/php5/cli/php.ini
9
 * echo 'extension=yaml.so' >> /etc/apache2/cli/php.ini
10
 * 
24 rodolico 11
 * alter table backups_run add skipped bigint(20),add file_name varchar(60),add notes text;
12
 * alter table backups_run modify end_time  datetime null, modify start_time datetime null;
23 rodolico 13
 * 
14
*/
15
 
16
require 'library.php';
24 rodolico 17
$VERSION='0.1.0';
23 rodolico 18
 
24 rodolico 19
$results = array();
23 rodolico 20
 
24 rodolico 21
function parseFile( $filename, $path, $maxLineLength = 4096 ) {
22
   $data = array ( 
23
                     'server_name' => '',
24
                     'report_date' => '',
25
                     'start_time' => '',
26
                     'version' => '',
27
                     'end_time' => '',
28
                     'files_count' => '',
29
                     'files_size' => '',
30
                     'transferred_count' => 0,
31
                     'transferred_size' => '',
32
                     'files_deleted' => 0,
33
                     'skipped' => 0,
34
                     'data_sent' => '',
35
                     'data_received' => '',
36
                     'disk_used' => '',
37
                     'notes' => '',
38
   );
23 rodolico 39
 
40
   /*
24 rodolico 41
    * This will return error codes
42
    * 1 - Invalid Data File Name
43
    * 2 - Could not open the file
23 rodolico 44
    */
45
 
24 rodolico 46
   $matches = array();
23 rodolico 47
 
24 rodolico 48
   $line;
23 rodolico 49
 
24 rodolico 50
   $data['file_name'] = $filename;
51
   # get server name from the file name, which should be
52
   # datetime_servername.backup.log
53
   if ( preg_match( '/(\d+)_([a-z0-9-.]+)\.backup\.log/', $filename, $matches ) ) {
54
      $data['report_date'] = $matches[1];
55
      $data['server_name'] = $matches[2];
56
   } else {
57
      # ensure only three parts returned
58
      $data['error'] = "1\tInvalid Data File Name";
59
      return $data;
23 rodolico 60
   }
61
 
24 rodolico 62
   $log = fopen ( $path . '/' . $filename , 'rb' );
63
   if ( $log ) {
64
      // get through the header lines
65
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
66
         if ( preg_match( '/^backup\s+v?([\d.]+)$/', $line, $matches ) ) {
67
            $data['version'] = $matches[1];
68
         }
69
         // this line is the end of the header lines
70
         if ( preg_match( '/sending incremental file list/', $line, $matches ) ) {
71
            break;
72
         }
23 rodolico 73
      }
74
 
24 rodolico 75
      // count line by line processing information. These are the actual lines
76
      // indicating files checked and how they were processed
77
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
78
         $line = rtrim($line);
79
         if ( $line ) {
80
            if ( ! preg_match( '~/$~', $line ) ) // count lines not ending in /, ie not directories
81
               $data['transferred_count']++;
82
            if ( preg_match( '/^deleting /', $line ) ) // count number deleted
83
               $data['files_deleted']++;
84
            if ( preg_match( '/^skipping /', $line ) )  // count number skipped
85
               $data['skipped']++ ;
86
         } else {
87
            break;
88
         }
23 rodolico 89
      }
24 rodolico 90
      $data['transferred_count'] -= $data['files_deleted'] + $data['skipped'];
23 rodolico 91
 
24 rodolico 92
      // we should have a stats summary at the end
93
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
94
         $data['notes'] .= $line; // everything here goes into notes
95
         if ( preg_match( '/Number of files:\s+(\d+)/', $line, $matches ) ) {
96
            $data['files_count'] = $matches[1];
97
         } elseif ( preg_match( '/Number of files transferred:\s+(\d+)/', $line, $matches ) ) {
98
            $data['transferred_count'] = $matches[1];
99
         } elseif ( preg_match( '/Total file size:\s+(\d+) bytes/', $line, $matches )  ) {
100
            $data['files_size'] = $matches[1];
101
         } elseif ( preg_match( '/Total transferred file size:\s+(\d+) bytes/', $line, $matches )  ) {
102
            $data['transferred_size'] = $matches[1];
103
         } elseif ( preg_match( '/Total bytes sent:\s+(\d+)/', $line, $matches )  ) {
104
            $data['data_sent'] = $matches[1];
105
         } elseif ( preg_match( '/Total bytes received:\s+(\d+)/', $line, $matches )  ) {
106
            $data['data_received'] = $matches[1];
107
         } elseif ( preg_match( '/Backup Version\s+v?([\d.]+)/', $line, $matches )  ) {
108
            // this is the end of the rsync stats summary, and the
109
            // beginning of the rsbackup summary
110
            $data['version'] = $matches[1];
111
            break;
112
         }
23 rodolico 113
      }
114
 
24 rodolico 115
      // process rsbackup summary
116
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
117
         $data['notes'] .= $line;
118
         if ( preg_match( '/^Begin\s+(\d+)/', $line, $matches )   ) {
119
            $data['start_time'] = $matches[1];
120
         } elseif ( preg_match( '/Complete\s+(\d+)/', $line, $matches )   ) {
121
            $data['end_time'] = $matches[1];
122
         } elseif ( preg_match( '/^Status:/', $line, $matches )   ) {
123
            break;
23 rodolico 124
         }
125
      }
24 rodolico 126
      // the rest of it just goes into notes
127
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
128
         $data['notes'] .= $line;
23 rodolico 129
      }
24 rodolico 130
      fclose ( $log );
131
   } else {
132
      $data['error'] = "2\tCould not open file name $filename for read";
23 rodolico 133
   }
24 rodolico 134
   return $data;
23 rodolico 135
 
24 rodolico 136
}
23 rodolico 137
 
138
 
24 rodolico 139
function recordMessage( $message ) {
140
   global $results;
141
   $results[] = $message;
142
}
23 rodolico 143
 
144
 
24 rodolico 145
/* 
146
 * checks for a duplicate report, ie one that has already been run.
147
 * if this computer has a report already for this date/time
148
 */ 
149
function checkDuplicate( $backups_id, $report_date) {
150
   $sql = "select count(*) from backups_run where backups_id = $backups_id and report_date = $report_date";
151
   $count = getOneDBValue( $sql );
152
   return $count ? "3\tDuplicate Report for $backups_id on $report_date" : null;
153
} // recordReport
23 rodolico 154
 
155
 
24 rodolico 156
function findServer( $name ) {
157
   $sql = "select distinct( device_id ) from (select device_id from device where name = '$name' union select device_id from device_alias where alias = '$name') a";
158
   $device_id = getOneDBValue( $sql );
159
   if ( ! isset( $device_id ) ) {
160
      recordMessage( "Could not locate device $name, not processing record" );
161
      return null;
23 rodolico 162
   }
24 rodolico 163
   $sql = "select backups_id from backups where device_id = $device_id";
164
   $backups_id = getOneDBValue( $sql );
165
   if ( isset( $backups_id ) ) {
166
      return $backups_id;
167
   } else {
168
      recordMessage( "Adding server $name to backups" );
169
      $sql = "insert into backups ( device_id,backups_server_id,notes ) values ( $device_id, 1, 'Automatically Added' )";
170
      $results = queryDatabaseExtended( $sql );
171
      return $results['insert_id'];
172
   }
173
}
23 rodolico 174
 
175
 
24 rodolico 176
/* 
177
 * Creates an entry in the backups_run table
178
 */ 
179
function recordReport( $report ) {
180
 
181
   $keys = array();
182
   $values = array();
183
 
184
   foreach ( $report as $keyfield => $value ) {
185
      if ( $keyfield == 'server_name' ) {
186
         $keys[] = 'backups_id';
187
         $device_id = findServer( $value );
188
         if ( isset( $device_id ) ) {
189
            $values[] = $device_id;
190
            $duplicate = checkDuplicate( $device_id, $report['report_date'] );
191
            if ( $duplicate )
192
               return $report['file_name'] . "\t$duplicate";
193
         } else {
194
            return $report['file_name'] . "\t4\tServer not found";
23 rodolico 195
         }
24 rodolico 196
      } else {
197
         $keys[] = $keyfield;
198
         $values[] = makeSafeSQLValue( $value );
23 rodolico 199
      }
24 rodolico 200
   }
201
   $sql = 'insert into backups_run (' . implode( ',', $keys ) . ') values (' . implode( ',', $values ) . ')';
202
   // if we made it this far, we are ok, so just add the report id
203
   $result = queryDatabaseExtended( $sql );
204
   return $report['file_name'] . "\t0\tok";
205
} // recordReport
23 rodolico 206
 
207
 
208
/*
209
 * we don't know where the configuration file will be, so we have a list
210
 * below (searchPaths) to look for it. It will load the first one it 
211
 * finds, then exit. THUS, you could have multiple configuration files
212
 * but only the first one in the list will be used
213
 */
214
 
24 rodolico 215
$confFileName = "rsbackupRead.conf.yaml";
216
$searchPaths = array( '/etc/camp', '/opt/camp', '/opt/camp/rsbackup', $_SERVER['SCRIPT_FILENAME'], getcwd() );
23 rodolico 217
$configuration = array();
218
foreach ( $searchPaths as $path ) {
219
   if ( file_exists( "$path/$confFileName" ) ) {
220
      $configuration = yaml_parse_file( "$path/$confFileName" );
221
      break; // exit out of the loop; we don't try to load it more than once
222
   } // if
223
} // foreach
224
 
24 rodolico 225
 
23 rodolico 226
mysql_connect( $configuration['database']['databaseServer'], $configuration['database']['databaseUsername'], $configuration['database']['databasePassword'] ) or die(mysql_error());
227
mysql_select_db( $configuration['database']['database'] ) or die(mysql_error());
228
 
229
 
230
 
24 rodolico 231
for ( $i = 1 ; $i < count( $argv ); $i++ ) {
232
   $filename = $argv[$i];
233
   $report = parseFile( $filename, $configuration['datapath'] . '/' . $configuration['unprocessed_path'] );
234
   if ( isset( $report['error'] ) ) { // we had an error processing the report
235
      $result[] = "$filename\t" . $report['error'];
236
   } else {
237
      $result[] = recordReport( $report );
238
   }
23 rodolico 239
}
240
 
24 rodolico 241
print implode( "\n", $result );
242
 
23 rodolico 243
?>