diff --git a/package-list.json b/package-list.json index f51d47fa52..f959ca9c5e 100644 --- a/package-list.json +++ b/package-list.json @@ -18,6 +18,7 @@ "Repo", ["ipfs/js-ipfs-repo", "ipfs-repo"], + ["AuHau/js-ipfs-repo-migrations", "ipfs-repo-migrations"], "Exchange", ["ipfs/js-ipfs-block-service", "ipfs-block-service"], diff --git a/package.json b/package.json index ededa8eea2..113663ee83 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "ipfs-mfs": "~0.10.2", "ipfs-multipart": "~0.1.0", "ipfs-repo": "~0.26.5", + "ipfs-repo-migrations": "AuHau/js-ipfs-repo-migrations#dev", "ipfs-unixfs": "~0.1.16", "ipfs-unixfs-exporter": "~0.36.1", "ipfs-unixfs-importer": "~0.38.5", diff --git a/src/core/boot.js b/src/core/boot.js index 23e1992d61..f1d282fd9e 100644 --- a/src/core/boot.js +++ b/src/core/boot.js @@ -27,6 +27,26 @@ module.exports = (self) => { cb(null, true) }) }, + // If migrations are enabled check & migrate repo + (repoOpened, cb) => { + self.config.get('repoDisableAutoMigration') + .catch(err => { + if (!err.message.match('does not exist')) { + return Promise.reject(err) + } + + // Option not found, but default value is false, lets continue + return false + }) + .then(repoDisableAutoMigration => { + if (repoOpened && !repoDisableAutoMigration) { + self.log('checking for migrations') + return self.repo.migrate() + } + }) + .then(() => cb(null, repoOpened)) + .catch(cb) + }, (repoOpened, cb) => { // Init with existing initialized, opened, repo if (repoOpened) { diff --git a/src/core/components/repo.js b/src/core/components/repo.js index 23116d8cf5..bdb29dc457 100644 --- a/src/core/components/repo.js +++ b/src/core/components/repo.js @@ -2,6 +2,8 @@ const promisify = require('promisify-es6') const repoVersion = require('ipfs-repo').repoVersion +const log = require('debug')('ipfs:repo') +const migrator = require('ipfs-repo-migrations') module.exports = function repo (self) { return { @@ -38,6 +40,25 @@ module.exports = function repo (self) { }) }), + migrate: async function tryMigrateRepo () { + // Reads the repo version from datastore, not from the ipfs-repo package + const currentRepoVersion = await migrator.getCurrentRepoVersion(self._repo.path) + + if (currentRepoVersion >= repoVersion) { + if (currentRepoVersion > repoVersion) { + log('Your repo\'s version is higher then this version of js-ipfs require! You should revert it.') + } + + return // Nothing to migrate + } + + if (repoVersion > migrator.getLatestMigrationVersion()) { + throw new Error('The ipfs-repo-migrations package does not have migration for version: ' + repoVersion) + } + + return migrator.migrate(self._repo.path, repoVersion, true, self._repo.options) + }, + gc: promisify((options, callback) => { if (typeof options === 'function') { callback = options diff --git a/src/core/config.js b/src/core/config.js index 2fb66bb558..ba8f4bdf90 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -27,6 +27,7 @@ const s = superstruct({ const configSchema = s({ repo: optional(s('object|string')), repoOwner: 'boolean?', + repoDisableAutoMigration: 'boolean?', preload: s({ enabled: 'boolean?', addresses: optional(s(['multiaddr'])),