mirror of
https://github.com/samsonjs/arq_restore.git
synced 2026-03-25 09:25:53 +00:00
better arq_restore output
This commit is contained in:
parent
cbe20c007e
commit
eb62c99ca2
5 changed files with 131 additions and 30 deletions
|
|
@ -41,6 +41,7 @@
|
|||
#import "Restorer.h"
|
||||
#import "NSErrorCodes.h"
|
||||
#import "NSError_extra.h"
|
||||
#import "UserAndComputer.h"
|
||||
|
||||
@interface ArqRestoreCommand (internal)
|
||||
- (BOOL)printArqFolders:(NSError **)error;
|
||||
|
|
@ -117,42 +118,55 @@
|
|||
if (![self validateS3Keys:error]) {
|
||||
return NO;
|
||||
}
|
||||
NSArray *s3BucketNames = [S3Service s3BucketNamesForAccessKeyID:accessKey];
|
||||
NSMutableArray *computerUUIDPaths = [NSMutableArray array];
|
||||
for (NSString *s3BucketName in s3BucketNames) {
|
||||
for (NSString *s3BucketName in [S3Service s3BucketNamesForAccessKeyID:accessKey]) {
|
||||
printf("S3 bucket: %s", [s3BucketName UTF8String]);
|
||||
NSString *computerUUIDPrefix = [NSString stringWithFormat:@"/%@/", s3BucketName];
|
||||
NSError *myError = nil;
|
||||
NSArray *computerUUIDs = [s3 commonPrefixesForPathPrefix:computerUUIDPrefix delimiter:@"/" error:&myError];
|
||||
if (computerUUIDs == nil) {
|
||||
if ([myError isErrorWithDomain:[S3Service errorDomain] code:ERROR_NOT_FOUND]) {
|
||||
// Skip.
|
||||
} else {
|
||||
if (error != NULL) {
|
||||
*error = myError;
|
||||
}
|
||||
return NO;
|
||||
if (computerUUIDs == nil && ![myError isErrorWithDomain:[S3Service errorDomain] code:ERROR_NOT_FOUND]) {
|
||||
if (error != NULL) {
|
||||
*error = myError;
|
||||
}
|
||||
}
|
||||
for (NSString *computerUUID in computerUUIDs) {
|
||||
[computerUUIDPaths addObject:[computerUUIDPrefix stringByAppendingPathComponent:computerUUID]];
|
||||
}
|
||||
}
|
||||
for (NSString *computerUUIDPath in computerUUIDPaths) {
|
||||
NSString *computerBucketsPrefix = [computerUUIDPath stringByAppendingPathComponent:@"buckets"];
|
||||
NSArray *s3BucketUUIDPaths = [s3 pathsWithPrefix:computerBucketsPrefix error:error];
|
||||
if (s3BucketUUIDPaths == nil) {
|
||||
return NO;
|
||||
}
|
||||
for (NSString *uuidPath in s3BucketUUIDPaths) {
|
||||
NSData *data = [s3 dataAtPath:uuidPath error:error];
|
||||
if (data == nil) {
|
||||
if ([computerUUIDs count] == 0) {
|
||||
printf(" (no computers found)");
|
||||
}
|
||||
printf("\n");
|
||||
for (NSString *computerUUID in computerUUIDs) {
|
||||
NSString *computerInfoPath = [NSString stringWithFormat:@"/%@/%@/computerinfo", s3BucketName, computerUUID];
|
||||
NSError *uacError = nil;
|
||||
NSData *uacData = [s3 dataAtPath:computerInfoPath error:&uacError];
|
||||
UserAndComputer *uac = nil;
|
||||
if (uacData != nil) {
|
||||
uac = [[[UserAndComputer alloc] initWithXMLData:uacData error:&uacError] autorelease];
|
||||
printf(" %s (%s)", [[uac computerName] UTF8String], [[uac userName] UTF8String]);
|
||||
} else {
|
||||
printf(" (unknown computer)");
|
||||
}
|
||||
NSString *computerUUIDPath = [computerUUIDPrefix stringByAppendingPathComponent:computerUUID];
|
||||
NSString *computerBucketsPrefix = [computerUUIDPath stringByAppendingPathComponent:@"buckets"];
|
||||
NSArray *s3BucketUUIDPaths = [s3 pathsWithPrefix:computerBucketsPrefix error:error];
|
||||
if (s3BucketUUIDPaths == nil) {
|
||||
return NO;
|
||||
}
|
||||
DictNode *plist = [DictNode dictNodeWithXMLData:data error:error];
|
||||
if (plist == nil) {
|
||||
return NO;
|
||||
if ([s3BucketUUIDPaths count] == 0) {
|
||||
printf(" (no folders found)");
|
||||
}
|
||||
printf("\n");
|
||||
for (NSString *uuidPath in s3BucketUUIDPaths) {
|
||||
NSData *data = [s3 dataAtPath:uuidPath error:error];
|
||||
if (data == nil) {
|
||||
return NO;
|
||||
}
|
||||
DictNode *plist = [DictNode dictNodeWithXMLData:data error:error];
|
||||
if (plist == nil) {
|
||||
return NO;
|
||||
}
|
||||
printf(" %s\n", [[[plist stringNodeForKey:@"LocalPath"] stringValue] UTF8String]);
|
||||
printf(" UUID: %s\n", [[uuidPath lastPathComponent] UTF8String]);
|
||||
printf(" restore command: arq_restore %s\n", [uuidPath UTF8String]);
|
||||
}
|
||||
printf("s3 path=%s\tlocal path=%s\n", [uuidPath UTF8String], [[[plist stringNodeForKey:@"LocalPath"] stringValue] UTF8String]);
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
|
|
@ -185,6 +199,20 @@
|
|||
NSString *computerUUID = [path substringWithRange:computerUUIDRange];
|
||||
NSString *bucketUUID = [path substringWithRange:bucketUUIDRange];
|
||||
NSString *bucketName = [[plist stringNodeForKey:@"BucketName"] stringValue];
|
||||
|
||||
printf("restoring %s from ", [bucketName UTF8String]);
|
||||
|
||||
NSError *uacError = nil;
|
||||
NSData *uacData = [s3 dataAtPath:[NSString stringWithFormat:@"/%@/%@/computerinfo", s3BucketName, computerUUID] error:&uacError];
|
||||
UserAndComputer *uac = nil;
|
||||
if (uacData != nil) {
|
||||
uac = [[[UserAndComputer alloc] initWithXMLData:uacData error:&uacError] autorelease];
|
||||
printf("%s (%s)", [[uac computerName] UTF8String], [[uac userName] UTF8String]);
|
||||
} else {
|
||||
printf("(unknown computer)");
|
||||
}
|
||||
printf(" to %s/%s\n", [[[NSFileManager defaultManager] currentDirectoryPath] UTF8String], [bucketName UTF8String]);
|
||||
|
||||
Restorer *restorer = [[[Restorer alloc] initWithS3Service:s3 s3BucketName:s3BucketName computerUUID:computerUUID bucketUUID:bucketUUID bucketName:bucketName encryptionKey:encryptionPassword] autorelease];
|
||||
if (![restorer restore:error]) {
|
||||
return NO;
|
||||
|
|
|
|||
20
UserAndComputer.h
Normal file
20
UserAndComputer.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// UserAndComputer.h
|
||||
// Arq
|
||||
//
|
||||
// Created by Stefan Reitshamer on 7/9/10.
|
||||
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface UserAndComputer : NSObject {
|
||||
NSString *userName;
|
||||
NSString *computerName;
|
||||
}
|
||||
- (id)initWithXMLData:(NSData *)theXMLData error:(NSError **)error;
|
||||
- (NSString *)userName;
|
||||
- (NSString *)computerName;
|
||||
- (NSData *)toXMLData;
|
||||
@end
|
||||
47
UserAndComputer.m
Normal file
47
UserAndComputer.m
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// UserAndComputer.m
|
||||
// Arq
|
||||
//
|
||||
// Created by Stefan Reitshamer on 7/9/10.
|
||||
// Copyright 2010 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UserAndComputer.h"
|
||||
#import "DictNode.h"
|
||||
|
||||
@implementation UserAndComputer
|
||||
- (id)initWithXMLData:(NSData *)theXMLData error:(NSError **)error {
|
||||
if (self = [super init]) {
|
||||
DictNode *plist = [DictNode dictNodeWithXMLData:theXMLData error:error];
|
||||
if (plist == nil) {
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
userName = [[[plist stringNodeForKey:@"userName"] stringValue] copy];
|
||||
computerName = [[[plist stringNodeForKey:@"computerName"] stringValue] copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)dealloc {
|
||||
[userName release];
|
||||
[computerName release];
|
||||
[super dealloc];
|
||||
}
|
||||
- (NSString *)userName {
|
||||
return userName;
|
||||
}
|
||||
- (NSString *)computerName {
|
||||
return computerName;
|
||||
}
|
||||
- (NSData *)toXMLData {
|
||||
DictNode *plist = [[[DictNode alloc] init] autorelease];
|
||||
[plist putString:userName forKey:@"userName"];
|
||||
[plist putString:computerName forKey:@"computerName"];
|
||||
return [plist XMLData];
|
||||
}
|
||||
|
||||
#pragma mark NSObject
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<UserAndComputer: userName=%@ computerName=%@>", userName, computerName];
|
||||
}
|
||||
@end
|
||||
|
|
@ -53,7 +53,7 @@ int main (int argc, const char **argv) {
|
|||
} else {
|
||||
NSError *myError = nil;
|
||||
if (![cmd execute:&myError]) {
|
||||
NSLog(@"%@", [myError localizedDescription]);
|
||||
fprintf(stderr, "restore error: %s\n", [[myError localizedDescription] UTF8String]);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@
|
|||
F8F4D5A1121D9FC2002D09C1 /* AppKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = F8F4D1E1121D7BC3002D09C1 /* AppKeychain.m */; };
|
||||
F8F4D5A2121D9FC9002D09C1 /* FarkPath.m in Sources */ = {isa = PBXBuildFile; fileRef = F8F4D1E6121D7DA2002D09C1 /* FarkPath.m */; };
|
||||
F8F4D5A3121D9FCF002D09C1 /* PackIndexWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = F8F4D1FD121D8409002D09C1 /* PackIndexWriter.m */; };
|
||||
F8F4D67E121DA542002D09C1 /* UserAndComputer.m in Sources */ = {isa = PBXBuildFile; fileRef = F8F4D67D121DA542002D09C1 /* UserAndComputer.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
|
@ -438,6 +439,8 @@
|
|||
F8F4D1FD121D8409002D09C1 /* PackIndexWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PackIndexWriter.m; sourceTree = "<group>"; };
|
||||
F8F4D205121D8696002D09C1 /* ArqRepo_Verifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArqRepo_Verifier.h; sourceTree = "<group>"; };
|
||||
F8F4D206121D8696002D09C1 /* ArqRepo_Verifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArqRepo_Verifier.m; sourceTree = "<group>"; };
|
||||
F8F4D67C121DA542002D09C1 /* UserAndComputer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserAndComputer.h; sourceTree = "<group>"; };
|
||||
F8F4D67D121DA542002D09C1 /* UserAndComputer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserAndComputer.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -477,8 +480,6 @@
|
|||
08FB7794FE84155DC02AAC07 /* arq_restore */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8F4D1FC121D8409002D09C1 /* PackIndexWriter.h */,
|
||||
F8F4D1FD121D8409002D09C1 /* PackIndexWriter.m */,
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
|
|
@ -495,6 +496,10 @@
|
|||
F805B8081160E7A1007EC01E /* io */,
|
||||
F805B7C91160E445007EC01E /* http */,
|
||||
F805B7651160DD60007EC01E /* s3 */,
|
||||
F8F4D1FC121D8409002D09C1 /* PackIndexWriter.h */,
|
||||
F8F4D1FD121D8409002D09C1 /* PackIndexWriter.m */,
|
||||
F8F4D67C121DA542002D09C1 /* UserAndComputer.h */,
|
||||
F8F4D67D121DA542002D09C1 /* UserAndComputer.m */,
|
||||
32A70AAB03705E1F00C91783 /* arq_restore_Prefix.pch */,
|
||||
08FB7796FE84155DC02AAC07 /* arq_restore.m */,
|
||||
F8F4D1C1121D79AC002D09C1 /* ArqFark.h */,
|
||||
|
|
@ -915,6 +920,7 @@
|
|||
F8F4D1E7121D7DA2002D09C1 /* FarkPath.m in Sources */,
|
||||
F8F4D1FE121D8409002D09C1 /* PackIndexWriter.m in Sources */,
|
||||
F8F4D207121D8696002D09C1 /* ArqRepo_Verifier.m in Sources */,
|
||||
F8F4D67E121DA542002D09C1 /* UserAndComputer.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue