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

dockerTools: fixes extraCommands for mkRootLayer. #40947

Merged
merged 2 commits into from May 24, 2018

Conversation

samueldr
Copy link
Member

@samueldr samueldr commented May 23, 2018

The extraCommands was, previously, simply put in the body of the script
using nix expansion ${extraCommands} (which looks exactly like bash
expansion!).

This causes issues like in #34779 where scripts will eventually create
invalid bash.

The solution used was to use $extraCommands the way mkPureLayer
does, by using the variable from the environment instead of expanding
it inside the script.


Fixes #34779

Motivation for this change

See #34779, this fixes it.

Things done
  • ✔️ Tested using sandboxing (nix.useSandbox on NixOS, or option build-use-sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • ✔️ NixOS
    • 🆖 macOS
    • ❌ other Linux distributions
  • ✔️ Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • ❌ Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • 🆖 Tested execution of all binary files (usually in ./result/bin/)
  • ✔️ Fits CONTRIBUTING.md.

This was verified using this:

nix-build -I nixpkgs=/path/to/checkout/of/nixpkgs repro.nix

Using this repro.nix:

with import <nixpkgs> {};
  dockerTools.buildImageWithNixDb {
    name = "nix";
    contents = [
      coreutils
      nix
    ];
    runAsRoot = ''
      #!${pkgs.stdenv.shell}
      echo "everything is working fine"
    '';
    config = {
      Env = [ "NIX_PAGER=cat" ];
    };
  }

This is now verified in a nixos test

NIX_PATH=nixpkgs=/path/to/checkout/of/nixpkgs nix-build '<nixpkgs/nixos/tests/docker-tools.nix>'

Apply the test before the fix to verify the test tests for regression.


cc @nlewo (who seemed to work on the docker tooling a bunch)

@nlewo
Copy link
Member

nlewo commented May 23, 2018

Thanks for your investigation!

I think your patch is not working since the extraCommands would not be present in the mkRootLayer build environment: the image is built because extraCommands are not evaluated :)
This is why a run-as-root script is created in the mkRootLayer function. So you should also create such kind of script for the extraCommands attribute.

Regarding the regression test, you could also reproduce with this expression (which is maybe more close to the issue since is not related to buildImageWithNixDb)

runAsRootExtraCommands = buildImage {
    name = "runAsRootExtraCommands";
    contents = [ pkgs.coreutils ];
    runAsRoot = ''echo "(runAsRoot)" > runAsRoot'';
    extraCommands = ''echo "extraCommand" > extraCommands'';
  };

At run time, we could check these files exist:

docker run runasrootextracommands cat extraCommands
docker run runasrootextracommands cat runAsRoot

@samueldr samueldr changed the title dockerTools: fixes extraCommands for mkRootLayer. WIP: dockerTools: fixes extraCommands for mkRootLayer. May 23, 2018
@samueldr
Copy link
Member Author

samueldr commented May 23, 2018

(Changed as WIP as I will verify the images later)

Thanks for the comments!

@samueldr
Copy link
Member Author

Oh wow, thanks for the tip on how to write a more proper test. I'm not used to docker, so I didn't know what and how to test. It's an elegant and simple way to check if the commands ran.

I'm not sure whether the unshare bit from runAsRoot is needed. I think it would not since the previous embedding didn't do anything like it.

I have, once again, checked the new test with and without the change. It does fail before my new fix, and does pass after the new fix. I tested it also with the old fix, and it failed, so you were right!

The PR has been updated accordingly.

@samueldr samueldr changed the title WIP: dockerTools: fixes extraCommands for mkRootLayer. dockerTools: fixes extraCommands for mkRootLayer. May 24, 2018
contents = [ pkgs.coreutils ];
# The parens here are to create problematic bash to embed and eval. In case
# this is *embedded* into the script (with nix expansion) the initial quotes
# will close the string and the following parens are unexpected
Copy link
Member

Choose a reason for hiding this comment

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

You can also mention the issue you've opened

let runAsRootScript = shellScript "run-as-root.sh" runAsRoot;
let
runAsRootScript = shellScript "run-as-root.sh" runAsRoot;
extraCommandsScript = shellScript "extracommands.sh" extraCommands;
Copy link
Member

Choose a reason for hiding this comment

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

Could you call it extra-commands.sh since run-as-root.sh is "dashed"

@nlewo
Copy link
Member

nlewo commented May 24, 2018

Thanks for you changes. There are just some minor comments.
I also think we don't have to use unshare for extraCommands.

The extraCommands was, previously, simply put in the body of the script
using nix expansion `${extraCommands}` (which looks exactly like bash
expansion!).

This causes issues like in NixOS#34779 where scripts will eventually create
invalid bash.

The solution is to use a script like `run-as-root`.

 * * *

Fixes NixOS#34779
@samueldr
Copy link
Member Author

Updated with the relevant changes.

@@ -16,6 +16,17 @@ import ./make-test.nix ({ pkgs, ... }: {
};
};

runAsRootExtraCommands = pkgs.dockerTools.buildImage {
Copy link
Member

Choose a reason for hiding this comment

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

Arf, sorry, I haven't seen this image was in this file:/ Could you either move it to docker/examples.nix or in a

let runAsRootExtraCommands =... 
in import ./make-test.nix....

@samueldr
Copy link
Member Author

No worries, I want this to be as best as possible. Though I hope now all is well :)

@nlewo
Copy link
Member

nlewo commented May 24, 2018

@GrahamcOfBorg test docker-tools

@GrahamcOfBorg
Copy link

Success on aarch64-linux

Attempted: tests.docker-tools

No partial log is available.

@GrahamcOfBorg
Copy link

Success on x86_64-linux (full log)

Attempted: tests.docker-tools

Partial log (click to expand)

syncing
docker: running command: sync
docker# [   85.824394] dhcpcd[773]: docker0: carrier lost
docker: exit status 0
test script finished in 86.93s
cleaning up
killing docker (pid 593)
vde_switch: EOF on stdin, cleaning up and exiting
vde_switch: Could not remove ctl dir '/build/vde1.ctl': Directory not empty
/nix/store/kwhzsf8y4xsjc3vj48wq3vs7zs0sw327-vm-test-run-docker-tools

@nlewo
Copy link
Member

nlewo commented May 24, 2018

Thanks!

@nlewo nlewo merged commit 2e98e0c into NixOS:master May 24, 2018
@samueldr samueldr deleted the fix/34779 branch June 1, 2018 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dockerTools.buildImageWithNixDb fails when also using runAsRoot
3 participants