From 7f46a637f50f774f56d027d9eef6842566a52be9 Mon Sep 17 00:00:00 2001 From: Scott Date: Mon, 1 Nov 2021 18:56:40 +1100 Subject: [PATCH] wip --- src/agent/agentService.ts | 5 ++- src/vaults/VaultInternal.ts | 32 +++++++++------- src/vaults/VaultManager.ts | 61 +++++++++++++++++++++++++++++++ tests/vaults/VaultManager.test.ts | 9 +++-- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/agent/agentService.ts b/src/agent/agentService.ts index 81eefb8468..a021c706b8 100644 --- a/src/agent/agentService.ts +++ b/src/agent/agentService.ts @@ -75,7 +75,8 @@ function createAgentService({ vaultId = makeVaultId(idUtils.fromString(vaultNameOrId)); vaultName = await vaultManager.getVaultName(vaultId); } catch (err) { - throw new vaultsErrors.ErrorVaultUndefined(); + await genWritable.throw(new vaultsErrors.ErrorVaultUndefined()); + return; } } else { vaultName = vaultNameOrId; @@ -141,7 +142,7 @@ function createAgentService({ try { vaultId = makeVaultId(vaultNameOrId); } catch (err) { - throw new vaultsErrors.ErrorVaultUndefined(); + return; } } await vaultManager.openVault(vaultId); diff --git a/src/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index 0a0e938fbd..ff640e6131 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -51,6 +51,9 @@ class VaultInternal { const dir = path.join(vaultsUtils.makeVaultIdPretty(vaultId), 'contents'); const gitdir = path.join(vaultsUtils.makeVaultIdPretty(vaultId), '.git'); if (fresh) { + logger.info( + `Initialising Vault '${vaultsUtils.makeVaultIdPretty(vaultId)}'`, + ); try { await efs.rmdir(vaultsUtils.makeVaultIdPretty(vaultId), { recursive: true, @@ -92,12 +95,9 @@ class VaultInternal { workingDir, logger, }); - logger.info( - `Initialising vault at '${vaultsUtils.makeVaultIdPretty(vaultId)}'`, - ); return vault; } else { - // Loading an existing vault. + logger.info(`Starting Vault '${vaultsUtils.makeVaultIdPretty(vaultId)}'`); const efsVault = await efs.chroot(dir); await efsVault.start(); const workingDir = (await efs.readFile(path.join(gitdir, 'workingDir'), { @@ -111,9 +111,6 @@ class VaultInternal { workingDir, logger, }); - logger.info( - `Starting vault at '${vaultsUtils.makeVaultIdPretty(vaultId)}'`, - ); return vault; } } @@ -149,6 +146,9 @@ class VaultInternal { public async destroy(): Promise { const release = await this.lock.acquire(); + this.logger.info( + `Destroying Vault '${vaultsUtils.makeVaultIdPretty(this.vaultId)}'`, + ); try { await this.efsRoot.writeFile( path.join( @@ -161,9 +161,6 @@ class VaultInternal { } finally { release(); } - this.logger.info( - `Destroying vault at '${vaultsUtils.makeVaultIdPretty(this.vaultId)}'`, - ); } @ready(new vaultsErrors.ErrorVaultDestroyed()) @@ -230,6 +227,11 @@ class VaultInternal { } } if (message.length !== 0) { + this.logger.info( + `Committing to Vault '${vaultsUtils.makeVaultIdPretty( + this.vaultId, + )}'`, + ); this.workingDir = await git.commit({ fs: this.efsRoot, dir: this.baseDir, @@ -299,7 +301,8 @@ class VaultInternal { return { oid: readCommit.oid, committer: readCommit.commit.committer.name, - timeStamp: readCommit.commit.committer.timestamp * 1000, // Needs to be in milliseconds for Date. + // Needs to be in milliseconds for Date + timeStamp: readCommit.commit.committer.timestamp * 1000, message: readCommit.commit.message, }; }); @@ -307,11 +310,14 @@ class VaultInternal { @ready(new vaultsErrors.ErrorVaultDestroyed()) public async version(commit: string): Promise { - // Checking for special tags. + // Checking for special tags const commit_ = commit.toLowerCase() === lastTag ? 'HEAD' : commit; - // TODO: add a tag for the start of the histoy so we can use that as the operator. + // TODO: add a tag for the start of the histoy so we can use that as the operator try { + this.logger.info( + `Checking out Vault '${vaultsUtils.makeVaultIdPretty(this.vaultId)}'`, + ); await git.checkout({ fs: this.efsRoot, dir: this.baseDir, diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index 018e339b3a..05a96beaa8 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -226,6 +226,9 @@ class VaultManager { const lock = new Mutex(); this.vaultsMap.set(idUtils.toString(vaultId), { lock }); return await this._transaction(async () => { + this.logger.info( + `Storing metadata for Vault ${vaultsUtils.makeVaultIdPretty(vaultId)}`, + ); await this.db.put(this.vaultsNamesDbDomain, idUtils.toBuffer(vaultId), { name: vaultName, }); @@ -243,6 +246,9 @@ class VaultManager { @ready(new vaultsErrors.ErrorVaultManagerDestroyed()) public async destroyVault(vaultId: VaultId) { + this.logger.info( + `Destroying Vault ${vaultsUtils.makeVaultIdPretty(vaultId)}`, + ); await this._transaction(async () => { const vaultName = await this.getVaultName(vaultId); if (!vaultName) return; @@ -287,6 +293,9 @@ class VaultManager { vaultId: VaultId, newVaultName: VaultName, ): Promise { + this.logger.info( + `Renaming Vault ${vaultsUtils.makeVaultIdPretty(vaultId)}`, + ); await this._transaction(async () => { const meta = await this.db.get( this.vaultsNamesDbDomain, @@ -363,6 +372,11 @@ class VaultManager { const vaultId = await this.generateVaultId(); const lock = new Mutex(); this.vaultsMap.set(idUtils.toString(vaultId), { lock }); + this.logger.info( + `Cloning Vault ${vaultsUtils.makeVaultIdPretty( + vaultId, + )} on Node ${nodeId}`, + ); return await this._transaction(async () => { await this.efs.mkdir( path.join(vaultsUtils.makeVaultIdPretty(vaultId), 'contents'), @@ -405,6 +419,8 @@ class VaultManager { } }); // The polykey error is caught and the error flag set + // If there was an error, we return an empty generator so + // isomorphic git does not complain about an undefined res body try { for await (const resp of response) { yield resp.getChunk_asU8(); @@ -412,6 +428,18 @@ class VaultManager { } catch (err) { error = err; throw err; + } finally { + if (error) { + // eslint-disable-next-line + return { + url: url, + method: method, + body: [], + headers: headers, + statusCode: 400, + statusMessage: 'Server Error', + }; + } } }, }; @@ -513,6 +541,11 @@ class VaultManager { defaultPullNode: nodeId, defaultPullVault: idUtils.toString(remoteVaultId), }); + this.logger.info( + `Cloned Vault ${vaultsUtils.makeVaultIdPretty( + vaultId, + )} on Node ${nodeId}`, + ); return vault; }, [vaultId]); } @@ -557,6 +590,13 @@ class VaultManager { vaultMeta.defaultPullVault = idUtils.toString(pullVaultNameOrId); } } + this.logger.info( + `Pulling Vault ${vaultsUtils.makeVaultIdPretty( + pullVaultNameOrId, + )} on Node ${pullNodeId} into Vault ${vaultsUtils.makeVaultIdPretty( + vaultId, + )}`, + ); const nodeConnection = await this.nodeManager.getConnectionToNode( pullNodeId!, ); @@ -594,6 +634,8 @@ class VaultManager { } }); // The polykey error is caught and the error flag set + // If there was an error, we return an empty generator so + // isomorphic git does not complain about an undefined res body try { for await (const resp of response) { yield resp.getChunk_asU8(); @@ -601,6 +643,18 @@ class VaultManager { } catch (err) { error = err; throw err; + } finally { + if (error) { + // eslint-disable-next-line + return { + url: url, + method: method, + body: [], + headers: headers, + statusCode: 400, + statusMessage: 'Server Error', + }; + } } }, }; @@ -689,6 +743,13 @@ class VaultManager { } const vault = await this.getVault(vaultId); await vault.readWorkingDirectory(); + this.logger.info( + `Pulling Vault ${vaultsUtils.makeVaultIdPretty( + pullVaultNameOrId, + )} on Node ${pullNodeId} into Vault ${vaultsUtils.makeVaultIdPretty( + vaultId, + )}`, + ); return vault; }, [vaultId]); } diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index cb10cb5f4e..ee3786af87 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -7,6 +7,7 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { utils as idUtils } from '@matrixai/id'; import { KeyManager } from '@/keys'; import { NodeManager } from '@/nodes'; @@ -24,7 +25,6 @@ import { IAgentServer } from '@/proto/js/Agent_grpc_pb'; import { errors as vaultErrors } from '@/vaults'; import { makeCrypto } from '../utils'; import { makeVaultId } from '@/vaults/utils'; -import { utils as idUtils } from '@matrixai/id'; describe('VaultManager', () => { const password = 'password'; @@ -776,6 +776,9 @@ describe('VaultManager', () => { firstVault.vaultId, nodeManager.getNodeId(), ); + await expect(() => + vaultManager.cloneVault(targetNodeId, 'not-existing' as VaultName), + ).rejects.toThrow(vaultErrors.ErrorVaultUndefined); await vaultManager.cloneVault(targetNodeId, vaultName); const vaultId = await vaultManager.getVaultId(vaultName); const vaultClone = await vaultManager.openVault(vaultId!); @@ -837,7 +840,7 @@ describe('VaultManager', () => { names.sort(), ); }, - global.defaultTimeout * 3, + global.defaultTimeout * 4, ); test( 'reject cloning and pulling when permissions are not set', @@ -994,7 +997,7 @@ describe('VaultManager', () => { names.sort(), ); }, - global.defaultTimeout * 3, + global.defaultTimeout * 5, ); test( 'manage pulling from different remotes',