summaryrefslogtreecommitdiff
path: root/packages/anastasis-cli/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-cli/src/index.ts')
-rw-r--r--packages/anastasis-cli/src/index.ts87
1 files changed, 87 insertions, 0 deletions
diff --git a/packages/anastasis-cli/src/index.ts b/packages/anastasis-cli/src/index.ts
new file mode 100644
index 000000000..7c011569f
--- /dev/null
+++ b/packages/anastasis-cli/src/index.ts
@@ -0,0 +1,87 @@
+import { clk } from "@gnu-taler/taler-util/clk";
+import {
+ discoverPolicies,
+ getBackupStartState,
+ getRecoveryStartState,
+ reduceAction,
+} from "@gnu-taler/anastasis-core";
+import fs from "fs";
+import { j2s } from "@gnu-taler/taler-util";
+
+export const reducerCli = clk.program("anastasis-cli", {
+ help: "Command line interface for Anastasis.",
+});
+
+reducerCli
+ .subcommand("reducer", "reduce", {
+ help: "Run the anastasis reducer",
+ })
+ .flag("initBackup", ["-b", "--backup"])
+ .flag("initRecovery", ["-r", "--restore"])
+ .maybeOption("argumentsJson", ["-a", "--arguments"], clk.STRING)
+ .maybeArgument("action", clk.STRING)
+ .maybeArgument("stateFile", clk.STRING)
+ .action(async (x) => {
+ if (x.reducer.initBackup) {
+ console.log(JSON.stringify(await getBackupStartState()));
+ return;
+ } else if (x.reducer.initRecovery) {
+ console.log(JSON.stringify(await getRecoveryStartState()));
+ return;
+ }
+
+ const action = x.reducer.action;
+ if (!action) {
+ console.log("action required");
+ return;
+ }
+
+ let lastState: any;
+ if (x.reducer.stateFile) {
+ const s = fs.readFileSync(x.reducer.stateFile, { encoding: "utf-8" });
+ lastState = JSON.parse(s);
+ } else {
+ const s = await read(process.stdin);
+ lastState = JSON.parse(s);
+ }
+
+ let args: any;
+ if (x.reducer.argumentsJson) {
+ args = JSON.parse(x.reducer.argumentsJson);
+ } else {
+ args = {};
+ }
+
+ const nextState = await reduceAction(lastState, action, args);
+ console.log(JSON.stringify(nextState));
+ });
+
+reducerCli
+ .subcommand("discover", "discover", {
+ help: "Run the anastasis reducer",
+ })
+ .maybeArgument("stateFile", clk.STRING)
+ .action(async (args) => {
+ let lastState: any;
+ if (args.discover.stateFile) {
+ const s = fs.readFileSync(args.discover.stateFile, { encoding: "utf-8" });
+ lastState = JSON.parse(s);
+ } else {
+ const s = await read(process.stdin);
+ lastState = JSON.parse(s);
+ }
+ const res = await discoverPolicies(lastState);
+ console.log(j2s(res));
+ });
+
+async function read(stream: NodeJS.ReadStream): Promise<string> {
+ const chunks = [];
+ for await (const chunk of stream) {
+ chunks.push(chunk);
+ }
+ return Buffer.concat(chunks).toString("utf8");
+}
+
+export function reducerCliMain() {
+ reducerCli.run();
+}