diff --git a/installer/default.nix b/installer/default.nix index 46a1c941c8cb..6eb94bc3fc3c 100644 --- a/installer/default.nix +++ b/installer/default.nix @@ -7,6 +7,56 @@ let isExecutable = true; }); + inherit (pkgs.lib) id all whatis escapeShellArg concatMapStrings concatMap + mapAttrs concatLists flattenAttrs filter; + + # f adds svn defaults + # returns in any case: + # { type = git/svn; + # target = path; + # initialize = cmd; # must create target dir, dirname target will exist + # update = cmd; # pwd will be target + # default = true/false; + # } + f = repo : attrs : + assert (__isAttrs attrs); + assert (repo + "" == repo); + if (! (attrs ? type)) then + throw "repo type is missing of : ${whatis attrs}" + else if attrs.type == "svn" then + let a = { # add svn defaults + url = "https://svn.nixos.org/repos/nix/${repo}/trunk"; + target = "/etc/nixos/${repo}"; + } // attrs; in + rec { + inherit (a) type target; + default = if a ? default then a.default else false; + initialize = "svn co ${a.url} ${a.target}"; + update = initialize; # co is just as fine as svn update + } + else if attrs.type == "git" then # sanity check for existing attrs + assert (all id (map ( attr : if __hasAttr attr attrs then true + else throw "git repository item is missing attribute ${attr}") + [ "target" "initialize" "update" ] + )); + let t = escapeShellArg attrs.target; in + rec { + inherit (attrs) type target; + default = if attrs ? default then attrs.default else false; + update = "cd ${t}; ${attrs.update}"; + initialize = '' + cd $(dirname ${t}); ${attrs.initialize} + [ -d ${t} ] || { echo "git initialize failed to create target directory ${t}"; exit 1; } + ${update}''; + } + else throw "unkown repo type ${attrs.type}"; in + + # apply f on each repo definition + let repos = mapAttrs ( repo : list : map (x : (f repo x) // { inherit repo; } ) list ) config.installer.repos; + + defaultRepo = list : __head ( (filter ( attrs : attrs ? default && attrs.default == true ) list) + ++ list ); + in { @@ -27,6 +77,8 @@ in }; nixosRebuild = makeProg { + defaultNIXOS = (defaultRepo repos.nixos ).target; + defaultNIXPKGS = (defaultRepo repos.nixpkgs).target; name = "nixos-rebuild"; src = ./nixos-rebuild.sh; }; @@ -36,9 +88,36 @@ in src = ./nixos-gen-seccure-keys.sh; }; - nixosCheckout = makeProg { + nixosCheckout = + makeProg { name = "nixos-checkout"; - src = ./nixos-checkout.sh; + src = pkgs.writeScript "nixos-checkout" ('' + #! @shell@ -e + # this file is automatically generated from nixos configuration file settings (installer.repos) + backupTimestamp=$(date "+%Y%m%d%H%M%S") + '' + concatMapStrings ( attrs : + let repoType = __getAttr attrs.type config.installer.repoTypes; + target = escapeShellArg attrs.target; in + '' + # ${attrs.type} repo ${target} + PATH= + for path in ${builtins.toString repoType.env}; do + PATH=$PATH:$path/bin:$path/sbin + done + if [ -d ${target} ] && { cd ${target} && { ${ repoType.valid}; }; }; then + echo; echo '>> ' updating ${attrs.type} repo ${target} + set -x; ${attrs.update}; set +x + else # [ make backup and ] initialize + [ -e ${target} ] && mv ${target} ${target}-$backupTimestamp + target=${target} + [ -d "$(dirname ${target})" ] || mkdir -p "$(dirname ${target})" + echo; echo '>> 'initializing ${attrs.type} repo ${target} + set -x; ${attrs.initialize}; set +x + fi + '' + ) # flatten all repo definition to one list adding the repository + ( concatLists (flattenAttrs repos) ) + ); }; nixosHardwareScan = makeProg { diff --git a/installer/nixos-checkout.sh b/installer/nixos-checkout.sh deleted file mode 100644 index 0457f4d7cb7b..000000000000 --- a/installer/nixos-checkout.sh +++ /dev/null @@ -1,62 +0,0 @@ -#! @shell@ -e -set -x - -# Pull the manifests defined in the configuration (the "manifests" -# attribute). Wonderfully hacky *and* cut&pasted from nixos-installer.sh!!! -if test -z "$NIXOS"; then NIXOS=/etc/nixos/nixos; fi -if test -z "$NIXOS_NO_PULL"; then - manifests=$(nix-instantiate --eval-only --xml --strict $NIXOS -A manifests \ - | grep ' version.nix diff --git a/installer/nixos-rebuild.sh b/installer/nixos-rebuild.sh index 5ee1d29dd9c7..c173787d585a 100644 --- a/installer/nixos-rebuild.sh +++ b/installer/nixos-rebuild.sh @@ -42,8 +42,8 @@ fi # Allow the location of NixOS sources and the system configuration # file to be overridden. -NIXOS=${NIXOS:-/etc/nixos/nixos} -NIXPKGS=${NIXPKGS:-$NIXOS/pkgs} +NIXOS=${NIXOS:-@defaultNIXOS@} +NIXPKGS=${NIXPKGS:-@defaultNIXPKGS@} NIXOS_CONFIG=${NIXOS_CONFIG:-/etc/nixos/configuration.nix} diff --git a/system/options.nix b/system/options.nix index 8db9703c09bb..bea68e5283b5 100644 --- a/system/options.nix +++ b/system/options.nix @@ -2424,6 +2424,52 @@ in "; }; + repos = { + nixos = mkOption { + default = [ { type = "svn"; } ]; + example = [ { type = "svn"; url = "https://svn.nixos.org/repos/nix/nixos/branches/stdenv-updates"; target = "/etc/nixos/nixos-stdenv-updates"; } + { type = "git"; initialize = ''git clone git://mawercer.de/nixos $target''; update = "git pull origin"; target = "/etc/nixos/nixos-git"; } + ]; + description = "The nixos repository from which the system will be build. + nixos-checkout will update all defined repositories, + nixos-rebuild will use the the first item which has + the attribute default = true falling back to the + first item. the type defines the repository tool added + to the path. It also defines a \"valid\" repository. + If the target directory already exists and it's not + valid it will be moved to the backup location + \${dir}-date. + For svn the default target and repositories are + /etc/nixos/nixos and + https://svn.nixos.org/repos/nix/nixos/trunk. + For git repositories update is called after + initialization when the repo is initialized. + The initialize code is run from working directory + dirname \$target and should create the directory + \$target. (git clone url nixos/nixpkgs/services should do) + "; + }; + + nixpkgs = mkOption { + default = [ { type = "svn"; } ]; + description = "same as "; + }; + + services = mkOption { + default = [ { type = "svn"; } ]; + description = "same as "; + }; + }; + + repoTypes = mkOption { + default = { + svn = { valid = "[ -d .svn ]"; env = [ pkgs.coreutils pkgs.subversion ]; }; + git = { valid = "[ -d .git ]"; env = [ pkgs.coreutils pkgs.git pkgs.gnused /* FIXME: use full path to sed in nix-pull */ ]; }; + }; + description = "defines PATH environment and when directory is considered beeing a valid repository. + If it's not it's moved to a backup directory"; + }; + manifests = mkOption { default = [http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST]; example =