mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-22 11:21:28 +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>
|
2013-07-06 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* EcConsole.m: Strip spaces from command line to avoid a space
|
* 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>
|
@interface EcCommand : EcProcess <Command>
|
||||||
{
|
{
|
||||||
NSString *host;
|
NSString *host;
|
||||||
|
@ -106,6 +135,9 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
||||||
unsigned revSequence;
|
unsigned revSequence;
|
||||||
float nodesFree;
|
float nodesFree;
|
||||||
float spaceFree;
|
float spaceFree;
|
||||||
|
NSTimeInterval uncompressed;
|
||||||
|
NSTimeInterval undeleted;
|
||||||
|
BOOL sweeping;
|
||||||
}
|
}
|
||||||
- (NSFileHandle*) openLog: (NSString*)lname;
|
- (NSFileHandle*) openLog: (NSString*)lname;
|
||||||
- (void) cmdGnip: (id <CmdPing>)from
|
- (void) cmdGnip: (id <CmdPing>)from
|
||||||
|
@ -275,7 +307,27 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
||||||
DESTROY(environment);
|
DESTROY(environment);
|
||||||
if ([d isKindOfClass: [NSDictionary class]] == YES)
|
if ([d isKindOfClass: [NSDictionary class]] == YES)
|
||||||
{
|
{
|
||||||
|
NSMutableDictionary *m;
|
||||||
NSString *k;
|
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"];
|
launchInfo = [d objectForKey: @"Launch"];
|
||||||
if ([launchInfo isKindOfClass: [NSDictionary class]] == NO)
|
if ([launchInfo isKindOfClass: [NSDictionary class]] == NO)
|
||||||
|
@ -1470,6 +1522,8 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
||||||
{
|
{
|
||||||
if (nil != (self = [super initWithDefaults: defs]))
|
if (nil != (self = [super initWithDefaults: defs]))
|
||||||
{
|
{
|
||||||
|
uncompressed = 0.0;
|
||||||
|
undeleted = 0.0;
|
||||||
nodesFree = 0.1;
|
nodesFree = 0.1;
|
||||||
spaceFree = 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.
|
* Tell all our clients to quit, and wait for them to do so.
|
||||||
* If called while already terminating ... force immediate shutdown.
|
* If called while already terminating ... force immediate shutdown.
|
||||||
|
|
|
@ -887,6 +887,10 @@ extern NSString* cmdVersion(NSString *ver);
|
||||||
*/
|
*/
|
||||||
- (void) ecTestLog: (NSString*)fmt, ...;
|
- (void) ecTestLog: (NSString*)fmt, ...;
|
||||||
|
|
||||||
|
/** Returns the directory set as the root for files owned by the ECCL user
|
||||||
|
*/
|
||||||
|
- (NSString*) ecUserDirectory;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface NSObject (RemoteServerDelegate)
|
@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
|
- (void) setCmdDebug: (NSString*)mode withDescription: (NSString*)desc
|
||||||
{
|
{
|
||||||
[cmdDebugKnown setObject: desc forKey: mode];
|
[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
|
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/Control.plist, ~xxx/Data/Command/Operators.plist, and
|
||||||
~xxx/Data/Command/AlertConfig.plist before the Control server will start.
|
~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