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.fakeNss: init #105685

Merged
merged 2 commits into from Dec 2, 2020
Merged

dockerTools.fakeNss: init #105685

merged 2 commits into from Dec 2, 2020

Conversation

flokli
Copy link
Contributor

@flokli flokli commented Dec 2, 2020

This provides a /etc/passwd and /etc/group that contain root and nobody.

Useful when packaging binaries that insist on using nss to look up
username/groups (like nginx).

The current nginx example used the runAsRoot parameter to setup
/etc/group and /etc/passwd (which also doesn't exist in
buildLayeredImage), so we can now just use fakeNss there and use
buildLayeredImage.

Motivation for this change

Packaging applications using nss with buildLayeredImage.

Successfully ran nixos/tests/docker-tools.nix after this.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • 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 nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Copy link
Member

@andir andir left a comment

Choose a reason for hiding this comment

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

This seems overly specific for the NGINX use case. Why don't we just run the shadowSetup (slightly modified so the root dir can be set to $out) in a runCommand and use that as additional layer image? That would probably give a more general solution to this problem.

name = "fake-nss";
paths = [
(writeTextDir "etc/passwd" ''
root:x:0:0:root user:/root:/bin/sh
Copy link
Member

Choose a reason for hiding this comment

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

That shell entry is likely bogus as not every container has /bin/sh. Same is true for the home directories of the two users.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about /var/empty as homedir for both?

I'd like to introduce another attribute with bin/sh (and usr/bin/env) as a separate derivation, so we don't pull in a shell unconditionally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I included var/empty in fakeNss, and added a dockerTools.binSh derivation that provides bin/sh.

This provides a /etc/passwd and /etc/group that contain root and nobody.

Useful when packaging binaries that insist on using nss to look up
username/groups (like nginx).

The current nginx example used the `runAsRoot` parameter to setup
/etc/group and /etc/passwd (which also doesn't exist in
buildLayeredImage), so we can now just use fakeNss there and use
buildLayeredImage.
@flokli
Copy link
Contributor Author

flokli commented Dec 2, 2020

This seems overly specific for the NGINX use case. Why don't we just run the shadowSetup (slightly modified so the root dir can be set to $out) in a runCommand and use that as additional layer image? That would probably give a more general solution to this problem.

shadowSetup runs at container runtime IIRC. I can understand people might want to keep a mutable /etc/{passwd,group}, but for static usecases, I'd prefer to use fakeNss.

fakeNss itself is generally valid for all applications that rely on nss lookups at runtime - nginx is just an example.

I included an empty /var/empty in the dockerTools.fakeNss output, and introduced dockerTools.binSh, which provides bin/sh, like on NixOS, but kept it in separate derivations, so if one does not want bash in the container it's still possible.

@flokli flokli requested a review from andir December 2, 2020 20:35
Copy link
Member

@utdemir utdemir left a comment

Choose a reason for hiding this comment

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

FWIW, I've used very similar tricks multiple times in the past for the exact reason (buildLayaredImage not supporting runAsRoot) and I would be keen to have it included in dockerTools.

My main concern would be whether the values hardcoded would work with a variety of the programs or not (eg. some of them might want the home directory to exist). But we can always tweak those in future (unfortunately breaking the existing code), and they can always use shadowSetup if they have more complicated needs.

@flokli
Copy link
Contributor Author

flokli commented Dec 2, 2020

Alright, let's merge this in then. It's an additional derivation covering some basic usecases, and if people don't like it, or it's not enough, they can just not add it their contents.

@flokli flokli merged commit 7a34bcc into NixOS:master Dec 2, 2020
@flokli flokli deleted the dockertools-fakenss branch December 2, 2020 22:34
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.

None yet

3 participants