@ps-aux/nodebup 0.6.0 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -0,0 +1 @@
1
+
@@ -5,25 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.AggregateBackupController = void 0;
7
7
 
8
- var _FsSyncer = require("../fs/fssync/FsSyncer");
8
+ var _FsSyncer = require("../../fs/fssync/FsSyncer");
9
9
 
10
- var _Gpg = require("../tools/gpg/Gpg");
10
+ var _Gpg = require("../../tools/gpg/Gpg");
11
11
 
12
- var _Fs = require("../fs/Fs");
12
+ var _Fs = require("../../fs/Fs");
13
13
 
14
- var _SshKeyManager = require("../tools/ssh/SshKeyManager");
14
+ var _SshKeyManager = require("../../tools/ssh/SshKeyManager");
15
15
 
16
16
  var _inversify = require("inversify");
17
17
 
18
- var _ContextSymbols = require("../ctx/ContextSymbols");
18
+ var _ContextSymbols = require("../../ctx/ContextSymbols");
19
19
 
20
- var _AppLogger = require("../log/AppLogger");
20
+ var _AppLogger = require("../../log/AppLogger");
21
21
 
22
- var _Path = require("../fs/path/Path");
22
+ var _Path = require("../../fs/path/Path");
23
23
 
24
- var _config = require("../config");
24
+ var _config = require("../../config");
25
25
 
26
- var _StorageBackendProvider = require("../storage/StorageBackendProvider");
26
+ var _StorageBackendProvider = require("../../storage/StorageBackendProvider");
27
27
 
28
28
  var _dec, _dec2, _dec3, _dec4, _class;
29
29
 
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DataBackupController = void 0;
7
+
8
+ var _inversify = require("inversify");
9
+
10
+ var _AppLogger = require("../../log/AppLogger");
11
+
12
+ var _Path = require("../../fs/path/Path");
13
+
14
+ var _StorageBackendProvider = require("../../storage/StorageBackendProvider");
15
+
16
+ var _dec, _dec2, _dec3, _class;
17
+
18
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+
20
+ let DataBackupController = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("design:type", Function), _dec3 = Reflect.metadata("design:paramtypes", [typeof _AppLogger.AppLogger === "undefined" ? Object : _AppLogger.AppLogger, typeof _StorageBackendProvider.StorageBackendProvider === "undefined" ? Object : _StorageBackendProvider.StorageBackendProvider]), _dec(_class = _dec2(_class = _dec3(_class = class DataBackupController {
21
+ constructor(log, storageBackendProvider) {
22
+ this.log = log;
23
+ this.storageBackendProvider = storageBackendProvider;
24
+
25
+ _defineProperty(this, "storage", inp => {
26
+ const storage = this.storageBackendProvider.provide();
27
+
28
+ const path = _Path.AbsPath.from(inp.path);
29
+
30
+ return {
31
+ backup: () => {
32
+ this.log.info(`Backing up from ${path} to '${storage}'`);
33
+ storage.store(path);
34
+ },
35
+ restore: () => {
36
+ this.log.info(`Restoring from '${storage}' to ${path}`);
37
+ storage.restore(path);
38
+ }
39
+ };
40
+ });
41
+ }
42
+
43
+ }) || _class) || _class) || _class);
44
+ exports.DataBackupController = DataBackupController;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PgBackupController = void 0;
7
+
8
+ var _Fs = require("../../fs/Fs");
9
+
10
+ var _inversify = require("inversify");
11
+
12
+ var _AppLogger = require("../../log/AppLogger");
13
+
14
+ var _Shell = require("../../tools/shell/Shell");
15
+
16
+ var _Path = require("../../fs/path/Path");
17
+
18
+ var _StorageBackendProvider = require("../../storage/StorageBackendProvider");
19
+
20
+ var _Zipper = require("../../tools/compression/Zipper");
21
+
22
+ var _dec, _dec2, _dec3, _class, _class2, _temp;
23
+
24
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
25
+
26
+ const parseConnectionUrl = url => {
27
+ var _url$match;
28
+
29
+ const regex = /postgres:\/\/(?<username>.*):(?<password>.*)@(?<host>.*):(?<port>\d*)$/;
30
+ const match = (_url$match = url.match(regex)) === null || _url$match === void 0 ? void 0 : _url$match.groups;
31
+ if (!match || !match.username || !match.password || !match.host || !match.port) throw new Error(`The Postgres connection URL does not match required regex: ${regex.toString()}`);
32
+ return {
33
+ username: match.username,
34
+ password: match.password,
35
+ host: match.host,
36
+ port: parseInt(match.port, 10)
37
+ };
38
+ };
39
+
40
+ let PgBackupController = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("design:type", Function), _dec3 = Reflect.metadata("design:paramtypes", [typeof _Fs.Fs === "undefined" ? Object : _Fs.Fs, typeof _AppLogger.AppLogger === "undefined" ? Object : _AppLogger.AppLogger, typeof _StorageBackendProvider.StorageBackendProvider === "undefined" ? Object : _StorageBackendProvider.StorageBackendProvider, typeof _Shell.Shell === "undefined" ? Object : _Shell.Shell, typeof _Zipper.Zipper === "undefined" ? Object : _Zipper.Zipper]), _dec(_class = _dec2(_class = _dec3(_class = (_temp = _class2 = class PgBackupController {
41
+ constructor( // private gpg: Gpg,
42
+ // private ssh: SshKeyManager,
43
+ fs, // private fsSyncer: FsSyncer,
44
+ log, storageBackendProvider, // @inject(AppConfig_) private cfg: Config,
45
+ sh, zip) {
46
+ this.fs = fs;
47
+ this.log = log;
48
+ this.storageBackendProvider = storageBackendProvider;
49
+ this.sh = sh;
50
+ this.zip = zip;
51
+
52
+ _defineProperty(this, "now", () => {
53
+ const d = new Date();
54
+ const fields = [d.getFullYear(), d.getMonth(), d.getDay(), d.getUTCHours(), d.getMinutes(), d.getSeconds()];
55
+ return fields.join('-');
56
+ });
57
+
58
+ _defineProperty(this, "getVersion", version => version || PgBackupController.defaultPgVersion);
59
+
60
+ _defineProperty(this, "outFileName", 'backup.sql');
61
+
62
+ _defineProperty(this, "backup", ({
63
+ pgUrl,
64
+ pgVersion
65
+ }) => {
66
+ const storage = this.storageBackendProvider.provide();
67
+ const version = this.getVersion(pgVersion); // TODO validate url
68
+
69
+ this.log.info(`Backing up Postgres database, version=${version}`);
70
+ const connParams = parseConnectionUrl(pgUrl);
71
+ const pass = connParams.password;
72
+ this.fs.inTmpDir('pg-backup', dir => {
73
+ const outputDir = _Path.AbsPath.from(dir);
74
+
75
+ this.log.info('Dumping database to a file');
76
+ const bashCmds = [`echo "*:*:*:*:${pass}" > ~/.pgpass`, `chmod 400 ~/.pgpass`, `pg_dumpall -d ${pgUrl}`]; // TODO improve sh logging to avoid showing secrets
77
+
78
+ const b = this.sh.execAndReturnBuffer(`docker run --network host ` + `postgres:${version} ` + `bash -c '${bashCmds.join(' && ')}'`);
79
+ const dumpOut = outputDir.resolve(this.outFileName);
80
+ this.fs.writeFile(dumpOut, b);
81
+ this.log.info('Compressing');
82
+ const zipOutputName = `pg-backup-${this.now()}.zip`;
83
+ this.zip.zipDir(outputDir, outputDir.resolve(zipOutputName));
84
+ this.fs.rmFile(dumpOut);
85
+ this.log.info('Uploading');
86
+ storage.store(_Path.AbsPath.from(dir));
87
+ });
88
+ });
89
+
90
+ _defineProperty(this, "restore", ({
91
+ pgUrl,
92
+ pgVersion
93
+ }) => {
94
+ const version = this.getVersion(pgVersion);
95
+ const storage = this.storageBackendProvider.provide(); // To validate
96
+
97
+ parseConnectionUrl(pgUrl);
98
+ this.log.info(`Restoring Postgres database, version=${version}`);
99
+ this.fs.inTmpDir('pg-restore', dirStr => {
100
+ const dir = _Path.AbsPath.from(dirStr);
101
+
102
+ storage.restore(dir); // TODO check if the dir contains the with the expected name
103
+
104
+ const zipFile = this.fs.listFiles(dir)[0];
105
+ this.zip.unzipDir(zipFile, dir);
106
+ this.fs.rmFile(zipFile);
107
+ const outFile = this.fs.listFiles(dir)[0];
108
+ this.sh.exec(`docker run --network host ` + `-v "${outFile.str()}":/pg/import.sql -w /pg ` + `postgres:${version} ` + `psql ${pgUrl} -v ON_ERROR_STOP=0 -f import.sql`);
109
+ });
110
+ });
111
+ }
112
+
113
+ }, _defineProperty(_class2, "defaultPgVersion", '14.2'), _temp)) || _class) || _class) || _class);
114
+ exports.PgBackupController = PgBackupController;
package/lib/cli/app.js CHANGED
@@ -13,38 +13,41 @@ var _Config = require("../config/Config");
13
13
 
14
14
  var _Context = require("../ctx/Context");
15
15
 
16
- var _AggregateBackupController = require("../bup/AggregateBackupController");
16
+ var _AggregateBackupController = require("../bup/aggregate/AggregateBackupController");
17
17
 
18
18
  var _ResticController = require("../storage/restic/ResticController");
19
19
 
20
- var _BackupController = require("../bup/BackupController");
20
+ var _DataBackupController = require("../bup/dir/DataBackupController");
21
+
22
+ var _PgBackupController = require("../bup/pg/PgBackupController");
21
23
 
22
24
  const storageNameOpt = {
23
25
  name: 'storage-name',
24
26
  convertCase: true,
25
27
  fromConfig: 'storage.name'
26
28
  };
29
+ const singleStorageOptions = [storageNameOpt, {
30
+ name: 'storage-type',
31
+ convertCase: true,
32
+ fromConfig: 'storage.type'
33
+ }, {
34
+ name: 'storage-repo',
35
+ convertCase: true,
36
+ fromConfig: 'storage.repo'
37
+ }, {
38
+ name: 'storage-password',
39
+ convertCase: true,
40
+ fromConfig: 'storage.password'
41
+ }, {
42
+ name: 'storage-credentials',
43
+ convertCase: true,
44
+ fromConfig: 'storage.credentials'
45
+ }];
27
46
 
28
47
  const createApp = () => _nclif.CliApp.of({
29
48
  commands: {
30
49
  data: (0, _nclif.cmdGroup)({
31
- options: [storageNameOpt, {
32
- name: 'storage-type',
33
- convertCase: true,
34
- fromConfig: 'storage.type'
35
- }, {
36
- name: 'storage-repo',
37
- convertCase: true,
38
- fromConfig: 'storage.repo'
39
- }, {
40
- name: 'storage-password',
41
- convertCase: true,
42
- fromConfig: 'storage.password'
43
- }, {
44
- name: 'storage-credentials',
45
- convertCase: true,
46
- fromConfig: 'storage.credentials'
47
- }],
50
+ options: singleStorageOptions,
48
51
  commands: {
49
52
  backup: (0, _nclif.cmd)({
50
53
  description: 'Backup a dir to the given storage',
@@ -52,7 +55,7 @@ const createApp = () => _nclif.CliApp.of({
52
55
  name: 'path',
53
56
  required: true
54
57
  }],
55
- run: (cmd, c) => c.get(_BackupController.BackupController).storage(cmd).backup()
58
+ run: (cmd, c) => c.get(_DataBackupController.DataBackupController).storage(cmd).backup()
56
59
  }),
57
60
  restore: (0, _nclif.cmd)({
58
61
  description: 'Restore the storage to the given dir',
@@ -60,7 +63,7 @@ const createApp = () => _nclif.CliApp.of({
60
63
  name: 'path',
61
64
  required: true
62
65
  }],
63
- run: (cmd, c) => c.get(_BackupController.BackupController).storage(cmd).restore()
66
+ run: (cmd, c) => c.get(_DataBackupController.DataBackupController).storage(cmd).restore()
64
67
  })
65
68
  }
66
69
  }),
@@ -77,7 +80,8 @@ const createApp = () => _nclif.CliApp.of({
77
80
  })
78
81
  }
79
82
  }),
80
- restic
83
+ restic,
84
+ pg
81
85
  }
82
86
  }).envConfig('NODEBUP').addObjectConfig(pwd => (0, _Config.readConfig)(pwd)).context(({
83
87
  config,
@@ -88,8 +92,29 @@ exports.createApp = createApp;
88
92
  const restic = (0, _nclif.cmdGroup)({
89
93
  commands: {
90
94
  'init-repo': (0, _nclif.cmd)({
91
- options: [storageNameOpt],
92
- run: (arg, c) => c.get(_ResticController.ResticController).initRepo()
95
+ options: singleStorageOptions,
96
+ run: (_, c) => c.get(_ResticController.ResticController).initRepo()
97
+ })
98
+ }
99
+ });
100
+ const pg = (0, _nclif.cmdGroup)({
101
+ options: [...singleStorageOptions, {
102
+ name: 'pg-url',
103
+ convertCase: true,
104
+ fromConfig: 'pg.url',
105
+ required: true
106
+ }, {
107
+ name: 'pg-version',
108
+ convertCase: true,
109
+ fromConfig: 'pg.version',
110
+ description: `Postgres version - default is ${_PgBackupController.PgBackupController.defaultPgVersion}`
111
+ }],
112
+ commands: {
113
+ backup: (0, _nclif.cmd)({
114
+ run: (inp, c) => c.get(_PgBackupController.PgBackupController).backup(inp)
115
+ }),
116
+ restore: (0, _nclif.cmd)({
117
+ run: (inp, c) => c.get(_PgBackupController.PgBackupController).restore(inp)
93
118
  })
94
119
  }
95
120
  });
@@ -13,6 +13,10 @@ var _validateConfigAgainstSchema = require("./validateConfigAgainstSchema");
13
13
 
14
14
  var _expandAndCreatePath = require("./expandAndCreatePath");
15
15
 
16
+ var _Fs = require("../fs/Fs");
17
+
18
+ var _AppLogger = require("../log/AppLogger");
19
+
16
20
  const expandPaths = (cfg, exp) => {
17
21
  cfg.aggregates.forEach(a => {
18
22
  a.sources.file.forEach(f => {
@@ -26,15 +30,27 @@ const expandPaths = (cfg, exp) => {
26
30
  if (f.to) f.to = _Path.RelativePath.from(f.to);
27
31
  });
28
32
  });
33
+ }; // TODO
34
+
35
+
36
+ const readFromFile = cwd => {
37
+ // TODO get from the context, maybe move FS to CLI framework later?
38
+ const fs = new _Fs.Fs(cwd, new _AppLogger.AppLogger());
39
+ const cfgPath = cwd.resolve('bup.yaml');
40
+ const cfg = fs.exists(cfgPath) ? (0, _readYaml.readYaml)(cfgPath.str()) : {
41
+ aggregates: [],
42
+ storage: []
43
+ };
44
+ (0, _validateConfigAgainstSchema.validateConfigAgainstSchema)(cfg);
45
+ return cfg;
29
46
  };
30
47
 
31
48
  const readConfig = pwdStr => {
32
49
  const cwd = _Path.AbsPath.from(pwdStr);
33
50
 
34
- const cfgFile = (0, _readYaml.readYaml)(cwd.resolve('bup.yaml').str());
35
- (0, _validateConfigAgainstSchema.validateConfigAgainstSchema)(cfgFile);
36
- const cfg = cfgFile;
37
- cfg.pwd = cwd;
51
+ const cfg = { ...readFromFile(cwd),
52
+ pwd: cwd
53
+ };
38
54
  cfg.aggregates.forEach(t => {
39
55
  const {
40
56
  sources
@@ -19,7 +19,7 @@ var _inversify = require("inversify");
19
19
 
20
20
  var _ContextSymbols = require("./ContextSymbols");
21
21
 
22
- var _AggregateBackupController = require("../bup/AggregateBackupController");
22
+ var _AggregateBackupController = require("../bup/aggregate/AggregateBackupController");
23
23
 
24
24
  var _AppLogger = require("../log/AppLogger");
25
25
 
@@ -33,10 +33,14 @@ var _B2CredentialsProvider = require("../storage/b2/B2CredentialsProvider");
33
33
 
34
34
  var _RCloneClientFactory = require("../storage/rclone/RCloneClientFactory");
35
35
 
36
- var _BackupController = require("../bup/BackupController");
36
+ var _DataBackupController = require("../bup/dir/DataBackupController");
37
37
 
38
38
  var _StorageConfigProvider = require("../storage/StorageConfigProvider");
39
39
 
40
+ var _PgBackupController = require("../bup/pg/PgBackupController");
41
+
42
+ var _Zipper = require("../tools/compression/Zipper");
43
+
40
44
  const createContext = (cfg, inp) => {
41
45
  const c = new _inversify.Container();
42
46
  c.bind(_ContextSymbols.AppConfig_).toConstantValue(cfg);
@@ -45,7 +49,7 @@ const createContext = (cfg, inp) => {
45
49
  c.bind(_ContextSymbols.Log_).toConstantValue(log);
46
50
  c.bind(_AppLogger.AppLogger).toConstantValue(log);
47
51
  c.bind(_Fs.Fs).toConstantValue(new _Fs.Fs(cfg.pwd, log));
48
- const self = [_Gpg.Gpg, _Shell.Shell, _FsSyncer.FsSyncer, _SshKeyManager.SshKeyManager, _StorageBackendProvider.StorageBackendProvider, _StorageConfigProvider.StorageConfigProvider, _ResticClientFactory.ResticClientFactory, _AggregateBackupController.AggregateBackupController, _ResticController.ResticController, _B2CredentialsProvider.B2CredentialsProvider, _RCloneClientFactory.RCloneClientFactory, _BackupController.BackupController];
52
+ const self = [_Gpg.Gpg, _Shell.Shell, _FsSyncer.FsSyncer, _SshKeyManager.SshKeyManager, _StorageBackendProvider.StorageBackendProvider, _StorageConfigProvider.StorageConfigProvider, _ResticClientFactory.ResticClientFactory, _AggregateBackupController.AggregateBackupController, _ResticController.ResticController, _B2CredentialsProvider.B2CredentialsProvider, _RCloneClientFactory.RCloneClientFactory, _DataBackupController.DataBackupController, _PgBackupController.PgBackupController, _Zipper.Zipper];
49
53
  self.forEach(s => c.bind(s).toSelf());
50
54
  return c;
51
55
  };
package/lib/fs/Fs.js CHANGED
@@ -7,6 +7,8 @@ exports.Fs = void 0;
7
7
 
8
8
  var _fs = _interopRequireDefault(require("fs"));
9
9
 
10
+ var _path = _interopRequireDefault(require("path"));
11
+
10
12
  var _Path = require("./path/Path");
11
13
 
12
14
  var _inversify = require("inversify");
@@ -15,6 +17,8 @@ var _AppLogger = require("../log/AppLogger");
15
17
 
16
18
  var _expandAndCreatePath = require("../config/expandAndCreatePath");
17
19
 
20
+ var _os = _interopRequireDefault(require("os"));
21
+
18
22
  var _dec, _dec2, _dec3, _class;
19
23
 
20
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -47,6 +51,30 @@ let Fs = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("design:
47
51
  });
48
52
  });
49
53
 
54
+ _defineProperty(this, "rmFile", path => {
55
+ _fs.default.rmSync(path.str());
56
+ });
57
+
58
+ _defineProperty(this, "listFiles", path => {
59
+ return _fs.default.readdirSync(path.str()).map(f => path.resolve(f));
60
+ });
61
+
62
+ _defineProperty(this, "inTmpDir", (name, withDir) => {
63
+ const dir = this.mkTmpDir(name);
64
+
65
+ try {
66
+ withDir(dir);
67
+ } finally {
68
+ this.rmDir(_Path.AbsPath.from(dir));
69
+ }
70
+ });
71
+
72
+ _defineProperty(this, "mkTmpDir", name => {
73
+ const dir = _fs.default.mkdtempSync(_path.default.resolve(_os.default.tmpdir(), name));
74
+
75
+ return dir;
76
+ });
77
+
50
78
  _defineProperty(this, "ensureIsDir", p => {
51
79
  if (!this.isDir(p)) throw new Error(`${p} is not a dir`);
52
80
  });
@@ -24,7 +24,11 @@ class AbsPath {
24
24
  return AbsPath.from(_path.default.resolve(this.path, '..'));
25
25
  });
26
26
 
27
- _defineProperty(this, "str", () => this.path);
27
+ _defineProperty(this, "basename", () => {
28
+ return _path.default.basename(this.path);
29
+ });
30
+
31
+ _defineProperty(this, "str", () => _path.default.resolve(this.path));
28
32
 
29
33
  if (!_path.default.isAbsolute(path)) throw new Error(`Path ${path} must be absolute`);
30
34
  }
@@ -25,8 +25,8 @@ exports.StorageSchema = StorageSchema;
25
25
  const CliStorageConfigSchema = () => _joi.default.object({
26
26
  storageType: _joi.default.string().valid(_types.StorageType.Restic, _types.StorageType.RClone),
27
27
  storageRepo: _joi.default.string(),
28
- storageCredentials: _joi.default.string().optional(),
29
- storagePassword: _joi.default.string().optional()
28
+ storageCredentials: _joi.default.string().allow(null).optional(),
29
+ storagePassword: _joi.default.string().allow(null).optional()
30
30
  });
31
31
 
32
32
  exports.CliStorageConfigSchema = CliStorageConfigSchema;
@@ -76,7 +76,7 @@ let RcloneClient = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadat
76
76
  return res;
77
77
  });
78
78
 
79
- _defineProperty(this, "obscure", str => this.shell.execAndReturnVal(`rclone obscure ${str}`));
79
+ _defineProperty(this, "obscure", str => this.shell.execAndReturnString(`rclone obscure ${str}`));
80
80
  }
81
81
 
82
82
  get actualRemoteName() {
@@ -42,7 +42,7 @@ let ResticClientFactory = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.
42
42
  if (!creds) throw new Error(`Credentials must be provided for b2 repo in '${props.repo.url}'`);
43
43
  props.backblaze = this.b2.fromString(creds);
44
44
  } else {
45
- if (creds) throw new Error('Credentials can be supported only for the B2 restic backend');
45
+ if (creds) throw new Error('Credentials can be set only for the B2 restic backend');
46
46
  }
47
47
 
48
48
  return new _ResticClient.ResticClient(props, this.sh, this.log);
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Zipper = void 0;
7
+
8
+ var _admZip = _interopRequireDefault(require("adm-zip"));
9
+
10
+ var _inversify = require("inversify");
11
+
12
+ var _AppLogger = require("../../log/AppLogger");
13
+
14
+ var _dec, _dec2, _dec3, _class;
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+
20
+ let Zipper = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("design:type", Function), _dec3 = Reflect.metadata("design:paramtypes", [typeof _AppLogger.AppLogger === "undefined" ? Object : _AppLogger.AppLogger]), _dec(_class = _dec2(_class = _dec3(_class = class Zipper {
21
+ constructor(log) {
22
+ this.log = log;
23
+
24
+ _defineProperty(this, "zipDir", (dir, to) => {
25
+ this.log.debug(`Zipping ${dir} to ${to}`);
26
+ const z = new _admZip.default();
27
+ z.addLocalFolder(dir.str());
28
+ z.writeZip(to.str());
29
+ });
30
+
31
+ _defineProperty(this, "unzipDir", (zipFile, toDir) => {
32
+ this.log.debug(`Unzipping ${zipFile} to ${toDir}`);
33
+ const z = new _admZip.default(zipFile.str());
34
+ z.extractAllTo(toDir.str());
35
+ });
36
+ }
37
+
38
+ }) || _class) || _class) || _class);
39
+ exports.Zipper = Zipper;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var _Zipper = require("./Zipper");
4
+
5
+ var _Path = require("../../fs/path/Path");
6
+
7
+ var _testHelper = require("../../../test/testHelper");
8
+
9
+ var _AppLogger = require("../../log/AppLogger");
10
+
11
+ it('zip', () => {
12
+ const z = new _Zipper.Zipper(new _AppLogger.AppLogger());
13
+
14
+ const out = _Path.AbsPath.from(__dirname).resolve('../../test-data/out.zip');
15
+
16
+ const dir = _Path.AbsPath.from(__dirname).resolve('../../../test/foo');
17
+
18
+ z.zipDir(dir, out);
19
+
20
+ const extDir = _Path.AbsPath.from(__dirname).resolve('../../test-data/foo-out');
21
+
22
+ z.unzipDir(out, extDir);
23
+ (0, _testHelper.expectDirsToBeTheSame)(dir.str(), extDir.str());
24
+ });
@@ -25,7 +25,7 @@ let Gpg = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("design
25
25
  });
26
26
 
27
27
  _defineProperty(this, "exportKey", id => {
28
- const res = this.sh.execAndReturnVal(`gpg --batch --pinentry-mode=loopback --pinentry-mode=loopback --yes --passphrase foo123 --export-secret-key --armor ${id}`);
28
+ const res = this.sh.execAndReturnString(`gpg --batch --pinentry-mode=loopback --pinentry-mode=loopback --yes --passphrase foo123 --export-secret-key --armor ${id}`);
29
29
  if (!res) throw new Error(`Key '${id}' not in keyring`);
30
30
  return res;
31
31
  });
@@ -22,8 +22,7 @@ let Shell = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("desi
22
22
 
23
23
  _defineProperty(this, "exec", (cmd, opts = {}) => {
24
24
  this.log.debug(cmd);
25
- (0, _shellCmd.shellCmd)(cmd, { ...opts,
26
- returnStdout: false
25
+ (0, _shellCmd.shellCmd)(cmd, { ...opts
27
26
  });
28
27
  });
29
28
 
@@ -34,15 +33,22 @@ let Shell = (_dec = (0, _inversify.injectable)(), _dec2 = Reflect.metadata("desi
34
33
  }) => {
35
34
  this.log.debug(`<stdin> > ${cmd}`);
36
35
  (0, _shellCmd.shellCmd)(cmd, { ...opts,
37
- stdin,
38
- returnStdout: false
36
+ stdin
37
+ });
38
+ });
39
+
40
+ _defineProperty(this, "execAndReturnString", (cmd, ops = {}) => {
41
+ this.log.debug(cmd, '[stdout consumed]');
42
+ return (0, _shellCmd.shellCmd)(cmd, {
43
+ returnStdout: 'string',
44
+ ...ops
39
45
  });
40
46
  });
41
47
 
42
- _defineProperty(this, "execAndReturnVal", (cmd, ops = {}) => {
48
+ _defineProperty(this, "execAndReturnBuffer", (cmd, ops = {}) => {
43
49
  this.log.debug(cmd, '[stdout consumed]');
44
50
  return (0, _shellCmd.shellCmd)(cmd, {
45
- returnStdout: true,
51
+ returnStdout: 'buffer',
46
52
  ...ops
47
53
  });
48
54
  });
@@ -16,10 +16,16 @@ const shellCmd = (cmd, {
16
16
  const res = (0, _child_process.execSync)(cmd, {
17
17
  cwd,
18
18
  input: stdin,
19
- stdio: [stdin ? undefined : 'inherit', returnStdout ? undefined : 'inherit', 'inherit'],
19
+ stdio: [stdin ? undefined : 'inherit', returnStdout ? undefined : 'inherit', 'pipe' // TODO changed from 'inherit' as the message is not shown in the console - find out how to catch the stderr output
20
+ ],
20
21
  env
21
22
  });
22
- if (returnStdout) return res.toString().trim();
23
+
24
+ if (returnStdout) {
25
+ if (returnStdout === 'string') return res.toString().trim();
26
+ return res;
27
+ }
28
+
23
29
  return null;
24
30
  };
25
31
 
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@ps-aux/nodebup",
3
- "version": "0.6.0",
3
+ "version": "0.7.2",
4
4
  "description": "",
5
5
  "module": "lib/index.js",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {
8
8
  "build": "rm -rf build && babel --extensions '.ts,.js,.md' src -d lib src",
9
+ "publish:local": "npm run build && chmod +x lib/cli/bin.js && npm link",
9
10
  "pub": "npm publish --access public",
10
11
  "test": "jest",
12
+ "test:ci": "jest --group=-no-ci",
11
13
  "tc": "tsc --noEmit",
12
14
  "format": "prettier \"**/*.{js,ts,tsx}\" --write",
13
15
  "build-n-run": "npm run build && ",
@@ -41,12 +43,14 @@
41
43
  "@types/jest": "^27.4.0",
42
44
  "@types/jest-when": "^2.7.4",
43
45
  "@types/node": "^17.0.6",
46
+ "@types/pg": "^8.6.5",
44
47
  "@types/ramda": "^0.27.62",
45
48
  "@typescript-eslint/eslint-plugin": "^5.8.1",
46
49
  "@typescript-eslint/parser": "^5.8.1",
47
50
  "babel-plugin-module-resolver": "^4.1.0",
48
51
  "babel-plugin-transform-typescript-metadata": "^0.3.2",
49
52
  "dir-compare": "^4.0.0",
53
+ "docker-compose": "^0.23.17",
50
54
  "eslint": "^8.6.0",
51
55
  "eslint-config-standard": "^16.0.3",
52
56
  "eslint-plugin-import": "^2.25.3",
@@ -57,9 +61,11 @@
57
61
  "husky": "^7.0.4",
58
62
  "jest": "^27.4.5",
59
63
  "jest-extended": "^1.2.0",
64
+ "jest-runner-groups": "^2.2.0",
60
65
  "jest-when": "^3.5.0",
61
66
  "lint-staged": "^12.1.4",
62
67
  "npm-check-updates": "^12.0.5",
68
+ "pg": "^8.7.3",
63
69
  "prettier": "^2.5.1",
64
70
  "ts-jest": "^27.1.2",
65
71
  "typescript": "^4.5.4"
@@ -74,6 +80,7 @@
74
80
  "@hapi/joi": "^17.1.1",
75
81
  "@ps-aux/nclif": "^0.0.7-alpha.1",
76
82
  "@types/hapi__joi": "^17.1.8",
83
+ "adm-zip": "^0.5.9",
77
84
  "axios": "^0.24.0",
78
85
  "handlebars": "^4.7.7",
79
86
  "ini": "^2.0.0",
@@ -1,63 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.BackupController = void 0;
7
-
8
- var _FsSyncer = require("../fs/fssync/FsSyncer");
9
-
10
- var _Gpg = require("../tools/gpg/Gpg");
11
-
12
- var _Fs = require("../fs/Fs");
13
-
14
- var _SshKeyManager = require("../tools/ssh/SshKeyManager");
15
-
16
- var _inversify = require("inversify");
17
-
18
- var _ContextSymbols = require("../ctx/ContextSymbols");
19
-
20
- var _AppLogger = require("../log/AppLogger");
21
-
22
- var _Path = require("../fs/path/Path");
23
-
24
- var _StorageBackendProvider = require("../storage/StorageBackendProvider");
25
-
26
- var _config = require("../config");
27
-
28
- var _dec, _dec2, _dec3, _dec4, _class;
29
-
30
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
31
-
32
- let BackupController = (_dec = (0, _inversify.injectable)(), _dec2 = function (target, key) {
33
- return (0, _inversify.inject)(_ContextSymbols.AppConfig_)(target, undefined, 6);
34
- }, _dec3 = Reflect.metadata("design:type", Function), _dec4 = Reflect.metadata("design:paramtypes", [typeof _Gpg.Gpg === "undefined" ? Object : _Gpg.Gpg, typeof _SshKeyManager.SshKeyManager === "undefined" ? Object : _SshKeyManager.SshKeyManager, typeof _Fs.Fs === "undefined" ? Object : _Fs.Fs, typeof _FsSyncer.FsSyncer === "undefined" ? Object : _FsSyncer.FsSyncer, typeof _AppLogger.AppLogger === "undefined" ? Object : _AppLogger.AppLogger, typeof _StorageBackendProvider.StorageBackendProvider === "undefined" ? Object : _StorageBackendProvider.StorageBackendProvider, typeof _config.Config === "undefined" ? Object : _config.Config]), _dec(_class = _dec2(_class = _dec3(_class = _dec4(_class = class BackupController {
35
- constructor(gpg, ssh, fs, fsSyncer, log, storageBackendProvider, cfg) {
36
- this.gpg = gpg;
37
- this.ssh = ssh;
38
- this.fs = fs;
39
- this.fsSyncer = fsSyncer;
40
- this.log = log;
41
- this.storageBackendProvider = storageBackendProvider;
42
- this.cfg = cfg;
43
-
44
- _defineProperty(this, "storage", inp => {
45
- const storage = this.storageBackendProvider.provide();
46
-
47
- const path = _Path.AbsPath.from(inp.path);
48
-
49
- return {
50
- backup: () => {
51
- this.log.info(`Backing up from ${path} to '${storage}'`);
52
- storage.store(path);
53
- },
54
- restore: () => {
55
- this.log.info(`Restoring from '${storage}' to ${path}`);
56
- storage.restore(path);
57
- }
58
- };
59
- });
60
- }
61
-
62
- }) || _class) || _class) || _class) || _class);
63
- exports.BackupController = BackupController;