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

Proof Of Concept Repl Bots via nix-shell #32

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft

Conversation

solomon-b
Copy link
Member

Adds python and nodejs repl bots as a proof of concept.

app/Main.hs Outdated Show resolved Hide resolved
nodeBot = replBot "node: "

nodeConfig :: ProcessConfig Handle Handle ()
nodeConfig = replConfig "nix-shell -p nodejs --run 'node -i' 2>&1"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i need to get this command running in a docker container.

ghci = mkImage pkgs.ghc [ "ghci" ];
};
in
pkgs.runCommand "repls" { } (mkPath images)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JonathanLorimer for REPL bots I am building docker images with nix. Do you have any thoughts on how we can design this derivation to be more scalable for adding more languages?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly think these could all just be systemd jobs inside nix shells though...

  systemd.services.python-repl = {
      description = "Python repl";
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" ];
      serviceConfig = {
        Type = "notify";
        ExecStart = "nix-shell -p python3 --command "python -iq"";
      };
    };

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could abstract the python specific stuff in a nix module and then your nixos configuration would just do this:

sercives.language-repls = [
  {name = "python"; package = pkgs.python3; binName = "python3"; opts = "-iq";}
   ...
]; 

you wouldn't even need the nix shell bit above if you did direct interpolation:
ExecStart = "${package}/bin/${binName} ${opts}"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JonathanLorimer I don't think that's a good idea. The point of containerization is to isolate the server from untrusted code execution, so that if someone runs rm -rf / as a joke it doesn't actually nuke the entire server. You can increase the isolation of the server from these untrusted REPLs by using Linux namespacing stuff, but the more of that you do, the more of existing containerization solutions you reinvent.

Comment on lines +93 to +116
deploy-bot =
pkgs.writeScript "deploy-bot"
''
#!${pkgs.bash}/bin/bash
set -euxo pipefail

image=$(${pkgs.docker}/bin/docker load -i ${bot-image} | sed -n 's#^Loaded image: \([a-zA-Z0-9\.\/\-\:]*\)#\1#p')
${pkgs.docker}/bin/docker push $image

for x in ${repls}/*; do
image=$(${pkgs.docker}/bin/docker load -i $x | sed -n 's#^Loaded image: \([a-zA-Z0-9\.\/\-\:]*\)#\1#p')
${pkgs.docker}/bin/docker push $image
done
'';

deploy-repls =
pkgs.writeScript "deploy-bot"
''
#!${pkgs.bash}/bin/bash
set -euxo pipefail
for x in ${repls}/*; do
${pkgs.docker}/bin/docker load -i $x
done
'';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JonathanLorimer We are building these scripts for building deploy scripts for the bot and the repl images. We tried to make these apps rather then packages with pkgs.runCommand but werent able to run docker load. Do you know of any tricks to perform side effects in a flake output or is that off the table?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we need to get these images onto the server and loaded into docker. I don't want to put them on the github docker hub because they are going to take up too much space as we add more images. Can we modify our github deploy action to sync them onto the server directly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the scripts, I would suggest moving them to a separate file parameterized by their dependencies.
I would also suggest using writeShellApplication https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/trivial-builders.nix#L274-L305 it will set a bunch of sane defaults as well as the shebang, and you can specify sed as a runtime input. It will also run shellcheck in the check phase.

Comment on lines +22 to +29
images =
{
python = mkImage pkgs.python3 [ "python" "-iq" ];
node = mkImage pkgs.nodejs [ "node" "-i" ];
ghci = mkImage pkgs.ghc [ "ghci" ];
mitScheme = mkImage pkgs.mitscheme [ "mit-scheme" ];
sbcl = mkImage pkgs.sbcl [ "sbcl" ];
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
images =
{
python = mkImage pkgs.python3 [ "python" "-iq" ];
node = mkImage pkgs.nodejs [ "node" "-i" ];
ghci = mkImage pkgs.ghc [ "ghci" ];
mitScheme = mkImage pkgs.mitscheme [ "mit-scheme" ];
sbcl = mkImage pkgs.sbcl [ "sbcl" ];
};
images =
foldl' (acc {name, package, cmd}: acc // { "${name}" = mkImage package cmd }) {} supportedLanguages;
supportedLanguages =
[ { name = "python"; package = pkgs.python3; cmd = [ "python" "-iq" ]}
{ name = "node"; package = pkgs.nodejs; cmd = [ "node" "-i]}
{ name = "ghci"; package = pgks.ghc; cmd = [ "ghci"]}
{ name = "mitScheme"; package = pkgs.mitscheme; cmd = [ "mit-scheme ]
{ name = "sbcl"; package = pkgs.sbcl; cmd = [ "sbcl"]}
];

By more scalable do you mean something like this (like easier to add, although I am not sure this is an improvement). Or do you mean that a lot of docker containers is expensive.

ghci = mkImage pkgs.ghc [ "ghci" ];
};
in
pkgs.runCommand "repls" { } (mkPath images)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly think these could all just be systemd jobs inside nix shells though...

  systemd.services.python-repl = {
      description = "Python repl";
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" ];
      serviceConfig = {
        Type = "notify";
        ExecStart = "nix-shell -p python3 --command "python -iq"";
      };
    };

ghci = mkImage pkgs.ghc [ "ghci" ];
};
in
pkgs.runCommand "repls" { } (mkPath images)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could abstract the python specific stuff in a nix module and then your nixos configuration would just do this:

sercives.language-repls = [
  {name = "python"; package = pkgs.python3; binName = "python3"; opts = "-iq";}
   ...
]; 

you wouldn't even need the nix shell bit above if you did direct interpolation:
ExecStart = "${package}/bin/${binName} ${opts}"

Comment on lines +93 to +116
deploy-bot =
pkgs.writeScript "deploy-bot"
''
#!${pkgs.bash}/bin/bash
set -euxo pipefail

image=$(${pkgs.docker}/bin/docker load -i ${bot-image} | sed -n 's#^Loaded image: \([a-zA-Z0-9\.\/\-\:]*\)#\1#p')
${pkgs.docker}/bin/docker push $image

for x in ${repls}/*; do
image=$(${pkgs.docker}/bin/docker load -i $x | sed -n 's#^Loaded image: \([a-zA-Z0-9\.\/\-\:]*\)#\1#p')
${pkgs.docker}/bin/docker push $image
done
'';

deploy-repls =
pkgs.writeScript "deploy-bot"
''
#!${pkgs.bash}/bin/bash
set -euxo pipefail
for x in ${repls}/*; do
${pkgs.docker}/bin/docker load -i $x
done
'';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the scripts, I would suggest moving them to a separate file parameterized by their dependencies.
I would also suggest using writeShellApplication https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/trivial-builders.nix#L274-L305 it will set a bunch of sane defaults as well as the shebang, and you can specify sed as a runtime input. It will also run shellcheck in the check phase.

@solomon-b solomon-b added the WIP Work in Progress label Jan 19, 2022
@solomon-b solomon-b marked this pull request as draft November 19, 2022 09:35
@solomon-b solomon-b linked an issue Nov 28, 2022 that may be closed by this pull request
@isovector isovector removed their request for review March 15, 2024 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WIP Work in Progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Generalized REPL Bot System
4 participants