UNPKG

3.85 kBJavaScriptView Raw
1'use strict'
2
3const multiaddr = require('multiaddr')
4const merge = require('merge-options').bind({ ignoreUndefined: true })
5const { repoExists, removeRepo, checkForRunningApi, tmpDir, defaultRepo } = require('./utils')
6const debug = require('debug')
7
8const daemonLog = {
9 info: debug('ipfsd-ctl:proc:stdout'),
10 err: debug('ipfsd-ctl:proc:stderr')
11}
12/** @typedef {import("./index").ControllerOptions} ControllerOptions */
13
14/**
15 * Controller for in process nodes
16 */
17class InProc {
18 /**
19 * @param {ControllerOptions} opts
20 */
21 constructor (opts) {
22 /** @type ControllerOptions */
23 this.opts = opts
24 this.path = this.opts.ipfsOptions.repo || (opts.disposable ? tmpDir(opts.type) : defaultRepo(opts.type))
25 this.disposable = opts.disposable
26 this.initialized = false
27 this.started = false
28 this.clean = true
29 this.apiAddr = null
30 this.gatewayAddr = null
31 this.api = null
32 }
33
34 async setExec () {
35 if (this.api !== null) {
36 return
37 }
38
39 const IPFS = this.opts.ipfsModule
40
41 this.api = await IPFS.create(merge({
42 silent: true,
43 repo: this.path
44 }, this.opts.ipfsOptions))
45 }
46
47 /**
48 * @private
49 * @param {string} addr
50 */
51 _setApi (addr) {
52 this.apiAddr = multiaddr(addr)
53 this.api = this.opts.ipfsHttpModule(addr)
54 this.api.apiHost = this.apiAddr.nodeAddress().address
55 this.api.apiPort = this.apiAddr.nodeAddress().port
56 }
57
58 /**
59 * @private
60 * @param {string} addr
61 */
62 _setGateway (addr) {
63 this.gatewayAddr = multiaddr(addr)
64 this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
65 this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
66 }
67
68 /**
69 * Initialize a repo.
70 *
71 * @param {Object} [initOptions={}] - @see https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsinit
72 * @returns {Promise<InProc>}
73 */
74 async init (initOptions) {
75 this.initialized = await repoExists(this.path)
76 if (this.initialized) {
77 this.clean = false
78 return this
79 }
80
81 // Repo not initialized
82 const opts = merge(
83 {
84 emptyRepo: false,
85 bits: this.opts.test ? 1024 : 2048,
86 profiles: this.opts.test ? ['test'] : []
87 },
88 typeof this.opts.ipfsOptions.init === 'boolean' ? {} : this.opts.ipfsOptions.init,
89 typeof initOptions === 'boolean' ? {} : initOptions
90 )
91
92 await this.setExec()
93 await this.api.init(opts)
94
95 this.clean = false
96 this.initialized = true
97 return this
98 }
99
100 /**
101 * Delete the repo that was being used.
102 * If the node was marked as `disposable` this will be called
103 * automatically when the process is exited.
104 *
105 * @returns {Promise<InProc>}
106 */
107 async cleanup () {
108 if (!this.clean) {
109 await removeRepo(this.path)
110 this.clean = true
111 }
112 return this
113 }
114
115 /**
116 * Start the daemon.
117 *
118 * @returns {Promise<InProc>}
119 */
120 async start () {
121 // Check if a daemon is already running
122 const api = checkForRunningApi(this.path)
123 if (api) {
124 this._setApi(api)
125 } else {
126 await this.setExec()
127 await this.api.start()
128 }
129
130 this.started = true
131 // Add `peerId`
132 const id = await this.api.id()
133 this.api.peerId = id
134 daemonLog.info(id)
135 return this
136 }
137
138 /**
139 * Stop the daemon.
140 *
141 * @returns {Promise<InProc>}
142 */
143 async stop () {
144 if (!this.started) {
145 return this
146 }
147
148 await this.api.stop()
149 this.started = false
150
151 if (this.disposable) {
152 await this.cleanup()
153 }
154 return this
155 }
156
157 /**
158 * Get the pid of the `ipfs daemon` process.
159 *
160 * @returns {undefined}
161 */
162 pid () {
163 throw new Error('not implemented')
164 }
165
166 /**
167 * Get the version of ipfs
168 *
169 * @returns {Promise<Object>}
170 */
171 async version () {
172 await this.setExec()
173 return this.api.version()
174 }
175}
176
177module.exports = InProc