Skip to content

Commit

Permalink
Devcontainer for working on Plutus projects (IntersectMBO#2910)
Browse files Browse the repository at this point in the history
* Devcontainer for working on Plutus projects

This adds a derivation that builds a vscode devcontainer that can be
used with the `plutus-starter` project (or probably `plutus` itself!).

This is an egregious series of hacks, so we should hopefully try and
improve it in future.

* Move stuff out of default.nix
  • Loading branch information
michaelpj authored Mar 26, 2021
1 parent 71c41e2 commit e46422f
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 3 deletions.
5 changes: 3 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
, enableHaskellProfiling ? false
}:
let
inherit (packages) pkgs plutus;
inherit (packages) pkgs plutus sources;
inherit (pkgs) lib haskell-nix;
inherit (plutus) haskell iohkNix git-rev set-git-rev agdaPackages;
inherit (plutus) easyPS sphinxcontrib-haddock;
Expand Down Expand Up @@ -96,5 +96,6 @@ rec {
inherit plutus marlowe-playground plutus-playground;
};

deployment-shell = pkgs.callPackage ./deployment/shell.nix { };
# This builds a vscode devcontainer that can be used with the plutus-starter project (or probably the plutus project itself).
devcontainer = import ./nix/devcontainer/plutus-devcontainer.nix { inherit pkgs plutus; };
}
2 changes: 1 addition & 1 deletion nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ let

in
{
inherit pkgs plutus;
inherit pkgs plutus sources;
}
27 changes: 27 additions & 0 deletions nix/devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Skeleton of a devcontainer for working on Plutus projects, based on https://github.com/hamishmack/docker-nixpkgs/blob/hkm/nix-devcontainer/images/devcontainer with some tweaks.
The main derivation is in `default.nix` in the root, since it needs to add some extra things.

Usage:
1. `docker load < $(nix-build default.nix -A devcontainer)`
2. Create `.devcontainer/devcontainer.json` in your project as below, the "image" property is most important
3. Install the Remote Development extension pack in VSCode
4. Open the folder "in the container"

Example `devcontainer.json`:
```
{
"name": "My Plutus Project",
"image": "plutus-devcontainer:latest",
// Use 'settings' to set *default* container specific settings.json values on container create.
// You can edit these settings after create using File > Preferences > Settings > Remote.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// IDs of extensions inside container.
"extensions": [
"haskell.haskell"
],
}
```
102 changes: 102 additions & 0 deletions nix/devcontainer/devcontainer.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{ name ? "devcontainer"
, tag ? null
, extraContents ? [ ]
, extraCommands ? ""
, dockerTools
, bashInteractive
, cacert
, closureInfo
, coreutils
, curl
, direnv
, findutils
, gcc-unwrapped
, git
, glibc
, gnugrep
, gnused
, gnutar
, gzip
, iana-etc
, iproute
, less
, lib
, nix
, openssh
, procps
, shadow
, xz
, which
}:
let
# I think we should be able to use buildLayeredImage, but for some reason it
# produces a nonfunctional image
image = dockerTools.buildImage {
inherit name tag;

contents = [
./root
coreutils
procps
gnugrep
gnused
less

# add /bin/sh
bashInteractive

# runtime dependencies of nix
cacert
git
gnutar
gzip
xz

# for haskell binaries
iana-etc

# for user management
shadow

# for the vscode extension
gcc-unwrapped
iproute
findutils
# yes, it breaks without `which`!
which
] ++ extraContents;

extraCommands = ''
# for /usr/bin/env
mkdir usr
ln -s ../bin usr/bin
# make sure /tmp exists
mkdir -m 1777 tmp
# need a HOME
mkdir -vp root
# allow ubuntu ELF binaries to run. VSCode copies it's own.
chmod +w lib64
ln -s ${glibc}/lib64/ld-linux-x86-64.so.2 lib64/ld-linux-x86-64.so.2
ln -s ${gcc-unwrapped.lib}/lib64/libstdc++.so.6 lib64/libstdc++.so.6
chmod -w lib64
'' + extraCommands;

config = {
Cmd = [ "/bin/bash" ];
Env = [
"BASH_ENV=/etc/profile.d/env.sh"
"GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt"
"LD_LIBRARY_PATH=${gcc-unwrapped.lib}/lib64"
"PAGER=less"
"PATH=/usr/bin:/bin"
"SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt"
"USER=root"
];
};
};
in
image // { meta = nix.meta // image.meta; }
41 changes: 41 additions & 0 deletions nix/devcontainer/plutus-devcontainer.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This builds a vscode devcontainer that can be used with the plutus-starter project (or probably the plutus project itself).
{ pkgs, plutus }:
let
shell = (plutus.haskell.project.shellFor { withHoogle = false; });
# This is an evil hack to allow us to have a docker container with a "similar" environment to
# our haskell.nix shell without having it actually run nix-shell. In particular, we need some
# of the flags that the stdenv setup hooks set based on the build inputs, like NIX_LDFLAGS.
# The result of this derivation is a file that can be sourced to set the variables we need.
horrible-env-vars-hack = pkgs.runCommand "exfiltrate-env-vars"
{
inherit (shell) buildInputs nativeBuildInputs propagatedBuildInputs;
} ''
set | grep -v -E '^BASHOPTS=|^BASH_VERSINFO=|^EUID=|^PPID=|^SHELLOPTS=|^UID=|^HOME=|^TEMP=|^TMP=|^TEMPDIR=|^TMPDIR=|^NIX_ENFORCE_PURITY=' >> $out
'';
in
pkgs.callPackage (import ./devcontainer.nix) {
name = "plutus-devcontainer";
tag = "latest";
extraContents = [
shell.ghc
plutus.haskell-language-server
plutus.cabal-install
pkgs.binutils
];
extraCommands = ''
# Put the environment stuff somewhere convenient
chmod +w etc
mkdir -p etc/profile.d
echo 'set -o allexport' >> etc/profile.d/env.sh
echo 'source ${horrible-env-vars-hack}' >> etc/profile.d/env.sh
echo 'set +o allexport' >> etc/profile.d/env.sh
# We just clobbered this, put it back
echo 'export PATH=$PATH:/usr/bin:/bin' >> etc/profile.d/env.sh
echo 'export NIX_BUILD_TOP=$(mktemp -d)' >> etc/profile.d/env.sh
# Load all the stuff in an interactive session too
chmod +w root
echo 'source /etc/profile.d/env.sh' >> root/.bashrc
'';
}
6 changes: 6 additions & 0 deletions nix/devcontainer/root/etc/bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# interactive session
if [[ $- == *i* ]]; then

PS1='\[\033[0;32;40m\][nix]$\[\033[0m\] '

fi
6 changes: 6 additions & 0 deletions nix/devcontainer/root/etc/group
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root:x:0:
wheel:x:1:
tty:x:3:
users:x:100:
nixbld:x:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10,nixbld11,nixbld12,nixbld13,nixbld14,nixbld15,nixbld16,nixbld17,nixbld18,nixbld19,nixbld20,nixbld21,nixbld22,nixbld23,nixbld24,nixbld25,nixbld26,nixbld27,nixbld28,nixbld29,nixbld30
nogroup:x:65534:
11 changes: 11 additions & 0 deletions nix/devcontainer/root/etc/nsswitch.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
passwd: files mymachines systemd
group: files mymachines systemd
shadow: files

hosts: files mymachines dns myhostname
networks: files

ethers: files
services: files
protocols: files
rpc: files
4 changes: 4 additions & 0 deletions nix/devcontainer/root/etc/pam.d/other
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
account sufficient pam_unix.so
auth sufficient pam_rootok.so
password requisite pam_unix.so nullok sha512
session required pam_unix.so
32 changes: 32 additions & 0 deletions nix/devcontainer/root/etc/passwd
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
root:x:0:0:root:/root:/nix/var/nix/profiles/default/bin/bash
nixbld1:x:30001:30000:Nix build user 1:/var/empty:/sbin/nologin
nixbld2:x:30002:30000:Nix build user 2:/var/empty:/sbin/nologin
nixbld3:x:30003:30000:Nix build user 3:/var/empty:/sbin/nologin
nixbld4:x:30004:30000:Nix build user 4:/var/empty:/sbin/nologin
nixbld5:x:30005:30000:Nix build user 5:/var/empty:/sbin/nologin
nixbld6:x:30006:30000:Nix build user 6:/var/empty:/sbin/nologin
nixbld7:x:30007:30000:Nix build user 7:/var/empty:/sbin/nologin
nixbld8:x:30008:30000:Nix build user 8:/var/empty:/sbin/nologin
nixbld9:x:30009:30000:Nix build user 9:/var/empty:/sbin/nologin
nixbld10:x:30010:30000:Nix build user 10:/var/empty:/sbin/nologin
nixbld11:x:30011:30000:Nix build user 11:/var/empty:/sbin/nologin
nixbld12:x:30012:30000:Nix build user 12:/var/empty:/sbin/nologin
nixbld13:x:30013:30000:Nix build user 13:/var/empty:/sbin/nologin
nixbld14:x:30014:30000:Nix build user 14:/var/empty:/sbin/nologin
nixbld15:x:30015:30000:Nix build user 15:/var/empty:/sbin/nologin
nixbld16:x:30016:30000:Nix build user 16:/var/empty:/sbin/nologin
nixbld17:x:30017:30000:Nix build user 17:/var/empty:/sbin/nologin
nixbld18:x:30018:30000:Nix build user 18:/var/empty:/sbin/nologin
nixbld19:x:30019:30000:Nix build user 19:/var/empty:/sbin/nologin
nixbld20:x:30020:30000:Nix build user 20:/var/empty:/sbin/nologin
nixbld21:x:30021:30000:Nix build user 21:/var/empty:/sbin/nologin
nixbld22:x:30022:30000:Nix build user 22:/var/empty:/sbin/nologin
nixbld23:x:30023:30000:Nix build user 23:/var/empty:/sbin/nologin
nixbld24:x:30024:30000:Nix build user 24:/var/empty:/sbin/nologin
nixbld25:x:30025:30000:Nix build user 25:/var/empty:/sbin/nologin
nixbld26:x:30026:30000:Nix build user 26:/var/empty:/sbin/nologin
nixbld27:x:30027:30000:Nix build user 27:/var/empty:/sbin/nologin
nixbld28:x:30028:30000:Nix build user 28:/var/empty:/sbin/nologin
nixbld29:x:30029:30000:Nix build user 29:/var/empty:/sbin/nologin
nixbld30:x:30030:30000:Nix build user 30:/var/empty:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
32 changes: 32 additions & 0 deletions nix/devcontainer/root/etc/shadow
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
root:!::0:::::
nixbld1:!:18237:0:99999:7:::
nixbld2:!:18237:0:99999:7:::
nixbld3:!:18237:0:99999:7:::
nixbld4:!:18237:0:99999:7:::
nixbld5:!:18237:0:99999:7:::
nixbld6:!:18237:0:99999:7:::
nixbld7:!:18237:0:99999:7:::
nixbld8:!:18237:0:99999:7:::
nixbld9:!:18237:0:99999:7:::
nixbld10:!:18237:0:99999:7:::
nixbld11:!:18237:0:99999:7:::
nixbld12:!:18237:0:99999:7:::
nixbld13:!:18237:0:99999:7:::
nixbld14:!:18237:0:99999:7:::
nixbld15:!:18237:0:99999:7:::
nixbld16:!:18237:0:99999:7:::
nixbld17:!:18237:0:99999:7:::
nixbld18:!:18237:0:99999:7:::
nixbld19:!:18237:0:99999:7:::
nixbld20:!:18237:0:99999:7:::
nixbld21:!:18237:0:99999:7:::
nixbld22:!:18237:0:99999:7:::
nixbld23:!:18237:0:99999:7:::
nixbld24:!:18237:0:99999:7:::
nixbld25:!:18237:0:99999:7:::
nixbld26:!:18237:0:99999:7:::
nixbld27:!:18237:0:99999:7:::
nixbld28:!:18237:0:99999:7:::
nixbld29:!:18237:0:99999:7:::
nixbld30:!:18237:0:99999:7:::
nobody:!::0:::::

0 comments on commit e46422f

Please sign in to comment.