This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-23
Channels
- # ai (1)
- # aleph (1)
- # announcements (7)
- # babashka (87)
- # beginners (34)
- # biff (9)
- # clerk (4)
- # clojars (37)
- # clojure (144)
- # clojure-art (12)
- # clojure-europe (13)
- # clojure-nl (1)
- # clojure-norway (4)
- # clojure-uk (2)
- # clr (5)
- # conjure (1)
- # data-science (1)
- # datahike (7)
- # datalevin (6)
- # datomic (13)
- # events (1)
- # fulcro (1)
- # graalvm (5)
- # gratitude (1)
- # honeysql (4)
- # hyperfiddle (122)
- # malli (26)
- # nbb (2)
- # off-topic (16)
- # portal (93)
- # practicalli (1)
- # re-frame (1)
- # reitit (15)
- # releases (3)
- # remote-jobs (1)
- # shadow-cljs (5)
- # tools-deps (6)
- # xtdb (4)
Idea for a self contained bb script - jvm
jvm install 19
Same idea as nvm
for node https://github.com/nvm-sh/nvm#intro
Congratulations! Well deserved!
Hello everyone, I have been working on a script doing some DB migrations, and it's been going quite well so far, but I have hit a wall with one requirement, and I'm hoping that someone could take the time to give me a few pointers. I have a SSH public key string, and I need to calculate the MD5 and SHA256 fingerprints. I am able to do it in Bash no problem, but not in Babashka (I've never been very comfortable with for interacting with the shell in Babashka or Clojure), but really that's just a last resort when I can't do what I need natively or using Java interrop. Here's how I can do what I need in Bash for the SHA256 fingerprint: Given a SSH public key string,
KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDieM/AoMdcDtggIQmjZTzr7UWSbuiKS0Miv9/LUWqAcj+UIrb+hhlT1UnQLpmj5LFVOgO8frGSl/f9Ybjo5j9BmR1NgEVI0O9IBsKaP54MYBUbNUVTZToRh6Dtw0rDmNDSRFQQGbNR+15n34GAI7yQeLHjk8xFYhy7a9qKxNuG+7RXG/7L3EeGzXgzx3b11i6V3XwR6z9cWysfb/MLbplawSHeVVgY2XBeAYzngr2/yfrDHWO9X+EPraHqd2WQ1Yq8+v9uBawTZML3aiPVbPHXOWjCauQSgdcAAmPjyfloo3Jgw3vmPaAEtk3fDA90DyewMWyf9jhQ32pVc/eZkbN5 "
Get the fingerprint information from ssh-keygen
,
ssh-keygen -lf - <<<"${KEY}"
2048 SHA256:DCMPcoQpscLxl0s/YrknEGoIy2Q+1Zk0AUZJhPltzzM (RSA)
From which I need the Base64 expression,
echo "$(ssh-keygen -lf - <<<${KEY}|grep -oP '(?<=SHA256:)[^ ]*')="
DCMPcoQpscLxl0s/YrknEGoIy2Q+1Zk0AUZJhPltzzM=
And finally the SHA256 fingerprint in the hexadecimal format I require,
echo "$(ssh-keygen -lf - <<<${KEY}|grep -oP '(?<=SHA256:)[^ ]*')="|base64 -d|od -A n -t x1 -v | tr -d ' \n'
0c230f728429b1c2f1974b3f62b927106a08cb643ed5993401464984f96dcf33
As a sanity check, I can reverse the final value with,
echo "0c230f728429b1c2f1974b3f62b927106a08cb643ed5993401464984f96dcf33"|xxd -r -p|base64
DCMPcoQpscLxl0s/YrknEGoIy2Q+1Zk0AUZJhPltzzM=
Ideally I'd love to just import (what I believe to be) the required Java libraries java.security.KeyPair
, java.security.PublicKey
, java.security.interfaces.DSAPublicKey
, java.security.interfaces.ECPublicKey
, java.security.interfaces.RSAPublicKey
, and perhaps java.security.NoSuchAlgorithmException
, but I don't know how I can do that without going down an enormous rabbit hole.
Would someone be kind enough to show me how I could accomplish what I need from my Babashka script? There's not too much data, so performance is not an issue. I just need something that works, and I'm hopeful that I won't have to resort to my fallback fallback position of writing a Bash script and calling it from Babashka! ๐
Why not translate the shell command to babashka.process/shell one to one? You can always do it more cleanly with pure java later
I wouldn't bother with pipes. Just pass in data to each subcommand
Then you can optionally translate each one into pure clojure/java
Pro tip: write a unit test so you can refactor with confidence. A shell script is a program like any other, so software engineering practices apply
sha256 can be done in bb as follows: https://gist.github.com/kubek2k/8446062
to make this even easier, you can use the clj-commons digest lib: https://github.com/clj-commons/digest/blob/master/test/digest_test.clj
Thanks to you both. I did actually try various approaches in Babashka for encoding, but I was not able to generate the required output.
@U06F82LES I'll have another go with shell
as you suggest. I've been spoiled by shell pipes and threading macros over the years, but yes, there's no harm in doing things piecemeal, especially as performance is not a concern.
Maybe you can post the code you have tried with shelling out. It should not be hard, but a common confusion is that you can copy paste bash code in there
I was trying things out in a bb repl which is closed now. All the shell code I was working with (assuming I work with shell
) is in the fourth code block, before the sanity check. If you have a Linux shell you should be able to just copy and past that example along with the declaration of the KEY variable the test it out.
As awesome as Clojure is, the capabilities of the humble Unix shell is a testament to the genius of its inventors. In Bash, a single line does what I need. If only we could use all the little Unix utilities as libraries in our code instead of all the awkwardness we have to wrestle with!
I guess I misinterpreted "I've never been very comfortable with for interacting with the shell in Babashka"
I interpreted shell
as "shelling out", the REPL is never called "the shell" in the context of Clojure, that is blasphemy ;)
Maybe we do need a rough bash2bb translator
How hard can it be? :-)
Does anyone know a parser for bash that understands its quirky quoting rules? That would be half the battle
you could look at the project https://explainshell.com/
Or maybe this. Json AST sounds prefect https://github.com/vorpaljs/bash-parser
Heh heh, I'm no blasphemer. I was using babashka.process/shell from the repl. ๐
Solved by eliminating my miscomprehension of what the Java/Clojure/Babashka shell is actually doing. None of them are actually running a shell! I can get the kind of solution I was after by only using babashka.process/shell to call bash and pass it the command sequence I want.
(defn bash [command]
(shell {:out :string :err :string} "bash" "-c" command))
(defn ssh-key-sha256 [key-text]
(-> (bash (str "echo \"$(ssh-keygen -lf - <<<'" key-text "'"
"|grep -oP '(?<=SHA256:)[^ ]*')=\""
"|base64 -d|od -A n -t x1 -v | tr -d ' \n'")) :out))
Using the key I provided for my example (`(def key-text "ssh-rsa AAA...)`),
clj๊user๊> (ssh-key-sha256 key-text)
"0c230f728429b1c2f1974b3f62b927106a08cb643ed5993401464984f96dcf33"
clj๊user๊>
When worlds collide!Note for my purposes I know that all the key strings are valid, so it's safe for me to just grab the output without worrying about :err
.
I wonder if I should deprecate the name shell
and change it to something else, since shell
seems to confuse people, although the docstring clearly says it does not start a new shell, but it stands for "shelling out" ;)
Didn't notice the docstring, but for Linux folks at least, "shell" has definite connotations. exec
would be okay, but it's already taken. Why not cmd
? Or run
maybe?
yeah, to make things worse, clojure 1.12 now introduces a clojure.java.process/exec
function which does something else ;)
but run
already does something else in babashka.tasks
where it is available without referring it, like shell
You could change shell
to be something more like the bash
function above, where it passes a string to the user's default shell (e.g. bash
). That would be very useful for Babashka scripting I think, and a pretty comfortable fallback for people used to shell programming. As you can see from my example, using the bash
function is clean, and allows me to tap into the power of shell programming without having to leave Babashka.
I don't like this because babashka promotes writing OS-agnostic scripts, not tied to bash
I understand, but it's unavoidable with pretty much all the process facilities, no?
I think in all of my projects I have maybe only 1 script where I shell out to sed
and I could even rewrite that to pure clojure
Ideally Babashka would be able to look at the external commands and inform the user if they aren't available on the current system, a la "missing dependencies"
Babashka is meant to be an alternative to things like Bash scripts though, right? It's a bigger ask for users if they have to make significant compromises if they choose it over what they are accustomed to.
bb scripts replace bash scripts, but it does not try to imitate bash syntax, never has. just learn clojure and if you must, use bash as a fallback, but be explicit about it:
(shell "bash -c 'rm -rf /tmp/*')
All those little programs (in Unix-like OS's at least) are kind of like the "standard library" of shell programming, so the goal should be excellent interrop IMHO.
The combination if babashka.fs, babashka.process, babashka.http-client and babashka.json should get you a long way. bb doesn't try to imitate posix utilities to the letter
"(in Unix-like OS's at least)" - this is one of the points bb departs from: it does not assume you are on a specific OS, all things are OS-agnostic like in Java
I only turned to Bash when I couldn't find an economical alternative in Babashka, and that's fine with me. Clojure is wonderful and I love using it, but I don't want to jump through hoops when an external command, or sequence of commands helps me get things done.
That said, I'm completely happy with my solution for now, and it doesn't require any changes to Babashka at all.
Well, there might be a situation where someone writes something targeting a Linux system (so call out to Bash), and someone else comes along who wants to add support for another OS. If there were something along the lines of #clj and #cljs, but for different execution environments, that might be something useful.
Apart from the ambiguous name shell
, I should think you needn't really make any changes. If such interoperability or integration is really useful, someone will come along and contribute something that fits the bill. I suspect that it's a fairly decent rabbit hole that demands some real thought, and not something that can be solved with a little tweak here and there.
I can't think of any [non shell-] programming language that seamlessly integrates POSIX, so it's either a killer feature that people have overlooked for decades, or something that's ultimately not worth it. What we have is probably good enough!
can only load from a file atm, and requires the pair... but might be useful. Can generate keys if thats part of what you need.
Nice! I actually looked into bbsh earlier on. I'll definitely look into it again, see if I can use it to get the plain hex dump of the SHA256 fingerprint.
I released a new version 0.4.0 and bumped the version of JSch (the underlying java lib) and this new version can load keys directly from vars so I exposed that in pod.epiccastle.bbssh.key-pair/load-bytes
Yes, I read that commit ๐ The reason I need something so strange is that we are migrating our Git repositories to GitLab and the available migration tool from the GitLab folks only use facilities available through the APIs. One of the non-migrated items is users' SSH keys, and the SHA256 fingerprint of the public key is stored as a binary value in the GitLab database. The MD5 fingerprint is stored as plain text, so at least that bit's easy! It's awesome that Babashka has a way to work with SSH protocols and keys though bbssh and JSch. Lovely work!!
Love the babaska.fs
lib, really smooth to use!
What do you think about extending the fs
api with a file-owner
fn that returns the file's owner?
Currently I use java.nio.file.Files/getOwner
and it works, but since it takes an array of LinkOption and such you have to get a little bit ugly to make it work.
With some internal fs
fn usage you can get it down to:
(Files/getOwner (fs/path "/home/someguy/")
(#'fs/->link-opts true))
Same question as @U06BE1L6T I guess? https://clojurians.slack.com/archives/CLX41ASCS/p1684744468650889
Btw is it more annoying that I ask here first or that you get an issue asking the same thing?
Sorry, I'm a bit late to the party . Thanks @U6T7M9DBR for taking the lead! O:-)
I gave up on the additional tests, but opened another PR that updates the CHANGELOG.md
to use owner
instead, other than that I feel done unless you want more changes ๐
and I might have already fixed that by a commit that was in-flight during a broken connection ๐
yoooo babashka conf!! ๐ Turns out Iโll be over in EU in poland just the week before for Lambda Days and I was thinking of making a Berlin pit stop otw are there any other people coming from out of town? where are you staying?