Fork me on GitHub
#babashka
<
2022-06-16
>
jmglov07:06:41

I've got an interesting issue on NixOS. I've cloned borkdude's https://github.com/borkdude/blog in order to start using that tooling for my own blog, and when I run bb render, I get a ZipException when trying to download the clj-kondo pod:

[[email protected]:~/Documents/code/jmglov.net/blog]$ bb render
Downloading pod clj-kondo/clj-kondo (2021.10.19)
----- Error --------------------------------------------------------------------
Type:     java.util.zip.ZipException
Message:  invalid entry CRC (expected 0x7463ff01 but got 0x6bbe279e)
I'm running Babashka v0.8.156 on OpenJDK 17:
[[email protected]:~/Documents/code/jmglov.net/blog]$ java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment (build 17.0.3+7-nixos)
OpenJDK 64-Bit Server VM (build 17.0.3+7-nixos, mixed mode, sharing)
Any ideas here?

borkdude07:06:30

This probably is because you have a different zlib than graalvm expects. Have you compiled babashka yourself?

jmglov07:06:35

Yes. Looks like the https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/interpreters/clojure/babashka.nix derivation is building it with the following flags:

"-H:+ReportExceptionStackTraces"
    "--no-fallback"
    "--native-image-info"

jmglov07:06:41

NixOS is always the most fun. ๐Ÿ˜…

borkdude07:06:04

I've seen this error before when the environment uses zlib other than ZLIB_VERSION="1.2.11"

jmglov07:06:25

Hrm, lemme see what zlib bb is using.

jmglov07:06:54

Yeah, I have 1.2.12.

borkdude07:06:23

I think it's better if the derivation compiled a static binary with 1.2.11 in the environment

borkdude07:06:41

You can download the static binary yourself and that should work (although that would be against the nix spirit I guess)

jmglov07:06:03

I can whip up an overlay that does this. It's odd that the person who updated Babashka from 0.8.2 to 0.8.156 didn't run into this issue, but as that commit is only 7 days old, maybe it just hasn't been used enough in the wild to uncover this issue.

borkdude07:06:36

you only hit this error when you do zip stuff

jmglov07:06:04

I guess all Babashka pods need to be unzipped though, right?

jmglov07:06:26

Or is this just something clj-kondo is doing?

borkdude07:06:36

no, it's bb

borkdude07:06:53

but pods aren't touched when building + testing in nix I guess

jmglov07:06:40

Is there an example anywhere of which flags to pass to compile a static binary?

kokada07:06:45

Static will not work in GraalVM from nixpkgs as-is

borkdude07:06:54

yes, check out the linux-static job on circleci in the bb repo. but note that this only works for linux amd64

borkdude07:06:26

ah I see. then forcing zlib 1.2.11 should be the solution for now

kokada07:06:33

And it wouldn't solve the issue anyway since you would still use zlib 1.2.12

borkdude07:06:36

until 1.2.13 or so comes out

jmglov07:06:13

Yeah, 1.2.13 would be best. I could also apply the Arch patch when building zlib, I suppose.

kokada07:06:40

I can probably backport the same patch Arch is using if this does fix the issue though, at least until 1.2.13 is released

๐Ÿ’ก 1
jmglov07:06:47

In fact, that might be the easiest thing to do, though it would probably rebuild everything on my system. ๐Ÿ˜…

kokada07:06:13

No, it doesn't

jmglov07:06:20

Haha, great minds think alike.

kokada07:06:32

You should only backport this patch to GraalVM derivation

kokada07:06:38

Not globally

jmglov07:06:03

Right, that's smart!

kokada07:06:35

I need to repro this issue first though. Do the babashka test suite includes a test for this case?

borkdude07:06:51

yes, the CI will definitely fail

jmglov07:06:52

So I need to overlay a zlib derivation that applies the Arch patch, then overlay a graal derivation that uses that zlib.

borkdude07:06:16

no, I think only having the patched zlib in your environment will be enough, since it's dynamically linked

jmglov07:06:21

@UFDRD93RR Are you running NixOS? I can give you a snippet that will definitely blow up.

borkdude07:06:45

Perhaps using fs/unzip will also trigger this

kokada07:06:58

But I still want to check this automatically

kokada07:06:08

If possible, of course

borkdude07:06:22

Why does nix want to create 32 users on my mac?

build users:
    Username:	UID
     _nixbld1:	301
     _nixbld2:	302
     _nixbld3:	303
     _nixbld4:	304
     _nixbld5:	305
     _nixbld6:	306
     _nixbld7:	307
     _nixbld8:	308
     _nixbld9:	309
     _nixbld10:	310

๐Ÿ˜‚ 1
kokada07:06:34

For building

kokada07:06:44

Nix build things in isolation

kokada07:06:12

The approach for this is to create separate users, so each package is build in isolation from one another

borkdude07:06:45

and why 32 and not 16 or 128?

kokada07:06:46

You could have only 1 user, but then you would have to build one package at a time

jmglov07:06:46

Nix also has a single user mode, but that's a PITA to get working on a Mac, AFAIK.

jmglov07:06:21

I guess it assumes that most CPUs have max 16 hyperthreaded cores?

kokada07:06:59

I think you can increase or decrease the number of users, but 32 looks like a good default anyway

jmglov08:06:10

Hence running nix build with more than -j 32 is something no reasonable person would ever do. ๐Ÿ˜‰

kokada08:06:39

This is a different thing

kokada08:06:50

You can have one derivation using more than 32 cores

jmglov08:06:56

I'm deep in a rabbit hole that started when I just wanted to write a short blog entry. ๐Ÿ˜…

kokada08:06:13

But you can't have more than 32 different derivations building simultaneously

borkdude08:06:22

> I'm deep in a rabbit hole This has been the case every time I tried to use nix ;)

jmglov08:06:34

Sure, you can do. I'm talking about the flag that tells nix build how many parallel builds to attempt.

borkdude08:06:46

I'm going to install nix once again though

jmglov08:06:53

Or maybe that flag is just passed straight to compilers?

kokada08:06:04

But you don't need to pass any flags btw

kokada08:06:18

Nix automatically gets the number of CPUs and pass to the derivation

kokada08:06:36

The derivation itself needs to declare that it is multicores safe though

kokada08:06:54

enableParallelBuilding = true;

kokada08:06:15

And why a derivation wouldn't be multicores safe? Well, reproducibility

kokada08:06:42

Some derivations doesn't reproduce a consistent result in a multicores environment

kokada08:06:47

And yeah, this is fun

kokada08:06:08

But anyway, going back to the issue

kokada08:06:13

Please send me a repro

๐Ÿ‘ 1
kokada08:06:39

But I will probably try to get the test suite of babashka working in nixpkgs

borkdude08:06:22

ok, on macos I also see zlib 1.2.12:

$ otool -L $(which bb)
/nix/store/msgq0r8v9kma3fqxmsr0mdylrxgv1y8x-babashka-0.8.156/bin/bb:
	/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1122.11.0)
	/nix/store/kzba6lbw9sgzmvip6jjf35nz3nnmri8y-libcxx-11.1.0/lib/libc++.1.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/nix/store/7zfc5xjjigzh5i33rv7ph1hnma5x4rzz-zlib-1.2.12/lib/libz.dylib (compatibility version 1.0.0, current version 1.2.12)
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1770.255.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.60.1)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1770.255.0)

borkdude08:06:58

Hmm, on macOS I can't reproduce the issue though

jmglov08:06:23

This should explode:

$(nix-build ~/Downloads/bb.nix)/bin/bb <something that unzips stuff>

borkdude08:06:28

[nix-shell:~]$ rm -rf ~/.babashka/pods/repository

[nix-shell:~]$ bb -e "(babashka.pods/load-pod 'clj-kondo/clj-kondo \"2022.02.09\")"
Downloading pod clj-kondo/clj-kondo (2022.02.09)
Successfully installed pod clj-kondo/clj-kondo (2022.02.09)
#:pod{:id "pod.borkdude.clj-kondo"}

jmglov08:06:50

I wonder if it's just a Linux thing?

jmglov08:06:06

@U04V15CAJ Which bb version is that?

borkdude08:06:19

$ bb --version
babashka v0.8.156

jmglov08:06:22

And which JDK?

kokada08:06:29

The bb version is irrelevant

kokada08:06:32

Or the JDK

borkdude08:06:52

the JDK version doesn't matter, bb does not rely on a JDK except for shelling out to download some deps

kokada08:06:58

GraalVM doesn't use the JDK from your system

jmglov08:06:13

Makes sense.

kokada08:06:14

And this is especially true for nixpkgs

jmglov08:06:55

I'm brand new to GraalVM, so most of my assumptions about how Java stuff works are gonna be really wrong. ๐Ÿ˜‚

borkdude08:06:20

GraalVM is its own JDK

kokada08:06:21

How do I download a pod?

borkdude08:06:43

@UFDRD93RR

[nix-shell:~]$ rm -rf ~/.babashka/pods/repository

[nix-shell:~]$ bb -e "(babashka.pods/load-pod 'clj-kondo/clj-kondo \"2022.02.09\")"
Downloading pod clj-kondo/clj-kondo (2022.02.09)
Successfully installed pod clj-kondo/clj-kondo (2022.02.09)
#:pod{:id "pod.borkdude.clj-kondo"}

jmglov08:06:59

lol, you're fast!

kokada08:06:06

bb -e "(babashka.pods/load-pod 'clj-kondo/clj-kondo \"2022.02.09\")"
----- Error --------------------------------------------------------------------
Type:     java.io.IOException
Message:  Cannot run program "/home/thiagoko/.babashka/pods/repository/borkdude/clj-kondo/2022.02.09/clj-kondo": error=2, No such file or directory
Location: <expr>:1:1

----- Context ------------------------------------------------------------------
1: (babashka.pods/load-pod 'clj-kondo/clj-kondo "2022.02.09")
   ^--- Cannot run program "/home/thiagoko/.babashka/pods/repository/borkdude/clj-kondo/2022.02.09/clj-kondo": error=2, No such file or directory

----- Stack trace --------------------------------------------------------------
babashka.pods.impl/run-pod           - <built-in>
babashka.pods.impl/load-pod          - <built-in>
babashka.pods.sci/load-pod/fn--30887 - <built-in>
babashka.pods.sci/load-pod           - <built-in>
clojure.core/apply                   - <built-in>
babashka.impl.pods/load-pod          - <built-in>
user

kokada08:06:12

This is exactly what I tried

jmglov08:06:30

I'm going to make some breakfast. Thanks so much for all of your help, folks!

borkdude08:06:39

@UFDRD93RR Try the rm -rf first though

kokada08:06:45

bb -e "(babashka.pods/load-pod 'clj-kondo/clj-kondo \"2022.02.09\")"
Downloading pod clj-kondo/clj-kondo (2022.02.09)
Successfully installed pod clj-kondo/clj-kondo (2022.02.09)
----- Error --------------------------------------------------------------------
Type:     java.io.IOException
Message:  Cannot run program "/home/thiagoko/.babashka/pods/repository/borkdude/clj-kondo/2022.02.09/clj-kondo": error=2, No such file or directory
Location: <expr>:1:1

----- Context ------------------------------------------------------------------
1: (babashka.pods/load-pod 'clj-kondo/clj-kondo "2022.02.09")
   ^--- Cannot run program "/home/thiagoko/.babashka/pods/repository/borkdude/clj-kondo/2022.02.09/clj-kondo": error=2, No such file or directory

----- Stack trace --------------------------------------------------------------
babashka.pods.impl/run-pod           - <built-in>
babashka.pods.impl/load-pod          - <built-in>
babashka.pods.sci/load-pod/fn--30887 - <built-in>
babashka.pods.sci/load-pod           - <built-in>
clojure.core/apply                   - <built-in>
babashka.impl.pods/load-pod          - <built-in>
user                                 - <expr>:1:1

kokada08:06:54

Ok, I think I know what it is

kokada08:06:05

clj-kondo probaby is not a static binary

kokada08:06:25

But it seems to download and extracts fine

kokada08:06:52

So I don't think this is related to the zlib 1.2.12 issue at all

kokada08:06:16

Is there any other pod I can test that is compiled static :thinking_face: ?

borkdude08:06:06

let me update the clj-kondo pod to use a static one

borkdude08:06:41

@UFDRD93RR Try 2022.05.31 - should work now

borkdude08:06:09

> So I don't think this is related to the zlib 1.2.12 issue at all I do think it's related: I've seen this happen before several times

kokada08:06:10

I think they fixed the zlib issue on the latest release of GraalVM (22.1.0)

kokada08:06:27

bb -e "(babashka.pods/load-pod 'clj-kondo/clj-kondo \"2022.05.31\")"
Downloading pod clj-kondo/clj-kondo (2022.05.31)
----- Error --------------------------------------------------------------------
Type:     java.util.zip.ZipException
Message:  invalid entry CRC (expected 0x269cdf2c but got 0x13b86fd8)
Location: <expr>:1:1
Huh... maybe not

kokada08:06:40

Ok, I will take a look at this issue later them

borkdude08:06:14

Is there a way to force zlib to be on 1.2.11 in nix?

kokada08:06:30

The nice thing is that we can probably force just for GraalVM

kokada08:06:51

Because otherwise we would reintroduce a very big and serious security issue

kokada08:06:56

(It was quite nasty one)

kokada08:06:17

But even better, maybe we can backport the same patch Arch is using (that is from zlib master branch)

borkdude08:06:22

On a positive note, I've now got nix installed again and this time I don't have any issues. Last time it broke my native zsh install

kokada08:06:05

The nix installer improved a lot for macOS

kokada08:06:11

It was kinda of a pain before, for sure

jmglov08:06:37

I'm gonna hack up the GraalVM derivation now. ๐Ÿ™‚

๐Ÿš€ 1
jmglov10:06:28

Oh my goodness, it looks like one can't override zlib in an overlay! https://github.com/NixOS/nixpkgs/issues/61682

jmglov10:06:39

This is gonna get yucky. ๐Ÿ˜‚

kokada10:06:17

It is easier to fix this issue in nixpkgs itself by overriding the zlib

jmglov10:06:05

Yeah, that's what I'm working on now.

jmglov10:06:17

At least I think we're talking about the same approach.

jmglov10:06:34

And since I can't overlay zlib, I really have no clue how I can inject it all the way down there without overlaying graalvm and doing some creative copy and paste.

jmglov10:06:52

@UFDRD93RR Do you have any better ideas?

borkdude10:06:21

maybe use a flake? I got something here with the help of @UFDRD93RR https://github.com/borkdude/graalvm-nix

๐Ÿ‘€ 1
borkdude10:06:15

(not sure why I forked this again, it's a while ago)

borkdude10:06:36

oh it was only because of musl

borkdude10:06:04

you should be using @UFDRD93RRโ€™s version

jmglov10:06:07

Oh my, I forgot that I still haven't learned flakes. I think I'm rapidly wading out of my depth here. ๐Ÿ˜…

jmglov10:06:36

I'll wait to see if kokada has any ideas before continuing to bash my head against this wall. ๐Ÿ˜‰

borkdude10:06:52

until you can patch zlib, you could just manually download the clj-kondo pod (v2022.05.31) and use an absolute path with load-pod

borkdude10:06:56

@UFDRD93RR I guess @U054AT6KT can try your: https://github.com/thiagokokada/nixpkgs/tree/fix-graalvm-zlib fork as his nixpkgs now right, to test this locally?

kokada10:06:22

Yeah, if he want

jmglov05:06:17

@UFDRD93RR Youโ€™re an absolute legend! Iโ€™ll try this out in an hour or two. Today's blog entry is actually all about my fun rabbit hole trying to blog. ๐Ÿ˜‚

jmglov09:06:23

@UFDRD93RR This worked, of course! ๐Ÿ†

jmglov09:06:12

Now the next mole to whack: I guess I need to run patchelf on the pod after downloading it, otherwise this happens:

[[email protected]:~/Documents/code/jmglov.net/blog]$ bb render
Downloading pod clj-kondo/clj-kondo (2021.10.19)
Successfully installed pod clj-kondo/clj-kondo (2021.10.19)
----- Error --------------------------------------------------------------------
Type:     java.io.IOException
Message:  Cannot run program "/home/jmglov/.babashka/pods/repository/borkdude/clj-kondo/2021.10.19/clj-kondo": error=2, No such file or directory

borkdude09:06:42

@U054AT6KT Please update to the newest clj-kondo pod (2022.05.31), that one is fully static and should not need any patching

wow 1
jmglov09:06:17

You've bloody well thought of everything, haven't you!?

borkdude09:06:44

Well it's a good practice to make pods as static as possible because of these problems

1
jmglov09:06:07

Yikes! highlighter.clj loads clj-kondo with an explicit version rather than using the one specified in deps.edn:

(pods/load-pod 'clj-kondo/clj-kondo "2021.10.19")
Is that done for any particular reason? If I leave off the version, will it just load whichever pod is on the "classpath"?

borkdude09:06:09

@U054AT6KT Are you using a fork of my blog? There's a better way of doing that now

jmglov09:06:23

I have forked your blog, yes. ๐Ÿ˜‰

borkdude09:06:33

I can update my blog to show the better approach

borkdude09:06:38

just a moment

jmglov09:06:51

I wanted a low-friction way to get started. ๐Ÿ˜‰

jmglov09:06:51

Michiel, you are so incredibly generous with your time. Thank you so much! ๐Ÿ’œ

jmglov09:06:46

This is seriously seriously cool!

jmglov09:06:06

And now I'll replace your posts with my own so as not to be naughty. ๐Ÿ˜‰

jmglov09:06:32

Thanks again! This was a really fun adventure.

โค๏ธ 1
borkdude09:06:36

btw clj-kondo pod is only necessary for highlighting, I did it as a home-made solution, but if you don't like this, you can simply use highlight.js which I did before

borkdude09:06:07

the idea is you own your own blog code and you can simplify or make it more complex at your convenience

๐Ÿ† 1
jmglov10:06:04

This coming week, I'm going to try to make a custom Lambda runtime for Babashka so I can edit my Babashka stuff in the Lambda console, then port my email over from JDK Clojure to Babashka.

๐Ÿ‘ 1
borkdude10:06:20

Same for the CSS: I'm not a CSS expert so if you make it more fancy, I might steal some of your ideas

jmglov10:06:48

I am not great at CSS either, but I'll see what I can do. ๐Ÿ™‚

solf11:06:39

Question about babashka.process (using the jvm, not bb, donโ€™t know if thereโ€™s a better channel?). I have a command that takes a few minutes and I want to run it blocking and print itโ€™s output as it arrives. I modified a bit the example in the README so it would the recursive loop stops when both the process has finish running (using (.isAlive (:proc p)) and weโ€™ve finished printing itโ€™s output (using (.ready rdr)). Is there a simpler way?

(let [p (process ["some-long-command"] {:err :inherit
                                        :shutdown p/destroy})]
  (with-open [rdr (io/reader (:out p))]
    (binding [*in* rdr]
      (loop []
        (let [line (read-line)]
          (println line))

        (when (or (.ready rdr) (.isAlive (:proc p)))
          (recur))))))

borkdude11:06:52

Why don't you use :out :inherit as well?

borkdude11:06:59

And then just use @(process ...) to block until it's done

solf11:06:25

Thatโ€ฆ does seem much better yes

borkdude11:06:34

The equivalent of that would be p/shell: (p/shell "some-long-command")

solf11:06:12

Thanks, I knew I was missing something very basic ๐Ÿ˜…

solf11:06:04

Oh right, I did want to pre-process the output before printing it, but I think I removed that at some point

solf11:06:42

In that case, I do need the whole loop right? (like adding a \t before outputting each line)

borkdude11:06:11

in that case you need to do the loop yourself yes

borkdude11:06:26

maybe we could have some function in process which helps with that since it seems fairly common

solf11:06:17

Got it, thanks for the help. I think for now redirecting :out is enough for me