Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rash in Jupyter (with iracket) #92

Open
ixemad opened this issue Jun 26, 2022 · 5 comments
Open

Rash in Jupyter (with iracket) #92

ixemad opened this issue Jun 26, 2022 · 5 comments

Comments

@ixemad
Copy link

ixemad commented Jun 26, 2022

First of all, congratulations for this beautiful piece of code.

Recently, I have been using it in my daily work with Emacs + Org-mode to create "literate scripts". I would also like to propose my colleagues to use it but they feel Emacs as a real obstacle. They are more receptive to Jupyter, though.

So, trying to connect the dots, I found a Racket kernel for Jupyter (iRacket). However, I have not been able to create Jupyter cells that make use of the Rash reader on it. Would it be possible?

@willghatch
Copy link
Owner

willghatch commented Jul 8, 2022 via email

@ixemad
Copy link
Author

ixemad commented Jul 9, 2022

Yeah, I tried to use linea both ways but it did not work. I get the following error in the Jupyter's backend if I set the reader to linea/reader:

open-input-file: cannot open module file
  module path: linea/reader
  path: /home/user/.local/share/racket/8.5/pkgs/linea/reader.rkt
  system error: no such file or directory; rkt_err=3
  context...:
   /home/user/.local/share/racket/8.5/pkgs/iracket/lang.rkt:65:2: config:get-read-syntax
   /home/user/.local/share/racket/8.5/pkgs/iracket/private/kernel.rkt:124:13

Oh the other hand, there is no iRacket complaint if I just set linea as the reader. However, it fails to execute any Rash cell.

imagen

Of course, I tested that iRacket was correctly installed in my machine.

imagen

@ixemad
Copy link
Author

ixemad commented Jul 9, 2022

With respect to the (amazing) Org-mode example, the next one is likely not the clearest one but it will allow me to expose how flexible (and powerful) is the combination of Org-mode + Rash (+ Qi):

#+name: vulnerable_lambda/lambda-arn
#+header: :var assumed-role=vulnerable_lambda/assumed-role
#+header: :var regions=ALL-REGIONS
#+begin_src racket :lang rash
  (require racket/function
           racket/string
           racket/stream
           json
           qi )

  (define (/ entry-name)
    (☯ (~> (hash-ref entry-name) (if list? sep _))))

  (define (@ entry-name op entry-value)
    (☯ (pass (esc (λ (key) (op (hash-ref key entry-name) entry-value))))) )

  (void (putenv "AWS_ACCESS_KEY_ID"     #{ echo $assumed-role | jq -r ".Credentials.AccessKeyId" }))
  (void (putenv "AWS_SECRET_ACCESS_KEY" #{ echo $assumed-role | jq -r ".Credentials.SecretAccessKey" }))
  (void (putenv "AWS_SESSION_TOKEN"     #{ echo $assumed-role | jq -r ".Credentials.SessionToken" }))

  (let ([lambdas
         (for*/stream ([region (string-split regions)]
                       [result (in-list
                                (with-handlers ([exn:fail? (const '())])
                                  #{ aws lambda list-functions \
                                         --region $region \
                                         |>> string->jsexpr \
                                         |> (☯ (~> (/ 'Functions)
                                                   (>< (/ 'FunctionArn))
                                                   ▽)) } ) ) ] )
           result) ])
    (if (stream-empty? lambdas)
        "no lambdas in any region"
        (~> (lambdas) stream-first display) ) )
#+end_src
#+RESULTS[087d42e5287904de8dadb0f07a8eae4e90888f72]: vulnerable_lambda/lambda-arn
: arn:aws:lambda:us-east-1:7245XXXX8614:function:vulnerable_lambda_cgidb34c8zbk3d-policy_applier_lambda1

So, the Org-mode block vulnerable_lambda/lambda-arn is using as input parameters (assumed-role, regions) the output of other two previous blocks (vulnerable_lambda/assumed-role and ALL-REGIONS). This block combines Racket, Rash, Qi and jq to get as a cached result arn:aws:lambda:us-east-1:7245XXXX8614:function:vulnerable_lambda_cgidb34c8zbk3d-policy_applier_lambda1 which can be reused by another block. Beautiful, isn't it? 😄

@ixemad
Copy link
Author

ixemad commented Jul 10, 2022

I saw but didn't notice that iRacket code runs in a sandbox. A far as I can see, the sandbox refuses to run the following example code:

(require shell/pipeline)
(run-subprocess-pipeline '(echo))
subprocess: `execute' access denied for /usr/bin/echo
  context...:
   body of top-level
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:663:0: run-pipeline-members
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:510:0: run-pipeline/spec
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:441:0: run-subprocess-pipeline
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:555:3

So, my colleagues will have to love Emacs 😄

@ixemad
Copy link
Author

ixemad commented Jul 11, 2022

Alright, with respect to my previous comment, iRacket can be hacked to allow the execute permission in the sandbox (specifically, by modifying the sandbox-path-permissions parameter). Of course, this is a sensitive decision that must be weighed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants