Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

feat: mfs implementation #1360

Merged
merged 2 commits into from
Jul 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ You can check the development status at the [Waffle Board](https://waffle.io/ipf
- [Network](#network)
- [Node Management](#node-management)
- [Domain data types](#domain-data-types)
- [Util](#util)
- [FAQ](#faq)
- [Running js-ipfs with Docker](#running-js-ipfs-with-docker)
- [Packages](#packages)
Expand Down
2 changes: 1 addition & 1 deletion examples/browser-script-tag/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h2>Some suggestions</h2>
<code style="display:block; white-space:pre-wrap; background-color:#d7d6d6">
node.files.add(new node.types.Buffer('Hello world!'), (err, filesAdded) => {
if (err) {
return console.error('Error - ipfs files add', err, res)
return console.error('Error - ipfs add', err, res)
}

filesAdded.forEach((file) => console.log('successfully stored', file.hash))
Expand Down
2 changes: 1 addition & 1 deletion examples/circuit-relaying/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"ipfs-pubsub-room": "~0.3.0"
},
"devDependencies": {
"aegir": "^13.0.5",
"aegir": "^14.0.0",
"http-server": "~0.10.0",
"ipfs-css": "~0.2.0",
"parcel-bundler": "^1.6.2",
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"ipfs-block": "~0.7.1",
"ipfs-block-service": "~0.14.0",
"ipfs-http-response": "~0.1.2",
"ipfs-mfs": "~0.0.14",
"ipfs-multipart": "~0.1.0",
"ipfs-repo": "~0.22.1",
"ipfs-unixfs": "~0.1.15",
Expand Down Expand Up @@ -166,7 +167,8 @@
"through2": "^2.0.3",
"update-notifier": "^2.5.0",
"yargs": "^12.0.1",
"yargs-parser": "^10.1.0"
"yargs-parser": "^10.1.0",
"yargs-promise": "^1.1.0"
},
"optionalDependencies": {
"prom-client": "^11.1.1",
Expand Down
87 changes: 53 additions & 34 deletions src/cli/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

'use strict'

const YargsPromise = require('yargs-promise')
const yargs = require('yargs')
const updateNotifier = require('update-notifier')
const readPkgUp = require('read-pkg-up')
const fs = require('fs')
const path = require('path')
const utils = require('./utils')
const print = utils.print
const mfs = require('ipfs-mfs/cli')
const debug = require('debug')('ipfs:cli')

const pkg = readPkgUp.sync({cwd: __dirname}).pkg
updateNotifier({
Expand All @@ -18,10 +19,6 @@ updateNotifier({

const args = process.argv.slice(2)

// Determine if the first argument is a sub-system command
const commandNames = fs.readdirSync(path.join(__dirname, 'commands'))
const isCommand = commandNames.includes(`${args[0]}.js`)

const cli = yargs
.option('silent', {
desc: 'Write no output',
Expand All @@ -34,14 +31,6 @@ const cli = yargs
type: 'string',
default: ''
})
.commandDir('commands', {
// Only include the commands for the sub-system we're using, or include all
// if no sub-system command has been passed.
include (path, filename) {
if (!isCommand) return true
return `${args[0]}.js` === filename
}
})
.epilog(utils.ipfsPathHelp)
.demandCommand(1)
.fail((msg, err, yargs) => {
Expand All @@ -56,27 +45,15 @@ const cli = yargs
yargs.showHelp()
})

// If not a sub-system command then load the top level aliases
if (!isCommand) {
// NOTE: This creates an alias of
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
const addCmd = require('./commands/files/add')
const catCmd = require('./commands/files/cat')
const getCmd = require('./commands/files/get')
const aliases = [addCmd, catCmd, getCmd]
aliases.forEach((alias) => {
cli.command(alias.command, alias.describe, alias.builder, alias.handler)
})
}

// Need to skip to avoid locking as these commands
// don't require a daemon
if (args[0] === 'daemon' || args[0] === 'init') {
cli
.help()
.strict()
.completion()
.command(require('./commands/daemon'))
.command(require('./commands/init'))
.parse(args)
} else {
// here we have to make a separate yargs instance with
Expand All @@ -86,19 +63,61 @@ if (args[0] === 'daemon' || args[0] === 'init') {
if (err) {
throw err
}

utils.getIPFS(argv, (err, ipfs, cleanup) => {
if (err) { throw err }
if (err) {
throw err
}

// add mfs commands
mfs(cli)

// NOTE: This creates an alias of
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
const addCmd = require('./commands/files/add')
const catCmd = require('./commands/files/cat')
const getCmd = require('./commands/files/get')
const aliases = [addCmd, catCmd, getCmd]
aliases.forEach((alias) => {
cli.command(alias)
})

cli
.commandDir('commands')
.help()
.strict()
.completion()
.parse(args, { ipfs: ipfs }, (err, argv, output) => {
if (output) { print(output) }

cleanup(() => {
if (err) { throw err }
})
let exitCode = 0

const parser = new YargsPromise(cli, { ipfs })
parser.parse(args)
.then(({ data, argv }) => {
if (data) {
print(data)
}
})
.catch((arg) => {
debug(arg)

// the argument can have a different shape depending on where the error came from
if (arg.message) {
print(arg.message)
} else if (arg.error && arg.error.message) {
print(arg.error.message)
} else {
print('Unknown error, please re-run the command with DEBUG=ipfs:cli to see debug output')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to have some consistency here - the rest of the cli debug prefixes are cli:* and elsewhere in the code we have jsipfs:*. One for a separate PR 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love it if we could standardise on one prefix for all ipfs related DEBUG values. Just doing ipfs:* instead of ipfs:*,ipfsd-ctl:*,ipfs-api:*,etc is my dream.

}

exitCode = 1
})
.then(() => cleanup())
.catch(() => {})
.then(() => {
if (exitCode !== 0) {
process.exit(exitCode)
}
})
})
})
Expand Down
20 changes: 0 additions & 20 deletions src/cli/commands/files.js

This file was deleted.

1 change: 1 addition & 0 deletions src/cli/commands/files/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function fileHandler (dir) {
callback(err)
} else {
const fullFilePath = path.join(dir, file.path)

if (file.content) {
file.content
.pipe(fs.createWriteStream(fullFilePath))
Expand Down
9 changes: 5 additions & 4 deletions src/cli/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const log = debug('cli')
log.error = debug('cli:error')
const Progress = require('progress')
const byteman = require('byteman')
const promisify = require('promisify-es6')

exports = module.exports

Expand Down Expand Up @@ -40,7 +41,7 @@ function getAPICtl (apiAddr) {

exports.getIPFS = (argv, callback) => {
if (argv.api || isDaemonOn()) {
return callback(null, getAPICtl(argv.api), (cb) => cb())
return callback(null, getAPICtl(argv.api), promisify((cb) => cb()))
}

// Required inline to reduce startup time
Expand All @@ -55,13 +56,13 @@ exports.getIPFS = (argv, callback) => {
}
})

const cleanup = (cb) => {
const cleanup = promisify((cb) => {
if (node && node._repo && !node._repo.closed) {
node._repo.close(() => cb())
node._repo.close((err) => cb(err))
} else {
cb()
}
}
})

node.on('error', (err) => {
throw err
Expand Down
1 change: 1 addition & 0 deletions src/core/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ exports.dht = require('./dht')
exports.dns = require('./dns')
exports.key = require('./key')
exports.stats = require('./stats')
exports.mfs = require('ipfs-mfs/core')
1 change: 1 addition & 0 deletions src/core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const schema = Joi.object().keys({
Joi.object(), // TODO: schema for IPFS repo
Joi.string()
).allow(null),
repoOwner: Joi.boolean().default(true),
init: Joi.alternatives().try(
Joi.boolean(),
Joi.object().keys({ bits: Joi.number().integer() })
Expand Down
7 changes: 7 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ class IPFS extends EventEmitter {
isIPFS: isIPFS
}

// ipfs.files
const mfs = components.mfs(this, this._options)

Object.keys(mfs).forEach(key => {
this.files[key] = mfs[key]
})

boot(this)
}
}
Expand Down
19 changes: 12 additions & 7 deletions src/http/api/resources/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ exports.parseKey = (request, reply) => {
if (!request.query.arg) {
return reply({
Message: "Argument 'key' is required",
Code: 0
Code: 0,
Type: 'error'
}).code(400).takeover()
}

Expand All @@ -54,7 +55,8 @@ exports.parseKey = (request, reply) => {
log.error(err)
return reply({
Message: 'invalid ipfs ref path',
Code: 0
Code: 0,
Type: 'error'
}).code(500).takeover()
}

Expand All @@ -81,9 +83,9 @@ exports.cat = {
if (err) {
log.error(err)
if (err.message === 'No such file') {
reply({Message: 'No such file'}).code(500)
reply({Message: 'No such file', Code: 0, Type: 'error'}).code(500)
} else {
reply({Message: 'Failed to cat file: ' + err, Code: 0}).code(500)
reply({Message: 'Failed to cat file: ' + err, Code: 0, Type: 'error'}).code(500)
}
return
}
Expand Down Expand Up @@ -177,7 +179,8 @@ exports.add = {
if (!request.payload) {
return reply({
Message: 'Array, Buffer, or String is required.',
code: 0
Code: 0,
Type: 'error'
}).code(400).takeover()
}

Expand Down Expand Up @@ -211,7 +214,8 @@ exports.add = {
if (!filesParsed) {
return reply({
Message: "File argument 'data' is required.",
code: 0
Code: 0,
Type: 'error'
}).code(400).takeover()
}
fileAdder.end()
Expand Down Expand Up @@ -302,7 +306,8 @@ exports.immutableLs = {
if (err) {
return reply({
Message: 'Failed to list dir: ' + err.message,
Code: 0
Code: 0,
Type: 'error'
}).code(500).takeover()
}

Expand Down
3 changes: 3 additions & 0 deletions src/http/api/routes/files.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const resources = require('./../resources')
const mfs = require('ipfs-mfs/http')

module.exports = (server) => {
const api = server.select('API')
Expand Down Expand Up @@ -54,4 +55,6 @@ module.exports = (server) => {
handler: resources.files.immutableLs.handler
}
})

mfs(api)
}
9 changes: 8 additions & 1 deletion src/http/error-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ module.exports = (api, server) => {

let statusCode = 200
let msg = 'Sorry, something went wrong, please retrace your steps.'
let code = 1

if (res.isBoom) {
statusCode = res.output.payload.statusCode
msg = res.output.payload.message

if (res.data && res.data.code !== undefined) {
code = res.data.code
}

if (res.message && res.isDeveloperError) {
msg = res.message.replace('Uncaught error: ', '')
Expand All @@ -36,7 +42,8 @@ module.exports = (api, server) => {

reply({
Message: msg,
Code: 1
Code: code,
Type: 'error'
}).code(statusCode)
return
}
Expand Down
Loading