Skip to content

Commit

Permalink
feat: expose gRPC addr on daemon (#561)
Browse files Browse the repository at this point in the history
Adds a `grpcAddr` property to IPFS daemon instances that contains the multiaddr of the gPRC websocket server exposed if available.
  • Loading branch information
achingbrain authored Dec 18, 2020
1 parent e8853dd commit 1bed9f0
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 12 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"peerDependencies": {
"go-ipfs": "*",
"ipfs": "*",
"ipfs-client": "*",
"ipfs-http-client": "*"
},
"repository": {
Expand Down
3 changes: 2 additions & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ module.exports = ({ type }) => {
Addresses: {
Swarm: swarm,
API: '/ip4/127.0.0.1/tcp/0',
Gateway: '/ip4/127.0.0.1/tcp/0'
Gateway: '/ip4/127.0.0.1/tcp/0',
RPC: '/ip4/127.0.0.1/tcp/0'
}
}
}
4 changes: 3 additions & 1 deletion src/endpoint/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module.exports = (server, createFactory) => {
id: id,
apiAddr: nodes[id].apiAddr ? nodes[id].apiAddr.toString() : '',
gatewayAddr: nodes[id].gatewayAddr ? nodes[id].gatewayAddr.toString() : '',
grpcAddr: nodes[id].grpcAddr ? nodes[id].grpcAddr.toString() : '',
initialized: nodes[id].initialized,
started: nodes[id].started,
disposable: nodes[id].disposable,
Expand Down Expand Up @@ -125,7 +126,8 @@ module.exports = (server, createFactory) => {

return {
apiAddr: nodes[id].apiAddr ? nodes[id].apiAddr.toString() : '',
gatewayAddr: nodes[id].gatewayAddr ? nodes[id].gatewayAddr.toString() : ''
gatewayAddr: nodes[id].gatewayAddr ? nodes[id].gatewayAddr.toString() : '',
grpcAddr: nodes[id].grpcAddr ? nodes[id].grpcAddr.toString() : ''
}
} catch (err) {
badRequest(err)
Expand Down
50 changes: 45 additions & 5 deletions src/ipfsd-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Client {

this._setApi(remoteState.apiAddr)
this._setGateway(remoteState.gatewayAddr)
this._setGrpc(remoteState.grpcAddr)
this._createApi()
}

/**
Expand All @@ -46,9 +48,6 @@ class Client {
_setApi (addr) {
if (addr) {
this.apiAddr = multiaddr(addr)
this.api = this.opts.ipfsHttpModule(addr)
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port
}
}

Expand All @@ -59,8 +58,47 @@ class Client {
_setGateway (addr) {
if (addr) {
this.gatewayAddr = multiaddr(addr)
this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
}
}

/**
* @private
* @param {string} addr
*/
_setGrpc (addr) {
if (addr) {
this.grpcAddr = multiaddr(addr)
}
}

/**
* @private
*/
_createApi () {
if (this.opts.ipfsClientModule && this.grpcAddr && this.apiAddr) {
this.api = this.opts.ipfsClientModule({
grpc: this.grpcAddr,
http: this.apiAddr
})
} else if (this.apiAddr) {
this.api = this.opts.ipfsHttpModule(this.apiAddr)
}

if (this.api) {
if (this.apiAddr) {
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port
}

if (this.gatewayAddr) {
this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
}

if (this.grpcAddr) {
this.api.grpcHost = this.grpcAddr.nodeAddress().address
this.api.grpcPort = this.grpcAddr.nodeAddress().port
}
}
}

Expand Down Expand Up @@ -133,6 +171,8 @@ class Client {

this._setApi(res.apiAddr)
this._setGateway(res.gatewayAddr)
this._setGrpc(res.grpcAddr)
this._createApi()

this.started = true
}
Expand Down
51 changes: 46 additions & 5 deletions src/ipfsd-daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Daemon {
this.started = false
this.clean = true
this.apiAddr = null
this.grpcAddr = null
this.gatewayAddr = null
this.api = null
}
Expand All @@ -58,9 +59,14 @@ class Daemon {
*/
_setApi (addr) {
this.apiAddr = multiaddr(addr)
this.api = this.opts.ipfsHttpModule(addr)
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port
}

/**
* @private
* @param {string} addr
*/
_setGrpc (addr) {
this.grpcAddr = multiaddr(addr)
}

/**
Expand All @@ -69,8 +75,36 @@ class Daemon {
*/
_setGateway (addr) {
this.gatewayAddr = multiaddr(addr)
this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
}

_createApi () {
if (this.opts.ipfsClientModule && this.grpcAddr) {
this.api = this.opts.ipfsClientModule({
grpc: this.grpcAddr,
http: this.apiAddr
})
} else if (this.apiAddr) {
this.api = this.opts.ipfsHttpModule(this.apiAddr)
}

if (!this.api) {
throw new Error(`Could not create API from http '${this.apiAddr}' and/or gRPC '${this.grpcAddr}'`)
}

if (this.apiAddr) {
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port
}

if (this.gatewayAddr) {
this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
}

if (this.grpcAddr) {
this.api.grpcHost = this.grpcAddr.nodeAddress().address
this.api.grpcPort = this.grpcAddr.nodeAddress().port
}
}

/**
Expand Down Expand Up @@ -150,6 +184,7 @@ class Daemon {

if (api) {
this._setApi(api)
this._createApi()
} else if (!this.exec) {
throw new Error('No executable specified')
} else {
Expand All @@ -168,6 +203,7 @@ class Daemon {
output += data.toString()
const apiMatch = output.trim().match(/API .*listening on:? (.*)/)
const gwMatch = output.trim().match(/Gateway .*listening on:? (.*)/)
const grpcMatch = output.trim().match(/gRPC .*listening on:? (.*)/)

if (apiMatch && apiMatch.length > 0) {
this._setApi(apiMatch[1])
Expand All @@ -177,8 +213,13 @@ class Daemon {
this._setGateway(gwMatch[1])
}

if (grpcMatch && grpcMatch.length > 0) {
this._setGrpc(grpcMatch[1])
}

if (output.match(/(?:daemon is running|Daemon is ready)/)) {
// we're good
this._createApi()
this.started = true
this.subprocess.stdout.off('data', readyHandler)
resolve(this.api)
Expand Down
51 changes: 51 additions & 0 deletions test/create.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,57 @@ describe('`createController` should return the correct class', () => {

expect(f).to.be.instanceOf(Client)
})

it.skip('should use ipfs-client if passed', async () => {
let clientCreated = false
let httpCreated = false

await createController({
type: 'js',
disposable: false,
ipfsModule: require('ipfs'),
ipfsClientModule: (opts) => {
clientCreated = true

return require('ipfs-client')(opts)
},
ipfsHttpModule: (opts) => {
httpCreated = true

return require('ipfs-http-client')(opts)
},
ipfsBin: pathJoin(__dirname, '../node_modules/ipfs/src/cli/bin.js')
})

expect(clientCreated).to.be.true()
expect(httpCreated).to.be.false()
})

it.skip('should use ipfs-client for remote if passed', async () => {
let clientCreated = false
let httpCreated = false

const f = await createController({
remote: true,
disposable: false,
ipfsModule: require('ipfs'),
ipfsClientModule: (opts) => {
clientCreated = true

return require('ipfs-client')(opts)
},
ipfsHttpModule: (opts) => {
httpCreated = true

return require('ipfs-http-client')(opts)
},
ipfsBin: pathJoin(__dirname, '../node_modules/ipfs/src/cli/bin.js')
})

expect(f).to.be.instanceOf(Client)
expect(clientCreated).to.be.true()
expect(httpCreated).to.be.false()
})
})

const defaultOps = {
Expand Down

0 comments on commit 1bed9f0

Please sign in to comment.