DoomHammer / brewstrap

Bootstraps Linuxbrew on machines lacking necessary tools (such as Chromebooks and embedded)
Other
6 stars 0 forks source link

initial look, some issues #1

Open minektur opened 8 years ago

minektur commented 8 years ago

first issue with brewstrap: chromebooks have the user homedir mounted noexec - so... I see that you're extracting and running in $HOME - I set my $home to /usr/local/tempbrew, which is ok in the short run - might want to prompt for a spot, or pick $HOMEBREW_PREFIX/.brewstrap or something My goal is to end up with linuxbrew installed in /usr/local, but still have a normal ~.linuxbrew directory with cache and logs etc.

This brings up the point that I need to set $HOMEBREW_PREFIX to the right place (/usr/local in my case) Perhaps update the readme to mention setting it.

In this case this is what I do...

export HOMEBREW_PREFIX=/usr/local
bash brewstrap-0.1.sh

brewstrap-0.1.sh: line 16 /home/chronos/user/.linuxbrew/Cellar/brewstrap/0.1/bin/ruby: Permission denied

so I edit brewstrap-0.1.sh and change BREWSTRAP_DIR to BREWSTRAP_DIR=$HOMEBREW_PREFIX/.linuxbrew/Cellar/brewstrap/$VERSION and fix up a few other places it is used (replacing $HOME)

Next, the linuxbrew-install file you download hard-code munges HOMEBREW_PREFIX overwriting the one I set... even though the script comments at the top claim otherwise... so I fake that by inserting a sleep in brewstrap-0.1.sh just before linuxbrew-install is invoked, I swap in a modified version that sets HOMEBREW_PREFIX right.

Second, at some point you swap out /usr/bin/which with /bin/which or something or other. On my chromebook /bin/which doesn't exist, only /usr/bin/which.... curl also - it lives at /usr/bin/curl but... hm. I just edited linuxbrew-install to just call 'which' rather than by full path. This probably isn't the right long term fix.

Press RETURN to continue or any other key to abort
==> Downloading and installing Linuxbrew...
sh: /bin/which: not found
curl:  (1) Protocol "git" not supported or disabled in libcurl

gzip: stdin: unexpected end of file
tar: Child returned status 1

followed by a bunch of brew: command not found lines...

So, fixing up /bin/which back to /usr/bin/which makes that work and the curl error above also disappears.

A lot more happens - lots of git-clone errors and stuff I'll have to dig in to later.

Looks like some stuff is missing, some ends up in /usr/local/.linuxbrew/Cellar and some stuff is in /usr/local/

so far most of the issues seem to be related to the fact that I'm NOT building in $HOME/.linuxbrew (because of the noexec thing...)

DoomHammer commented 8 years ago

First of all: thanks for trying this out. You are the first known user of brewstrap :)

Second: this was not written with Chromebooks in mind, but it would be great if brewstrap could work with Chromebooks (and generally Chrom(e|ium)OS). Since I lack the machine myself I hope I could try a VM.

Third: yeah, replacing one set of hardcoded paths to another set of hardcoded paths is not very wise, I shall deal with it.

As for the installer overriding $HOMEBREW_PREFIX @sjackman is the competent person, I think.

I'll try to take into account your suggestions and come up with another version.

sjackman commented 8 years ago

I think that comments means edit the script and change the value of HOMEBREW_PREFIX, which isn't terribly user friendly. I believe it's intentional that the environment variable HOMEBREW_PREFIX is ignored, in case the user has that variable set unintentionally. Homebrew doesn't encourage installing in directories other than /usr/local, but Linuxbrew does, so there should be some mechanism to specify the destination directory. Perhaps a command line argument.

As a work around, to install in a different directory, you could set HOME to /usr/local for example to install in /usr/local/.linuxbrew.

It's not recommended to install Linuxbrew in /usr/local itself, because the libraries installed in /usr/local/lib could break your host system, because /usr/local/lib is usually in the default library search path. Homebrew avoids linking libraries that would break your host system, but Linuxbrew does not, by design.

minektur commented 8 years ago

Yeah. Ideally, what I'd like is for stuff to end up all in /usr/local. I'd be ok with a ~/.linuxbrew that has a bottle/sourcecode cache.

My main issue seems to be that /home/chronos is mounted noexec and this installer seems to want to put executables there.

As for setting $HOME to be /usr/local.... well I tried that and I got a different set of issues. I'm happy to retry later. I'm really just trying to get a working mostly full linux environment, non-virtualized, non-containerized on my chromebook.

Crouton is OK, if you like ubuntu and can stand a dual-view of the world, chromebrew is very out of date and doesn't have many packages, though for the most part it works ok. Linuxbrew would make me feel more at home (because I've been using homebrew on my macbook)... I spent some effort following the 'chromebrew to bootstrap linuxbrew' as detailed elsewhere and got about 90% of the way to a working system. I've still got some lingering glibc package issue and I had to wrap the gcc command with a script that always adds -B/usr/local/linuxbrew/bin, but I'm still kind of stuck. brewstrap is an idea I had forming in the back of my mind through all of this - a tool that would run on a very minimal system and NOT use the normal tools to make an install, but would just dump a possibly outdated, but working full tool-chain that could then update itself/self-host.

At any rate... well, I'm making incremental progress. Thanks both of you for your efforts.

sjackman commented 8 years ago

and I had to wrap the gcc command with a script that always adds -B/usr/local/linuxbrew/bin

You can instead export GCC_EXEC_PREFIX=/usr/local/linuxbrew/bin See https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

DoomHammer commented 8 years ago

Found a VM wih ChromiumOS but it is constantly rebooting for me. @minektur any idea when I can get a stable/working one?

minektur commented 8 years ago

@sjackman the issue was that the arguments passed to ld didn't give crt1.o and crti.o by full path, and the link would fail because of it. (and the built in paths didn't get passed right to ld) Eventually I noticed that -B would give me what I wanted - it's kind of a shotgun approach since it modifies the paths for compilation, assembly, and linking. I never could get the right behaviour with the build-stage-specific flags or environment variables. I confess that I didn't try setting GCC_EXEC_PREFIX and I'll try it out tonight. I've got tarballs of the linuxbrew at that state so it should be a quick test.

@doomhammer - you're looking for an image for docker? or for virtualbox? kvm? I'll look around and see what I can find.

sjackman commented 8 years ago

I belive setting LIBRARY_PATH to the location of crt1.o and crti.o should work.

DoomHammer commented 8 years ago

Vagrant/Virtualbox would be good, Docker as well. I can even live with a raw .img as long as it behaves like a Chromebook should.

minektur commented 8 years ago

Ok - to get a virtual chromeos build similar to what I have with a real chromebook you can use 'cloudready'.

http://www.neverware.com/

Download the free-for-personal use image, use 7z to unzip (because some builds of zip dont support the right compression), and then follow the instructions here:

https://equk.co.uk/2016/02/19/cloudready-virtualbox/

to turn it in to a virtualbox image. (note the required special virtualbox settings)

Once you boot that up, you have to do a bunch of initial setup that they prompt for, including using some google account for authentication.

Once you're there, then:

cntrl-alt-f2 gets you to a console screen that you'll only use once generally. log in as root (no password) and run chromeos-setdevpasswd

This password is what you'll use as the password for the "main" chromeos user - chronos. It will also work for sudo. Exit from that shell, and you'll be back to the desktop - run chromium and open a shell tab with cntrl-alt-t to get to a chrosh prompt. type 'shell' here and you'll be the chronos user logged in.

You'll note that for some reason you dont start in your home directory .... At any rate, your home directory is writable by you, but is mounted noexec. A 'real' chromebook has an empty /usr/local at this point and that is where I started trying to install chromebrew->linuxbrew and brewstrap->linuxbrew

Since this is not an official google build, there is a bunch of extra cloudready-provided stuff in /usr/local.

At this point, try brewstrap and you'll see the same issues I'm having...

edit: you may want to install the chronos chrome browser plugin for cut-and-paste integration also...

minektur commented 8 years ago

Oh, one more thing - one other difference between cloudready and chromeos is that on chromeos /usr/local is owned by and rwx-able by chronos user - you'll have to fix that.

I've been testing by making /usr/local/fred/ and dropping all my temp files there and running brewstrap from there.

DoomHammer commented 8 years ago

Seems working OK, will see what I can do :)

DoomHammer commented 8 years ago

So far so good. Basic tools installed to /opt/linuxbrew, but failing on gdbm (required by perl required by openssl required by curl, git, and such). Investigating.

DoomHammer commented 8 years ago

Ah, noexec on /tmp :)

sjackman commented 8 years ago

You can set HOMEBREW_TEMP to $HOME/tmp.

DoomHammer commented 8 years ago

@sjackman yeah, I figured that, just writing down obstacles for further reference :)

@minektur could you check out #7? I tested it with my ChromiumOS thus:

sudo mount -oremount,rw /
sudo mkdir -p /opt/linuxbrew
sudo chown chronos:chronos /opt/linuxbrew
HOMEBREW_DIR=/opt/linuxbrew sh brewstrap-0.1.sh

It is installed to /opt because /usr/local lacked the necessary space in my case. Installation took around 2h on my VM, but some of this time could be shaved by using bottled formulae. For this, though, we should first agree where Linuxbrew should be installed on Chromebooks ;)

sjackman commented 8 years ago

we should first agree where Linuxbrew should be installed on Chromebooks ;)

Does installing Linuxbrew in /home/linuxbrew/.linuxbrew require unlocking the device? As a workaround hack, /home/linuxbrew/.linuxbrew could be a symlink to /opt/linuxbrew.

minektur commented 8 years ago

So, MOST chromebooks only have /usr/local available to install software without noexec. There are a couple of layers of "unlocking" a chromebook that people can do:

1) dev mode - it enables shell access, you can (and should) set a root password, and you get access as the one unix uid that all the default chromebook stuff runs under (chronos). You CAN write to /tmp and ~ and /usr/local and that's about it.

2) You can also, after step 1, run a special command to make everything else RW instead of read-only and then have true, full control over the machine.

From my perspective, it would be desirable to NOT require item 2 on this list to install linuxbrew. The benefits you get from this are:

The costs of this are many, but perhaps livable:

So, what I was hoping for was for linuxbrew to be installed in /usr/local/* or failing that, in /usr/local/linuxbrew (or /usr/local/linuxbrew/.linuxbrew ?). I'm hoping I can get enough comfortable tools to not need crouton because... well, bloat and complication. If there were a centos-cli-only target I'd probably have never ended up looking at homebrew/chromebrew/linuxbrew). I'm about 95% of the way there by just building a crouton image, HOME=/usr/local/linuxbrew, HOMEBREW_TEMP=/usr/local/tmp and then doing a 'normal' installation as a non-privileged user inside crouton, then taring it up and dropping it outside the chroot. If I had a little more fine-grained control over directories and some better skill with patchelf (and a lot more patience) I could just make it all install in /usr/local...

All of that said, I COULD try your install, but it would involve a factory-wipe of my chromebook 2 times.... But if I could sweet-talk you into changing it to be /usr/local/linuxbrew or or /usr/local then I could just tar up my current /usr/local, do your install, and try it out, and then just rm-then-unpack to be back to normal.... Would it be possible to change this? Let me know - I dont want to be a demanding irritant and then not respond to your reasonable requests, but I'm reluctant to do the magic needed to make / RW, and I dont really want to end up there in the long run anyway.

minektur commented 8 years ago

I might add that step 1 is all crouton requires, and they actually mildly advise against step2 in unlocking.... I'm not saying that linuxbrew should be just like them, but... more that it seems like a lower hurdle to ask of users...

DoomHammer commented 8 years ago

@minektur I have used /opt/linuxbrew myself, but the script should work as well with /usr/local. Just try HOMEBREW_DIR=/usr/local sh brewstrap-0.1.sh with brewstrap deployed from #7. It should do most of what you need.

minektur commented 8 years ago

Sorry for the long delay in response.

Here is a gist that shows both what I did to start the install, and the output:

https://gist.github.com/minektur/29694ec4b41e33e7c79b520d0145a484

At this point some stuff works - a random sampling - more, bash, tset file, od all run.

Git is missing, brew wont run because ruby seems to be missing

which: no ruby in (/usr/local/linuxbrew/.linuxbrew/bin:/usr/local/linuxbrew/.linuxbrew/sbin:/usr/local/linuxbrew/.linuxbrew/b    in:/usr/local/linuxbrew/.linuxbrew/sbin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/local/bin:/usr/local/bin)
Error: No Ruby found, cannot proceed.

bash-4.3$ find /usr/local/linuxbrew -name 'ruby'
/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/include/ruby-2.1.0/x86_64-linux/ruby
/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/include/ruby-2.1.0/ruby
/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/lib/ruby
/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/bin/ruby
/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/bin.real/ruby
/usr/local/linuxbrew/.linuxbrew/Cellar/libmagic/5.25/share/misc/magic/ruby

And glibc doesn't seem to be 'brew link'd correctly or maybe it's a build path problem. @sjackman was saying that it should be solvable by LD_LIBRARY_PATH settings but I've not found a magic combination that works:

/usr/local/linuxbrew/.linuxbrew/bin/ld: cannot find crt1.o: No such file or directory
/usr/local/linuxbrew/.linuxbrew/bin/ld: cannot find crti.o: No such file or directory

env | grep LD_LIB
LD_LIBRARY_PATH=/usr/local/linuxbrew/.linuxbrew/lib:/usr/local/linuxbrew/.linuxbrew/lib64

I could see the compiler that brewstrap was using doing the right thing so something must be different in the environment, path, etc.

DoomHammer commented 8 years ago

Great, thanks for testing, I will check this later :)

sjackman commented 8 years ago

Not LD_LIBRARY_PATH but LIBRARY_PATH to specify the link-time location of crt1.o

DoomHammer commented 8 years ago

brew sh should take care for setting $LIBRARY_PATH correctly for ld.

DoomHammer commented 8 years ago

OK, @minektur, from what I see openssl failed to install in your case. Could you post the following as well?

PATH=/usr/local/linuxbrew/.linuxbrew/Cellar/brewstrap/0.1/bin:/usr/local/linuxbrew/.linuxbrew/bin:$PATH /usr/local/linuxbrew/.linuxbrew/bin/brew postinstall openssl
DoomHammer commented 8 years ago

I think I see where the problem might have come from. Updated the PR, could you try again @minektur ?

minektur commented 8 years ago

Results here:

https://gist.github.com/minektur/272c47111ee7fbf9a3cfe0fc90309566

Notes: I THINK somehow along the way my HOMEBREW_TEMP directory got deleted... I had to recreate it after everything was done.

There are two output files - output 1 is where it died the first time (I verified this twice by restarting from scratch). It couldn't download curl for some reason. So, I downloaded it manually and dropped it in ~/.cache/Homebrew and wiped /usr/local/linuxbrew and restarted (hm did I nuke /usr/local/linuxbrew/tmp?)

After I restarted it seemed to succede - no major errors I noticed.

I was then able to

brew install less

and it worked...

I think made the ?mistake? of doing

brew update

and you can see the results - a bunch of local changes in my tree got stashed, and then brew wouldn't work any more, and a git pop had merge conflicts.

DoomHammer commented 8 years ago

Should have mentioned earlier: brewstrapped systems should use sbrew instead of brew (at least for now). This is a wrapper that takes care of update process as well as uses internal bash in cases when system one is unavailable.

Other than that it seems to be looking good, am I right?

As for the curl: downloading it wasn't necessary as I have fixed the problem that led to broken openssl installation.

aghasemi commented 7 years ago

Hi, I tried to follow the instructions here and install brewstrap using chrombrew as host on a ChromiumOS. I ran these

sudo mount -oremount,rw /
sudo mkdir -p /opt/linuxbrew
sudo chown chronos:chronos /opt/linuxbrew
HOMEBREW_DIR=/usr/local/linuxbrew sh brewstrap-0.1.sh

Here is what happened:

==> This script will install:
/usr/local/.linuxbrew/bin/brew
/usr/local/.linuxbrew/Library/...
/usr/local/.linuxbrew/share/doc/homebrew
/usr/local/.linuxbrew/share/man/man1/brew.1
/usr/local/.linuxbrew/share/zsh/site-functions/_brew
/usr/local/.linuxbrew/etc/bash_completion.d/brew
/usr/local/.cache/Homebrew/

Press RETURN to continue or any other key to abort
==> Downloading and installing Linuxbrew...
remote: Counting objects: 1040, done.
remote: Compressing objects: 100% (930/930), done.
remote: Total 1040 (delta 106), reused 481 (delta 75), pack-reused 0
Receiving objects: 100% (1040/1040), 1.01 MiB | 806.00 KiB/s, done.
Resolving deltas: 100% (106/106), done.
From git://github.com/Linuxbrew/brew
 * [new branch]      master     -> origin/master
HEAD is now at e12daa5 pull: Support brew pull --tap=homebrew/dupes 1234
sed: can't read /usr/local/.linuxbrew/Library/brew.sh: No such file or directory
sed: can't read /usr/local/.linuxbrew/Library/ENV/scm/git: No such file or directory
To restore the stashed changes to /usr/local/.linuxbrew run:
  'cd /usr/local/.linuxbrew && git stash pop'
==> Homebrew has enabled anonymous aggregate user behaviour analytics
Read the analytics documentation (and how to opt-out) here:
  https://git.io/brew-analytics
==> Tapping homebrew/core
Cloning into '/usr/local/.linuxbrew/Library/Taps/homebrew/homebrew-core'...
remote: Counting objects: 3773, done.
remote: Compressing objects: 100% (3663/3663), done.
remote: Total 3773 (delta 12), reused 334 (delta 1), pack-reused 0
Receiving objects: 100% (3773/3773), 3.05 MiB | 1.19 MiB/s, done.
Resolving deltas: 100% (12/12), done.
Checking connectivity... done
Tapped 3651 formulae (3,800 files, 9.5M)
Error: No such file or directory - /usr/local/linuxbrew/tmp/github_api_headers20161106-18757-1nfkimv
Error: Failure while executing: /usr/local/.linuxbrew/bin/brew tap homebrew/core
Warning: /usr/local/.linuxbrew/bin is not in your PATH.
==> Installation successful!
==> Next steps
Install the Linuxbrew dependencies:

Debian, Ubuntu, etc.:
  `sudo apt-get install build-essential`

Fedora, Red Hat, CentOS, etc.:
  `sudo yum groupinstall 'Development Tools'`

See http://linuxbrew.sh/#dependencies for more information.

Add to your ~/.bash_profile by running
  echo 'export PATH="/usr/local/.linuxbrew/bin:$PATH"' >>~/.bash_profile
  echo 'export MANPATH="/usr/local/.linuxbrew/share/man:$MANPATH"' >>~/.bash_profile
  echo 'export INFOPATH="/usr/local/.linuxbrew/share/info:$INFOPATH"' >>~/.bash_profile

We recommend you install GCC by running `brew install gcc`.
Run `brew help` to get started
Further documentation: https://git.io/brew-docs
==> Homebrew has enabled anonymous aggregate user behaviour analytics
Read the analytics documentation (and how to opt-out) here:
  https://git.io/brew-analytics
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: brew: not found
./dist/brewstrap-0.1.sh: 109: cannot create /bin/sbrew: Permission denied
./dist/brewstrap-0.1.sh: 109: brew: not found
chmod: cannot access ‘/bin/sbrew’: No such file or directory
./dist/brewstrap-0.1.sh: 109: sbrew: not found
./dist/brewstrap-0.1.sh: 109: sbrew: not found

Any suggestion?