Skip to content
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

Unable to install hyperdrive-daemon on a Raspberry Pi #49

Open
reaktivo opened this issue May 15, 2020 · 20 comments
Open

Unable to install hyperdrive-daemon on a Raspberry Pi #49

reaktivo opened this issue May 15, 2020 · 20 comments

Comments

@reaktivo
Copy link
Contributor

Describe the bug
I've managed to get the hyperdrive-daemon working on macOS by installing latest Fuse and switching to Node 12 and it's working fantastic.

But I'm still having trouble installing the hyperdrive-daemon on a Raspberry Pi, without any issues. It's hard to tell if the following error is the origin of the issue, since we npm only considers fuse-native an optional dependency, but it might be a clue.

I would love to get this working since I have a few rPi distributed in different places that I would like to have connected to each other so I can help debugging.

I have a rPi running at home, and I can provide you root ssh access if it would help debugging. Just let me know.

➜  ~ npm i hyperdrive-daemon@latest -g
/home/me/.node/bin/hyperdrive -> /home/me/.node/lib/node_modules/hyperdrive-daemon/bin/run/run

> fuse-native@2.2.1 install /home/me/.node/lib/node_modules/hyperdrive-daemon/node_modules/fuse-native
> node-gyp-build

make: Entering directory '/home/me/.node/lib/node_modules/hyperdrive-daemon/node_modules/fuse-native/build'
  CC(target) Release/obj.target/fuse/fuse-native.o
  SOLINK_MODULE(target) Release/obj.target/fuse.node
/usr/bin/ld: /home/me/.node/lib/node_modules/hyperdrive-daemon/node_modules/fuse-shared-library-linux/libfuse/lib/libfuse.so: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
make: *** [fuse.target.mk:142: Release/obj.target/fuse.node] Error 1
make: Leaving directory '/home/me/.node/lib/node_modules/hyperdrive-daemon/node_modules/fuse-native/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:310:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Linux 5.4.0-1008-raspi
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/me/.node/lib/node_modules/hyperdrive-daemon/node_modules/fuse-native
gyp ERR! node -v v12.16.3
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/hyperdrive-daemon/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"arm64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fuse-native@2.2.1 (node_modules/hyperdrive-daemon/node_modules/fuse-native):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fuse-native@2.2.1 install: `node-gyp-build`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1

+ hyperdrive-daemon@1.13.8
updated 1 package in 33.935s
➜  ~ node -v
v12.16.3
➜  ~ npm -v
6.14.4

To Reproduce
npm install -g hyperdrive-daemon

Expected Behavior
What did you expect to happen?

A working install of hyperdrive-daemon

** OS **

➜  ~ uname -a
Linux black 5.4.0-1008-raspi #8-Ubuntu SMP Wed Apr 8 11:13:06 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
➜  ~ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04 LTS
Release:	20.04
Codename:	focal

** Node version **

➜  ~ node -v
v12.16.3

** Was the daemon installed from NPM or bundled with Beaker? **

Installed via NPM

Add any other context about the problem here.

Noticed that the hyperdrive directory on home is never created either

Added a asciinema recording here: https://asciinema.org/a/ycJvsngG7P8RBtrMVmzAL7sW9

Important Note: Daemon errors are likely to be found in ~/.hyperdrive/log.json or ~/.hyperdrive/output.log (the latter is for unexpected, non-JSON output). These files might contain sensitive drive keys, so don't upload the whole thing -- just extract any stack traces or odd error messages!

@andrewosh
Copy link
Member

Hey @reaktivo,

Glad you got the other issue fixed and it's working well on the other machine :)

Hmm we do have a prebuilt FUSE shared library for ARM that should work on your Raspberry Pi, but I don't think we've done any end-to-end tests on ARM with the daemon.

Does the installation fail completely, or are you still able to start the daemon and get a status out (hyperdrive status)?

@reaktivo
Copy link
Contributor Author

Hey @andrewosh,

I'm getting:

➜  ~ hyperdrive fuse-setup
FUSE bindings are not available on this platform.
FUSE installation failed. You will be unable to mount your hyperdrives.
➜  ~ hyperdrive status
FUSE bindings are not available on this platform.
The Hyperdrive daemon is running:

  API Version:             0
  Daemon Version:          1.13.8
  Client Version:          1.14.7
  Schema Version:          1.9.1
  Hyperdrive Version:      10.10.4
  Fuse Native Version:
  Hyperdrive Fuse Version:

  Holepunchable:           false
  Remote Address:

  Fuse Available:          false
  Fuse Configured:         false

  Uptime:                  0 Days 5 Hours 32 Minutes 29 Seconds

@bndw
Copy link

bndw commented May 16, 2020

I was able to successfully install on a raspberry pi, but the daemon seems to fail silently.

hyperdrive start
✔ Hyperdrive daemon listening on localhost:3101
hyperdrive status
The Hyperdrive daemon is not running.

EDIT: Looks like I'm OOM... I'll retest with a fresh pi and post an update.

cat ~/.hyperdrive/log.json
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

@andrewosh
Copy link
Member

Thanks @reaktivo and @bndw.

@reaktivo it looks like the FUSE failure doesn't block the rest of the installation (as intended), so your daemon is still running, but you won't be able to use FUSE-related commands. Most the the CLI commands require FUSE so this doesn't leave you with much at the moment :(

I have a raspberry pi so I'm gonna debug this next week. Definitely want FUSE to work there, we just haven't tested it enough.

@bndw interesting. How much ram does your pi have? I'll look into this when working on the FUSE fix too.

Thanks again

@bndw
Copy link

bndw commented May 16, 2020

Testing on a Raspberry Pi 3 Model B+ running Raspbian Buster Lite with 1GB of ram.

free -m
              total        used        free      shared  buff/cache   available
Mem:            926          64         307           6         554         795
Swap:            99           0          99

I just retested with a fresh install of the OS and hit the same allocation failures--

hyperdrive start
✔ Hyperdrive daemon listening on localhost:3101

hyperdrive status
The Hyperdrive daemon is not running.

cat ~/.hyperdrive/log.json
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

cat ~/.hyperdrive/output.log

<--- Last few GCs --->

[1324:0x5168c90]      285 ms: Mark-sweep 1.0 (3.5) -> 1.0 (3.5) MB, 8.8 / 0.0 ms  (average mu = 0.708, current mu = 0.122) allocation failure GC in old space requested
[1324:0x5168c90]      293 ms: Mark-sweep 1.0 (3.5) -> 1.0 (2.0) MB, 6.6 / 0.0 ms  (average mu = 0.596, current mu = 0.153) last resort GC in old space requested
[1324:0x5168c90]      301 ms: Mark-sweep 1.0 (2.0) -> 1.0 (2.0) MB, 8.2 / 0.0 ms  (average mu = 0.419, current mu = 0.007) last resort GC in old space requested

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x5348e4ad <JSObject>
    0: builtin exit frame: compileFunction(this=0x3fd41ca1 <JSGlobal Object>,0x5349973d <String[2]: fs>,0x3fd41ca1 <JSGlobal Object>)

    1: compileForInternalLoader [0x2d7437e5] [internal/bootstrap/loaders.js:275] [bytecode=0x534a1a91 offset=75](this=0x2d744281 <NativeModule map = 0x3d4c77f1>)
    2: nativeModuleRequire(aka nativeModuleRequire) [0x534aa9b1] [internal/bootstrap/loaders.js:305] [byt...

@andrewosh Happy to help debug or retest, lmk.

@andrewosh
Copy link
Member

Thanks for the info @bndw, we should probably expose a way to start the daemon with a configurable heap size. It looks like I didn't expose a flag for that on hyperdrive start unfortunately.

If it's easy for you to try, mind hard-coding the heap size on this line to 512?

var interpreterArgs = `--max-old-space-size=${opts.heapSize}`

Let's see if that does the trick. I'm gonna get my raspberry pi set up for testing this weekend :)

@bndw
Copy link

bndw commented May 17, 2020

@andrewosh hard-coding heap size to 512 got the server to boot successfully 👍

{"level":30,"time":1589676280544,"pid":851,"hostname":"raspberrypi","name":"hyperdrive","component":"server","msg":"memory only? false no announce? false","v":1}
{"level":30,"time":1589676280688,"pid":851,"hostname":"raspberrypi","name":"hyperdrive","component":"server","swarmId":"5809e18aca8c2307641b1b52d07a0ba6f4f37deb425ed337328615022980fa3f","seed":"abb404224c090ce5fb565713e2fc4c7cd47bb59457a7bcac6c3bf407fe4f2f84","msg":"creating replication keypair and swarm ID","v":1}
{"level":30,"time":1589676280746,"pid":851,"hostname":"raspberrypi","name":"hyperdrive","component":"server","port":3101,"msg":"server listening","v":1}

How would I test seeding a drive with this daemon? I tried hyperdrive mount --seed . hyper://my-profile-drive but got errors about not being contained within the Hyperdrive mountpoint.

@andrewosh
Copy link
Member

Nice! OK I'll expose a heap size flag for this.

Did you run that command from within ~/Hyperdrive? You'll want to give it a named path (not just '.'), so something like:
hyperdrive mount --seed ~/Hyperdrive/beaker-profile hyper://...

@andrewosh
Copy link
Member

andrewosh commented May 17, 2020

To be clear though if you're planning on using your raspberry pi as an always-online seeder, that command's not gonna cut it (because it's not going to eagerly sync changes from your main machine). To do that, you currently have to do something ugly involving running the export command (which watches the drive for changes) in the background.

Adding a mirror command that can be used for archiving or making always-online seeders is at the top of my non-bug-related feature list though :)

@bndw
Copy link

bndw commented May 17, 2020

Ahh, I was indeed hoping to use the pi as an always-online seeder. Sounds like it's not yet possible. Thanks!

@akavel
Copy link

akavel commented May 28, 2020

@andrewosh is there some issue somewhere that I could subscribe to to track the progress on the mirror command? I'd love it if I could have my RPi mirror and serve any stuff I created or archived/mirrored/hosted from a Beaker Browser running on my main PC!

@erangell
Copy link

erangell commented Jun 6, 2020

When people figure out how to get hyperdrive-daemon running on a Raspberry Pi, can someone create an Ansible script to automate the tasks, like this: https://piperhaywood.com/raspberry-pi-homebase-dat/

@andrewosh
Copy link
Member

Hey @akavel @erangell there's no top-level issue tracking it at the moment, but I've added the necessary bits to Hyperdrive (this PR) so now it's just a matter of adding an API method for it in the daemon.

Been trudging through bugs for a while, but this is at the top of the feature list for this week.

@akavel
Copy link

akavel commented Jun 7, 2020

@andrewosh Uhh, not really sure what this means, I don't yet really know anything about internal architecture of Hyper at all, but it sounds great and I'm really happy it apparently is close to being available! 😄 And more than that, that you cared so much that you let us know here in this issue! ❤️ ❤️ I understand that asking you to also kindly let us know once the... umm, what was it... API Method Is Added To The Daemon™ (assuming that this probably means I can write hyper mirror and there are some docs/help about how to use it?) might be too much of a stretch, but I'll let myself still try and do it anyway, crossing fingers that you might have enough patience for us to drop by here once again when you're done! 😋 💖

@andrewosh
Copy link
Member

@akavel Yep hyperdrive mirror (some-drive-key) and hyperdrive unmirror (some-drive-key) is exactly what the CLI usage will look like! I'll definitely update this issue when it's out :)

@FergusFettes
Copy link

also looking forward to a working raspberry pi install

I was going to chip in that mounting seemed to mirror fine for me (I set up a hyperdrive in a free gcloud instance since my RPi wasnt working) but I guess thats because I was browsing the file heirarchy, so they all got downloaded right? And If I wasn't there poking around they wouldn't have? Thats funny, kinda Schroedingerian :D. Looking forward to eager mirroring!

@scottsweb
Copy link

scottsweb commented Jun 28, 2020

Watching this with interest. I plan to make a docker container for my Pi that will take a JSON file of hyperdrives and seed them all.

I was also thinking that the JSON file get pulled in from a hyperdrive too - so I could edit it on my machine and have it sync over to the Pi. Might even be able to let others submit their drives too. One step at a time though 😄

@BonsNeuf
Copy link

BonsNeuf commented Aug 23, 2020

I'm excited to see this progress, I set Beaker up on my Mac and it's working fine but I'm massively interested in seeing this progress for a couple of non-tech projects I'm working on. I managed to get an RPi 3 B+ running Raspbian to the boot screen, but had the daemon issue, but I've not been able to get it to build from source on the RPi 4 8GB running Ubuntu 20.04 I put together this weekend. I've tried with node.js 14 and 12, but no joy as yet.

I'm not a coder (although I have started to learn some basics over the last few months) so there are probably solutions to my build issue, I'm don't currently have the understanding. I've had a few of the other issues (sqlite3) etc I've seen in the forums so will try to work through.


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! sqlite3@4.2.0 install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the sqlite3@4.2.0 install script.

Have got the hyperdrive running though.

The Hyperdrive daemon is running:

  API Version:             0
  Daemon Version:          1.14.5
  Client Version:          1.16.0
  Schema Version:          1.11.0
  Hyperdrive Version:      10.17.1
  Fuse Native Version:     
  Hyperdrive Fuse Version: 

  Holepunchable:           false
  Remote Address:          

  Fuse Available:          false
  Fuse Configured:         false

  Uptime:                  0 Days 0 Hours 3 Minutes 16 Seconds

I'm a curator/producer but work in tech in a Product Owner capacity. I am really interested in the P-2-P web for it's educational/knowledge sharing use cases (I came to it having recently discovered the DAT Library/Samiz-DAT project).

Really keen to see an RPI build, as it's an accessible tool to get people on board with the P-2-P web and enabling them to self publish. Great project.

@HDegroote
Copy link

Below I outline my experience in trying to get beaker/hyperdrive to work on a Raspberry Pi 4. It does not help in resolving this issue, but it details a work-around for those looking to use a Raspberry Pi as an always-online seeder for their websites and hyperdrives. In terms of attained functionality, I only managed the bare minimum: reliably hosting a website/drive from the Raspberry Pi itself. Reseeding a drive created elsewhere is possible, but appears to be quite unstable.
Note: I did not manage to get the new @hyperspace/hyperdrive daemon to work (a proposed solution in beakerbrowser/beaker#1767), but the older hyperdrive daemon (of this repository) does work, although anything FUSE-related fails.

I am quite interested in the hyperdrive/beaker project, and particularly in getting it to work properly on a Raspberry Pi. So do let me know if I can help out in any way.

My experience

The npm package for FUSE fails to install on Raspberry Pi 4. However, hypercore and hyperdrive themselves seem to work without problems: the hyperdrive-daemon can be installed successfully, and its import and export statements (which do not rely on FUSE) can be used to host or download drives.
Unfortunately, it seems that FUSE is included as an obligatory dependency in the more recent (and recommended) @hyperspace/hyperdrive package, so this package cannot be used, even though in theory it is possible to use some commands of this package without FUSE (notably import and export). To clarify: @hyperspace/hyperdrive can be installed, but when executing any hyperdrive command, an error is thrown stating that FUSE should be installed.

Instructions for installing the hyperdrive-daemon on Raspberry Pi

(I used a fresh install of Ubuntu server 20.04)

sudo apt update
sudo apt upgrade

Install node V12

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs

Install make and other gcc dependencies

sudo apt-get install build-essential

Install libtool

sudo apt-get install libtool

Using npm out of the box results in permission problems. A clean solution is provided here:
https://www.sitepoint.com/npm-guide/ (Note: there might be a simpler solution. I am new to Node).

Relevant commands:

cd ~ && mkdir .node_modules_global
npm config set prefix=$HOME/.node_modules_global
npm install npm@latest -g
export PATH="$HOME/.node_modules_global/bin:$PATH"

Note: the export PATH command lasts only for the session length. To make the addition to the path permanent (or rather, automatically loaded):
vim ~/.profile

Then add the line at the end of the file (without the export):
PATH="$HOME/.node_modules_global/bin:$PATH"

Install hyperdrive daemon:

npm i hyperdrive-daemon -g

The hyperdrive daemon should now be installed.

Permanent hosting of a hyperdrive on a Raspberry Pi

I found that the easiest way to have a permanent hosting service for a hyperdrive is to simply serve the files directly from the Raspberry Pi. This generally implies preparing the files on another machine, then copying them to the raspberry pi and importing them into hyperdrive, after which they are being served. If the hyperdrive contains a website, it will be rendered as such when visited through Beaker browser.

Once a directory has been imported 100% it is no longer necessary to keep the import command running (if you do leave it running the raspberry pi should automatically serve all changes to the local files, but I have not tested this—I simply re-execute the import statement whenever my files change).

Command to import a local directory into hyperdrive:

hyperdrive import *The path of the dir*

Result:

FUSE is not available on your platform.
Importing *dir_name* into *HASH* (Ctrl+c to exit)...

Importing | ======================================== | 100% | 62/62 Files^C
Exit signal received. Stopping upload...

The hyperdrive should now be reachable remotely, through its hash.

Instructions for reseeding with a Raspberry Pi (note: does not work well)

A more elegant permanent hosting service is achieved by creating and hosting the hyperdrive/beaker website on your main machine, and reseeding it on the Raspberry Pi. To do so, simply export the hyperdrive to the local file system on the Raspberry Pi:

hyperdrive start
hyperdrive export *the_hash_of_the_drive*

By executing this command, the raspberry pi will reseed the drive. It will continue to do so as long as the hyperdrive daemon is running. However, for reasons I do not understand it sometimes takes a really long time (potentially forever) for the raspberry pi to actually offer the content of the drive remotely (Note: I recall reading about similar behaviour in some other issues). I did not bother to extensively debug this issue, but did find an ad-hoc solution for when it occurs. It seems to be solved by importing a new local directory into the hyperdrive system:

mkdir stupid_dir
vim stupid_dir/stupid_file
(now write something stupid in the file, then save it)
hyperdrive import stupid_dir

And instantly I have remote access to not only stupid_dir’s newly created hyperdrive, but also to the one I really want to be hosting.

@phoenixbyrd
Copy link

Hi!

So This is where I currently am... I can get beaker built and running, I can get hyperdrive built and running, but I still can't use beaker as a browser. I'm not sure what's going on or what I'm doing wrong. Just keeps saying Failed to connect to daemon with nothing else really useful. Doesn't matter if I let beaker initialize hyperdrive or if I start hyperdrive manually first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants