diff --git a/garlic/garlicd/garlicd b/garlic/garlicd/garlicd index bb2f9c5..abfc466 100755 --- a/garlic/garlicd/garlicd +++ b/garlic/garlicd/garlicd @@ -29,8 +29,17 @@ mountdir_rel=$(echo "$garlic_sandbox" | sed 's@^/garlic=@@g') mountdir=$(readlink -f "$mountdir_rel") run="$mountdir/run" completed="$mountdir/completed" +wipe="$mountdir/wipe" -for fifo in "$run" "$completed"; do +handle_bad_signal() { + msg "cleaning FIFO pipes" + rm -f "$run" "$completed" "$wipe" + exit 1 +} + +trap handle_bad_signal SIGINT + +for fifo in "$run" "$completed" "$wipe"; do if [ ! -e "$fifo" ]; then mkfifo "$fifo" # FIXME: Use more resctrictive permissions @@ -54,19 +63,22 @@ while true; do garlic -R "$tre" msg "Fetching results..." - results=$(garlic -Fv "$tre") + garlic -FKv "$tre" - msg "results=\"$results\"" - - msg "Searching drv..." - drv=$(nix-store -q --deriver $results) + echo -n "$tre" >> "$completed" - msg "drv = \"$drv\"" - if [ -z "$drv" ]; then - msg "Something failed, drv is empty. Check the logs." + msg "Waiting for nix to finish the build..." + + read -r tre2 < "$wipe" + if [ "$tre" != "$tre2" ]; then + msg "error: trebuchet mismatch" exit 1 fi - echo -n "$drv" >> "$completed" - msg "execution completed :-)" + msg "Removing temporal files..." + garlic -D "$tre" + + echo -n "$tre" >> "$completed" + + msg "Execution completed :-)" done diff --git a/garlic/pp/store.nix b/garlic/pp/store.nix index a7fd38e..3944286 100644 --- a/garlic/pp/store.nix +++ b/garlic/pp/store.nix @@ -3,52 +3,77 @@ }: { - experimentStage -, trebuchetStage + trebuchet, + experiment }: with builtins; -#assert typeOf experimentStage == "string"; -#assert typeOf trebuchetStage == "string"; - let - # We cannot keep the context of the string when called from a derivation, as - # they will produce a different resultTree derivation vs called from the - # garlic script tool. - #_experimentStage = unsafeDiscardStringContext experimentStage; - #_trebuchetStage = unsafeDiscardStringContext trebuchetStage; - - experimentName = baseNameOf (experimentStage); - trebuchetName = baseNameOf (trebuchetStage); - garlicTemp = "/tmp/garlic"; + experimentName = baseNameOf (experiment); + trebuchetName = baseNameOf (trebuchet); in - #assert hasContext _trebuchetStage == false; - #assert hasContext _experimentStage == false; stdenv.mkDerivation { name = "resultTree"; preferLocalBuild = true; - __noChroot = true; phases = [ "installPhase" ]; installPhase = '' - exp=${garlicTemp}/${experimentName} + echo "resultTree: searching for garlicd daemon..." + if [ -e /garlic/run ]; then + echo "resultTree: asking the daemon to run and fetch the experiment" + + echo ${trebuchet} >> /garlic/run + echo "resultTree: waiting for experiment results..." + res=$(cat /garlic/completed) + + if [ "$res" != "${trebuchet}" ]; then + echo "resultTree: unknown trebuchet received" + exit 1 + fi + else + echo "resultTree: garlicd not detected: /garlic/run not found" + echo "resultTree: assuming results are already in /garlic" + fi + + echo "resultTree: attempting to copy the results from /garlic ..." + + exp=/garlic/cache/${experimentName} if [ ! -e "$exp" ]; then - echo "$exp: not found" - echo "Run the experiment and fetch the results with:" + echo "resultTree: $exp: not found" + echo "resultTree: run the experiment and fetch the results with:" echo - echo -e "\e[30;48;5;2mgarlic -RFv ${trebuchetStage}\e[0m" + echo -e "\e[30;48;5;2mgarlic -RFv ${trebuchet}\e[0m" echo - echo "See garlic(1) for more details." - echo "cannot continue building $out, aborting" + echo "resultTree: see garlic(1) for more details." + echo "resultTree: cannot continue building $out, aborting" exit 1 fi + echo "resultTree: copying results from /garlic into the nix store..." + mkdir -p $out cp -aL $exp $out/ - ln -s ${trebuchetStage} $out/trebuchet - ln -s ${experimentStage} $out/experiment + ln -s ${trebuchet} $out/trebuchet + ln -s ${experiment} $out/experiment + + + if [ -e /garlic/run ]; then + echo "resultTree: removing temp files..." + echo ${trebuchet} >> /garlic/wipe + echo "resultTree: waiting confimation from daemon..." + cat /garlic/completed > /dev/null + else + echo "resultTree: garlicd not detected: /garlic/run not found" + echo "resultTree: ignoring temp files" + fi + + echo "resultTree: successfully copied into the nix store" + + echo " experiment: ${experiment}" + echo " trebuchet: ${trebuchet}" + echo " resultTree: $out" ''; } diff --git a/garlic/sh/default.nix b/garlic/sh/default.nix index ed1ab77..63d252a 100644 --- a/garlic/sh/default.nix +++ b/garlic/sh/default.nix @@ -11,7 +11,6 @@ with garlicTools; let garlicPrefix = "/mnt/garlic"; - garlicTemp = "/tmp/garlic"; in stdenv.mkDerivation { name = "garlic-tool"; @@ -22,7 +21,7 @@ in src = ./.; - inherit garlicPrefix garlicTemp sshHost; + inherit garlicPrefix sshHost; installPhase = '' substituteAllInPlace garlic diff --git a/garlic/sh/garlic b/garlic/sh/garlic index c976dfa..01dbd41 100755 --- a/garlic/sh/garlic +++ b/garlic/sh/garlic @@ -1,15 +1,9 @@ #!/bin/bash -e garlicPrefix=@garlicPrefix@ -garlicTemp=@garlicTemp@ sshHost=@sshHost@ PATH=@PATH@ -#garlicPrefix=/mnt/garlic -#garlicTemp=/tmp/garlic -#sshHost=mn1 -#PATH=/nix/store/yjkcxbf0y1jdlbj0axghlg2fndc4dqkz-patchelf-0.11/bin:/nix/store/6is25fyx29d731idycngl7qmgcax5xng-gcc-wrapper-9.3.0/bin:/nix/store/h986r9i2j9x5z8i5g8aj0z8jdd129wyx-gcc-9.3.0/bin:/nix/store/48dypl6qdsj3vdzh7hjg5qnngfpdcz7h-glibc-2.31-bin/bin:/nix/store/zmac3n79ayg4fdqgznmi2v3lmcprzx4g-coreutils-8.31/bin:/nix/store/dmnnqr6j7kqgcr357b5qwiwvjvg2yyhd-binutils-wrapper-2.31.1/bin:/nix/store/gmi6xrkl95h6iypv00dvdpm3f4md9i6i-binutils-2.31.1/bin:/nix/store/48dypl6qdsj3vdzh7hjg5qnngfpdcz7h-glibc-2.31-bin/bin:/nix/store/zmac3n79ayg4fdqgznmi2v3lmcprzx4g-coreutils-8.31/bin:/nix/store/a41ky6icdgxa54jzps32gfgcrdyx94hs-rsync-3.1.3/bin:/nix/store/sxll2dlamfm32xd2nyfx7v8mlnx0gxks-openssh-8.3p1/bin:/nix/store/3gp7gv5z9jj3g92czxadvgphpwiviv28-nix-2.3.7/bin:/nix/store/zmac3n79ayg4fdqgznmi2v3lmcprzx4g-coreutils-8.31/bin:/nix/store/f2hn65ksj194nmy58nrjikv9r9w25irh-findutils-4.7.0/bin:/nix/store/m39n3m5c7r22b3ma2phnwmp0jj8a5jja-diffutils-3.7/bin:/nix/store/ray7jgwsr5xbxp28wvr427vywd08nz9s-gnused-4.8/bin:/nix/store/gzc092gzsanvym4c6sjgh22dsh9fzj4s-gnugrep-3.4/bin:/nix/store/mn412q9rz9afdrhl9v2ybf605r91wzl2-gawk-5.1.0/bin:/nix/store/xca341k5x5b4hcmi310gjhdlgqm4l56m-gnutar-1.32/bin:/nix/store/zvb8qad72bz6j7ia60dcsf3dfncxxqc7-gzip-1.10/bin:/nix/store/9pb8zp3zyykw09rg60f2nv32plamhd7h-bzip2-1.0.6.0.1-bin/bin:/nix/store/fm2p1d8w9sx4gbaf8qfv2rsailsyhvm3-gnumake-4.3/bin:/nix/store/npfsrhkjww5q7sax7p7ijcrj3wlbrxn7-bash-4.4-p23/bin:/nix/store/72m0m8v6mbp58vbngjgv5pn2scqhs6kk-patch-2.7.6/bin:/nix/store/7vh7fckk2srlkmmkfhs9y85icwm9rhj5-xz-5.2.5-bin/bin - usage() { echo "Usage: garlic [-RFwv] trebuchet" 1>&2; exit 1; } findClosure() { @@ -32,6 +26,23 @@ findExperiment() { grep -o -- "/nix/store/.*-experiment" "$1" } +findOutputDir() { + garlic_sandbox=$(nix show-config |\ + grep extra-sandbox-paths |\ + grep -o '/garlic=[^ ]*' || true) + + if [ -z "$garlic_sandbox" ]; then + >&2 echo "Missing extra-sandbox-paths /garlic mountpoint" + >&2 echo "Check the ~/.config/nix/nix.conf file" + exit 1 + fi + + mountdir_rel=$(echo "$garlic_sandbox" | sed 's@^/garlic=@@g') + mountdir=$(readlink -f "$mountdir_rel") + + echo "$mountdir/cache" +} + drvFromOutput() { nix-store -q --deriver $1 } @@ -138,7 +149,7 @@ do_fetch() { test $verbose && >&2 echo "$exp: execution complete, fetching results" - mkdir -p $garlicTemp + mkdir -p "$outputDir" rsync -rt --copy-links \ --include='*/*/garlic_config.json' \ @@ -147,15 +158,17 @@ do_fetch() { --include='*/*/*/.garlic' \ --include='*/*/*/.garlic/*' \ --exclude='*/*/*/*' \ - $exp $garlicTemp + "$exp" "$outputDir" - nix-build -E "(with import ./default.nix; \ - garlic.pp.store { \ - experimentStage = import \"$experimentDrv\"; - trebuchetStage = import \"$trebuchetDrv\"; - })" + if [ ! $enableKeep ]; then + nix-build -E "(with import ./default.nix; \ + garlic.pp.store { \ + trebuchet = (import \"$trebuchetDrv\" ); \ + experiment = (import \"$experimentDrv\"); \ + })" - rm -rf $garlicTemp/$expName + rm -rf "$outputDir/$expName" + fi } do_run() { @@ -163,17 +176,26 @@ do_run() { >&2 $trebuchet } +do_delete() { + expName=$(basename $experiment) + rm -rf $outputDir/$expName +} + waitResults=1 verbose= operation= target= enableRun= enableFetch= +enableKeep= +enableDelete= -while getopts "vwRF" o; do +while getopts "vwRFKD" o; do case "${o}" in R) enableRun=1 ;; F) enableFetch=1 ;; + K) enableKeep=1 ;; + D) enableDelete=1 ;; w) waitResults=0 ;; v) verbose=1 ;; *) usage ;; @@ -182,7 +204,7 @@ done shift $((OPTIND-1)) trebuchet="$1" -if [ -z "$enableRun" -a -z "$enableFetch" ]; then +if [ -z "$enableRun" -a -z "$enableFetch" -a -z "$enableDelete" ]; then >&2 echo "missing operation" usage fi @@ -196,6 +218,8 @@ checkMountpoint checkTrebuchet $trebuchet +outputDir=$(findOutputDir) + experiment=$(findExperiment "$trebuchet") checkExperiment $experiment @@ -204,3 +228,4 @@ experimentDrv=$(drvFromOutput $experiment) if [ $enableRun ]; then do_run; fi if [ $enableFetch ]; then do_fetch; fi +if [ $enableDelete ]; then do_delete; fi diff --git a/garlic/stdexp.nix b/garlic/stdexp.nix index e9a9d27..efddd96 100644 --- a/garlic/stdexp.nix +++ b/garlic/stdexp.nix @@ -35,7 +35,10 @@ rec { }; }; in trebuchet // rec { - result = pp.resultFromLauncher (pp.launcher trebuchet); + result = pp.store { + trebuchet=trebuchet; + experiment=trebuchet.experiment; + }; timetable = pp.timetable result; };