mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-21 19:01:16 +00:00
compress/delete improvements.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@36879 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0479a99ef8
commit
8192603611
5 changed files with 245 additions and 3 deletions
|
@ -1,3 +1,10 @@
|
|||
2013-07-12 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* EcProcess.h: New method to get EC user directory
|
||||
* EcProcess.m: implement new method
|
||||
* EcCommand.m: Add simple auto compress/delete of logs
|
||||
CompressLogsAfter and DeleteLogsAfter control this.
|
||||
|
||||
2013-07-06 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* EcConsole.m: Strip spaces from command line to avoid a space
|
||||
|
|
228
EcCommand.m
228
EcCommand.m
|
@ -85,7 +85,36 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Special configuration options are:
|
||||
*
|
||||
* CompressLogsAfter
|
||||
* A positive integer number of days after which logs should be compressed
|
||||
* defaults to 14.
|
||||
*
|
||||
* DeleteLogsAfter
|
||||
* A positive integer number of days after which logs should be deleted.
|
||||
* Constrained to be at least as large as CompressLogsAfter.
|
||||
* Defaults to 1000, but logs may still be deleted as if this were set
|
||||
* to CompressLogsAfter if NodesFree or SpaceFree is reached.
|
||||
*
|
||||
* Environment
|
||||
* A dictionary setting the default environment for launched processes.
|
||||
*
|
||||
* Launch
|
||||
* A dictionary describing the processes which the server is responsible
|
||||
* for launching.
|
||||
*
|
||||
* NodesFree
|
||||
* A string giving a percentage of the total nodes on the disk below
|
||||
* which an alert should be raised. Defaults to 10.
|
||||
* Minimum 2, Maximum 90.
|
||||
*
|
||||
* SpaceFree
|
||||
* A string giving a percentage of the total space on the disk below
|
||||
* which an alert should be raised. Defaults to 10.
|
||||
* Minimum 2, Maximum 90.
|
||||
*
|
||||
*/
|
||||
@interface EcCommand : EcProcess <Command>
|
||||
{
|
||||
NSString *host;
|
||||
|
@ -106,6 +135,9 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
unsigned revSequence;
|
||||
float nodesFree;
|
||||
float spaceFree;
|
||||
NSTimeInterval uncompressed;
|
||||
NSTimeInterval undeleted;
|
||||
BOOL sweeping;
|
||||
}
|
||||
- (NSFileHandle*) openLog: (NSString*)lname;
|
||||
- (void) cmdGnip: (id <CmdPing>)from
|
||||
|
@ -275,7 +307,27 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
DESTROY(environment);
|
||||
if ([d isKindOfClass: [NSDictionary class]] == YES)
|
||||
{
|
||||
NSMutableDictionary *m;
|
||||
NSString *k;
|
||||
NSString *err;
|
||||
|
||||
m = [[d mutableCopy] autorelease];
|
||||
d = m;
|
||||
NS_DURING
|
||||
[self cmdUpdate: m];
|
||||
NS_HANDLER
|
||||
[self cmdError: @"Problem before updating config: %@",
|
||||
localException];
|
||||
NS_ENDHANDLER
|
||||
NS_DURING
|
||||
err = [self cmdUpdated];
|
||||
NS_HANDLER
|
||||
err = [localException description];
|
||||
NS_ENDHANDLER
|
||||
if ([err length] > 0)
|
||||
{
|
||||
[self cmdError: @"Problem after updating config: %@", err];
|
||||
}
|
||||
|
||||
launchInfo = [d objectForKey: @"Launch"];
|
||||
if ([launchInfo isKindOfClass: [NSDictionary class]] == NO)
|
||||
|
@ -1470,6 +1522,8 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
{
|
||||
if (nil != (self = [super initWithDefaults: defs]))
|
||||
{
|
||||
uncompressed = 0.0;
|
||||
undeleted = 0.0;
|
||||
nodesFree = 0.1;
|
||||
spaceFree = 0.1;
|
||||
|
||||
|
@ -1991,6 +2045,178 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
}
|
||||
}
|
||||
|
||||
- (void) ecNewHour: (NSCalendarDate*)when
|
||||
{
|
||||
static const NSTimeInterval day = 24.0 * 60.0 * 60.0;
|
||||
NSInteger compressAfter;
|
||||
NSInteger deleteAfter;
|
||||
NSTimeInterval latestCompressAt;
|
||||
NSTimeInterval latestDeleteAt;
|
||||
NSTimeInterval now;
|
||||
NSTimeInterval ti;
|
||||
NSFileManager *mgr;
|
||||
NSString *logs;
|
||||
NSString *file;
|
||||
NSAutoreleasePool *arp;
|
||||
|
||||
if (sweeping == YES)
|
||||
{
|
||||
NSLog(@"Argh - nested sweep attempt");
|
||||
return;
|
||||
}
|
||||
|
||||
sweeping = YES;
|
||||
|
||||
arp = [NSAutoreleasePool new];
|
||||
now = [when timeIntervalSinceReferenceDate];
|
||||
|
||||
logs = [[self ecUserDirectory] stringByAppendingPathComponent: @"Logs"];
|
||||
|
||||
/* get number of days after which to do log compression/deletion.
|
||||
*/
|
||||
compressAfter = [[self cmdDefaults] integerForKey: @"CompressLogsAfter"];
|
||||
if (compressAfter < 1)
|
||||
{
|
||||
compressAfter = 14;
|
||||
}
|
||||
deleteAfter = [[self cmdDefaults] integerForKey: @"DeleteLogsAfter"];
|
||||
if (deleteAfter < 1)
|
||||
{
|
||||
deleteAfter = 1000;
|
||||
}
|
||||
if (deleteAfter < compressAfter)
|
||||
{
|
||||
deleteAfter = compressAfter;
|
||||
}
|
||||
|
||||
mgr = [NSFileManager defaultManager];
|
||||
|
||||
if (0.0 == undeleted)
|
||||
{
|
||||
undeleted = now - 365.0 * day;
|
||||
}
|
||||
ti = undeleted;
|
||||
latestDeleteAt = now - day * deleteAfter;
|
||||
while (ti < latestDeleteAt)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
|
||||
when = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: ti];
|
||||
file = [[logs stringByAppendingPathComponent:
|
||||
[when descriptionWithCalendarFormat: @"%Y-%m-%d"]]
|
||||
stringByStandardizingPath];
|
||||
if ([mgr fileExistsAtPath: file])
|
||||
{
|
||||
[mgr removeFileAtPath: file handler: nil];
|
||||
}
|
||||
ti += day;
|
||||
[pool release];
|
||||
}
|
||||
undeleted = ti;
|
||||
|
||||
if (uncompressed < undeleted)
|
||||
{
|
||||
uncompressed = undeleted;
|
||||
}
|
||||
ti = uncompressed;
|
||||
latestCompressAt = now - day * compressAfter;
|
||||
while (ti < latestCompressAt)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSDirectoryEnumerator *enumerator;
|
||||
BOOL isDirectory;
|
||||
NSString *base;
|
||||
|
||||
when = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: ti];
|
||||
base = [[logs stringByAppendingPathComponent:
|
||||
[when descriptionWithCalendarFormat: @"%Y-%m-%d"]]
|
||||
stringByStandardizingPath];
|
||||
if ([mgr fileExistsAtPath: base isDirectory: &isDirectory] == NO
|
||||
|| NO == isDirectory)
|
||||
{
|
||||
continue; // No log directory for this date.
|
||||
}
|
||||
|
||||
enumerator = [mgr enumeratorAtPath: base];
|
||||
while ((file = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSString *src;
|
||||
NSString *dst;
|
||||
NSFileHandle *sh;
|
||||
NSFileHandle *dh;
|
||||
NSDictionary *a;
|
||||
NSData *d;
|
||||
|
||||
if (YES == [[file pathExtension] isEqualToString: @"gz"])
|
||||
{
|
||||
continue; // Already compressed
|
||||
}
|
||||
a = [enumerator fileAttributes];
|
||||
if (NSFileTypeRegular != [a fileType])
|
||||
{
|
||||
continue; // Not a regular file ... can't compress
|
||||
}
|
||||
|
||||
src = [base stringByAppendingPathComponent: file];
|
||||
|
||||
if ([a fileSize] == 0)
|
||||
{
|
||||
[mgr removeFileAtPath: src handler: nil];
|
||||
continue; // Nothing to compress
|
||||
}
|
||||
|
||||
dst = [src stringByAppendingPathExtension: @"gz"];
|
||||
if ([mgr fileExistsAtPath: dst isDirectory: &isDirectory] == YES)
|
||||
{
|
||||
[mgr removeFileAtPath: dst handler: nil];
|
||||
}
|
||||
|
||||
[mgr createFileAtPath: dst contents: nil attributes: nil];
|
||||
dh = [NSFileHandle fileHandleForWritingAtPath: dst];
|
||||
if (NO == [dh useCompression])
|
||||
{
|
||||
[dh closeFile];
|
||||
[mgr removeFileAtPath: dst handler: nil];
|
||||
[self cmdError: @"Unable to compress %@ to %@", src, dst];
|
||||
continue;
|
||||
}
|
||||
|
||||
sh = nil;
|
||||
NS_DURING
|
||||
{
|
||||
NSAutoreleasePool *inner;
|
||||
|
||||
sh = [NSFileHandle fileHandleForReadingAtPath: src];
|
||||
inner = [NSAutoreleasePool new];
|
||||
while ([(d = [sh readDataOfLength: 1000000]) length] > 0)
|
||||
{
|
||||
[dh writeData: d];
|
||||
[inner release];
|
||||
inner = [NSAutoreleasePool new];
|
||||
}
|
||||
[inner release];
|
||||
[sh closeFile];
|
||||
[dh closeFile];
|
||||
[mgr removeFileAtPath: src handler: nil];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
[mgr removeFileAtPath: dst handler: nil];
|
||||
[sh closeFile];
|
||||
[dh closeFile];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
ti += day;
|
||||
[pool release];
|
||||
}
|
||||
uncompressed = ti;
|
||||
|
||||
DESTROY(arp);
|
||||
sweeping = NO;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell all our clients to quit, and wait for them to do so.
|
||||
* If called while already terminating ... force immediate shutdown.
|
||||
|
|
|
@ -887,6 +887,10 @@ extern NSString* cmdVersion(NSString *ver);
|
|||
*/
|
||||
- (void) ecTestLog: (NSString*)fmt, ...;
|
||||
|
||||
/** Returns the directory set as the root for files owned by the ECCL user
|
||||
*/
|
||||
- (NSString*) ecUserDirectory;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSObject (RemoteServerDelegate)
|
||||
|
|
|
@ -2185,6 +2185,11 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString*) ecUserDirectory
|
||||
{
|
||||
return cmdUserDir();
|
||||
}
|
||||
|
||||
- (void) setCmdDebug: (NSString*)mode withDescription: (NSString*)desc
|
||||
{
|
||||
[cmdDebugKnown setObject: desc forKey: mode];
|
||||
|
|
2
README
2
README
|
@ -21,5 +21,5 @@ where 'xxx' is your username, to tell the system it should be running as you.
|
|||
3. Configuration is in ~xxx/Data. Specifically, you need to configure
|
||||
~xxx/Data/Command/Control.plist, ~xxx/Data/Command/Operators.plist, and
|
||||
~xxx/Data/Command/AlertConfig.plist before the Control server will start.
|
||||
There are examples in thee same directory as this README
|
||||
There are examples in the same directory as this README
|
||||
|
||||
|
|
Loading…
Reference in a new issue