babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
solf 2021-05-07T02:00:42.030Z

I’m using a M1 Air and installed bb through homebrew. I didn’t even notice it wasn’t native 😅

plexus 2021-05-07T10:32:34.031600Z

Any idea what this error means exactly?

(require 'lambdaisland.uri)
java.lang.IllegalArgumentException: No implementation of method: :getName of protocol: #'sci.impl.vars/HasName found for class: nil [at /home/arne/github/lambdaisland/uri/src/lambdaisland/uri.cljc:12:1]

plexus 2021-05-07T10:32:59.031800Z

offending code is here: https://github.com/lambdaisland/uri/blob/main/src/lambdaisland/uri.cljc#L12

borkdude 2021-05-07T10:35:33.032400Z

@plexus Yes, defrecord in sci currently has the limitation that you cannot implement Java interfaces on it, only Clojure protocols

borkdude 2021-05-07T10:35:48.032700Z

The error message could be more informative though

plexus 2021-05-07T10:35:55.032900Z

I see, I guess that makes sense

plexus 2021-05-07T10:36:29.033500Z

what a shame, I was hoping lambdaisland/uri would "just work" since it's largely pure clojure

plexus 2021-05-07T10:37:53.034400Z

looking at that code I do wonder why I'm implementing invoke 😅 , that should be default record behavior... and I guess I can also just define a print handler instead of implementing toString

borkdude 2021-05-07T10:38:25.034900Z

@plexus you could use :bb reader conditionals to support the subset of Clojure that sci supports

plexus 2021-05-07T10:38:58.035700Z

yeah that's what I was thinking, I think there's a way to do the same stuff that would be simpler and more interoperable anyway

borkdude 2021-05-07T10:39:15.036100Z

The rules for this: the :clj branch will be taken, unless there is a :bb branch preceding it

borkdude 2021-05-07T10:40:46.037600Z

I was running into the same issue with a parser combinator library which implemented Comparable on a defrecord. That was the only change I had to make to make it compatible with bb. I can in theory support this, but you can only implement one Java interface at a time, so if you try to do two, like in your example, you're already out again.

plexus 2021-05-07T10:42:10.038100Z

the second one is overriding a method on a base class, I guess the same stuff applies?

borkdude 2021-05-07T10:43:43.039Z

yeah, it's tricky when it comes to implementing Java stuff. I can "emulate" most stuff but I can't really trick the Java type system.

borkdude 2021-05-07T10:47:59.042300Z

I had a hack for reify before which went like this: at compile time, I created multiple reified objects that implemented all subsets of all supported interfaces. At runtime I would choose the most fitting type which would then dispatch to the interpreted implementations. But this didn't work out since you can get a combinatorial explosion of types, e.g. when you have 100 interfaces to support, you can't really do it anymore, since it generates such a huge list. The other approach I tried was: generate one reify object which implements all supported interfaces. But this didn't work out with instance? checks, since it would return true for a lot of stuff you would not expect it to.

borkdude 2021-05-07T10:49:04.043Z

So right now you can use reify with at most one Java interface + any combination of protocols, for this reason. I could extend that approach to defrecord.

borkdude 2021-05-07T11:36:55.043600Z

Another sweet bb.edn :tasks, this time by @lee https://github.com/clj-commons/rewrite-clj/blob/main/bb.edn

borkdude 2021-05-07T11:44:01.044300Z

Cool library to show "status lines". You can hook this up to your tasks. https://github.com/lread/status-line

lread 2021-05-07T12:31:24.049100Z

Thanks for bb tasks @borkdude! Moving from scripts to bb tasks also swayed my brain to focus more on usability. My tasks are better named than my scripts were and the cmd line args my tasks accept are a bit more consistent.

🎉 2
NPException 2021-05-07T13:41:31.054900Z

Hi @borkdude, I hope it's okay if I tag you directly. I just started playing around with babashka and I love it so far! I'm trying to rewrite a small Java CLI tool in Clojure using babashka, but I've hit a road block for now. Part of the tool is creating a zip file. To do that I was using java.util.zip.ZipOutputStream , which is unfortunately not available in bb. I've seen that bb comes with a few other classes from the java.util.zip package, and I was wondering if you could add the ZipOutputStream to bb as well. (Or if you would consider a PR with the necessary changes)

borkdude 2021-05-07T13:43:20.055500Z

yeah, a PR is welcome. We already have GZIPOutputStream so it's a bit silly that we don't have ZIP

NPException 2021-05-07T13:44:17.055900Z

Awesome! 🙂

borkdude 2021-05-07T14:27:30.056200Z

@d.wetzel86 New binaries are available in #babashka-circleci-builds with your change

NPException 2021-05-07T14:31:12.056300Z

I'm afraid I need to wait for the next release since I'm using bb on Windows 😅

borkdude 2021-05-07T14:32:26.056500Z

https://ci.appveyor.com/project/borkdude/babashka/build/artifacts 🎉

🎊 1
kokada 2021-05-07T23:13:20.057500Z

Is there any reason that the AWS pod is not statically linked for Linux :thinking_face: ? I use NixOS and the current binaries doesn't work

borkdude 2021-05-08T07:57:00.059300Z

tzzh/aws is compiled using Go and that usually works on any platform since it doesn't depend on libc++ like graalvm binaries

borkdude 2021-05-08T07:57:34.059500Z

You can load pods from anywhere on the file system, you just can provide a file path

borkdude 2021-05-08T07:58:31.059700Z

On nixOS you likely have to install libc++ alongside the binary to make it work. You can see this using the ldd command

borkdude 2021-05-08T08:01:17.059900Z

there is likely a nixOS package for babashka or clj-kondo too, this should work similarly

kokada 2021-05-08T18:15:54.080200Z

> On nixOS you likely have to install libc++ alongside the binary to make it work. You can see this using the ldd command @borkdude NixOS doesn't have the libraries in the common location (.e.g.: they're on /nix/store, not in /usr/lib), so even when they're "installed" most programs can't find them

kokada 2021-05-08T18:17:30.080500Z

> there is likely a nixOS package for babashka or clj-kondo too, this should work similarly Actually, the static linux binaries from Babashka works well in NixOS, and I think if AWS pod were compiled statically it would works as well

borkdude 2021-05-08T18:18:09.080700Z

@ericdallo Can you shine more light on this, since you are also using nixOS and bb?

borkdude 2021-05-08T18:18:49.081Z

The static binary doesn't work on every system, the use case for it is mostly alpine/busybox docker images

kokada 2021-05-08T18:18:58.081200Z

Well, I helped @ericdallo with NixOS issues too

kokada 2021-05-08T18:19:38.081400Z

> The static binary doesn't work on every system, the use case for it is mostly alpine/busybox docker images Huh... Curious, can you give an example where it doesn't :thinking_face: ?

ericdallo 2021-05-08T18:21:12.081600Z

AFAIK static libs should work with any linux distribution including NixOS, also only static bb works fine on NixOS last time I tested it

borkdude 2021-05-08T18:21:32.081800Z

@thiagokokada I don't have a specific example, but it comes up every now and then when people try the static linux binary on their linux system and run into problems with it. My default question is: did you try the static binary... try the dynamic one instead. It has come up a handful of times. @rahul080327 knows more about the trade-offs between static and dynamic here

ericdallo 2021-05-08T18:21:57.082100Z

the issue is that every lib should be static, for example, even if compile clojure-lsp as static, it still fails since sqlite lib is not static

borkdude 2021-05-08T18:22:32.082300Z

Having said this, it's no problem to provide a static binary for the aws pod

👍 2
kokada 2021-05-08T18:22:45.082600Z

Yeah, I know about this issue @ericdallo, but in this case Babashka looks like a fully static library

ericdallo 2021-05-08T18:23:01.082800Z

yes, it looks indeed

kokada 2021-05-08T18:23:04.083Z

It doesn't seem to try to load anything dynamically neither

kokada 2021-05-08T18:25:44.083300Z

@borkdude > You can load pods from anywhere on the file system, you just can provide a file path Yeah, I know about it, but I am thinking about the best solution for having some custom pods without needing to commit them to repository, for example

kokada 2021-05-08T18:25:54.083500Z

If we could have custom repositories, this would be a breeze

borkdude 2021-05-08T18:25:58.083700Z

@thiagokokada Please make a PR to https://github.com/babashka/pod-babashka-aws. It needs an environment variable in the circleci config to say whether it should include the static flag or not. And then the script/compile script should pick up on that environment variable. I apply this in clj-kondo/clj-kondo and babashka/babashka as well, so you could use those as examples. After that there will be a static pod, but currently there is no way to retrieve a static binary from the registry pod so you will have to load it using a relative or absolute path yourself.

kokada 2021-05-08T18:26:17.084100Z

But I can find other solutions if this isn't desirable

borkdude 2021-05-08T18:26:38.084300Z

I haven't thought about custom repositories but that doesn't sound too hard

kokada 2021-05-08T18:26:56.084500Z

> After that there will be a static pod, but currently there is no way to retrieve a static binary from the registry pod so you will have to load it using a relative or absolute path yourself. Yeah, this is also another reason why I think custom repositories would be interesting

kokada 2021-05-08T18:27:14.084700Z

I could for example point the repositories to the static version of the pods

borkdude 2021-05-08T18:28:03.084900Z

Maybe the base URL of the repository can be tweaked using an environment variable, or maybe we should support a list of base-urls which will be tried in order? Have to think about. AFK for groceries now :)

👍 1
kokada 2021-05-08T18:49:20.085200Z

I was thinking maybe allowing pods/load-pods receive an extra argument for options (probably a map or something), or maybe have the URL in a using (def ^:dynamic ...) var that could be overwrite with binding (I would prefer to avoid environment variables though) Having a list of URLs instead of only one would be useful too

borkdude 2021-05-08T18:50:33.085700Z

Yeah, that makes sense

kokada 2021-05-08T22:33:32.091100Z

https://github.com/babashka/pod-babashka-aws/pull/35 :reviewplease:

lispyclouds 2021-05-09T07:10:40.095600Z

> Huh... Curious, can you give an example where it doesn't @thiagokokada we have seen issues with the static binary having issues when its being run in an environment providing a different/newer versions of ABI. The linux kernel verion being different also causes it to segfault. The binary produced by the static graalvm compilation is liked for Linux 2.6.32 and whenever we see it being run in a higher kernel version it segfaults at various places. Most notably when doing network IO. I'm not really sure what exactly is the root cause, haven't gotten around to explore that deep.

lispyclouds 2021-05-09T07:15:03.095800Z

its mostly something to do with the linking done by the graal native image. Go binaries which are mostly static seem to this better. Also my hunch is around the musl versions linked to the graal binary. since Go neither uses musl nor glibc, its able to produce more portable static binaries. My very uneducated guess would be the version of musl used to by graal to build native images fails when the kernel is different. Specially when the OS is glibc/dynamic linking based like Debian etc and not musl based like Alpine

lispyclouds 2021-05-09T07:22:09.099100Z

@ben.sless have a look here if you wanna know the issues we have faced with static binary, if you have some ideas, they are most welcome! 🙂

Ben Sless 2021-05-09T07:25:21.099500Z

> musl I don't want to condemn it but you may be SOL. A static built with musl on glibc systems even starting up is a miracle

lispyclouds 2021-05-09T07:27:10.101500Z

yeah 😕 its something we need to address upstream with the GraalVM devs somehow.

Ben Sless 2021-05-09T07:27:10.101700Z

Go binaries are built completely differently, even its concept of assembly is different

lispyclouds 2021-05-09T07:27:39.102500Z

exactly!

borkdude 2021-05-09T07:27:46.102900Z

The only difference between normal bb is that it has been built with the static flag of GraalVM native image. I don’t think it has anything specific to musl, but perhaps read the docs

lispyclouds 2021-05-09T07:28:19.103100Z

@borkdude we do need to specify --libc=musl right?

borkdude 2021-05-09T07:28:45.103400Z

No

borkdude 2021-05-09T07:29:23.104200Z

We are just using the static flag, which I can’t type on my phone

borkdude 2021-05-09T07:29:51.105Z

The other variations were introduced much later in GraalVM

lispyclouds 2021-05-09T07:31:09.105200Z

right, the docs on Graal static says

To build a static native image, use:

native-image --static --libc=musl [other arguments] Class
https://www.graalvm.org/reference-manual/native-image/StaticImages/

lispyclouds 2021-05-09T07:31:42.105400Z

but in order to have a static binary on linux we definitely need to have musl linkage

lispyclouds 2021-05-09T07:32:15.105600Z

i guess they could be adding it by default with --static

borkdude 2021-05-09T08:30:00.106800Z

@thiagokokada Could you perhaps try the same that bsless tried in the main channel, on nixOs with the static bb image? (shelling out)

borkdude 2021-05-09T08:30:18.107Z

Perhaps there is some issue around ProcessBuilder in the static image on some OS/kernels?

lispyclouds 2021-05-09T08:37:24.107200Z

Ben's versions:

OS: Pop 20.10 groovy
Kernel: x86_64 Linux 5.11.0-7614-generic

borkdude 2021-05-09T08:40:29.107400Z

This seems to work on alpine:

$ docker run --rm -i babashka/babashka:0.4.0-alpine <<< '(:out (babashka.process/sh "ls"))'
Babashka v0.4.0 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.

user=> "bin\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsrv\nsys\ntmp\nusr\nvar\n"

lispyclouds 2021-05-09T08:42:34.107600Z

@borkdude whats the kernel version here?

borkdude 2021-05-09T08:43:14.107800Z

/ # uname -r
4.19.121-linuxkit

lispyclouds 2021-05-09T17:50:54.112Z

@thiagokokada could you try https://329-325868827-gh.circle-artifacts.com/0/release/pod-babashka-aws-0.0.5-linux-amd64-static.zip ? this is the freshly brewed musl linked binary!

kokada 2021-05-09T17:57:06.112600Z

@rahul080327 Just did a static build from Babashka too: https://github.com/babashka/babashka/pull/827 My approach is different since I build musl from scratch, but I will try your binary

lispyclouds 2021-05-09T17:58:37.112900Z

yeah i managed to shave off the really long musl compilation

lispyclouds 2021-05-09T17:59:22.113100Z

musl-tools is installed via apt and seems to work fine

lispyclouds 2021-05-09T18:00:19.113300Z

also @borkdude and i were thinking is musl works fine, we can make that the static one

kokada 2021-05-09T18:03:34.113500Z

@rahul080327 Yeah, it works :thumbsup:. But keep in mind I never had issues with other static binaries from Babashka, so maybe I am not the best person to test this.

lispyclouds 2021-05-09T18:04:44.113700Z

Yay! well we havent compiled any other clojure pods statically and i think using musl should be much more stable

kokada 2021-05-09T18:05:33.113900Z

> musl-tools is installed via apt and seems to work fine As far I understand, there is some disadvantages of using musl-tools - It is an out-dated version of musl (in my branch it uses an 1.2.0 that is also out-dated, ideally we should use musl 1.2.2 since it has a much better malloc implementation; but building from scratch is easier to update musl) - Also, I am not sure that copying libz.a from Debian as is isn't going to cause some problems.

kokada 2021-05-09T18:06:10.114100Z

But I am fine either way, if it works the advantage of your approach is not building musl (that takes quite a long time)

lispyclouds 2021-05-09T18:07:00.114300Z

yeah so i build the libz after building with musl-tools, that should be okay? i copied the libz build from the link you sent

kokada 2021-05-09T18:07:50.114500Z

Yeah, I think building libz with musl-tools should be a better approach to avoid issues

kokada 2021-05-09T18:08:11.114800Z

Should avoid e.g.: ABI incompatibilities

lispyclouds 2021-05-09T18:09:19.115Z

yeah so explicitly copied that one instead of installing. i agree on trying on using a newer musl-tools, building it from source is really long 😕 maybe we can get around it with caching?

kokada 2021-05-09T18:09:38.115200Z

BTW, bb statically-build with musl is slightly smaller too:

ls -lah bb
-rwxr-xr-x 1 thiagoko users 80M mai  8 13:15 bb
ls -lah bb
-rwxr-xr-x 1 thiagoko users 76M mai  9 14:45 bb

kokada 2021-05-09T18:11:12.115400Z

> maybe we can get around it with caching? Yeah, I think caching would be the way to go if we want to build musl from source

lispyclouds 2021-05-09T18:15:11.115700Z

do you reckon there could be a way to install the newer musl-tools? maybe using the debian-testing mirrors?

lispyclouds 2021-05-09T18:15:55.115900Z

> BTW, bb statically-build with musl is slightly smaller too this is awesome!

kokada 2021-05-09T18:23:14.116100Z

> do you reckon there could be a way to install the newer musl-tools? maybe using the debian-testing mirrors? I think using musl-tools from testing in stable is risk for the same reason that using glibc for static linking is risk (there is a chance for glibc version mismatch)

borkdude 2021-05-09T18:23:38.116300Z

> Yay! well we havent compiled any other clojure pods statically We have, the sql pods are also available as static compiled

1
kokada 2021-05-09T18:23:44.116500Z

If it is available in debian backports it would be safer, but even debian-testing has a chance of being out-dated

kokada 2021-05-09T18:25:30.116900Z

> I think using musl-tools from testing in stable is risk for the same reason that using glibc for static linking is risk (there is a chance for glibc version mismatch) Unless musl-tools is build statically, them it should be safe to use it

kokada 2021-05-09T18:25:52.117100Z

@rahul080327 https://packages.debian.org/unstable/musl-tools In unstable musl-tools is up-to-date ☝️

lispyclouds 2021-05-09T18:28:42.118100Z

yeah so we can add the apt sources and just pull musl tools from it?

borkdude 2021-05-09T18:29:19.118300Z

I'm fine with any approach, but maybe we should document this somewhere, possibly in the https://github.com/lread/clj-graal-docs repo (once the correct approach is figured out)

kokada 2021-05-09T18:29:21.118600Z

> yeah so we can add the apt sources and just pull musl tools from it? Yeah, I think we can try Just avoid installing anything unnecessary from unstable (otherwise we may break something else)

kokada 2021-05-09T18:30:20.119200Z

I think the best way is to add unstable with low priority, and explicitly install musl-tools from unstable

lispyclouds 2021-05-09T18:30:32.119400Z

yeah thats what im thinking

👍 1
kokada 2021-05-09T18:31:30.119600Z

> I think the best way is to add unstable with low priority, and explicitly install musl-tools from unstable http://jaqque.sbih.org/kplug/apt-pinning.html

kokada 2021-05-09T18:49:16.119900Z

With musl 1.2.2 the binaries are almost the same as glibc in size:

ls -lah bb
-rwxr-xr-x 1 thiagoko users 79M mai  9 15:44 bb

lispyclouds 2021-05-09T19:01:03.120900Z

test are passing @borkdude!

lispyclouds 2021-05-09T19:01:28.121100Z

if youre okay with this approach @thiagokokada what say we stick to this?

kokada 2021-05-09T19:01:42.121300Z

LGTM

1
borkdude 2021-05-09T19:03:22.121600Z

@rahul080327 Maybe you can add a few comments to the setup-musl script to explain why this approach was chosen?

lispyclouds 2021-05-09T19:04:15.121800Z

sure, should i add it as a comment in the file itself?

borkdude 2021-05-09T19:05:33.122Z

yeah, I think that's the best place

borkdude 2021-05-09T19:05:47.122200Z

just a few comments at the start

lispyclouds 2021-05-09T19:06:23.122400Z

on it

lispyclouds 2021-05-09T19:10:33.122600Z

pushed

lispyclouds 2021-05-09T19:15:43.122800Z

@borkdude i think its good to merge?

kokada 2021-05-09T19:22:13.123200Z

Seems to works fine :thumbsup:

1
borkdude 2021-05-09T19:26:33.124500Z

@rahul080327 Do you have a PR I should merge?

lispyclouds 2021-05-09T19:27:01.124700Z

the musl branch, should i raise a PR?

lispyclouds 2021-05-09T19:27:30.124900Z

raising one now

lispyclouds 2021-05-09T19:28:29.125100Z

https://github.com/babashka/pod-babashka-aws/pull/37

borkdude 2021-05-09T19:30:17.125500Z

merged

borkdude 2021-05-09T19:30:25.125700Z

🙏 !

lispyclouds 2021-05-09T19:31:04.126Z

🎉

🙌 1
kokada 2021-05-07T23:20:52.057600Z

BTW, the tzzh/aws works

kokada 2021-05-07T23:23:31.057800Z

Another kinda related question, can we have private pod registries :thinking_face: ?

kokada 2021-05-07T23:38:27.058Z

Well, seeing the pod code it doesn't seem to be possible to have private pods registries