Explorar el Código

Ajout des utilitaire bin/backup et bin/restore

develop
William Petit hace 1 año
padre
commit
45fa3eeec4
Se han modificado 5 ficheros con 192 adiciones y 1 borrados
  1. 1
    0
      .gitignore
  2. 18
    0
      README.md
  3. 76
    0
      bin/backup
  4. 93
    0
      bin/restore
  5. 4
    1
      lib/config.js

+ 1
- 0
.gitignore Ver fichero

@@ -4,3 +4,4 @@
4 4
 node_modules
5 5
 .marangrc
6 6
 /packages-dist
7
+/backup

+ 18
- 0
README.md Ver fichero

@@ -38,6 +38,24 @@ cd marang
38 38
 ```
39 39
 L'utilitaire affichera une chaine de la forme `<algorithm>:<iterations>:<salt>:<derived_key>` que vous pourrez stocker dans votre fichier de configuration.
40 40
 
41
+## Sauvegarde et restauration
42
+
43
+Deux utilitaires sont disponibles pour effectuer la sauvegarde et la restauration des données de Marang: `bin/backup` et `bin/restore`.
44
+
45
+### Utilisation
46
+
47
+**Créer une sauvegarde**
48
+```shell
49
+MARANG_PASSWORD="Mot de passe Marang" ./bin/backup
50
+```
51
+
52
+Un fichier horodaté sera créé dans le répertoire de sauvegarde (par défaut `./backup`, voir la configuration pour changer celui ci). Pour le moment, seuls les `slots` sont sauvegardés.
53
+
54
+**Restaurer une sauvegarde**
55
+```shell
56
+MARANG_PASSWORD="Mot de passe Marang" MARANG_BACKUP_FILE="Chemin vers le fichier de sauvegarde à restaurer" ./bin/restore
57
+```
58
+
41 59
 ## Licence
42 60
 
43 61
 AGPL-3.0

+ 76
- 0
bin/backup Ver fichero

@@ -0,0 +1,76 @@
1
+#!/usr/bin/env node
2
+
3
+var fs = require('fs');
4
+var path = require('path');
5
+var http = require('http');
6
+var config = require('../lib/config');
7
+
8
+fetchAPI('/api/slots', (err, slots) => {
9
+  if (err) {
10
+    console.error(err.message);
11
+    process.exit(1);
12
+  }
13
+
14
+  var backup = {
15
+    meta: "Marang Backup",
16
+    format: 0,
17
+    date: new Date(),
18
+    slots: slots,
19
+  };
20
+
21
+  var exists = fs.existsSync(config.backupPath);
22
+  if (!exists) {
23
+    console.error("Destination directory '%s' does not exist.", config.backupPath);
24
+    process.exit(1);
25
+  }
26
+
27
+  var now = new Date();
28
+  var backupName = now.toJSON() + '.json';
29
+  var destFile = path.join(config.backupPath, backupName);
30
+
31
+  fs.writeFile(destFile, JSON.stringify(backup), (err) => {
32
+    if (err) {
33
+      console.error(err.message);
34
+      process.exit(1);
35
+    }
36
+    console.log('data saved in ' + destFile);
37
+  });
38
+
39
+});
40
+
41
+
42
+function fetchAPI(path, cb) {
43
+  var credentials = config.webApp.credentials.username +
44
+    ':' +
45
+    process.env.MARANG_PASSWORD
46
+  ;
47
+  var opts = {
48
+    host: config.webApp.host,
49
+    port: config.webApp.port,
50
+    path: path,
51
+    auth: credentials
52
+  }
53
+  http.get(opts, res => {
54
+    if(res.statusCode < 200 || res.statusCode >= 400) {
55
+      return cb(new Error('Unexpected HTTP response: ' + res.statusCode + ' ' + res.statusMessage));
56
+    }
57
+    res.setEncoding('utf8');
58
+    var data = '';
59
+    res.on('data', chunk => {
60
+      data += chunk;
61
+    });
62
+    res.once('end', () => {
63
+      var json;
64
+      try {
65
+        json = JSON.parse(data);
66
+      } catch(err) {
67
+        return cb(err);
68
+      }
69
+      cb(null, json);
70
+    });
71
+    res.once('error', (err) => {
72
+      res.removeAllListeners();
73
+      cb(err);
74
+    });
75
+  });
76
+}

+ 93
- 0
bin/restore Ver fichero

@@ -0,0 +1,93 @@
1
+#!/usr/bin/env node
2
+
3
+var fs = require('fs');
4
+var path = require('path');
5
+var http = require('http');
6
+var config = require('../lib/config');
7
+
8
+var backupFile = process.env.MARANG_BACKUP_FILE;
9
+
10
+if (!backupFile) {
11
+  console.error('You must provide the path of a backup file via the "MARANG_BACKUP_FILE" environment variable.');
12
+  process.exit(1);
13
+}
14
+
15
+if (!fs.existsSync(backupFile)) {
16
+  console.error('Backup file "%s" does not exist.', backupFile);
17
+  process.exit(1);
18
+}
19
+
20
+var fileContent = fs.readFileSync(backupFile, 'utf8');
21
+
22
+var backup;
23
+try {
24
+  backup = JSON.parse(fileContent);
25
+} catch(err) {
26
+  console.error('The backup "%s" is not a valid JSON file.', backupFile);
27
+  process.exit(1);
28
+}
29
+
30
+console.log("Restoring slots...")
31
+Object.keys(backup.slots).forEach(slotKey => {
32
+  var slot = backup.slots[slotKey];
33
+  postAPI('/api/slots/'+slotKey, slot, err => {
34
+    if (err) {
35
+      console.error(err.message);
36
+      process.exit(1);
37
+    }
38
+    console.log("Restored slot '%s'.", slotKey);
39
+  });
40
+});
41
+
42
+function postAPI(path, data, cb) {
43
+
44
+  var postData
45
+  try {
46
+    postData = JSON.stringify(data);
47
+  } catch(err) {
48
+    return cb(err);
49
+  }
50
+
51
+  var credentials = config.webApp.credentials.username +
52
+    ':' +
53
+    process.env.MARANG_PASSWORD
54
+  ;
55
+  var opts = {
56
+    host: config.webApp.host,
57
+    port: config.webApp.port,
58
+    path: path,
59
+    auth: credentials,
60
+    headers: {
61
+      "Content-Type": "application/json",
62
+      "Content-Length": Buffer.byteLength(postData)
63
+    },
64
+    method: "POST"
65
+  }
66
+  var req = http.request(opts, res => {
67
+    if(res.statusCode < 200 || res.statusCode >= 400) {
68
+      return cb(new Error('Unexpected HTTP response: ' + res.statusCode + ' ' + res.statusMessage));
69
+    }
70
+    res.setEncoding('utf8');
71
+    var data = '';
72
+    res.on('data', chunk => {
73
+      data += chunk;
74
+    });
75
+    res.once('end', () => {
76
+      var json;
77
+      try {
78
+        json = JSON.parse(data);
79
+      } catch(err) {
80
+        return cb(err);
81
+      }
82
+      cb(null, json);
83
+    });
84
+    res.once('error', (err) => {
85
+      res.removeAllListeners();
86
+      cb(err);
87
+    });
88
+  });
89
+
90
+  req.write(postData);
91
+  req.end();
92
+
93
+}

+ 4
- 1
lib/config.js Ver fichero

@@ -23,6 +23,9 @@ module.exports = require('rc')('marang', {
23 23
   dbPath: __dirname + '/../data',
24 24
 
25 25
   // Chemin d'accès vers les scripts "handlers"
26
-  handlersPath: __dirname + '/../handlers'
26
+  handlersPath: __dirname + '/../handlers',
27
+
28
+  // Checmin d'accès au répertoire de sauvegarde
29
+  backupPath: __dirname + '/../backup',
27 30
 
28 31
 });

Loading…
Cancelar
Guardar