-
Notifications
You must be signed in to change notification settings - Fork 886
feat: cleanup repository before starting up IPFS #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
63fb349
4190b45
fc7ce9b
af78067
fb90571
fd97e7d
f9a4703
748e958
a3d4a88
5b22ede
8e1b964
4b0c426
0580dcc
0dce216
8884399
ce30819
1ccc342
bc053f8
84188ff
97d13a6
e510c8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,104 @@ | ||
import IPFSFactory from 'ipfsd-ctl' | ||
import logger from './logger' | ||
import { showConnFailureErrorMessage } from './errors' | ||
import { join } from 'path' | ||
import fs from 'fs-extra' | ||
import { spawnSync } from 'child_process' | ||
import findExecutable from 'ipfsd-ctl/src/utils/find-ipfs-executable' | ||
hacdias marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export default async function createDaemon (opts) { | ||
opts.type = opts.type || 'go' | ||
opts.path = opts.path || '' | ||
opts.flags = opts.flags || ['--migrate=true', '--routing=dhtclient'] | ||
opts.keysize = opts.keysize || 4096 | ||
function repoFsck (path) { | ||
const exec = findExecutable('go', join(__dirname, '..')) | ||
spawnSync(exec, ['repo', 'fsck'], { | ||
env: { | ||
...process.env, | ||
IPFS_PATH: path | ||
} | ||
}) | ||
} | ||
|
||
if (opts.type !== 'go') { | ||
throw new Error(`${opts.type} connection is not supported yet`) | ||
async function configure (ipfsd) { | ||
const cfgFile = join(ipfsd.repoPath, 'config') | ||
const cfg = await fs.readJSON(cfgFile) | ||
|
||
let origins = [] | ||
try { | ||
origins = cfg.API.HTTPHeaders['Access-Control-Allow-Origin'] | ||
} catch (e) { | ||
logger.warn(e) | ||
} | ||
|
||
const factory = IPFSFactory.create({ type: opts.type }) | ||
if (!Array.isArray(origins)) { | ||
origins = [] | ||
} | ||
|
||
if (!origins.includes('webui://-')) origins.push('webui://-') | ||
lidel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!origins.includes('https://webui.ipfs.io')) origins.push('https://webui.ipfs.io') | ||
|
||
cfg.API.HTTPHeaders['Access-Control-Allow-Origin'] = origins | ||
cfg.API.HTTPHeaders['Access-Control-Allow-Methods'] = ['PUT', 'GET', 'POST'] | ||
|
||
await fs.writeJSON(cfgFile, cfg) | ||
} | ||
|
||
async function spawn ({ type, path, keysize }) { | ||
const factory = IPFSFactory.create({ type: type }) | ||
|
||
const ipfsd = await new Promise((resolve, reject) => { | ||
return new Promise((resolve, reject) => { | ||
factory.spawn({ | ||
disposable: false, | ||
defaultAddrs: true, | ||
repoPath: opts.path | ||
repoPath: path | ||
}, (e, ipfsd) => { | ||
if (e) return reject(e) | ||
if (ipfsd.initialized) { | ||
return resolve(ipfsd) | ||
} | ||
|
||
ipfsd.init({ | ||
directory: opts.path, | ||
keysize: opts.keysize | ||
directory: path, | ||
keysize: keysize | ||
}, e => { | ||
if (e) return reject(e) | ||
resolve(ipfsd) | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
if (!ipfsd.started) { | ||
await new Promise((resolve, reject) => { | ||
ipfsd.start(opts.flags, err => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
async function start (ipfsd, { flags }) { | ||
await new Promise((resolve, reject) => { | ||
ipfsd.start(flags, err => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
|
||
resolve() | ||
}) | ||
resolve() | ||
}) | ||
}) | ||
} | ||
|
||
export default async function (opts) { | ||
const ipfsd = await spawn(opts) | ||
await configure(ipfsd) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If ipfsd connects to an existing daemon process, and we change it's config, we would need to restart that process for the config to be applied. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @olizilla we're now editing the config file directly so we won't even be able to change the config of remote daemons. Perhaps it would be better to revert this change and use the API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ping @olizilla There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
if (!ipfsd.started) { | ||
await start(ipfsd, opts) | ||
} | ||
|
||
let origins = [] | ||
try { | ||
origins = await ipfsd.api.config.get('API.HTTPHeaders.Access-Control-Allow-Origin') | ||
await ipfsd.api.id() | ||
} catch (e) { | ||
logger.warn(e) | ||
} | ||
if (!e.message.includes('ECONNREFUSED')) { | ||
hacdias marked this conversation as resolved.
Show resolved
Hide resolved
|
||
throw e | ||
} | ||
|
||
if (!origins.includes('webui://-')) origins.push('webui://-') | ||
if (!origins.includes('https://webui.ipfs.io')) origins.push('https://webui.ipfs.io') | ||
if (!showConnFailureErrorMessage(ipfsd.repoPath, ipfsd.apiAddr)) { | ||
throw new Error('exit') | ||
} | ||
|
||
await ipfsd.api.config.set('API.HTTPHeaders.Access-Control-Allow-Origin', origins) | ||
await ipfsd.api.config.set('API.HTTPHeaders.Access-Control-Allow-Methods', ['PUT', 'GET', 'POST']) | ||
repoFsck(ipfsd.repoPath) | ||
await start(ipfsd, opts) | ||
} | ||
|
||
return ipfsd | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { app, dialog, shell } from 'electron' | ||
|
||
const issueTemplate = (e) => `Please describe what you were doing when this error happened. | ||
hacdias marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
**Specifications** | ||
|
||
- **OS**: ${process.platform} | ||
- **IPFS Desktop Version**: ${app.getVersion()} | ||
- **Electron Version**: ${process.versions.electron} | ||
- **Chrome Version**: ${process.versions.chrome} | ||
|
||
**Error** | ||
|
||
\`\`\` | ||
${e.stack} | ||
\`\`\` | ||
` | ||
|
||
export function showErrorMessage (e) { | ||
const option = dialog.showMessageBox({ | ||
type: 'error', | ||
title: 'IPFS Desktop has shutdown', | ||
message: 'IPFS Desktop has shutdown because of an error. You can restart the app or report the error to the developers, which requires a GitHub account.', | ||
buttons: [ | ||
'Close', | ||
'Report the error to the developers', | ||
'Restart the app' | ||
], | ||
cancelId: 0 | ||
}) | ||
|
||
if (option === 1) { | ||
shell.openExternal(`https://github.com/ipfs-shipyard/ipfs-desktop/issues/new?body=${encodeURI(issueTemplate(e))}`) | ||
} else if (option === 2) { | ||
app.relaunch() | ||
} | ||
|
||
app.exit(1) | ||
} | ||
|
||
export function showConnFailureErrorMessage (path, addr) { | ||
const option = dialog.showMessageBox({ | ||
type: 'warning', | ||
title: 'IPFS Desktop', | ||
message: `IPFS Desktop failed to connect to an existing ipfs api at ${addr}. This can happen if you run 'ipfs daemon' manually and it has not shutdown cleanly. Would you like to try running 'ipfs repo fsck' to remove the lock and api files from ${path} and try again?`, | ||
buttons: [ | ||
'No, just quit', | ||
'Yes, run "ipfs repo fsck"' | ||
], | ||
cancelId: 0 | ||
}) | ||
|
||
return option === 1 | ||
} |
Uh oh!
There was an error while loading. Please reload this page.