diff --git a/src/adapters/ipfs/ipfs.js b/src/adapters/ipfs/ipfs.js index f750179..49e28df 100644 --- a/src/adapters/ipfs/ipfs.js +++ b/src/adapters/ipfs/ipfs.js @@ -11,10 +11,13 @@ // Global npm libraries // const IPFS = require('ipfs') const IPFS = require('@chris.troutner/ipfs') +const fs = require('fs') // Local libraries const config = require('../../../config') +const IPFS_DIR = './.ipfsdata/ipfs' + class IpfsAdapter { constructor (localConfig) { // Encapsulate dependencies @@ -23,6 +26,7 @@ class IpfsAdapter { // Properties of this class instance. this.isReady = false this.config = config + this.fs = fs } // Start an IPFS node. @@ -30,7 +34,7 @@ class IpfsAdapter { try { // Ipfs Options const ipfsOptions = { - repo: './.ipfsdata/ipfs', + repo: IPFS_DIR, start: true, config: { relay: { @@ -76,6 +80,12 @@ class IpfsAdapter { return this.ipfs } catch (err) { console.error('Error in ipfs.js/start()') + + // If IPFS crashes because the /blocks directory is full, wipe the directory. + if (err.message.includes('No space left on device')) { + this.rmBlocksDir() + } + throw err } } @@ -85,6 +95,26 @@ class IpfsAdapter { return true } + + // Remove the '/blocks' directory that is used to store IPFS data. + // Dev Note: It's assumed this node is not pinning any data and that + // everything in this directory is transient. This folder will regularly + // fill up and prevent IPFS from starting. + rmBlocksDir () { + try { + const dir = `${IPFS_DIR}/blocks` + console.log(`Deleting ${dir} directory...`) + + this.fs.rmdirSync(dir, { recursive: true }) + + console.log(`${dir} directory is deleted!`) + + return true // Signal successful execution. + } catch (err) { + console.log('Error in rmBlocksDir()') + throw err + } + } } module.exports = IpfsAdapter diff --git a/test/unit/adapters/ipfs.adapter.unit.js b/test/unit/adapters/ipfs.adapter.unit.js index b9e61bd..520d38c 100644 --- a/test/unit/adapters/ipfs.adapter.unit.js +++ b/test/unit/adapters/ipfs.adapter.unit.js @@ -60,4 +60,25 @@ describe('#IPFS-adapter', () => { assert.equal(result, true) }) }) + + describe('#rmBlocksDir', () => { + it('should delete the /blocks directory', () => { + const result = uut.rmBlocksDir() + + assert.equal(result, true) + }) + + it('should catch and throw an error', () => { + try { + // Force an error + sandbox.stub(uut.fs, 'rmdirSync').throws(new Error('test error')) + + uut.rmBlocksDir() + + assert.fail('Unexpected code path') + } catch (err) { + assert.equal(err.message, 'test error') + } + }) + }) })