iv-org / invidious

Invidious is an alternative front-end to YouTube
https://invidious.io
GNU Affero General Public License v3.0
16.36k stars 1.83k forks source link

[Meta] Research for proper BSD support #2388

Open TheFrenchGhosty opened 3 years ago

TheFrenchGhosty commented 3 years ago

Is your enhancement request related to a problem? Please describe.

Invidious currently doesn't support BSD system (at least correctly).

Describe the solution you'd like

Invidious should support BSD-based system. At a minimum it should support FreeBSD and OpenBSD. Both are supported by Crystal.

Describe alternatives you've considered

N/A

Additional context

Research done (in the Matrix room) - massive thanks to @git-bruh for the help:

Note: I have 0 experience with BSD, everything I was able to do was thanks to my GNU/Linux knowledge, and the documentation I could find.

https://user-images.githubusercontent.com/47571719/132380862-d9cfe130-8332-4eda-813f-1b653b11609c.mp4

https://user-images.githubusercontent.com/47571719/132381053-d41d689c-c40a-4304-9d06-439ef331297c.mp4

sqlite

unixfox commented 3 years ago

Mixed feelings about "Invidious should support BSD-based system", we already have some difficulties with linux itself when it comes to crashes or memory leak so supporting another different operating system is not a good idea.

If one wants to use invidious on bsd then he can launch invidious on docker. Same goes for Windows or MacOS.

At least on my side I'm not going to spend any time supporting a niche OS when invidious is already a niche project.

TheFrenchGhosty commented 3 years ago

@unixfox

Mixed feelings about "Invidious should support BSD-based system", we already have some difficulties with linux itself when it comes to crashes or memory leak so supporting another different operating system is not a good idea.

It's an objective, obviously it won't be done in a day. I worked on this entirely for research purpose, I'm not expecting Invidious to work as is (I wasn't expecting it to even go that far in the build process), however it's really something that I think we should head toward, if possible.

If one wants to use invidious on bsd then he can launch invidious on docker. Same goes for Windows or MacOS.

Well yeah, but it's not really what I was looking for.

PrestonN commented 3 years ago

If one wants to use invidious on bsd then he can launch invidious on docker. Same goes for Windows or MacOS.

I'm sorry, but this is bad advice.

Docker isn't fully supported on BSD. Even articles on installing Docker are suggesting that they run Docker in a virtual machine. The official documentation also mentions that their implementation is broken. With hoops like that, you'd be better off running a Linux server.

FreeBSD as a server is typically already a container and doesn't need most of the benefits of Docker, because those benefits are built natively into the OS via Jails.

I'd personally really love to see a BSD port of Invidious. If it's to happen though, Docker can't be included in the equation.

peepo5 commented 3 years ago

@unixfox It may be a less used OS but supporting BSD just adds to the diversity of the project. Supporting even the niche distro of the niche distros means more people get to use / impliment invidious and what it can do.

peepo5 commented 3 years ago

@TheFrenchGhosty Did you try to install libsqlite3?

TheFrenchGhosty commented 3 years ago

@peepopoggers Sorry I have been busy the last 2 weeks. I haven't done anything more than what was posted in this issue.

peepo5 commented 3 years ago

It's okay :)

unixfox commented 2 years ago

sha1sum command doesn't exist on *BSD so the build doesn't finish properly: https://github.com/iv-org/invidious/blob/master/scripts/fetch-player-dependencies.cr#L92

Reported on matrix by quinq

SamantazFox commented 2 years ago

sha1sum command doesn't exist on *BSD so the build doesn't finish properly: https://github.com/iv-org/invidious/blob/master/scripts/fetch-player-dependencies.cr#L92

Reported on matrix by quinq

Here's the patch they provided, btw:

From 2d88680529a01c70d2456d65c0038ec99368cab8 Mon Sep 17 00:00:00 2001
From: Quentin Rameau <quinq@fifth.space>
Date: Fri, 20 May 2022 20:14:35 +0200
Subject: [PATCH] Try falling back to sha1 if sha1sum isn't available

This would be useful for BSD systems that don't
sha1sum command but sha1 instead.
---
 scripts/fetch-player-dependencies.cr | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/scripts/fetch-player-dependencies.cr b/scripts/fetch-player-dependencies.cr
index ed658b51..3da0a425 100644
--- a/scripts/fetch-player-dependencies.cr
+++ b/scripts/fetch-player-dependencies.cr
@@ -1,6 +1,5 @@
 require "http"
 require "yaml"
-require "digest/sha1"
 require "option_parser"
 require "colorize"

@@ -89,8 +88,16 @@ dependencies_to_install.each do |dep|
       File.write("#{download_path}/package.tgz", data)

       # https://github.com/iv-org/invidious/pull/2397#issuecomment-922375908
-      if `sha1sum #{download_path}/package.tgz`.split(" ")[0] != required_dependencies[dep]["shasum"]
-        raise Exception.new("Checksum for '#{dep}' failed")
+      if `command -v sha1sum >/dev/null`
+        if `sha1sum #{download_path}/package.tgz`.split(" ")[0] != required_dependencies[dep]["shasum"]
+          raise Exception.new("Checksum for '#{dep}' failed")
+        end
+      elsif `command -v sha1 >/dev/null`
+        if `sha1 -q #{download_path}/package.tgz` != required_dependencies[dep]["shasum"]
+          raise Exception.new("Checksum for '#{dep}' failed")
+        end
+      else
+          raise Exception.new("Could not find a sha1 sum tool")
       end
     end

-- 
2.35.1
parski commented 1 year ago

Invidious actually runs out of the box on FreeBSD 13.2. Here's roughly what I did (output omitted):

# pkg install shards crystal postgresql15-server ImageMagick7-nox11 librsvg2 git sqlite3
# /usr/local/etc/rc.d/postgresql initdb
# sysrc postgresql_enable="YES"
# su postgres
$ psql -c "CREATE ROLE <dbuser> WITH PASSWORD '<dbpassword>';"
$ psql -c "ALTER ROLE <dbuser> WITH LOGIN;"
$ createdb -O <dbuser> invidious
$ exit
# git clone https://github.com/iv-org/invidious
# cd invidious
# shards install --production
# crystal build src/invidious.cr --release
# cp config/config.example.yml config/config.yml

Starting PostgreSQL with service postgresql start and running Invidious with ./invidious lets me connect to the machine via a web browser, register and watch videos. No problem.

This is not using the patch above and not setting any environmental variables. Like I said, out of the box. You edit the config like you'd do on a Linux install of course, changing hmac_key, credentials, etc, but no custom compilation or anything.

I have yet to put together an RC script and I have to go but it looks like FreeBSD is well supported now (I noticed that things like sha1sum are native to FreeBSD now, I assume for compatibility with software containing GNU-isms).

The only thing I've found that doesn't work is importing a playlist. That gives me an index out of bounds error. I haven't looked into why that happens.

brennoflavio commented 1 year ago

Invidious actually runs out of the box on FreeBSD 13.2. Here's roughly what I did (output omitted):

# pkg install shards crystal postgresql15-server ImageMagick7-nox11 librsvg2 git
# /usr/local/etc/rc.d/postgresql initdb
# sysrc postgresql_enable="YES"
# su postgres
$ psql -c "CREATE ROLE <dbuser> WITH PASSWORD '<dbpassword>';"
$ psql -c "ALTER ROLE <dbuser> WITH LOGIN;"
$ createdb -O <dbuser> invidious
$ exit
# git clone https://github.com/iv-org/invidious
# cd invidious
# shards install --production
# crystal build src/invidious.cr --release
# cp config/config.example.yml config/config.yml

Starting PostgreSQL with service postgresql start and running Invidious with ./invidious lets me connect to the machine via a web browser, register and watch videos. No problem.

This is not using the patch above and not setting any environmental variables. Like I said, out of the box. You edit the config like you'd do on a Linux install of course, changing hmac_key, credentials, etc, but no custom compilation or anything.

I have yet to put together an RC script and I have to go but it looks like FreeBSD is well supported now (I noticed that things like sha1sum are native to FreeBSD now, I assume for compatibility with software containing GNU-isms).

The only thing I've found that doesn't work is importing a playlist. That gives me an index out of bounds error. I haven't looked into why that happens.

I just spin up a FreeBSD Jail inside a Truenas Core and can confirm that this works exactly as mentioned. Only extra step I had to make is to install sqlite3 as the jail did not came with it pre installed.

I tried to install it in the past using the official documentation without success, glad to see that now its possible!

parski commented 1 year ago

I just spin up a FreeBSD Jail inside a Truenas Core and can confirm that this works exactly as mentioned. Only extra step I had to make is to install sqlite3 as the jail did not came with it pre installed.

Ah yes, I missed the sqlite3 package in my previous post. I installed that as well.

SamantazFox commented 1 year ago

What is needed to run invidious as a service, on FreeBSD (rc.d script I guess, though I never made those) ?

brennoflavio commented 1 year ago

What is needed to run invidious as a service, on FreeBSD (rc.d script I guess, though I never made those) ?

I like to use runit to manage those types of services. Although it's totally possible to run using freebsd init, I found it hard to configure.

I did a guide for myself based on this issue (to not forget when I want to host it again) that has some commands to get it running, you can check if you want:

https://brennoflavio.com.br/posts/invidious-freebsd/

gsuberland commented 11 months ago

I've been trying to get this working, but I've hit a stumbling block. crystal build src/invidious.cr --release runs for a short while, then gets into fetch-player-dependencies.cr, where it fails:

Checking player dependencies, this may take more than 20 minutes... If it is stuck, check your internet connection.
Showing last frame. Use --error-trace for full trace.

In src/invidious.cr:151:13

 151 | {% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
               ^--
Error: Error executing run (exit code: 1): ../scripts/fetch-player-dependencies.cr

stderr:

    Unhandled exception: Error opening file with mode 'r': 'assets/videojs/video.js/versions.yml': No such file or directory (File::NotFoundError)
      from /root/.cache/crystal/usr-share-invidious-scripts-fetch-player-dependencies.cr/macro_run in '__crystal_raise_overflow'
      from /root/.cache/crystal/usr-share-invidious-scripts-fetch-player-dependencies.cr/macro_run in '__crystal_realloc'
      from /root/.cache/crystal/usr-share-invidious-scripts-fetch-player-dependencies.cr/macro_run in '__crystal_main'
      from /root/.cache/crystal/usr-share-invidious-scripts-fetch-player-dependencies.cr/macro_run in 'main'

The assets/videojs/video.js/ directory is empty.

EDIT: Of course, the moment I post about it on here, I find the solution. This was due to a prior failed build. I had to go into assets/videojs and rm -rf ./* to delete the contents of that directory. The script was seeing the empty directories and assuming the dependencies were already met.

vedranmiletic commented 10 months ago

FWIW, I just tested tested the latest master on FreeBSD 14.0-RELEASE-p2 amd64. BSD make is not useful:

% make
make: "/home/iv-user/repo/invidious/Makefile" line 14: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 16: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 18: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 20: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 23: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 25: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 27: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 29: Invalid line type
make: "/home/iv-user/repo/invidious/Makefile" line 31: Invalid line type
make: Fatal errors encountered -- cannot continue
make: stopped in /home/iv-user/repo/invidious

After installing gmake, crystal, and shards:

# pkg install gmake crystal shards

After running gmake, I get:

% gmake
shards install --production
Resolving dependencies
Fetching https://github.com/crystal-lang/crystal-sqlite3.git
Fetching https://github.com/will/crystal-pg.git
Fetching https://github.com/iv-org/protodec.git
Fetching https://github.com/kemalcr/kemal.git
Fetching https://github.com/athena-framework/negotiation.git
Fetching https://github.com/jeromegn/kilt.git
Fetching https://github.com/crystal-lang/crystal-db.git
Fetching https://github.com/luislavena/radix.git
Fetching https://github.com/crystal-loot/exception_page.git
Fetching https://github.com/sija/backtracer.cr.git
Using db (0.10.1)
Using pg (0.24.0)
Using sqlite3 (0.18.0)
Using radix (0.4.1)
Using backtracer (1.2.1)
Using exception_page (0.2.2)
Using kemal (1.1.2)
Using kilt (0.6.1)
Using protodec (0.1.5)
Using athena-negotiation (0.1.1)
crystal build src/invidious.cr --release --debug --progress --stats --error-trace
Parse:                             00:00:00.000754141 (   1.08MB)
[2/13] Semantic (top level)
Checking player dependencies, this may take more than 20 minutes... If it is stuck, check your internet connection.
Player dependencies are satisfied

Done checking player dependencies, now compiling Invidious...
Semantic (top level):              00:00:01.152886258 ( 130.66MB)
Semantic (new):                    00:00:00.007427115 ( 130.66MB)
Semantic (type declarations):      00:00:00.079248419 ( 130.66MB)
Semantic (abstract def check):     00:00:00.046578348 ( 138.66MB)
Semantic (restrictions augmenter): 00:00:00.020878750 ( 146.66MB)
Semantic (ivars initializers):     00:00:00.819621550 ( 210.72MB)
Semantic (cvars initializers):     00:00:00.014882604 ( 218.72MB)
Semantic (main):                   00:00:22.100962382 ( 659.60MB)
Semantic (cleanup):                00:00:00.001624817 ( 659.60MB)
Semantic (recursive struct check): 00:00:00.004206486 ( 659.60MB)
Codegen (crystal):                 00:00:48.358046543 ( 964.60MB)
Codegen (bc+obj):                  00:01:34.325899652 ( 964.60MB)
ld: error: undefined symbol: EVP_MD_size
>>> referenced by digest.cr:77 (/usr/local/lib/crystal/openssl/digest.cr:77)
>>>               _main.o:(*OpenSSL::Digest#digest_size:Int32)
>>> referenced by digest.cr:77 (/usr/local/lib/crystal/openssl/digest.cr:77)
>>>               _main.o:(*Digest::MD5@OpenSSL::Digest#digest_size:Int32)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with code: 1: `cc "${@}" -o /home/iv-user/repo/invidious/invidious  -rdynamic -L/usr/local/bin/../lib/crystal -L/usr/local/lib -lyaml -L/usr/local/lib -lxml2 -L/usr/local/lib -lsqlite3 -lz `command-v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` -L/usr/lib -lcrypto -lpcre -lm -lgc-threaded -lpthread -L/usr/local/lib -levent -lpthread`
gmake: *** [Makefile:45: invidious] Greška 1

This seems like a failure in linking with OpenSSL. FreeBSD 14.0-RELEASE ships OpenSSL 3.0.12. Does Invidious require another version?

gsuberland commented 10 months ago

This seems like a failure in linking with OpenSSL. FreeBSD 14.0-RELEASE ships OpenSSL 3.0.2. Does Invidious require another version?

I'm pretty sure I ran into the exact same error during my attempt. IIRC it wasn't anything to do with OpenSSL, but instead was due to a prior build failing and leaving partial build artifacts in the ~/.cache/shards/ and invidious/lib/ directories. This caused the next build process to assume that the library prereqs were already built even though they hadn't actually completed. After deleting everything in both of those directories and running the build again (incl. the shards command) it stopped throwing this error.

I think the build scripts could probably be improved a little to avoid this. From what I remember of them, they essentially just check if the output directory exists and, if it does, assume that the library is already built. It'd probably be worth having something in the build script that generates some sort of completion indicator file (e.g. touch ./lib/foo/build-complete) once each library build finishes successfully, then do a clean & rebuild on each library if its completion file isn't present when the build is executed. I spent quite a while chasing bugs down rabbit holes that turned out to just be fixed by cleaning the library directories out and re-running the build.

vedranmiletic commented 10 months ago

I'm pretty sure I ran into the exact same error during my attempt. IIRC it wasn't anything to do with OpenSSL, but instead was due to a prior build failing and leaving partial build artifacts in the ~/.cache/shards/ and invidious/lib/ directories. This caused the next build process to assume that the library prereqs were already built even though they hadn't actually completed. After deleting everything in both of those directories and running the build again (incl. the shards command) it stopped throwing this error.

Tried removing both, but it didn't help.

gsuberland commented 10 months ago

The version I have in my jail is openssl32-3.2.0.a2 but I'm fairly certain I got it working on 3.0.12 too.

Maybe try openssl31-3.1.4_1 first, since the 3.2 build is an alpha.

vedranmiletic commented 10 months ago

The version I have in my jail is openssl32-3.2.0.a2 but I'm fairly certain I got it working on 3.0.12 too.

Maybe try openssl31-3.1.4_1 first, since the 3.2 build is an alpha.

Tried both openssl31-3.1.4_1 and openssl32-3.2.0. No change, same error.

Just to check if non-default libcrypto is even discovered, I tried libressl-3.8.2 and got a different error, so the library is discovered correctly. Of course, I didn't expect LibreSSL to work since it is not a drop-in replacement for OpenSSL so it has to be supported explicitely, and Invidious doesn't mention it as such.

SamantazFox commented 10 months ago

What version of Crystal are you using? Newer versions of the Crystal Compiler (>= 1.3) should support OpenSSL 3.x, otherwise you might be hitting https://github.com/crystal-lang/crystal/issues/11231

vedranmiletic commented 10 months ago

What version of Crystal are you using? Newer versions of the Crystal Compiler (>= 1.3) should support OpenSSL 3.x, otherwise you might be hitting crystal-lang/crystal#11231

Interesting, looks like the same linker error. My version is 1.7.3 from lang/crystal in Ports, so I am not sure why am I getting it.

vedranmiletic commented 9 months ago

What version of Crystal are you using? Newer versions of the Crystal Compiler (>= 1.3) should support OpenSSL 3.x, otherwise you might be hitting crystal-lang/crystal#11231

Interesting, looks like the same linker error. My version is 1.7.3 from lang/crystal in Ports, so I am not sure why am I getting it.

FWIW, with Crystal 1.10.1 from Ports, Invidious compiles fine, both with system OpenSSL 3.0 and with OpenSSL 3.2 from Ports.

gsuberland commented 6 months ago

Ran into this again. Solution was to install openssl111 package instead of any of the 3.x versions.

shithubsucks commented 6 months ago

Does anyone have an init script for FreeBSD?

evasil commented 6 months ago

Does anyone have an init script for FreeBSD?

I use this one below:

#!/bin/sh

# PROVIDE: invidious
# REQUIRE: LOGIN
# KEYWORD: shutdown
#
# Add these lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# invidious_enable (bool):       Set to NO by default.
#                               Set it to YES to enable invidious.
# invidious_path (path):       Set to /usr/local/etc/invidious/invidious.yaml
#                               by default.

. /etc/rc.subr

name=invidious
rcvar=invidious_enable
desc="invidious"

load_rc_config $name

: ${invidious_enable:=NO}
: ${invidious_chdir:="/home/invidious/invidious"}

command=/usr/sbin/daemon
procname=/home/invidious/invidious/invidious
pidfile=/var/run/${name}.pid

command_args="-p $pidfile -u invidious -f $procname"

run_rc_command "$1"

Note: invidious_path is not in use on my setup.

TheWanderer1983 commented 2 months ago

Trying to build on OpenBSD 7.5. I get this error at : crystal build src/invidious.cr --release Unhandled exception: SSL_connect: error:20FFF078:BIO routines:CRYPTO_internal:uninitialized (OpenSSL::SSL::Error) After doing some googling it turns out to be related to libreSSL.

https://github.com/crystal-lang/crystal/issues/12647

unixfox commented 2 months ago

two new tools have been released for fixing the latest error message:

I have not personally tested those on freebsd. But they should work with little modification.

Rust is available on freebsd and python too. tell us if something specific to freebsd doesn't work on these tools, ideally create a github issue on the dedicated github repository.

shithubsucks commented 3 weeks ago

Trying to build on OpenBSD 7.5. I get this error at : crystal build src/invidious.cr --release Unhandled exception: SSL_connect: error:20FFF078:BIO routines:CRYPTO_internal:uninitialized (OpenSSL::SSL::Error) After doing some googling it turns out to be related to libreSSL.

crystal-lang/crystal#12647

OpenBSD uses it's own fork of OpenSSL called LibreSSL. You'll need to either patch it to use LibreSSL's api or install OpenSSL and use that.

TheWanderer1983 commented 3 weeks ago

OpenBSD uses it's own fork of OpenSSL called LibreSSL. You'll need to either patch it to use LibreSSL's api or install OpenSSL and use that.

Not anymore, they have built in support for libreSSL.

https://github.com/crystal-lang/crystal/issues/12647