mirror of
https://github.com/ilyakooo0/nix-bundle.git
synced 2024-10-26 08:42:01 +03:00
Pull sources into repo.
nix-user-chroot now uses local version instead of lethalman's
This commit is contained in:
parent
2ce85648d9
commit
97dd6220f8
32
default.nix
32
default.nix
@ -1 +1,31 @@
|
|||||||
import ./nix-bootstrap.nix
|
{nixpkgs ? import <nixpkgs> {}}:
|
||||||
|
|
||||||
|
with nixpkgs;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
makeself = callPackage ./makeself.nix {};
|
||||||
|
makedir = callPackage ./makedir.nix {};
|
||||||
|
|
||||||
|
makebootstrap = callPackage ./makebootstrap.nix {
|
||||||
|
inherit makedir makeself;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix-user-chroot = callPackage ./nix-user-chroot.nix {};
|
||||||
|
|
||||||
|
nix-bootstrap = callPackage ./nix-bootstrap.nix {
|
||||||
|
inherit nix-user-chroot;
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
versionTest = makebootstrap {
|
||||||
|
name = "nix-bootstrap.sh";
|
||||||
|
target = nix-bootstrap {
|
||||||
|
name = "nix-bootstrap";
|
||||||
|
stage3 = "nix-env --version";
|
||||||
|
};
|
||||||
|
run = "/stage1.sh";
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
{ stdenv, fetchFromGitHub, nix, cacert }:
|
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "nix-bootstrap";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "matthewbauer";
|
|
||||||
repo = "nix-bootstrap";
|
|
||||||
rev = "cc882b2cb92d8de87dad9cb890ad1745b06a9787";
|
|
||||||
sha256 = "05w6xjg0cgz6a4szc7jd7v53bmy4zjrgph5xkgyj73g62jyq7ajf";
|
|
||||||
};
|
|
||||||
|
|
||||||
propagatedBuildInputs = [ nix cacert ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/
|
|
||||||
substitute install-nix-from-closure.sh $out/install \
|
|
||||||
--subst-var-by nix .${nix} \
|
|
||||||
--subst-var-by cacert .${cacert}
|
|
||||||
chmod +x $out/install
|
|
||||||
'';
|
|
||||||
}
|
|
@ -1,13 +1,4 @@
|
|||||||
{nixpkgs ? import <nixpkgs> {}}:
|
{makeself, makedir}:
|
||||||
|
|
||||||
with nixpkgs;
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
makeself = callPackage ./makeself.nix {};
|
|
||||||
makedir = callPackage ./makedir.nix {};
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
{ name, target, run }:
|
{ name, target, run }:
|
||||||
makeself {
|
makeself {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
storePaths=$(${perl}/bin/perl ${pathsFromGraph} ./closure)
|
storePaths=$(${perl}/bin/perl ${pathsFromGraph} ./closure)
|
||||||
printRegistration=1 ${perl}/bin/perl ${pathsFromGraph} ./closure > $out/.reginfo
|
printRegistration=1 ${perl}/bin/perl ${pathsFromGraph} ./closure > $out/.reginfo
|
||||||
for path in $storePaths; do
|
for path in $storePaths; do
|
||||||
cp --parents -r $path $out/
|
cp --parents -rp $path $out/
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,43 @@
|
|||||||
{nixpkgs ? import <nixpkgs> {}}:
|
{ stdenv, writeText, nix-user-chroot, nix, cacert, coreutils, bash }:
|
||||||
|
|
||||||
with nixpkgs;
|
{ name, stage3 }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
stage1 = writeText "stage1.sh" ''
|
||||||
|
./${nix-user-chroot}/bin/nix-user-chroot ./nix ./${bash}/bin/sh -c $(dirname $0)/stage2.sh
|
||||||
|
'';
|
||||||
|
|
||||||
makebootstrap = callPackage ./makebootstrap.nix {};
|
stage2 = writeText "stage2.sh" ''
|
||||||
install-nix-from-closure = callPackage ./install-nix-from-closure.nix {};
|
unset NIX_REMOTE NIX_PROFILES NIX_USER_PROFILE_DIR NIX_OTHER_STORES NIX_PATH
|
||||||
|
export NIX_CONF_DIR=/nix/etc/nix/
|
||||||
|
export NIX_PROFILE=/nix/var/nix/profiles/default
|
||||||
|
export SSL_CERT_FILE="${cacert}/etc/ssl/certs/ca-bundle.crt"
|
||||||
|
export PATH="${coreutils}/bin:${bash}/bin:${nix.out}/bin"
|
||||||
|
|
||||||
in makebootstrap {
|
chmod -R a-w /nix/
|
||||||
name = "nix-bootstrap.sh";
|
chmod u+w /nix/ /nix/store/
|
||||||
target = install-nix-from-closure;
|
mkdir -p /nix/etc/nix/ /nix/var/nix/profiles $HOME /bin/
|
||||||
run = "/install";
|
ln -s ${bash}/bin/sh /bin/sh
|
||||||
}
|
|
||||||
|
nix-store --init
|
||||||
|
nix-store --load-db < ./.reginfo
|
||||||
|
|
||||||
|
. ${nix.out}/etc/profile.d/nix.sh
|
||||||
|
|
||||||
|
nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
||||||
|
nix-channel --update nixpkgs
|
||||||
|
|
||||||
|
nix-shell --pure -p ${nix.out} --run "${stage3}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
inherit name;
|
||||||
|
buildInputs = [ nix-user-chroot nix cacert ];
|
||||||
|
buildCommand = ''
|
||||||
|
mkdir -p $out
|
||||||
|
install -m 755 ${stage1} $out/stage1.sh
|
||||||
|
install -m 755 ${stage2} $out/stage2.sh
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
21
nix-installer.nix
Normal file
21
nix-installer.nix
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{ stdenv, fetchFromGitHub, writeText, nix, cacert }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
run-from-closure = writeText "run-from-closure" (builtins.readFile ./run-from-closure.sh);
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "nix-bootstrap";
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ nix cacert ];
|
||||||
|
|
||||||
|
buildCommand = ''
|
||||||
|
mkdir -p $out/bin/
|
||||||
|
substitute ${run-from-closure} $out/bin/run-from-closure \
|
||||||
|
--subst-var-by nix ${nix.out} \
|
||||||
|
--subst-var-by cacert ${cacert}
|
||||||
|
chmod +x $out/bin/run-from-closure
|
||||||
|
'';
|
||||||
|
}
|
144
nix-user-chroot.c
Normal file
144
nix-user-chroot.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <sched.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define err_exit(format, ...) { fprintf(stderr, format ": %s\n", ##__VA_ARGS__, strerror(errno)); exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
|
static void usage(char *pname) {
|
||||||
|
fprintf(stderr, "Usage: %s <nixpath> <command>\n", pname);
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_map(char *mapping, char *map_file) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(map_file, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
err_exit("map open");
|
||||||
|
}
|
||||||
|
|
||||||
|
int map_len = strlen(mapping);
|
||||||
|
if (write(fd, mapping, map_len) != map_len) {
|
||||||
|
err_exit("map write");
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_path(const char* name, const char* rootdir) {
|
||||||
|
char path_buf[PATH_MAX];
|
||||||
|
char path_buf2[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(path_buf, sizeof(path_buf), "/%s", name);
|
||||||
|
|
||||||
|
struct stat statbuf;
|
||||||
|
if (stat(path_buf, &statbuf) < 0) {
|
||||||
|
fprintf(stderr, "Cannot stat %s: %s\n", path_buf, strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path_buf2, sizeof(path_buf2), "%s/%s", rootdir, name);
|
||||||
|
|
||||||
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
|
mkdir(path_buf2, statbuf.st_mode & ~S_IFMT);
|
||||||
|
if (mount(path_buf, path_buf2, "none", MS_BIND | MS_REC, NULL) < 0) {
|
||||||
|
fprintf(stderr, "Cannot bind mount %s to %s: %s\n", path_buf, path_buf2, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
usage(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char template[] = "/tmp/nixXXXXXX";
|
||||||
|
char *rootdir = mkdtemp(template);
|
||||||
|
if (!rootdir) {
|
||||||
|
err_exit("mkdtemp(%s)", template);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *nixdir = realpath(argv[1], NULL);
|
||||||
|
if (!nixdir) {
|
||||||
|
err_exit("realpath(%s)", argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uid_t uid = getuid();
|
||||||
|
gid_t gid = getgid();
|
||||||
|
|
||||||
|
if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) {
|
||||||
|
err_exit("unshare()");
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind mount all / stuff into rootdir
|
||||||
|
DIR* d = opendir("/");
|
||||||
|
if (!d) {
|
||||||
|
err_exit("open /");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_path("dev", rootdir);
|
||||||
|
add_path("proc", rootdir);
|
||||||
|
add_path("sys", rootdir);
|
||||||
|
add_path("run", rootdir);
|
||||||
|
add_path("tmp", rootdir);
|
||||||
|
add_path("var", rootdir);
|
||||||
|
|
||||||
|
struct stat statbuf2;
|
||||||
|
if (stat(nixdir, &statbuf2) < 0) {
|
||||||
|
err_exit("stat(%s)", nixdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
char path_buf[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(path_buf, sizeof(path_buf), "%s/nix", rootdir);
|
||||||
|
mkdir(path_buf, statbuf2.st_mode & ~S_IFMT);
|
||||||
|
if (mount(nixdir, path_buf, "none", MS_BIND | MS_REC, NULL) < 0) {
|
||||||
|
err_exit("mount(%s, %s)", nixdir, path_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixes issue #1 where writing to /proc/self/gid_map fails
|
||||||
|
// see user_namespaces(7) for more documentation
|
||||||
|
int fd_setgroups = open("/proc/self/setgroups", O_WRONLY);
|
||||||
|
if (fd_setgroups > 0) {
|
||||||
|
write(fd_setgroups, "deny", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
char map_buf[1024];
|
||||||
|
|
||||||
|
// map the original uid/gid in the new ns
|
||||||
|
snprintf(map_buf, sizeof(map_buf), "%d %d 1", uid, uid);
|
||||||
|
update_map(map_buf, "/proc/self/uid_map");
|
||||||
|
|
||||||
|
snprintf(map_buf, sizeof(map_buf), "%d %d 1", gid, gid);
|
||||||
|
update_map(map_buf, "/proc/self/gid_map");
|
||||||
|
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
|
||||||
|
if (!getcwd(cwd, PATH_MAX)) {
|
||||||
|
err_exit("getcwd()");
|
||||||
|
}
|
||||||
|
|
||||||
|
chdir("/");
|
||||||
|
if (chroot(rootdir) < 0) {
|
||||||
|
err_exit("chroot(%s)", rootdir);
|
||||||
|
}
|
||||||
|
chdir(cwd);
|
||||||
|
|
||||||
|
// execute the command
|
||||||
|
|
||||||
|
execvp(argv[2], argv+2);
|
||||||
|
err_exit("execvp(%s)", argv[2]);
|
||||||
|
}
|
10
nix-user-chroot.nix
Normal file
10
nix-user-chroot.nix
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{ stdenv, fetchFromGitHub }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "nix-user-chroot";
|
||||||
|
buildCommand = ''
|
||||||
|
cp ${./nix-user-chroot.c} nix-user-chroot.c
|
||||||
|
mkdir -p $out/bin/
|
||||||
|
cc nix-user-chroot.c -o $out/bin/nix-user-chroot
|
||||||
|
'';
|
||||||
|
}
|
39
run-from-closure.sh
Normal file
39
run-from-closure.sh
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
self="."
|
||||||
|
nix="@nix@"
|
||||||
|
cacert="@cacert@"
|
||||||
|
|
||||||
|
if ! [ -e $self/.reginfo ]; then
|
||||||
|
echo "$0: incomplete installer (.reginfo is missing)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "initialising Nix database..." >&2
|
||||||
|
if ! $nix/bin/nix-store --init; then
|
||||||
|
echo "$0: failed to initialize the Nix database" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $nix/bin/nix-store --load-db < $self/.reginfo; then
|
||||||
|
echo "$0: unable to register valid paths" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
. $nix/etc/profile.d/nix.sh
|
||||||
|
|
||||||
|
if ! $nix/bin/nix-env -i "$nix"; then
|
||||||
|
echo "$0: unable to install Nix into your default profile" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install an SSL certificate bundle.
|
||||||
|
if [ -z "$SSL_CERT_FILE" -o ! -f "$SSL_CERT_FILE" ]; then
|
||||||
|
$nix/bin/nix-env -i "$cacert"
|
||||||
|
export SSL_CERT_FILE="$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$nix/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
||||||
|
$nix/bin/nix-channel --update nixpkgs
|
Loading…
Reference in New Issue
Block a user