Skip to content

Commit

Permalink
agent restart command
Browse files Browse the repository at this point in the history
  • Loading branch information
emmacasolin committed Feb 25, 2022
1 parent 0f4b260 commit 8c25f3f
Show file tree
Hide file tree
Showing 12 changed files with 550 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/PolykeyAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,25 @@ class PolykeyAgent {
this.logger.info(`Destroyed ${this.constructor.name}`);
}

public async restart({
password,
networkConfig = {},
fresh = false,
}: {
password: string;
networkConfig?: NetworkConfig;
fresh?: boolean;
}) {
this.logger.info(`Restarting ${this.constructor.name}`);
await this.stop();
await this.start({
password,
networkConfig,
fresh,
});
this.logger.info(`Restarted ${this.constructor.name}`);
}

public setWorkerManager(workerManager: PolykeyWorkerManagerInterface) {
this.db.setWorkerManager(workerManager);
this.keyManager.setWorkerManager(workerManager);
Expand Down
2 changes: 2 additions & 0 deletions src/bin/agent/CommandAgent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import CommandLock from './CommandLock';
import CommandLockAll from './CommandLockAll';
import CommandRestart from './CommandRestart';
import CommandStart from './CommandStart';
import CommandStatus from './CommandStatus';
import CommandStop from './CommandStop';
Expand All @@ -13,6 +14,7 @@ class CommandAgent extends CommandPolykey {
this.description('Agent Operations');
this.addCommand(new CommandLock(...args));
this.addCommand(new CommandLockAll(...args));
this.addCommand(new CommandRestart(...args));
this.addCommand(new CommandStart(...args));
this.addCommand(new CommandStatus(...args));
this.addCommand(new CommandStop(...args));
Expand Down
86 changes: 86 additions & 0 deletions src/bin/agent/CommandRestart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type PolykeyClient from '../../PolykeyClient';
import CommandPolykey from '../CommandPolykey';
import * as binUtils from '../utils';
import * as binOptions from '../utils/options';
import * as binProcessors from '../utils/processors';
import * as binErrors from '../errors';
import config from '../../config';

class CommandRestart extends CommandPolykey {
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
super(...args);
this.name('restart');
this.description('Restart the Polykey Agent');
this.addOption(binOptions.nodeId);
this.addOption(binOptions.clientHost);
this.addOption(binOptions.clientPort);
this.addOption(binOptions.ingressHost);
this.addOption(binOptions.ingressPort);
this.addOption(binOptions.fresh);
this.action(async (options) => {
const { default: PolykeyClient } = await import('../../PolykeyClient');
const agentPB = await import('../../proto/js/polykey/v1/agent/agent_pb');
const clientStatus = await binProcessors.processClientStatus(
options.nodePath,
options.nodeId,
options.clientHost,
options.clientPort,
this.fs,
this.logger.getChild(binProcessors.processClientOptions.name),
);
const statusInfo = clientStatus.statusInfo;
if (statusInfo?.status === 'DEAD') {
this.logger.info('Agent is already dead');
return;
} else if (statusInfo?.status === 'STOPPING') {
this.logger.info('Agent is already stopping');
return;
} else if (statusInfo?.status === 'STARTING') {
throw new binErrors.ErrorCLIStatusStarting();
}
const meta = await binProcessors.processAuthentication(
options.passwordFile,
this.fs,
);
const password = await binProcessors.processPassword(
options.passwordFile,
this.fs,
);
// Either the statusInfo is undefined or LIVE
// Either way, the connection parameters now exist
let pkClient: PolykeyClient;
this.exitHandlers.handlers.push(async () => {
if (pkClient != null) await pkClient.stop();
});
try {
pkClient = await PolykeyClient.createPolykeyClient({
nodePath: options.nodePath,
nodeId: clientStatus.nodeId!,
host: clientStatus.clientHost!,
port: clientStatus.clientPort!,
logger: this.logger.getChild(PolykeyClient.name),
});
const restartMessage = new agentPB.RestartMessage();
restartMessage.setPassword(password);
restartMessage.setClientHost(
options.clientHost ?? config.defaults.networkConfig.clientHost,
);
restartMessage.setClientPort(
options.clientPort ?? config.defaults.networkConfig.clientPort,
);
restartMessage.setIngressHost(options.ingressHost);
restartMessage.setIngressPort(options.ingressPort);
restartMessage.setFresh(options.fresh);
await binUtils.retryAuthentication(
(auth) => pkClient.grpcClient.agentRestart(restartMessage, auth),
meta,
);
this.logger.info('Restarting Agent');
} finally {
if (pkClient! != null) await pkClient.stop();
}
});
}
}

export default CommandRestart;
8 changes: 8 additions & 0 deletions src/client/GRPCClientClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
)(...args);
}

@ready(new clientErrors.ErrorClientClientDestroyed())
public agentRestart(...args) {
return grpcUtils.promisifyUnaryCall<utilsPB.EmptyMessage>(
this.client,
this.client.agentRestart,
)(...args);
}

@ready(new clientErrors.ErrorClientClientDestroyed())
public vaultsList(
...args
Expand Down
47 changes: 47 additions & 0 deletions src/client/service/agentRestart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Host, Port } from '../../network/types';
import type * as grpc from '@grpc/grpc-js';
import type { Authenticate } from '../types';
import type PolykeyAgent from '../../PolykeyAgent';
import type * as agentPB from '../../proto/js/polykey/v1/agent/agent_pb';
import * as grpcUtils from '../../grpc/utils';
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';

function agentRestart({
authenticate,
pkAgent,
}: {
authenticate: Authenticate;
pkAgent: PolykeyAgent;
}) {
return async (
call: grpc.ServerUnaryCall<agentPB.RestartMessage, utilsPB.EmptyMessage>,
callback: grpc.sendUnaryData<utilsPB.EmptyMessage>,
): Promise<void> => {
const response = new utilsPB.EmptyMessage();
try {
const metadata = await authenticate(call.metadata);
call.sendMetadata(metadata);
// Respond first to close the GRPC connection
callback(null, response);
} catch (err) {
callback(grpcUtils.fromError(err), null);
return;
}
const password = call.request.getPassword();
const networkConfig = {
clientHost: call.request.getClientHost() as Host,
clientPort: call.request.getClientPort() as Port,
ingressHost: call.request.getIngressHost() as Host,
ingressPort: call.request.getIngressPort() as Port,
};
const fresh = call.request.getFresh();
await pkAgent.restart({
password,
networkConfig,
fresh,
});
return;
};
}

export default agentRestart;
2 changes: 2 additions & 0 deletions src/client/service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type { IClientServiceServer } from '../../proto/js/polykey/v1/client_serv
import type { FileSystem } from '../../types';
import Logger from '@matrixai/logger';
import agentLockAll from './agentLockAll';
import agentRestart from './agentRestart';
import agentStatus from './agentStatus';
import agentStop from './agentStop';
import agentUnlock from './agentUnlock';
Expand Down Expand Up @@ -122,6 +123,7 @@ function createService({
};
const service: IClientServiceServer = {
agentLockAll: agentLockAll(container),
agentRestart: agentRestart(container),
agentStatus: agentStatus(container),
agentStop: agentStop(container),
agentUnlock: agentUnlock(container),
Expand Down
35 changes: 35 additions & 0 deletions src/proto/js/polykey/v1/agent/agent_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,38 @@ export namespace InfoMessage {
rootCertChainPem: string,
}
}

export class RestartMessage extends jspb.Message {
getPassword(): string;
setPassword(value: string): RestartMessage;
getClientHost(): string;
setClientHost(value: string): RestartMessage;
getClientPort(): number;
setClientPort(value: number): RestartMessage;
getIngressHost(): string;
setIngressHost(value: string): RestartMessage;
getIngressPort(): number;
setIngressPort(value: number): RestartMessage;
getFresh(): boolean;
setFresh(value: boolean): RestartMessage;

serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): RestartMessage.AsObject;
static toObject(includeInstance: boolean, msg: RestartMessage): RestartMessage.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: RestartMessage, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): RestartMessage;
static deserializeBinaryFromReader(message: RestartMessage, reader: jspb.BinaryReader): RestartMessage;
}

export namespace RestartMessage {
export type AsObject = {
password: string,
clientHost: string,
clientPort: number,
ingressHost: string,
ingressPort: number,
fresh: boolean,
}
}
Loading

0 comments on commit 8c25f3f

Please sign in to comment.