Merge remote-tracking branch 'upstream/master' into fix-cross-jobs
This commit is contained in:
commit
b9a720c524
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -83,7 +83,6 @@
|
||||
/pkgs/applications/editors/eclipse @rycee
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/issues/31401
|
||||
/lib/maintainers.nix @ghost
|
||||
/lib/licenses.nix @ghost
|
||||
|
||||
# Qt / KDE
|
||||
|
@ -81,6 +81,10 @@ pkgs.stdenv.mkDerivation {
|
||||
inputFile = ./languages-frameworks/vim.md;
|
||||
outputFile = "./languages-frameworks/vim.xml";
|
||||
}
|
||||
+ toDocbook {
|
||||
inputFile = ./languages-frameworks/emscripten.md;
|
||||
outputFile = "./languages-frameworks/emscripten.xml";
|
||||
}
|
||||
+ ''
|
||||
echo ${lib.nixpkgsVersion} > .version
|
||||
|
||||
|
185
doc/languages-frameworks/emscripten.md
Normal file
185
doc/languages-frameworks/emscripten.md
Normal file
@ -0,0 +1,185 @@
|
||||
# User's Guide to Emscripten in Nixpkgs
|
||||
|
||||
[Emscripten](https://github.com/kripken/emscripten): An LLVM-to-JavaScript Compiler
|
||||
|
||||
This section of the manual covers how to use `emscripten` in nixpkgs.
|
||||
|
||||
Minimal requirements:
|
||||
|
||||
* nix
|
||||
* nixpkgs
|
||||
|
||||
Modes of use of `emscripten`:
|
||||
|
||||
* **Imperative usage** (on the command line):
|
||||
|
||||
If you want to work with `emcc`, `emconfigure` and `emmake` as you are used to from Ubuntu and similar distributions you can use these commands:
|
||||
|
||||
* `nix-env -i emscripten`
|
||||
* `nix-shell -p emscripten`
|
||||
|
||||
* **Declarative usage**:
|
||||
|
||||
This mode is far more power full since this makes use of `nix` for dependency management of emscripten libraries and targets by using the `mkDerivation` which is implemented by `pkgs.emscriptenStdenv` and `pkgs.buildEmscriptenPackage`. The source for the packages is in `pkgs/top-level/emscripten-packages.nix` and the abstraction behind it in `pkgs/development/em-modules/generic/default.nix`.
|
||||
* build and install all packages:
|
||||
* `nix-env -iA emscriptenPackages`
|
||||
|
||||
* dev-shell for zlib implementation hacking:
|
||||
* `nix-shell -A emscriptenPackages.zlib`
|
||||
|
||||
|
||||
## Imperative usage
|
||||
|
||||
A few things to note:
|
||||
|
||||
* `export EMCC_DEBUG=2` is nice for debugging
|
||||
* `~/.emscripten`, the build artifact cache sometimes creates issues and needs to be removed from time to time
|
||||
|
||||
|
||||
## Declarative usage
|
||||
|
||||
Let's see two different examples from `pkgs/top-level/emscripten-packages.nix`:
|
||||
|
||||
* `pkgs.zlib.override`
|
||||
* `pkgs.buildEmscriptenPackage`
|
||||
|
||||
Both are interesting concepts.
|
||||
|
||||
A special requirement of the `pkgs.buildEmscriptenPackage` is the `doCheck = true` is a default meaning that each emscriptenPackage requires a `checkPhase` implemented.
|
||||
|
||||
* Use `export EMCC_DEBUG=2` from within a emscriptenPackage's `phase` to get more detailed debug output what is going wrong.
|
||||
* ~/.emscripten cache is requiring us to set `HOME=$TMPDIR` in individual phases. This makes compilation slower but also makes it more deterministic.
|
||||
|
||||
### Usage 1: pkgs.zlib.override
|
||||
|
||||
This example uses `zlib` from nixpkgs but instead of compiling **C** to **ELF** it compiles **C** to **JS** since we were using `pkgs.zlib.override` and changed stdenv to `pkgs.emscriptenStdenv`. A few adaptions and hacks were set in place to make it working. One advantage is that when `pkgs.zlib` is updated, it will automatically update this package as well. However, this can also be the downside...
|
||||
|
||||
See the `zlib` example:
|
||||
|
||||
zlib = (pkgs.zlib.override {
|
||||
stdenv = pkgs.emscriptenStdenv;
|
||||
}).overrideDerivation
|
||||
(old: rec {
|
||||
buildInputs = old.buildInputs ++ [ pkgconfig ];
|
||||
# we need to reset this setting!
|
||||
NIX_CFLAGS_COMPILE="";
|
||||
configurePhase = ''
|
||||
# FIXME: Some tests require writing at $HOME
|
||||
HOME=$TMPDIR
|
||||
runHook preConfigure
|
||||
|
||||
#export EMCC_DEBUG=2
|
||||
emconfigure ./configure --prefix=$out --shared
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
dontStrip = true;
|
||||
outputs = [ "out" ];
|
||||
buildPhase = ''
|
||||
emmake make
|
||||
'';
|
||||
installPhase = ''
|
||||
emmake make install
|
||||
'';
|
||||
checkPhase = ''
|
||||
echo "================= testing zlib using node ================="
|
||||
|
||||
echo "Compiling a custom test"
|
||||
set -x
|
||||
emcc -O2 -s EMULATE_FUNCTION_POINTER_CASTS=1 test/example.c -DZ_SOLO \
|
||||
libz.so.${old.version} -I . -o example.js
|
||||
|
||||
echo "Using node to execute the test"
|
||||
${pkgs.nodejs}/bin/node ./example.js
|
||||
|
||||
set +x
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "test failed for some reason"
|
||||
exit 1;
|
||||
else
|
||||
echo "it seems to work! very good."
|
||||
fi
|
||||
echo "================= /testing zlib using node ================="
|
||||
'';
|
||||
|
||||
postPatch = pkgs.stdenv.lib.optionalString pkgs.stdenv.isDarwin ''
|
||||
substituteInPlace configure \
|
||||
--replace '/usr/bin/libtool' 'ar' \
|
||||
--replace 'AR="libtool"' 'AR="ar"' \
|
||||
--replace 'ARFLAGS="-o"' 'ARFLAGS="-r"'
|
||||
'';
|
||||
});
|
||||
|
||||
### Usage 2: pkgs.buildEmscriptenPackage
|
||||
|
||||
This `xmlmirror` example features a emscriptenPackage which is defined completely from this context and no `pkgs.zlib.override` is used.
|
||||
|
||||
xmlmirror = pkgs.buildEmscriptenPackage rec {
|
||||
name = "xmlmirror";
|
||||
|
||||
buildInputs = [ pkgconfig autoconf automake libtool gnumake libxml2 nodejs openjdk json_c ];
|
||||
nativeBuildInputs = [ pkgconfig zlib ];
|
||||
|
||||
src = pkgs.fetchgit {
|
||||
url = "https://gitlab.com/odfplugfest/xmlmirror.git";
|
||||
rev = "4fd7e86f7c9526b8f4c1733e5c8b45175860a8fd";
|
||||
sha256 = "1jasdqnbdnb83wbcnyrp32f36w3xwhwp0wq8lwwmhqagxrij1r4b";
|
||||
};
|
||||
|
||||
configurePhase = ''
|
||||
rm -f fastXmlLint.js*
|
||||
# a fix for ERROR:root:For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was 234217728
|
||||
# https://gitlab.com/odfplugfest/xmlmirror/issues/8
|
||||
sed -e "s/TOTAL_MEMORY=234217728/TOTAL_MEMORY=268435456/g" -i Makefile.emEnv
|
||||
# https://github.com/kripken/emscripten/issues/6344
|
||||
# https://gitlab.com/odfplugfest/xmlmirror/issues/9
|
||||
sed -e "s/\$(JSONC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(LIBXML20_LDFLAGS)/\$(JSONC_LDFLAGS) \$(LIBXML20_LDFLAGS) \$(ZLIB_LDFLAGS) /g" -i Makefile.emEnv
|
||||
# https://gitlab.com/odfplugfest/xmlmirror/issues/11
|
||||
sed -e "s/-o fastXmlLint.js/-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]' -o fastXmlLint.js/g" -i Makefile.emEnv
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
HOME=$TMPDIR
|
||||
make -f Makefile.emEnv
|
||||
'';
|
||||
|
||||
outputs = [ "out" "doc" ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share
|
||||
mkdir -p $doc/share/${name}
|
||||
|
||||
cp Demo* $out/share
|
||||
cp -R codemirror-5.12 $out/share
|
||||
cp fastXmlLint.js* $out/share
|
||||
cp *.xsd $out/share
|
||||
cp *.js $out/share
|
||||
cp *.xhtml $out/share
|
||||
cp *.html $out/share
|
||||
cp *.json $out/share
|
||||
cp *.rng $out/share
|
||||
cp README.md $doc/share/${name}
|
||||
'';
|
||||
checkPhase = ''
|
||||
|
||||
'';
|
||||
};
|
||||
|
||||
### Declarative debugging
|
||||
|
||||
Use `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz` and from there you can go trough the individual steps. This makes it easy to build a good `unit test` or list the files of the project.
|
||||
|
||||
1. `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz`
|
||||
2. `cd /tmp/`
|
||||
3. `unpackPhase`
|
||||
4. cd libz-1.2.3
|
||||
5. `configurePhase`
|
||||
6. `buildPhase`
|
||||
7. ... happy hacking...
|
||||
|
||||
## Summary
|
||||
|
||||
Using this toolchain makes it easy to leverage `nix` from NixOS, MacOSX or even Windows (WSL+ubuntu+nix). This toolchain is reproducible, behaves like the rest of the packages from nixpkgs and contains a set of well working examples to learn and adapt from.
|
||||
|
||||
If in trouble, ask the maintainers.
|
||||
|
@ -30,6 +30,7 @@ such as Perl or Haskell. These are described in this chapter.</para>
|
||||
<xi:include href="rust.xml" />
|
||||
<xi:include href="texlive.xml" />
|
||||
<xi:include href="vim.xml" />
|
||||
<xi:include href="emscripten.xml" />
|
||||
|
||||
|
||||
</chapter>
|
||||
|
@ -177,5 +177,19 @@ you need it.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-perl-cross-compilation"><title>Cross-compiling modules</title>
|
||||
|
||||
<para>Nixpkgs has experimental support for cross-compiling Perl
|
||||
modules. In many cases, it will just work out of the box, even for
|
||||
modules with native extensions. Sometimes, however, the Makefile.PL
|
||||
for a module may (indirectly) import a native module. In that case,
|
||||
you will need to make a stub for that module that will satisfy the
|
||||
Makefile.PL and install it into
|
||||
<filename>lib/perl5/site_perl/cross_perl/${perl.version}</filename>.
|
||||
See the <varname>postInstall</varname> for <varname>DBI</varname> for
|
||||
an example.</para>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
@ -39,6 +39,9 @@ nix-repl> :l <nixpkgs>
|
||||
nix-repl> texlive.collection-<TAB>
|
||||
</programlisting>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Note that the wrapper assumes that the result has a chance to be useful. For example, the core executables should be present, as well as some core data files. The supported way of ensuring this is by including some scheme, for example <varname>scheme-basic</varname>, into the combination.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
@ -174,7 +174,7 @@ meta-attributes</title>
|
||||
maintainers of this Nix expression. If
|
||||
you would like to be a maintainer of a package, you may want to add
|
||||
yourself to <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/lib/maintainers.nix"><filename>nixpkgs/lib/maintainers.nix</filename></link>
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix"><filename>nixpkgs/maintainers/maintainer-list.nix</filename></link>
|
||||
and write something like <literal>[ stdenv.lib.maintainers.alice
|
||||
stdenv.lib.maintainers.bob ]</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
@ -21,7 +21,7 @@ let
|
||||
|
||||
# packaging
|
||||
customisation = callLibs ./customisation.nix;
|
||||
maintainers = import ./maintainers-list.nix;
|
||||
maintainers = import ../maintainers/maintainer-list.nix;
|
||||
meta = callLibs ./meta.nix;
|
||||
sources = callLibs ./sources.nix;
|
||||
versions = callLibs ./versions.nix;
|
||||
|
@ -179,6 +179,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "CeCILL-C Free Software License Agreement";
|
||||
};
|
||||
|
||||
cpal10 = spdx {
|
||||
spdxId = "CPAL-1.0";
|
||||
fullName = "Common Public Attribution License 1.0";
|
||||
};
|
||||
|
||||
cpl10 = spdx {
|
||||
spdxId = "CPL-1.0";
|
||||
fullName = "Common Public License 1.0";
|
||||
|
@ -437,6 +437,13 @@ rec {
|
||||
*/
|
||||
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
|
||||
|
||||
/* Check whether a value can be coerced to a string */
|
||||
isCoercibleToString = x:
|
||||
builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
||||
(builtins.isList x && lib.all isCoercibleToString x) ||
|
||||
x ? outPath ||
|
||||
x ? __toString;
|
||||
|
||||
/* Check whether a value is a store path.
|
||||
|
||||
Example:
|
||||
@ -450,7 +457,7 @@ rec {
|
||||
=> false
|
||||
*/
|
||||
isStorePath = x:
|
||||
builtins.isString x
|
||||
isCoercibleToString x
|
||||
&& builtins.substring 0 1 (toString x) == "/"
|
||||
&& dirOf (builtins.toPath x) == builtins.storeDir;
|
||||
|
||||
|
@ -21,9 +21,11 @@ rec {
|
||||
LittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
||||
|
||||
BSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
||||
Darwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
|
||||
Unix = [ BSD Darwin Linux SunOS Hurd Cygwin ];
|
||||
|
||||
Darwin = { kernel = kernels.darwin; };
|
||||
MacOS = { kernel = kernels.macos; };
|
||||
iOS = { kernel = kernels.ios; };
|
||||
Linux = { kernel = kernels.linux; };
|
||||
SunOS = { kernel = kernels.solaris; };
|
||||
FreeBSD = { kernel = kernels.freebsd; };
|
||||
|
@ -134,6 +134,7 @@ rec {
|
||||
|
||||
kernelFamilies = setTypes types.openKernelFamily {
|
||||
bsd = {};
|
||||
darwin = {};
|
||||
};
|
||||
|
||||
################################################################################
|
||||
@ -149,7 +150,10 @@ rec {
|
||||
types.kernel = enum (attrValues kernels);
|
||||
|
||||
kernels = with execFormats; with kernelFamilies; setTypes types.openKernel {
|
||||
darwin = { execFormat = macho; families = { }; };
|
||||
# TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as
|
||||
# the nnormalized name for macOS.
|
||||
macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; };
|
||||
ios = { execFormat = macho; families = { inherit darwin; }; };
|
||||
freebsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||
hurd = { execFormat = elf; families = { }; };
|
||||
linux = { execFormat = elf; families = { }; };
|
||||
@ -159,9 +163,13 @@ rec {
|
||||
solaris = { execFormat = elf; families = { }; };
|
||||
windows = { execFormat = pe; families = { }; };
|
||||
} // { # aliases
|
||||
# 'darwin' is the kernel for all of them. We choose macOS by default.
|
||||
darwin = kernels.macos;
|
||||
# TODO(@Ericson2314): Handle these Darwin version suffixes more generally.
|
||||
darwin10 = kernels.darwin;
|
||||
darwin14 = kernels.darwin;
|
||||
darwin10 = kernels.macos;
|
||||
darwin14 = kernels.macos;
|
||||
watchos = kernels.ios;
|
||||
tvos = kernels.ios;
|
||||
win32 = kernels.windows;
|
||||
};
|
||||
|
||||
@ -263,8 +271,8 @@ rec {
|
||||
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
|
||||
|
||||
doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
|
||||
if abi == abis.cygnus
|
||||
then "${cpu.name}-cygwin"
|
||||
/**/ if abi == abis.cygnus then "${cpu.name}-cygwin"
|
||||
else if kernel.families ? darwin then "${cpu.name}-darwin"
|
||||
else "${cpu.name}-${kernel.name}";
|
||||
|
||||
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
|
||||
|
@ -93,6 +93,7 @@ runTests {
|
||||
"${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
|
||||
in {
|
||||
storePath = isStorePath goodPath;
|
||||
storePathDerivation = isStorePath (import ../.. {}).hello;
|
||||
storePathAppendix = isStorePath
|
||||
"${goodPath}/bin/python";
|
||||
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
||||
@ -106,6 +107,7 @@ runTests {
|
||||
};
|
||||
expected = {
|
||||
storePath = true;
|
||||
storePathDerivation = true;
|
||||
storePathAppendix = false;
|
||||
nonAbsolute = false;
|
||||
asPath = true;
|
||||
|
@ -21,7 +21,7 @@ pkgs.stdenv.mkDerivation {
|
||||
nix-store --init
|
||||
|
||||
cd ${pkgs.path}/lib/tests
|
||||
./modules.sh
|
||||
bash ./modules.sh
|
||||
|
||||
[[ "$(nix-instantiate --eval --strict misc.nix)" == "[ ]" ]]
|
||||
|
||||
|
@ -63,6 +63,10 @@
|
||||
github = "DmitryTsygankov";
|
||||
name = "Dmitry Tsygankov";
|
||||
};
|
||||
Esteth = {
|
||||
email = "adam.copp@gmail.com";
|
||||
name = "Adam Copp";
|
||||
};
|
||||
FireyFly = {
|
||||
email = "nix@firefly.nu";
|
||||
github = "FireyFly";
|
||||
@ -87,6 +91,11 @@
|
||||
github = "MP2E";
|
||||
name = "Cray Elliott";
|
||||
};
|
||||
Mogria = {
|
||||
email = "m0gr14@gmail.com";
|
||||
github = "mogria";
|
||||
name = "Mogria";
|
||||
};
|
||||
MostAwesomeDude = {
|
||||
email = "cds@corbinsimpson.com";
|
||||
github = "MostAwesomeDude";
|
||||
@ -111,6 +120,11 @@
|
||||
github = "Profpatsch";
|
||||
name = "Profpatsch";
|
||||
};
|
||||
roosemberth = {
|
||||
email = "roosembert.palacios+nixpkgs@gmail.com";
|
||||
github = "roosemberth";
|
||||
name = "Roosembert (Roosemberth) Palacios";
|
||||
};
|
||||
SShrike = {
|
||||
email = "severen@shrike.me";
|
||||
github = "severen";
|
||||
@ -176,6 +190,11 @@
|
||||
github = "abigailbuccaneer";
|
||||
name = "Abigail Bunyan";
|
||||
};
|
||||
aborsu = {
|
||||
email = "a.borsu@gmail.com";
|
||||
github = "aborsu";
|
||||
name = "Augustin Borsu";
|
||||
};
|
||||
aboseley = {
|
||||
email = "adam.boseley@gmail.com";
|
||||
github = "aboseley";
|
||||
@ -276,6 +295,11 @@
|
||||
github = "akc";
|
||||
name = "Anders Claesson";
|
||||
};
|
||||
akru = {
|
||||
email = "mail@akru.me";
|
||||
github = "akru";
|
||||
name = "Alexander Krupenkin ";
|
||||
};
|
||||
alexvorobiev = {
|
||||
email = "alexander.vorobiev@gmail.com";
|
||||
github = "alexvorobiev";
|
||||
@ -314,6 +338,11 @@
|
||||
github = "amiloradovsky";
|
||||
name = "Andrew Miloradovsky";
|
||||
};
|
||||
aminechikhaoui = {
|
||||
email = "amine.chikhaoui91@gmail.com";
|
||||
github = "AmineChikhaoui";
|
||||
name = "Amine Chikhaoui";
|
||||
};
|
||||
amorsillo = {
|
||||
email = "andrew.morsillo@gmail.com";
|
||||
github = "AndrewMorsillo";
|
||||
@ -555,7 +584,6 @@
|
||||
};
|
||||
bjg = {
|
||||
email = "bjg@gnu.org";
|
||||
github = "civodul";
|
||||
name = "Brian Gough";
|
||||
};
|
||||
bjornfor = {
|
||||
@ -632,11 +660,6 @@
|
||||
github = "calbrecht";
|
||||
name = "Christian Albrecht";
|
||||
};
|
||||
calrama = {
|
||||
email = "moritz@ucworks.org";
|
||||
github = "MoritzMaxeiner";
|
||||
name = "Moritz Maxeiner";
|
||||
};
|
||||
calvertvl = {
|
||||
email = "calvertvl@gmail.com";
|
||||
github = "calvertvl";
|
||||
@ -1034,11 +1057,6 @@
|
||||
github = "dtzWill";
|
||||
name = "Will Dietz";
|
||||
};
|
||||
dupgit = {
|
||||
email = "olivier.delhomme@free.fr";
|
||||
github = "dupgit";
|
||||
name = "Olivier Delhomme";
|
||||
};
|
||||
dywedir = {
|
||||
email = "dywedir@protonmail.ch";
|
||||
github = "dywedir";
|
||||
@ -1247,6 +1265,11 @@
|
||||
github = "fare";
|
||||
name = "Francois-Rene Rideau";
|
||||
};
|
||||
fdns = {
|
||||
email = "fdns02@gmail.com";
|
||||
github = "fdns";
|
||||
name = "Felipe Espinoza";
|
||||
};
|
||||
fgaz = {
|
||||
email = "francygazz@gmail.com";
|
||||
github = "fgaz";
|
||||
@ -1549,6 +1572,11 @@
|
||||
github = "iblech";
|
||||
name = "Ingo Blechschmidt";
|
||||
};
|
||||
idontgetoutmuch = {
|
||||
email = "dominic@steinitz.org";
|
||||
github = "idontgetoutmuch";
|
||||
name = "Dominic Steinitz";
|
||||
};
|
||||
igsha = {
|
||||
email = "igor.sharonov@gmail.com";
|
||||
github = "igsha";
|
||||
@ -1663,7 +1691,7 @@
|
||||
name = "Johannes Frankenau";
|
||||
};
|
||||
jgeerds = {
|
||||
email = "jascha@jgeerds.name";
|
||||
email = "jascha@geerds.org";
|
||||
github = "jgeerds";
|
||||
name = "Jascha Geerds";
|
||||
};
|
||||
@ -1726,6 +1754,11 @@
|
||||
github = "johnazoidberg";
|
||||
name = "Daniel Schäfer";
|
||||
};
|
||||
johnchildren = {
|
||||
email = "john.a.children@gmail.com";
|
||||
github = "johnchildren";
|
||||
name = "John Children";
|
||||
};
|
||||
johnmh = {
|
||||
email = "johnmh@openblox.org";
|
||||
github = "johnmh";
|
||||
@ -2013,6 +2046,11 @@
|
||||
github = "lo1tuma";
|
||||
name = "Mathias Schreck";
|
||||
};
|
||||
lopsided98 = {
|
||||
email = "benwolsieffer@gmail.com";
|
||||
github = "lopsided98";
|
||||
name = "Ben Wolsieffer";
|
||||
};
|
||||
loskutov = {
|
||||
email = "ignat.loskutov@gmail.com";
|
||||
github = "loskutov";
|
||||
@ -2140,6 +2178,11 @@
|
||||
github = "markuskowa";
|
||||
name = "Markus Kowalewski";
|
||||
};
|
||||
marsam = {
|
||||
email = "marsam@users.noreply.github.com";
|
||||
github = "marsam";
|
||||
name = "Mario Rodas";
|
||||
};
|
||||
martijnvermaat = {
|
||||
email = "martijn@vermaat.name";
|
||||
github = "martijnvermaat";
|
||||
@ -2896,6 +2939,11 @@
|
||||
github = "rbasso";
|
||||
name = "Rafael Basso";
|
||||
};
|
||||
rdnetto = {
|
||||
email = "rdnetto@gmail.com";
|
||||
github = "rdnetto";
|
||||
name = "Reuben D'Netto";
|
||||
};
|
||||
redbaron = {
|
||||
email = "ivanov.maxim@gmail.com";
|
||||
github = "redbaron";
|
||||
@ -3155,6 +3203,11 @@
|
||||
github = "sellout";
|
||||
name = "Greg Pfeil";
|
||||
};
|
||||
sengaya = {
|
||||
email = "tlo@sengaya.de";
|
||||
github = "sengaya";
|
||||
name = "Thilo Uttendorfer";
|
||||
};
|
||||
sepi = {
|
||||
email = "raffael@mancini.lu";
|
||||
github = "sepi";
|
||||
@ -3418,6 +3471,11 @@
|
||||
github = "tavyc";
|
||||
name = "Octavian Cerna";
|
||||
};
|
||||
tazjin = {
|
||||
email = "mail@tazj.in";
|
||||
github = "tazjin";
|
||||
name = "Vincent Ambo";
|
||||
};
|
||||
teh = {
|
||||
email = "tehunger@gmail.com";
|
||||
github = "teh";
|
@ -13,7 +13,7 @@ from pyquery import PyQuery as pq
|
||||
|
||||
|
||||
maintainers_json = subprocess.check_output([
|
||||
'nix-instantiate', '-E', 'import ./lib/maintainers.nix {}', '--eval', '--json'
|
||||
'nix-instantiate', '-E', 'import ./maintainers/maintainer-list.nix {}', '--eval', '--json'
|
||||
])
|
||||
maintainers = json.loads(maintainers_json)
|
||||
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ packaging requests toolz ])' -p git
|
||||
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
|
||||
|
||||
"""
|
||||
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
||||
@ -358,4 +358,4 @@ def main():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
@ -6,11 +6,22 @@
|
||||
# TODO: add assert statements
|
||||
|
||||
let
|
||||
/* Remove duplicate elements from the list based on some extracted value. O(n^2) complexity.
|
||||
*/
|
||||
nubOn = f: list:
|
||||
if list == [] then
|
||||
[]
|
||||
else
|
||||
let
|
||||
x = pkgs.lib.head list;
|
||||
xs = pkgs.lib.filter (p: f x != f p) (pkgs.lib.drop 1 list);
|
||||
in
|
||||
[x] ++ nubOn f xs;
|
||||
|
||||
pkgs = import ./../../default.nix { };
|
||||
|
||||
packagesWith = cond: return: set:
|
||||
pkgs.lib.unique
|
||||
nubOn (pkg: pkg.updateScript)
|
||||
(pkgs.lib.flatten
|
||||
(pkgs.lib.mapAttrsToList
|
||||
(name: pkg:
|
||||
@ -34,7 +45,7 @@ let
|
||||
let
|
||||
maintainer =
|
||||
if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
|
||||
builtins.throw "Maintainer with name `${maintainer'} does not exist in `lib/maintainers.nix`."
|
||||
builtins.throw "Maintainer with name `${maintainer'} does not exist in `maintainers/maintainer-list.nix`."
|
||||
else
|
||||
builtins.getAttr maintainer' pkgs.lib.maintainers;
|
||||
in
|
||||
@ -65,7 +76,7 @@ let
|
||||
if package == null then
|
||||
builtins.throw "Package with an attribute name `${name}` does not exists."
|
||||
else if ! builtins.hasAttr "updateScript" package then
|
||||
builtins.throw "Package with an attribute name `${name}` does have an `passthru.updateScript` defined."
|
||||
builtins.throw "Package with an attribute name `${name}` does not have a `passthru.updateScript` attribute defined."
|
||||
else
|
||||
package;
|
||||
|
||||
|
@ -10,7 +10,7 @@ git_data="$(echo "$raw_git_log" | grep 'Author:' |
|
||||
|
||||
# Name - nick - email correspondence from log and from maintainer list
|
||||
# Also there are a few manual entries
|
||||
maintainers="$(cat "$(dirname "$0")/../../lib/maintainers.nix" |
|
||||
maintainers="$(cat "$(dirname "$0")/../maintainer-list.nix" |
|
||||
grep '=' | sed -re 's/\\"/''/g;
|
||||
s/[ ]*([^ =]*)[ ]*=[ ]*" *(.*[^ ]) *[<](.*)[>] *".*/\1\t\2\t\3/')"
|
||||
git_lines="$( ( echo "$git_data";
|
||||
|
@ -87,7 +87,7 @@ let
|
||||
echo "for hints about the offending path)."
|
||||
exit 1
|
||||
fi
|
||||
${libxslt.bin}/bin/xsltproc \
|
||||
${buildPackages.libxslt.bin}/bin/xsltproc \
|
||||
--stringparam revision '${revision}' \
|
||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||
'';
|
||||
@ -139,7 +139,7 @@ let
|
||||
|
||||
manual-combined = runCommand "nixos-manual-combined"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2 libxslt ];
|
||||
nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ];
|
||||
meta.description = "The NixOS manual as plain docbook XML";
|
||||
}
|
||||
''
|
||||
@ -194,7 +194,7 @@ let
|
||||
|
||||
olinkDB = runCommand "manual-olinkdb"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2 libxslt ];
|
||||
nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ];
|
||||
}
|
||||
''
|
||||
xsltproc \
|
||||
@ -244,7 +244,7 @@ in rec {
|
||||
# Generate the NixOS manual.
|
||||
manual = runCommand "nixos-manual"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2 libxslt ];
|
||||
nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ];
|
||||
meta.description = "The NixOS manual in HTML format";
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
@ -302,7 +302,7 @@ in rec {
|
||||
# Generate the NixOS manpages.
|
||||
manpages = runCommand "nixos-manpages"
|
||||
{ inherit sources;
|
||||
buildInputs = [ libxml2 libxslt ];
|
||||
nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ];
|
||||
allowedReferences = ["out"];
|
||||
}
|
||||
''
|
||||
|
@ -282,8 +282,8 @@ options.mod = mkOption {
|
||||
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
||||
|
||||
|
||||
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
||||
nof submodules</title>
|
||||
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
||||
of submodules</title>
|
||||
<screen>
|
||||
options.mod = mkOption {
|
||||
description = "submodule example";
|
||||
|
@ -227,6 +227,18 @@ $ sudo groupdel nixbld</screen>
|
||||
line)</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<note><para>Support for <literal>NIXOS_LUSTRATE</literal> was added
|
||||
in NixOS 16.09. The act of "lustrating" refers to the
|
||||
wiping of the existing distribution. Creating
|
||||
<literal>/etc/NIXOS_LUSTRATE</literal> can also be used on
|
||||
NixOS to remove all mutable files from your root partition
|
||||
(anything that's not in <literal>/nix</literal> or
|
||||
<literal>/boot</literal> gets "lustrated" on the next
|
||||
boot.</para>
|
||||
<para>lustrate /ˈlʌstreɪt/ verb.</para>
|
||||
<para>purify by expiatory sacrifice, ceremonial washing, or
|
||||
some other ritual action.</para></note>
|
||||
|
||||
<para>Let's create the files:</para>
|
||||
|
||||
<screen>
|
||||
|
@ -9,6 +9,7 @@
|
||||
<para>This section lists the release notes for each stable version of NixOS
|
||||
and current unstable revision.</para>
|
||||
|
||||
<xi:include href="rl-1809.xml" />
|
||||
<xi:include href="rl-1803.xml" />
|
||||
<xi:include href="rl-1709.xml" />
|
||||
<xi:include href="rl-1703.xml" />
|
||||
|
82
nixos/doc/manual/release-notes/rl-1809.xml
Normal file
82
nixos/doc/manual/release-notes/rl-1809.xml
Normal file
@ -0,0 +1,82 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09">
|
||||
|
||||
<title>Release 18.09 (“Jellyfish”, 2018/09/??)</title>
|
||||
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09-highlights">
|
||||
|
||||
<title>Highlights</title>
|
||||
|
||||
<para>In addition to numerous new and upgraded packages, this release
|
||||
has the following highlights: </para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
TODO
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09-new-services">
|
||||
|
||||
<title>New Services</title>
|
||||
|
||||
<para>The following new services were added since the last release:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09-incompatibilities">
|
||||
|
||||
<title>Backward Incompatibilities</title>
|
||||
|
||||
<para>When upgrading from a previous release, please be aware of the
|
||||
following incompatible changes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="sec-release-18.09-notable-changes">
|
||||
|
||||
<title>Other Notable Changes</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
</section>
|
@ -3,7 +3,11 @@
|
||||
with import ./build-vms.nix { inherit system minimal config; };
|
||||
with pkgs;
|
||||
|
||||
rec {
|
||||
let
|
||||
jquery-ui = callPackage ./testing/jquery-ui.nix { };
|
||||
jquery = callPackage ./testing/jquery.nix { };
|
||||
|
||||
in rec {
|
||||
|
||||
inherit pkgs;
|
||||
|
||||
@ -143,8 +147,8 @@ rec {
|
||||
test = passMeta (runTests driver);
|
||||
report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
|
||||
|
||||
in (if makeCoverageReport then report else test) // {
|
||||
inherit nodes driver test;
|
||||
in (if makeCoverageReport then report else test) // {
|
||||
inherit nodes driver test;
|
||||
};
|
||||
|
||||
runInMachine =
|
||||
|
@ -10,7 +10,7 @@ with lib;
|
||||
i18n = {
|
||||
glibcLocales = mkOption {
|
||||
type = types.path;
|
||||
default = pkgs.glibcLocales.override {
|
||||
default = pkgs.buildPackages.glibcLocales.override {
|
||||
allLocales = any (x: x == "all") config.i18n.supportedLocales;
|
||||
locales = config.i18n.supportedLocales;
|
||||
};
|
||||
|
@ -36,6 +36,7 @@ with lib;
|
||||
networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; };
|
||||
networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; };
|
||||
pinentry = pkgs.pinentry_ncurses;
|
||||
gobjectIntrospection = pkgs.gobjectIntrospection.override { x11Support = false; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ in
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
||||
ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
||||
};
|
||||
script = ''
|
||||
set -u
|
||||
|
@ -15,13 +15,19 @@ let
|
||||
|
||||
opengl = config.hardware.opengl;
|
||||
|
||||
kernel = pkgs.linux_4_9.override {
|
||||
extraConfig = ''
|
||||
KALLSYMS_ALL y
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
config = mkIf enabled {
|
||||
|
||||
nixpkgs.config.xorg.abiCompat = "1.18";
|
||||
nixpkgs.config.xorg.abiCompat = "1.19";
|
||||
|
||||
services.xserver.drivers = singleton
|
||||
{ name = "amdgpu"; modules = [ package ]; libPath = [ package ]; };
|
||||
@ -31,6 +37,9 @@ in
|
||||
|
||||
boot.extraModulePackages = [ package ];
|
||||
|
||||
boot.kernelPackages =
|
||||
pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
|
||||
|
||||
boot.blacklistedKernelModules = [ "radeon" ];
|
||||
|
||||
hardware.firmware = [ package ];
|
||||
@ -38,10 +47,15 @@ in
|
||||
system.activationScripts.setup-amdgpu-pro = ''
|
||||
mkdir -p /run/lib
|
||||
ln -sfn ${package}/lib ${package.libCompatDir}
|
||||
ln -sfn ${package} /run/amdgpu-pro
|
||||
'' + optionalString opengl.driSupport32Bit ''
|
||||
ln -sfn ${package32}/lib ${package32.libCompatDir}
|
||||
'';
|
||||
|
||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||
(isYes "KALLSYMS_ALL")
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"amd/amdrc".source = package + "/etc/amd/amdrc";
|
||||
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
||||
|
@ -75,10 +75,10 @@ in
|
||||
# Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
|
||||
services.udev.extraRules =
|
||||
''
|
||||
KERNEL=="nvidia", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidiactl c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 255'"
|
||||
KERNEL=="nvidia_modeset", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia-modeset c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 254'"
|
||||
KERNEL=="card*", SUBSYSTEM=="drm", DRIVERS=="nvidia", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia%n c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) %n'"
|
||||
KERNEL=="nvidia_uvm", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'"
|
||||
KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 255'"
|
||||
KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 254'"
|
||||
KERNEL=="card*", SUBSYSTEM=="drm", DRIVERS=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia%n c $(grep nvidia-frontend /proc/devices | cut -d \ -f 1) %n'"
|
||||
KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'"
|
||||
'';
|
||||
|
||||
boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ];
|
||||
|
@ -382,6 +382,6 @@ fi
|
||||
if [ "$action" = build-vm ]; then
|
||||
cat >&2 <<EOF
|
||||
|
||||
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
|
||||
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm)
|
||||
EOF
|
||||
fi
|
||||
|
@ -19,4 +19,6 @@ with lib;
|
||||
# Add some more video drivers to give X11 a shot at working in
|
||||
# VMware and QEMU.
|
||||
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
|
||||
|
||||
powerManagement.enable = false;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ in
|
||||
inherit (config.nixpkgs) config overlays system;
|
||||
}
|
||||
'';
|
||||
default = import ../../.. { inherit (cfg) config overlays system; };
|
||||
default = import ../../.. { inherit (cfg) config overlays system crossSystem; };
|
||||
type = pkgsType;
|
||||
example = literalExample ''import <nixpkgs> {}'';
|
||||
description = ''
|
||||
@ -130,6 +130,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
crossSystem = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
description = ''
|
||||
The description of the system we're cross-compiling to, or null
|
||||
if this isn't a cross-compile. See the description of the
|
||||
crossSystem argument in the nixpkgs manual.
|
||||
|
||||
Ignored when <code>nixpkgs.pkgs</code> is set.
|
||||
'';
|
||||
};
|
||||
|
||||
system = mkOption {
|
||||
type = types.str;
|
||||
example = "i686-linux";
|
||||
|
@ -85,8 +85,8 @@ in
|
||||
revision = mkIf (pathIsDirectory gitRepo) (mkDefault gitCommitId);
|
||||
versionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId));
|
||||
|
||||
# Note: code names must only increase in alphabetical order.
|
||||
codeName = "Impala";
|
||||
# Note: the first letter is bumped on every release. It's an animal.
|
||||
codeName = "Jellyfish";
|
||||
};
|
||||
|
||||
# Generate /etc/os-release. See
|
||||
|
@ -104,6 +104,7 @@
|
||||
./programs/shadow.nix
|
||||
./programs/shell.nix
|
||||
./programs/spacefm.nix
|
||||
./programs/singularity.nix
|
||||
./programs/ssh.nix
|
||||
./programs/ssmtp.nix
|
||||
./programs/sysdig.nix
|
||||
@ -159,6 +160,7 @@
|
||||
./services/audio/ympd.nix
|
||||
./services/backup/almir.nix
|
||||
./services/backup/bacula.nix
|
||||
./services/backup/borgbackup.nix
|
||||
./services/backup/crashplan.nix
|
||||
./services/backup/crashplan-small-business.nix
|
||||
./services/backup/mysql-backup.nix
|
||||
|
@ -10,4 +10,10 @@
|
||||
password = "demo";
|
||||
uid = 1000;
|
||||
};
|
||||
|
||||
services.xserver.displayManager.sddm.autoLogin = {
|
||||
enable = true;
|
||||
relogin = true;
|
||||
user = "demo";
|
||||
};
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ in
|
||||
programs.bash = {
|
||||
|
||||
shellInit = ''
|
||||
. ${config.system.build.setEnvironment}
|
||||
${config.system.build.setEnvironment.text}
|
||||
|
||||
${cfge.shellInit}
|
||||
'';
|
||||
|
@ -6,7 +6,7 @@ let
|
||||
cfg = config.programs.rootston;
|
||||
|
||||
rootstonWrapped = pkgs.writeScriptBin "rootston" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
if [[ "$#" -ge 1 ]]; then
|
||||
exec ${pkgs.rootston}/bin/rootston "$@"
|
||||
else
|
||||
|
20
nixos/modules/programs/singularity.nix
Normal file
20
nixos/modules/programs/singularity.nix
Normal file
@ -0,0 +1,20 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.programs.singularity;
|
||||
in {
|
||||
options.programs.singularity = {
|
||||
enable = mkEnableOption "Singularity";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.singularity ];
|
||||
systemd.tmpfiles.rules = [ "d /var/singularity/mnt/session 0770 root root -"
|
||||
"d /var/singularity/mnt/final 0770 root root -"
|
||||
"d /var/singularity/mnt/overlay 0770 root root -"
|
||||
"d /var/singularity/mnt/container 0770 root root -"
|
||||
"d /var/singularity/mnt/source 0770 root root -"];
|
||||
};
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ let
|
||||
|
||||
askPasswordWrapper = pkgs.writeScript "ssh-askpass-wrapper"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
export DISPLAY="$(systemctl --user show-environment | ${pkgs.gnused}/bin/sed 's/^DISPLAY=\(.*\)/\1/; t; d')"
|
||||
exec ${askPassword}
|
||||
'';
|
||||
|
@ -108,7 +108,7 @@ in
|
||||
if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi
|
||||
export __ETC_ZSHENV_SOURCED=1
|
||||
|
||||
. ${config.system.build.setEnvironment}
|
||||
${config.system.build.setEnvironment.text}
|
||||
|
||||
${cfge.shellInit}
|
||||
|
||||
|
@ -13,7 +13,7 @@ let
|
||||
};
|
||||
|
||||
disableScript = pkgs.writeScript "audit-disable" ''
|
||||
#!${pkgs.stdenv.shell} -eu
|
||||
#!${pkgs.runtimeShell} -eu
|
||||
# Explicitly disable everything, as otherwise journald might start it.
|
||||
auditctl -D
|
||||
auditctl -e 0 -a task,never
|
||||
@ -23,7 +23,7 @@ let
|
||||
# put in the store like this. At the same time, it doesn't feel like a huge deal and working
|
||||
# around that is a pain so I'm leaving it like this for now.
|
||||
startScript = pkgs.writeScript "audit-start" ''
|
||||
#!${pkgs.stdenv.shell} -eu
|
||||
#!${pkgs.runtimeShell} -eu
|
||||
# Clear out any rules we may start with
|
||||
auditctl -D
|
||||
|
||||
@ -43,7 +43,7 @@ let
|
||||
'';
|
||||
|
||||
stopScript = pkgs.writeScript "audit-stop" ''
|
||||
#!${pkgs.stdenv.shell} -eu
|
||||
#!${pkgs.runtimeShell} -eu
|
||||
# Clear the rules
|
||||
auditctl -D
|
||||
|
||||
|
@ -47,8 +47,8 @@ in
|
||||
default = true;
|
||||
description =
|
||||
''
|
||||
Whether users of the <code>wheel</code> group can execute
|
||||
commands as super user without entering a password.
|
||||
Whether users of the <code>wheel</code> group must
|
||||
provide a password to run commands as super user via <command>sudo</command>.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -215,7 +215,7 @@ in
|
||||
{ src = pkgs.writeText "sudoers-in" cfg.configFile; }
|
||||
# Make sure that the sudoers file is syntactically valid.
|
||||
# (currently disabled - NIXOS-66)
|
||||
"${pkgs.sudo}/sbin/visudo -f $src -c && cp $src $out";
|
||||
"${pkgs.buildPackages.sudo}/sbin/visudo -f $src -c && cp $src $out";
|
||||
target = "sudoers";
|
||||
mode = "0440";
|
||||
};
|
||||
|
580
nixos/modules/services/backup/borgbackup.nix
Normal file
580
nixos/modules/services/backup/borgbackup.nix
Normal file
@ -0,0 +1,580 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
isLocalPath = x:
|
||||
builtins.substring 0 1 x == "/" # absolute path
|
||||
|| builtins.substring 0 1 x == "." # relative path
|
||||
|| builtins.match "[.*:.*]" == null; # not machine:path
|
||||
|
||||
mkExcludeFile = cfg:
|
||||
# Write each exclude pattern to a new line
|
||||
pkgs.writeText "excludefile" (concatStringsSep "\n" cfg.exclude);
|
||||
|
||||
mkKeepArgs = cfg:
|
||||
# If cfg.prune.keep e.g. has a yearly attribute,
|
||||
# its content is passed on as --keep-yearly
|
||||
concatStringsSep " "
|
||||
(mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep);
|
||||
|
||||
mkBackupScript = cfg: ''
|
||||
on_exit()
|
||||
{
|
||||
exitStatus=$?
|
||||
# Reset the EXIT handler, or else we're called again on 'exit' below
|
||||
trap - EXIT
|
||||
${cfg.postHook}
|
||||
exit $exitStatus
|
||||
}
|
||||
trap 'on_exit' INT TERM QUIT EXIT
|
||||
|
||||
archiveName="${cfg.archiveBaseName}-$(date ${cfg.dateFormat})"
|
||||
archiveSuffix="${optionalString cfg.appendFailedSuffix ".failed"}"
|
||||
${cfg.preHook}
|
||||
'' + optionalString cfg.doInit ''
|
||||
# Run borg init if the repo doesn't exist yet
|
||||
if ! borg list > /dev/null; then
|
||||
borg init \
|
||||
--encryption ${cfg.encryption.mode} \
|
||||
$extraInitArgs
|
||||
${cfg.postInit}
|
||||
fi
|
||||
'' + ''
|
||||
borg create \
|
||||
--compression ${cfg.compression} \
|
||||
--exclude-from ${mkExcludeFile cfg} \
|
||||
$extraCreateArgs \
|
||||
"::$archiveName$archiveSuffix" \
|
||||
${escapeShellArgs cfg.paths}
|
||||
'' + optionalString cfg.appendFailedSuffix ''
|
||||
borg rename "::$archiveName$archiveSuffix" "$archiveName"
|
||||
'' + ''
|
||||
${cfg.postCreate}
|
||||
'' + optionalString (cfg.prune.keep != { }) ''
|
||||
borg prune \
|
||||
${mkKeepArgs cfg} \
|
||||
--prefix ${escapeShellArg cfg.prune.prefix} \
|
||||
$extraPruneArgs
|
||||
${cfg.postPrune}
|
||||
'';
|
||||
|
||||
mkPassEnv = cfg: with cfg.encryption;
|
||||
if passCommand != null then
|
||||
{ BORG_PASSCOMMAND = passCommand; }
|
||||
else if passphrase != null then
|
||||
{ BORG_PASSPHRASE = passphrase; }
|
||||
else { };
|
||||
|
||||
mkBackupService = name: cfg:
|
||||
let
|
||||
userHome = config.users.users.${cfg.user}.home;
|
||||
in nameValuePair "borgbackup-job-${name}" {
|
||||
description = "BorgBackup job ${name}";
|
||||
path = with pkgs; [
|
||||
borgbackup openssh
|
||||
];
|
||||
script = mkBackupScript cfg;
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
# Only run when no other process is using CPU or disk
|
||||
CPUSchedulingPolicy = "idle";
|
||||
IOSchedulingClass = "idle";
|
||||
ProtectSystem = "strict";
|
||||
ReadWritePaths =
|
||||
[ "${userHome}/.config/borg" "${userHome}/.cache/borg" ]
|
||||
# Borg needs write access to repo if it is not remote
|
||||
++ optional (isLocalPath cfg.repo) cfg.repo;
|
||||
PrivateTmp = true;
|
||||
};
|
||||
environment = {
|
||||
BORG_REPO = cfg.repo;
|
||||
inherit (cfg) extraInitArgs extraCreateArgs extraPruneArgs;
|
||||
} // (mkPassEnv cfg) // cfg.environment;
|
||||
inherit (cfg) startAt;
|
||||
};
|
||||
|
||||
# Paths listed in ReadWritePaths must exist before service is started
|
||||
mkActivationScript = name: cfg:
|
||||
let
|
||||
install = "install -o ${cfg.user} -g ${cfg.group}";
|
||||
in
|
||||
nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] (''
|
||||
# Eensure that the home directory already exists
|
||||
# We can't assert createHome == true because that's not the case for root
|
||||
cd "${config.users.users.${cfg.user}.home}"
|
||||
${install} -d .config/borg
|
||||
${install} -d .cache/borg
|
||||
'' + optionalString (isLocalPath cfg.repo) ''
|
||||
${install} -d ${escapeShellArg cfg.repo}
|
||||
''));
|
||||
|
||||
mkPassAssertion = name: cfg: {
|
||||
assertion = with cfg.encryption;
|
||||
mode != "none" -> passCommand != null || passphrase != null;
|
||||
message =
|
||||
"passCommand or passphrase has to be specified because"
|
||||
+ '' borgbackup.jobs.${name}.encryption != "none"'';
|
||||
};
|
||||
|
||||
mkRepoService = name: cfg:
|
||||
nameValuePair "borgbackup-repo-${name}" {
|
||||
description = "Create BorgBackup repository ${name} directory";
|
||||
script = ''
|
||||
mkdir -p ${escapeShellArg cfg.path}
|
||||
chown ${cfg.user}:${cfg.group} ${escapeShellArg cfg.path}
|
||||
'';
|
||||
serviceConfig = {
|
||||
# The service's only task is to ensure that the specified path exists
|
||||
Type = "oneshot";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
mkAuthorizedKey = cfg: appendOnly: key:
|
||||
let
|
||||
# Because of the following line, clients do not need to specify an absolute repo path
|
||||
cdCommand = "cd ${escapeShellArg cfg.path}";
|
||||
restrictedArg = "--restrict-to-${if cfg.allowSubRepos then "path" else "repository"} .";
|
||||
appendOnlyArg = optionalString appendOnly "--append-only";
|
||||
quotaArg = optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}";
|
||||
serveCommand = "borg serve ${restrictedArg} ${appendOnlyArg} ${quotaArg}";
|
||||
in
|
||||
''command="${cdCommand} && ${serveCommand}",restrict ${key}'';
|
||||
|
||||
mkUsersConfig = name: cfg: {
|
||||
users.${cfg.user} = {
|
||||
openssh.authorizedKeys.keys =
|
||||
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
|
||||
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
|
||||
useDefaultShell = true;
|
||||
};
|
||||
groups.${cfg.group} = { };
|
||||
};
|
||||
|
||||
mkKeysAssertion = name: cfg: {
|
||||
assertion = cfg.authorizedKeys != [ ] || cfg.authorizedKeysAppendOnly != [ ];
|
||||
message =
|
||||
"borgbackup.repos.${name} does not make sense"
|
||||
+ " without at least one public key";
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ dotlambda ];
|
||||
|
||||
###### interface
|
||||
|
||||
options.services.borgbackup.jobs = mkOption {
|
||||
description = "Deduplicating backups using BorgBackup.";
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
rootBackup = {
|
||||
paths = "/";
|
||||
exclude = [ "/nix" ];
|
||||
repo = "/path/to/local/repo";
|
||||
encryption = {
|
||||
mode = "repokey";
|
||||
passphrase = "secret";
|
||||
};
|
||||
compression = "auto,lzma";
|
||||
startAt = "weekly";
|
||||
};
|
||||
}
|
||||
'';
|
||||
type = types.attrsOf (types.submodule (let globalConfig = config; in
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
|
||||
paths = mkOption {
|
||||
type = with types; either path (nonEmptyListOf path);
|
||||
description = "Path(s) to back up.";
|
||||
example = "/home/user";
|
||||
apply = x: if isList x then x else [ x ];
|
||||
};
|
||||
|
||||
repo = mkOption {
|
||||
type = types.str;
|
||||
description = "Remote or local repository to back up to.";
|
||||
example = "user@machine:/path/to/repo";
|
||||
};
|
||||
|
||||
archiveBaseName = mkOption {
|
||||
type = types.strMatching "[^/{}]+";
|
||||
default = "${globalConfig.networking.hostName}-${name}";
|
||||
defaultText = "\${config.networking.hostName}-<name>";
|
||||
description = ''
|
||||
How to name the created archives. A timestamp, whose format is
|
||||
determined by <option>dateFormat</option>, will be appended. The full
|
||||
name can be modified at runtime (<literal>$archiveName</literal>).
|
||||
Placeholders like <literal>{hostname}</literal> must not be used.
|
||||
'';
|
||||
};
|
||||
|
||||
dateFormat = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Arguments passed to <command>date</command>
|
||||
to create a timestamp suffix for the archive name.
|
||||
'';
|
||||
default = "+%Y-%m-%dT%H:%M:%S";
|
||||
example = "-u +%s";
|
||||
};
|
||||
|
||||
startAt = mkOption {
|
||||
type = with types; either str (listOf str);
|
||||
default = "daily";
|
||||
description = ''
|
||||
When or how often the backup should run.
|
||||
Must be in the format described in
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle>
|
||||
<manvolnum>7</manvolnum></citerefentry>.
|
||||
If you do not want the backup to start
|
||||
automatically, use <literal>[ ]</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The user <command>borg</command> is run as.
|
||||
User or group need read permission
|
||||
for the specified <option>paths</option>.
|
||||
'';
|
||||
default = "root";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The group borg is run as. User or group needs read permission
|
||||
for the specified <option>paths</option>.
|
||||
'';
|
||||
default = "root";
|
||||
};
|
||||
|
||||
encryption.mode = mkOption {
|
||||
type = types.enum [
|
||||
"repokey" "keyfile"
|
||||
"repokey-blake2" "keyfile-blake2"
|
||||
"authenticated" "authenticated-blake2"
|
||||
"none"
|
||||
];
|
||||
description = ''
|
||||
Encryption mode to use. Setting a mode
|
||||
other than <literal>"none"</literal> requires
|
||||
you to specify a <option>passCommand</option>
|
||||
or a <option>passphrase</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
encryption.passCommand = mkOption {
|
||||
type = with types; nullOr str;
|
||||
description = ''
|
||||
A command which prints the passphrase to stdout.
|
||||
Mutually exclusive with <option>passphrase</option>.
|
||||
'';
|
||||
default = null;
|
||||
example = "cat /path/to/passphrase_file";
|
||||
};
|
||||
|
||||
encryption.passphrase = mkOption {
|
||||
type = with types; nullOr str;
|
||||
description = ''
|
||||
The passphrase the backups are encrypted with.
|
||||
Mutually exclusive with <option>passCommand</option>.
|
||||
If you do not want the passphrase to be stored in the
|
||||
world-readable Nix store, use <option>passCommand</option>.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
compression = mkOption {
|
||||
# "auto" is optional,
|
||||
# compression mode must be given,
|
||||
# compression level is optional
|
||||
type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?";
|
||||
description = ''
|
||||
Compression method to use. Refer to
|
||||
<command>borg help compression</command>
|
||||
for all available options.
|
||||
'';
|
||||
default = "lz4";
|
||||
example = "auto,lzma";
|
||||
};
|
||||
|
||||
exclude = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
Exclude paths matching any of the given patterns. See
|
||||
<command>borg help patterns</command> for pattern syntax.
|
||||
'';
|
||||
default = [ ];
|
||||
example = [
|
||||
"/home/*/.cache"
|
||||
"/nix"
|
||||
];
|
||||
};
|
||||
|
||||
doInit = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Run <command>borg init</command> if the
|
||||
specified <option>repo</option> does not exist.
|
||||
You should set this to <literal>false</literal>
|
||||
if the repository is located on an external drive
|
||||
that might not always be mounted.
|
||||
'';
|
||||
default = true;
|
||||
};
|
||||
|
||||
appendFailedSuffix = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Append a <literal>.failed</literal> suffix
|
||||
to the archive name, which is only removed if
|
||||
<command>borg create</command> has a zero exit status.
|
||||
'';
|
||||
default = true;
|
||||
};
|
||||
|
||||
prune.keep = mkOption {
|
||||
# Specifying e.g. `prune.keep.yearly = -1`
|
||||
# means there is no limit of yearly archives to keep
|
||||
# The regex is for use with e.g. --keep-within 1y
|
||||
type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]"));
|
||||
description = ''
|
||||
Prune a repository by deleting all archives not matching any of the
|
||||
specified retention options. See <command>borg help prune</command>
|
||||
for the available options.
|
||||
'';
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
within = "1d"; # Keep all archives from the last day
|
||||
daily = 7;
|
||||
weekly = 4;
|
||||
monthly = -1; # Keep at least one archive for each month
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
prune.prefix = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Only consider archive names starting with this prefix for pruning.
|
||||
By default, only archives created by this job are considered.
|
||||
Use <literal>""</literal> to consider all archives.
|
||||
'';
|
||||
default = config.archiveBaseName;
|
||||
defaultText = "\${archiveBaseName}";
|
||||
};
|
||||
|
||||
environment = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
description = ''
|
||||
Environment variables passed to the backup script.
|
||||
You can for example specify which SSH key to use.
|
||||
'';
|
||||
default = { };
|
||||
example = { BORG_RSH = "ssh -i /path/to/key"; };
|
||||
};
|
||||
|
||||
preHook = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands to run before the backup.
|
||||
This can for example be used to mount file systems.
|
||||
'';
|
||||
default = "";
|
||||
example = ''
|
||||
# To add excluded paths at runtime
|
||||
extraCreateArgs="$extraCreateArgs --exclude /some/path"
|
||||
'';
|
||||
};
|
||||
|
||||
postInit = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands to run after <command>borg init</command>.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
postCreate = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands to run after <command>borg create</command>. The name
|
||||
of the created archive is stored in <literal>$archiveName</literal>.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
postPrune = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands to run after <command>borg prune</command>.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
postHook = mkOption {
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands to run just before exit. They are executed
|
||||
even if a previous command exits with a non-zero exit code.
|
||||
The latter is available as <literal>$exitStatus</literal>.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
extraInitArgs = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Additional arguments for <command>borg init</command>.
|
||||
Can also be set at runtime using <literal>$extraInitArgs</literal>.
|
||||
'';
|
||||
default = "";
|
||||
example = "--append-only";
|
||||
};
|
||||
|
||||
extraCreateArgs = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Additional arguments for <command>borg create</command>.
|
||||
Can also be set at runtime using <literal>$extraCreateArgs</literal>.
|
||||
'';
|
||||
default = "";
|
||||
example = "--stats --checkpoint-interval 600";
|
||||
};
|
||||
|
||||
extraPruneArgs = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Additional arguments for <command>borg prune</command>.
|
||||
Can also be set at runtime using <literal>$extraPruneArgs</literal>.
|
||||
'';
|
||||
default = "";
|
||||
example = "--save-space";
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
options.services.borgbackup.repos = mkOption {
|
||||
description = ''
|
||||
Serve BorgBackup repositories to given public SSH keys,
|
||||
restricting their access to the repository only.
|
||||
Also, clients do not need to specify the absolute path when accessing the repository,
|
||||
i.e. <literal>user@machine:.</literal> is enough. (Note colon and dot.)
|
||||
'';
|
||||
default = { };
|
||||
type = types.attrsOf (types.submodule (
|
||||
{ name, config, ... }: {
|
||||
options = {
|
||||
|
||||
path = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Where to store the backups. Note that the directory
|
||||
is created automatically, with correct permissions.
|
||||
'';
|
||||
default = "/var/lib/borgbackup";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The user <command>borg serve</command> is run as.
|
||||
User or group needs write permission
|
||||
for the specified <option>path</option>.
|
||||
'';
|
||||
default = "borg";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The group <command>borg serve</command> is run as.
|
||||
User or group needs write permission
|
||||
for the specified <option>path</option>.
|
||||
'';
|
||||
default = "borg";
|
||||
};
|
||||
|
||||
authorizedKeys = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
Public SSH keys that are given full write access to this repository.
|
||||
You should use a different SSH key for each repository you write to, because
|
||||
the specified keys are restricted to running <command>borg serve</command>
|
||||
and can only access this single repository.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
authorizedKeysAppendOnly = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
Public SSH keys that can only be used to append new data (archives) to the repository.
|
||||
Note that archives can still be marked as deleted and are subsequently removed from disk
|
||||
upon accessing the repo with full write access, e.g. when pruning.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
allowSubRepos = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Allow clients to create repositories in subdirectories of the
|
||||
specified <option>path</option>. These can be accessed using
|
||||
<literal>user@machine:path/to/subrepo</literal>. Note that a
|
||||
<option>quota</option> applies to repositories independently.
|
||||
Therefore, if this is enabled, clients can create multiple
|
||||
repositories and upload an arbitrary amount of data.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
|
||||
quota = mkOption {
|
||||
# See the definition of parse_file_size() in src/borg/helpers/parseformat.py
|
||||
type = with types; nullOr (strMatching "[[:digit:].]+[KMGTP]?");
|
||||
description = ''
|
||||
Storage quota for the repository. This quota is ensured for all
|
||||
sub-repositories if <option>allowSubRepos</option> is enabled
|
||||
but not for the overall storage space used.
|
||||
'';
|
||||
default = null;
|
||||
example = "100G";
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf (with config.services.borgbackup; jobs != { } || repos != { })
|
||||
(with config.services.borgbackup; {
|
||||
assertions =
|
||||
mapAttrsToList mkPassAssertion jobs
|
||||
++ mapAttrsToList mkKeysAssertion repos;
|
||||
|
||||
system.activationScripts = mapAttrs' mkActivationScript jobs;
|
||||
|
||||
systemd.services =
|
||||
# A job named "foo" is mapped to systemd.services.borgbackup-job-foo
|
||||
mapAttrs' mkBackupService jobs
|
||||
# A repo named "foo" is mapped to systemd.services.borgbackup-repo-foo
|
||||
// mapAttrs' mkRepoService repos;
|
||||
|
||||
users = mkMerge (mapAttrsToList mkUsersConfig repos);
|
||||
|
||||
environment.systemPackages = with pkgs; [ borgbackup ];
|
||||
});
|
||||
}
|
@ -18,7 +18,7 @@ let
|
||||
hooksDir = let
|
||||
mkHookEntry = name: value: ''
|
||||
cat > $out/${name} <<EOF
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
set -e
|
||||
${value}
|
||||
EOF
|
||||
|
@ -145,6 +145,11 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# server references the dejavu fonts
|
||||
environment.systemPackages = [
|
||||
pkgs.dejavu_fonts
|
||||
];
|
||||
|
||||
users.extraGroups = optional (cfg.group == "jenkins") {
|
||||
name = "jenkins";
|
||||
gid = config.ids.gids.jenkins;
|
||||
@ -200,10 +205,12 @@ in {
|
||||
${replacePlugins}
|
||||
'';
|
||||
|
||||
# For reference: https://wiki.jenkins.io/display/JENKINS/JenkinsLinuxStartupScript
|
||||
script = ''
|
||||
${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
|
||||
--httpPort=${toString cfg.port} \
|
||||
--prefix=${cfg.prefix} \
|
||||
-Djava.awt.headless=true \
|
||||
${concatStringsSep " " cfg.extraOptions}
|
||||
'';
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
let
|
||||
cfg = config.services.fourStoreEndpoint;
|
||||
endpointUser = "fourstorehttp";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${endpointUser} -c";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${endpointUser} -c";
|
||||
in
|
||||
with lib;
|
||||
{
|
||||
|
@ -3,7 +3,7 @@ let
|
||||
cfg = config.services.fourStore;
|
||||
stateDir = "/var/lib/4store";
|
||||
fourStoreUser = "fourstore";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fourStoreUser}";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${fourStoreUser}";
|
||||
in
|
||||
with lib;
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ let
|
||||
cfg = config.services.emacs;
|
||||
|
||||
editorScript = pkgs.writeScriptBin "emacseditor" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
if [ -z "$1" ]; then
|
||||
exec ${cfg.package}/bin/emacsclient --create-frame --alternate-editor ${cfg.package}/bin/emacs
|
||||
else
|
||||
|
@ -146,7 +146,7 @@ let
|
||||
|
||||
echo "Generating hwdb database..."
|
||||
# hwdb --update doesn't return error code even on errors!
|
||||
res="$(${udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)"
|
||||
res="$(${pkgs.buildPackages.udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)"
|
||||
echo "$res"
|
||||
[ -z "$(echo "$res" | egrep '^Error')" ]
|
||||
mv etc/udev/hwdb.bin $out
|
||||
|
@ -57,7 +57,7 @@ in {
|
||||
chown ${fahUser} ${stateDir}
|
||||
cp -f ${pkgs.writeText "client.cfg" cfg.config} ${stateDir}/client.cfg
|
||||
'';
|
||||
script = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'";
|
||||
script = "${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${fahUser} -c 'cd ${stateDir}; ${pkgs.foldingathome}/bin/fah6'";
|
||||
};
|
||||
|
||||
services.foldingAtHome.config = ''
|
||||
|
@ -14,7 +14,7 @@ let
|
||||
# ExecStart= command with '@' doesn't work because we start a shell (new
|
||||
# process) that creates a new argv[0].)
|
||||
geoip-updater = pkgs.writeScriptBin "geoip-updater" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
skipExisting=0
|
||||
debug()
|
||||
{
|
||||
|
@ -4,6 +4,8 @@ with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gitea;
|
||||
pg = config.services.postgresql;
|
||||
usePostgresql = cfg.database.type == "postgres";
|
||||
configFile = pkgs.writeText "app.ini" ''
|
||||
APP_NAME = ${cfg.appName}
|
||||
RUN_USER = ${cfg.user}
|
||||
@ -16,6 +18,9 @@ let
|
||||
USER = ${cfg.database.user}
|
||||
PASSWD = #dbpass#
|
||||
PATH = ${cfg.database.path}
|
||||
${optionalString usePostgresql ''
|
||||
SSL_MODE = disable
|
||||
''}
|
||||
|
||||
[repository]
|
||||
ROOT = ${cfg.repositoryRoot}
|
||||
@ -35,6 +40,10 @@ let
|
||||
SECRET_KEY = #secretkey#
|
||||
INSTALL_LOCK = true
|
||||
|
||||
[log]
|
||||
ROOT_PATH = ${cfg.log.rootPath}
|
||||
LEVEL = ${cfg.log.level}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
@ -60,6 +69,19 @@ in
|
||||
description = "gitea data directory.";
|
||||
};
|
||||
|
||||
log = {
|
||||
rootPath = mkOption {
|
||||
default = "${cfg.stateDir}/log";
|
||||
type = types.str;
|
||||
description = "Root path for log files.";
|
||||
};
|
||||
level = mkOption {
|
||||
default = "Trace";
|
||||
type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
|
||||
description = "General log level.";
|
||||
};
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "gitea";
|
||||
@ -82,7 +104,7 @@ in
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 3306;
|
||||
default = (if !usePostgresql then 3306 else pg.port);
|
||||
description = "Database host port.";
|
||||
};
|
||||
|
||||
@ -123,6 +145,15 @@ in
|
||||
default = "${cfg.stateDir}/data/gitea.db";
|
||||
description = "Path to the sqlite3 database file.";
|
||||
};
|
||||
|
||||
createDatabase = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to create a local postgresql database automatically.
|
||||
This only applies if database type "postgres" is selected.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
appName = mkOption {
|
||||
@ -186,10 +217,11 @@ in
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.postgresql.enable = mkIf usePostgresql (mkDefault true);
|
||||
|
||||
systemd.services.gitea = {
|
||||
description = "gitea";
|
||||
after = [ "network.target" ];
|
||||
after = [ "network.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.gitea.bin ];
|
||||
|
||||
@ -231,12 +263,31 @@ in
|
||||
mkdir -p ${cfg.stateDir}/conf
|
||||
cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale
|
||||
fi
|
||||
'' + optionalString (usePostgresql && cfg.database.createDatabase) ''
|
||||
if ! test -e "${cfg.stateDir}/db-created"; then
|
||||
echo "CREATE ROLE ${cfg.database.user}
|
||||
WITH ENCRYPTED PASSWORD '$(head -n1 ${cfg.database.passwordFile})'
|
||||
NOCREATEDB NOCREATEROLE LOGIN" |
|
||||
${pkgs.sudo}/bin/sudo -u ${pg.superUser} ${pg.package}/bin/psql
|
||||
${pkgs.sudo}/bin/sudo -u ${pg.superUser} \
|
||||
${pg.package}/bin/createdb \
|
||||
--owner=${cfg.database.user} \
|
||||
--encoding=UTF8 \
|
||||
--lc-collate=C \
|
||||
--lc-ctype=C \
|
||||
--template=template0 \
|
||||
${cfg.database.name}
|
||||
touch "${cfg.stateDir}/db-created"
|
||||
fi
|
||||
'' + ''
|
||||
chown ${cfg.user} -R ${cfg.stateDir}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
WorkingDirectory = cfg.stateDir;
|
||||
PermissionsStartOnly = true;
|
||||
ExecStart = "${pkgs.gitea.bin}/bin/gitea web";
|
||||
Restart = "always";
|
||||
};
|
||||
@ -253,6 +304,7 @@ in
|
||||
description = "Gitea Service";
|
||||
home = cfg.stateDir;
|
||||
createHome = true;
|
||||
useDefaultShell = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@ let
|
||||
gititSh = hsPkgs: extras: with pkgs; let
|
||||
env = gititWithPkgs hsPkgs extras;
|
||||
in writeScript "gitit" ''
|
||||
#!${stdenv.shell}
|
||||
#!${runtimeShell}
|
||||
cd $HOME
|
||||
export NIX_GHC="${env}/bin/ghc"
|
||||
export NIX_GHCPKG="${env}/bin/ghc-pkg"
|
||||
|
@ -104,7 +104,6 @@ in {
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.home-assistant = {
|
||||
description = "Home Assistant";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
preStart = lib.optionalString (cfg.config != null) ''
|
||||
rm -f ${cfg.configDir}/configuration.yaml
|
||||
@ -121,6 +120,16 @@ in {
|
||||
ReadWritePaths = "${cfg.configDir}";
|
||||
PrivateTmp = true;
|
||||
};
|
||||
path = [
|
||||
"/run/wrappers" # needed for ping
|
||||
];
|
||||
};
|
||||
|
||||
systemd.targets.home-assistant = rec {
|
||||
description = "Home Assistant";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "home-assistant.service" ];
|
||||
after = wants;
|
||||
};
|
||||
|
||||
users.extraUsers.hass = {
|
||||
|
@ -55,7 +55,7 @@ in
|
||||
serviceConfig = {
|
||||
User = config.users.extraUsers.ihaskell.name;
|
||||
Group = config.users.extraGroups.ihaskell.name;
|
||||
ExecStart = "${pkgs.stdenv.shell} -c \"cd $HOME;${ihaskell}/bin/ihaskell-notebook\"";
|
||||
ExecStart = "${pkgs.runtimeShell} -c \"cd $HOME;${ihaskell}/bin/ihaskell-notebook\"";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -188,7 +188,7 @@ in {
|
||||
description = "Mesos Slave";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
path = [ pkgs.stdenv.shellPackage ];
|
||||
path = [ pkgs.runtimeShellPackage ];
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.mesos}/bin/mesos-slave \
|
||||
|
@ -30,7 +30,7 @@ let
|
||||
# /bin/sh in the sandbox as a bind-mount to bash. This means we
|
||||
# also need to include the entire closure of bash. Nix >= 2.0
|
||||
# provides a /bin/sh by default.
|
||||
sh = pkgs.stdenv.shell;
|
||||
sh = pkgs.runtimeShell;
|
||||
binshDeps = pkgs.writeReferencesToFile sh;
|
||||
in
|
||||
pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; } ''
|
||||
|
@ -43,7 +43,7 @@ let
|
||||
|
||||
helpScript = pkgs.writeScriptBin "nixos-help"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
browser="$BROWSER"
|
||||
if [ -z "$browser" ]; then
|
||||
browser="$(type -P xdg-open || true)"
|
||||
|
@ -8,7 +8,7 @@ let
|
||||
# in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM
|
||||
# looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix.
|
||||
fake-lsb-release = pkgs.writeScriptBin "lsb_release" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
|
||||
case "$1" in
|
||||
-i) echo "nixos";;
|
||||
|
@ -38,7 +38,7 @@ let
|
||||
];
|
||||
|
||||
shellCmdsForEventScript = eventname: commands: ''
|
||||
echo "#!${pkgs.stdenv.shell}" > "$out/${eventname}"
|
||||
echo "#!${pkgs.runtimeShell}" > "$out/${eventname}"
|
||||
echo '${commands}' >> "$out/${eventname}"
|
||||
chmod a+x "$out/${eventname}"
|
||||
'';
|
||||
|
@ -25,6 +25,7 @@ let
|
||||
DATABASE_USER = cfg.database.user;
|
||||
DATABASE_PASSWORD = cfg.database.password;
|
||||
DATABASE_PATH = cfg.database.path;
|
||||
DATABASE_CONN_MAX_LIFETIME = cfg.database.connMaxLifetime;
|
||||
|
||||
SECURITY_ADMIN_USER = cfg.security.adminUser;
|
||||
SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword;
|
||||
@ -143,6 +144,15 @@ in {
|
||||
default = "${cfg.dataDir}/data/grafana.db";
|
||||
type = types.path;
|
||||
};
|
||||
|
||||
connMaxLifetime = mkOption {
|
||||
description = ''
|
||||
Sets the maximum amount of time (in seconds) a connection may be reused.
|
||||
For MySQL this setting should be shorter than the `wait_timeout' variable.
|
||||
'';
|
||||
default = 14400;
|
||||
type = types.int;
|
||||
};
|
||||
};
|
||||
|
||||
security = {
|
||||
@ -241,7 +251,9 @@ in {
|
||||
description = "Grafana Service Daemon";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["networking.target"];
|
||||
environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
|
||||
environment = {
|
||||
QT_QPA_PLATFORM = "offscreen";
|
||||
} // mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
|
@ -14,7 +14,7 @@ let
|
||||
nx = cfg.notifications.x11;
|
||||
|
||||
smartdNotify = pkgs.writeScript "smartd-notify.sh" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
${optionalString nm.enable ''
|
||||
{
|
||||
${pkgs.coreutils}/bin/cat << EOF
|
||||
|
@ -11,7 +11,7 @@ let
|
||||
home = cfg.homeDir;
|
||||
|
||||
startupScript = class: configPath: pkgs.writeScript "xtreemfs-osd.sh" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
JAVA_HOME="${pkgs.jdk}"
|
||||
JAVADIR="${xtreemfs}/share/java"
|
||||
JAVA_CALL="$JAVA_HOME/bin/java -ea -cp $JAVADIR/XtreemFS.jar:$JAVADIR/BabuDB.jar:$JAVADIR/Flease.jar:$JAVADIR/protobuf-java-2.5.0.jar:$JAVADIR/Foundation.jar:$JAVADIR/jdmkrt.jar:$JAVADIR/jdmktk.jar:$JAVADIR/commons-codec-1.3.jar"
|
||||
|
@ -99,10 +99,10 @@ in
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
|
||||
${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${u} \
|
||||
-c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token'
|
||||
|
||||
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
|
||||
${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${u} \
|
||||
-c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory} --exclude-dirs=${cfg.excludes}'
|
||||
'';
|
||||
|
||||
|
@ -68,7 +68,7 @@ in
|
||||
'';
|
||||
|
||||
script = ''
|
||||
${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${user} \
|
||||
${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${user} \
|
||||
-c 'HOME="${cfg.dataDir}" ${pkgs.amuleDaemon}/bin/amuled'
|
||||
'';
|
||||
};
|
||||
|
@ -54,7 +54,7 @@ let
|
||||
'';
|
||||
|
||||
writeShScript = name: text: let dir = pkgs.writeScriptBin name ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${text}
|
||||
''; in "${dir}/bin/${name}";
|
||||
|
||||
|
@ -22,7 +22,7 @@ let
|
||||
|
||||
flashpolicydWrapper = pkgs.writeScriptBin "flashpolicyd"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
exec ${flashpolicyd}/Perl_xinetd/in.flashpolicyd.pl \
|
||||
--file=${pkgs.writeText "flashpolixy.xml" cfg.policy} \
|
||||
2> /dev/null
|
||||
|
@ -116,7 +116,7 @@ in
|
||||
include "${cfg.rulesetFile}"
|
||||
'';
|
||||
checkScript = pkgs.writeScript "nftables-check" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
if $(${pkgs.kmod}/bin/lsmod | grep -q ip_tables); then
|
||||
echo "Unload ip_tables before using nftables!" 1>&2
|
||||
exit 1
|
||||
|
@ -55,6 +55,8 @@ in
|
||||
environment.NIX_SECRET_KEY_FILE = cfg.secretKeyFile;
|
||||
|
||||
serviceConfig = {
|
||||
Restart = "always";
|
||||
RestartSec = "5s";
|
||||
ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
|
||||
"--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
|
||||
User = "nix-serve";
|
||||
|
@ -6,7 +6,7 @@
|
||||
with lib;
|
||||
let
|
||||
mergeHook = pkgs.writeScript "rdnssd-merge-hook" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${pkgs.openresolv}/bin/resolvconf -u
|
||||
'';
|
||||
in
|
||||
|
@ -50,12 +50,7 @@ in
|
||||
description = ''
|
||||
If enabled, start the Resilio Sync daemon. Once enabled, you can
|
||||
interact with the service through the Web UI, or configure it in your
|
||||
NixOS configuration. Enabling the <literal>resilio</literal> service
|
||||
also installs a systemd user unit which can be used to start
|
||||
user-specific copies of the daemon. Once installed, you can use
|
||||
<literal>systemctl --user start resilio</literal> as your user to start
|
||||
the daemon using the configuration file located at
|
||||
<literal>$HOME/.config/resilio-sync/config.json</literal>.
|
||||
NixOS configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -124,7 +124,7 @@ in
|
||||
|
||||
listenAddresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "127.0.0.1:631" ];
|
||||
default = [ "localhost:631" ];
|
||||
example = [ "*:631" ];
|
||||
description = ''
|
||||
A list of addresses and ports on which to listen.
|
||||
@ -321,7 +321,10 @@ in
|
||||
''}
|
||||
'';
|
||||
|
||||
serviceConfig.PrivateTmp = true;
|
||||
serviceConfig = {
|
||||
PrivateTmp = true;
|
||||
RuntimeDirectory = [ "cups" ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.cups-browsed = mkIf avahiEnabled
|
||||
|
@ -7,7 +7,7 @@ let
|
||||
torify = pkgs.writeTextFile {
|
||||
name = "tsocks";
|
||||
text = ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.tsocks.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
|
||||
'';
|
||||
executable = true;
|
||||
|
@ -23,7 +23,7 @@ let
|
||||
wrapTorsocks = name: server: pkgs.writeTextFile {
|
||||
name = name;
|
||||
text = ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (configFile server)} ${pkgs.torsocks}/bin/torsocks "$@"
|
||||
'';
|
||||
executable = true;
|
||||
|
@ -90,7 +90,7 @@ in
|
||||
# 1) Only the "transmission" user and group have access to torrents.
|
||||
# 2) Optionally update/force specific fields into the configuration file.
|
||||
serviceConfig.ExecStartPre = ''
|
||||
${pkgs.stdenv.shell} -c "mkdir -p ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && chmod 770 ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json"
|
||||
${pkgs.runtimeShell} -c "mkdir -p ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && chmod 770 ${homeDir} ${settingsDir} ${fullSettings.download-dir} ${fullSettings.incomplete-dir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json"
|
||||
'';
|
||||
serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port}";
|
||||
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
|
@ -505,7 +505,7 @@ let
|
||||
${cfg.database.name}''
|
||||
|
||||
else if cfg.database.type == "mysql" then ''
|
||||
echo '${e}' | ${pkgs.mysql}/bin/mysql \
|
||||
echo '${e}' | ${pkgs.sudo}/bin/sudo -u ${cfg.user} ${config.services.mysql.package}/bin/mysql \
|
||||
-u ${cfg.database.user} \
|
||||
${optionalString (cfg.database.password != null) "-p${cfg.database.password}"} \
|
||||
${optionalString (cfg.database.host != null) "-h ${cfg.database.host} -P ${toString dbPort}"} \
|
||||
|
@ -346,7 +346,7 @@ let
|
||||
postgresql = serverInfo.fullConfig.services.postgresql.package;
|
||||
|
||||
setupDb = pkgs.writeScript "setup-owncloud-db" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
PATH="${postgresql}/bin"
|
||||
createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
|
||||
createdb "${config.dbName}" -O "${config.dbUser}" || true
|
||||
|
@ -19,11 +19,7 @@ in
|
||||
options = {
|
||||
|
||||
services.tomcat = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable Apache Tomcat";
|
||||
};
|
||||
enable = mkEnableOption "Apache Tomcat";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
@ -36,10 +32,30 @@ in
|
||||
};
|
||||
|
||||
baseDir = mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/tomcat";
|
||||
description = "Location where Tomcat stores configuration files, webapplications and logfiles";
|
||||
};
|
||||
|
||||
logDirs = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.path;
|
||||
description = "Directories to create in baseDir/logs/";
|
||||
};
|
||||
|
||||
extraConfigFiles = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.path;
|
||||
description = "Extra configuration files to pull into the tomcat conf directory";
|
||||
};
|
||||
|
||||
extraEnvironment = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "ENVIRONMENT=production" ];
|
||||
description = "Environment Variables to pass to the tomcat service";
|
||||
};
|
||||
|
||||
extraGroups = mkOption {
|
||||
default = [];
|
||||
example = [ "users" ];
|
||||
@ -47,31 +63,46 @@ in
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "tomcat";
|
||||
description = "User account under which Apache Tomcat runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "tomcat";
|
||||
description = "Group account under which Apache Tomcat runs.";
|
||||
};
|
||||
|
||||
javaOpts = mkOption {
|
||||
type = types.either (types.listOf types.str) types.str;
|
||||
default = "";
|
||||
description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat";
|
||||
};
|
||||
|
||||
catalinaOpts = mkOption {
|
||||
type = types.either (types.listOf types.str) types.str;
|
||||
default = "";
|
||||
description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container";
|
||||
};
|
||||
|
||||
sharedLibs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications";
|
||||
};
|
||||
|
||||
serverXml = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "
|
||||
Verbatim server.xml configuration.
|
||||
This is mutually exclusive with the virtualHosts options.
|
||||
";
|
||||
};
|
||||
|
||||
commonLibs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "List containing JAR files or directories with JAR files which are libraries shared by the web applications and the servlet container";
|
||||
};
|
||||
@ -84,11 +115,21 @@ in
|
||||
};
|
||||
|
||||
virtualHosts = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "name of the virtualhost";
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
description = "List consisting of a virtual host name and a list of web applications to deploy on each virtual host";
|
||||
};
|
||||
|
||||
logPerVirtualHost = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable logging per virtual host.";
|
||||
};
|
||||
@ -104,11 +145,13 @@ in
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether to enable an Apache Axis2 container";
|
||||
};
|
||||
|
||||
services = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2";
|
||||
};
|
||||
|
||||
@ -140,130 +183,104 @@ in
|
||||
description = "Apache Tomcat server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
|
||||
preStart = ''
|
||||
# Create the base directory
|
||||
mkdir -p ${cfg.baseDir}
|
||||
mkdir -p \
|
||||
${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work}
|
||||
chown ${cfg.user}:${cfg.group} \
|
||||
${cfg.baseDir}/{conf,virtualhosts,logs,temp,lib,shared/lib,webapps,work}
|
||||
|
||||
# Create a symlink to the bin directory of the tomcat component
|
||||
ln -sfn ${tomcat}/bin ${cfg.baseDir}/bin
|
||||
|
||||
# Create a conf/ directory
|
||||
mkdir -p ${cfg.baseDir}/conf
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/conf
|
||||
|
||||
# Symlink the config files in the conf/ directory (except for catalina.properties and server.xml)
|
||||
for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml)
|
||||
do
|
||||
ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i`
|
||||
for i in $(ls ${tomcat}/conf | grep -v catalina.properties | grep -v server.xml); do
|
||||
ln -sfn ${tomcat}/conf/$i ${cfg.baseDir}/conf/`basename $i`
|
||||
done
|
||||
|
||||
# Create subdirectory for virtual hosts
|
||||
mkdir -p ${cfg.baseDir}/virtualhosts
|
||||
${if cfg.extraConfigFiles != [] then ''
|
||||
for i in ${toString cfg.extraConfigFiles}; do
|
||||
ln -sfn $i ${cfg.baseDir}/conf/`basename $i`
|
||||
done
|
||||
'' else ""}
|
||||
|
||||
# Create a modified catalina.properties file
|
||||
# Change all references from CATALINA_HOME to CATALINA_BASE and add support for shared libraries
|
||||
sed -e 's|''${catalina.home}|''${catalina.base}|g' \
|
||||
-e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \
|
||||
${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties
|
||||
-e 's|shared.loader=|shared.loader=''${catalina.base}/shared/lib/*.jar|' \
|
||||
${tomcat}/conf/catalina.properties > ${cfg.baseDir}/conf/catalina.properties
|
||||
|
||||
# Create a modified server.xml which also includes all virtual hosts
|
||||
sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${
|
||||
toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \
|
||||
${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml
|
||||
|
||||
# Create a logs/ directory
|
||||
mkdir -p ${cfg.baseDir}/logs
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs
|
||||
${if cfg.logPerVirtualHost then
|
||||
toString (map (h: ''
|
||||
mkdir -p ${cfg.baseDir}/logs/${h.name}
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name}
|
||||
'') cfg.virtualHosts) else ''''}
|
||||
|
||||
# Create a temp/ directory
|
||||
mkdir -p ${cfg.baseDir}/temp
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/temp
|
||||
|
||||
# Create a lib/ directory
|
||||
mkdir -p ${cfg.baseDir}/lib
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/lib
|
||||
|
||||
# Create a shared/lib directory
|
||||
mkdir -p ${cfg.baseDir}/shared/lib
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/shared/lib
|
||||
|
||||
# Create a webapps/ directory
|
||||
mkdir -p ${cfg.baseDir}/webapps
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps
|
||||
${if cfg.serverXml != "" then ''
|
||||
cp -f ${pkgs.writeTextDir "server.xml" cfg.serverXml}/* ${cfg.baseDir}/conf/
|
||||
'' else ''
|
||||
# Create a modified server.xml which also includes all virtual hosts
|
||||
sed -e "/<Engine name=\"Catalina\" defaultHost=\"localhost\">/a\ ${toString (map (virtualHost: ''<Host name=\"${virtualHost.name}\" appBase=\"virtualhosts/${virtualHost.name}/webapps\" unpackWARs=\"true\" autoDeploy=\"true\" xmlValidation=\"false\" xmlNamespaceAware=\"false\" >${if cfg.logPerVirtualHost then ''<Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs/${virtualHost.name}\" prefix=\"${virtualHost.name}_access_log.\" pattern=\"combined\" resolveHosts=\"false\"/>'' else ""}</Host>'') cfg.virtualHosts)}" \
|
||||
${tomcat}/conf/server.xml > ${cfg.baseDir}/conf/server.xml
|
||||
''
|
||||
}
|
||||
${optionalString (cfg.logDirs != []) ''
|
||||
for i in ${toString cfg.logDirs}; do
|
||||
mkdir -p ${cfg.baseDir}/logs/$i
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/$i
|
||||
done
|
||||
''}
|
||||
${optionalString cfg.logPerVirtualHost (toString (map (h: ''
|
||||
mkdir -p ${cfg.baseDir}/logs/${h.name}
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/logs/${h.name}
|
||||
'') cfg.virtualHosts))}
|
||||
|
||||
# Symlink all the given common libs files or paths into the lib/ directory
|
||||
for i in ${tomcat} ${toString cfg.commonLibs}
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
# If the given web application is a file, symlink it into the common/lib/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/lib/`basename $i`
|
||||
elif [ -d $i ]
|
||||
then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
for i in ${tomcat} ${toString cfg.commonLibs}; do
|
||||
if [ -f $i ]; then
|
||||
# If the given web application is a file, symlink it into the common/lib/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/lib/`basename $i`
|
||||
elif [ -d $i ]; then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
for j in $i/lib/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/lib/`basename $j`
|
||||
done
|
||||
fi
|
||||
for j in $i/lib/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/lib/`basename $j`
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# Symlink all the given shared libs files or paths into the shared/lib/ directory
|
||||
for i in ${toString cfg.sharedLibs}
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
# If the given web application is a file, symlink it into the common/lib/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i`
|
||||
elif [ -d $i ]
|
||||
then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
for i in ${toString cfg.sharedLibs}; do
|
||||
if [ -f $i ]; then
|
||||
# If the given web application is a file, symlink it into the common/lib/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/shared/lib/`basename $i`
|
||||
elif [ -d $i ]; then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
for j in $i/shared/lib/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j`
|
||||
done
|
||||
fi
|
||||
for j in $i/shared/lib/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/shared/lib/`basename $j`
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# Symlink all the given web applications files or paths into the webapps/ directory
|
||||
for i in ${toString cfg.webapps}
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
# If the given web application is a file, symlink it into the webapps/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/webapps/`basename $i`
|
||||
elif [ -d $i ]
|
||||
then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
for i in ${toString cfg.webapps}; do
|
||||
if [ -f $i ]; then
|
||||
# If the given web application is a file, symlink it into the webapps/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/webapps/`basename $i`
|
||||
elif [ -d $i ]; then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
for j in $i/webapps/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/webapps/`basename $j`
|
||||
done
|
||||
for j in $i/webapps/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/webapps/`basename $j`
|
||||
done
|
||||
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]
|
||||
then
|
||||
for j in $i/conf/Catalina/*
|
||||
do
|
||||
mkdir -p ${cfg.baseDir}/conf/Catalina/localhost
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
|
||||
done
|
||||
fi
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]; then
|
||||
for j in $i/conf/Catalina/*; do
|
||||
mkdir -p ${cfg.baseDir}/conf/Catalina/localhost
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
${toString (map (virtualHost: ''
|
||||
@ -275,94 +292,79 @@ in
|
||||
|
||||
# Symlink all the given web applications files or paths into the webapps/ directory
|
||||
# of this virtual host
|
||||
for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}"
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
# If the given web application is a file, symlink it into the webapps/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i`
|
||||
elif [ -d $i ]
|
||||
then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
for i in "${if virtualHost ? webapps then toString virtualHost.webapps else ""}"; do
|
||||
if [ -f $i ]; then
|
||||
# If the given web application is a file, symlink it into the webapps/ directory
|
||||
ln -sfn $i ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $i`
|
||||
elif [ -d $i ]; then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
for j in $i/webapps/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j`
|
||||
done
|
||||
for j in $i/webapps/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/virtualhosts/${virtualHost.name}/webapps/`basename $j`
|
||||
done
|
||||
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]
|
||||
then
|
||||
for j in $i/conf/Catalina/*
|
||||
do
|
||||
mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name}
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j`
|
||||
done
|
||||
fi
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]; then
|
||||
for j in $i/conf/Catalina/*; do
|
||||
mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name}
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j`
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'') cfg.virtualHosts)}
|
||||
|
||||
''
|
||||
) cfg.virtualHosts) }
|
||||
${optionalString cfg.axis2.enable ''
|
||||
# Copy the Axis2 web application
|
||||
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
|
||||
|
||||
# Create a work/ directory
|
||||
mkdir -p ${cfg.baseDir}/work
|
||||
chown ${cfg.user}:${cfg.group} ${cfg.baseDir}/work
|
||||
# Turn off addressing, which causes many errors
|
||||
sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml
|
||||
|
||||
${if cfg.axis2.enable then
|
||||
''
|
||||
# Copy the Axis2 web application
|
||||
cp -av ${pkgs.axis2}/webapps/axis2 ${cfg.baseDir}/webapps
|
||||
# Modify permissions on the Axis2 application
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
|
||||
|
||||
# Turn off addressing, which causes many errors
|
||||
sed -i -e 's%<module ref="addressing"/>%<!-- <module ref="addressing"/> -->%' ${cfg.baseDir}/webapps/axis2/WEB-INF/conf/axis2.xml
|
||||
# Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory
|
||||
for i in ${toString cfg.axis2.services}; do
|
||||
if [ -f $i ]; then
|
||||
# If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services
|
||||
ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i`
|
||||
elif [ -d $i ]; then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
# Modify permissions on the Axis2 application
|
||||
chown -R ${cfg.user}:${cfg.group} ${cfg.baseDir}/webapps/axis2
|
||||
for j in $i/webapps/axis2/WEB-INF/services/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j`
|
||||
done
|
||||
|
||||
# Symlink all the given web service files or paths into the webapps/axis2/WEB-INF/services directory
|
||||
for i in ${toString cfg.axis2.services}
|
||||
do
|
||||
if [ -f $i ]
|
||||
then
|
||||
# If the given web service is a file, symlink it into the webapps/axis2/WEB-INF/services
|
||||
ln -sfn $i ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $i`
|
||||
elif [ -d $i ]
|
||||
then
|
||||
# If the given web application is a directory, then iterate over the files
|
||||
# in the special purpose directories and symlink them into the tomcat tree
|
||||
|
||||
for j in $i/webapps/axis2/WEB-INF/services/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/webapps/axis2/WEB-INF/services/`basename $j`
|
||||
done
|
||||
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]
|
||||
then
|
||||
for j in $i/conf/Catalina/*
|
||||
do
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
''
|
||||
else ""}
|
||||
'';
|
||||
|
||||
script = ''
|
||||
${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${tomcat}/bin/startup.sh'
|
||||
'';
|
||||
|
||||
preStop = ''
|
||||
echo "Stopping tomcat..."
|
||||
CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${cfg.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${tomcat}/bin/shutdown.sh
|
||||
# Also symlink the configuration files if they are included
|
||||
if [ -d $i/conf/Catalina ]; then
|
||||
for j in $i/conf/Catalina/*; do
|
||||
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
''}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
PermissionsStartOnly = true;
|
||||
PIDFile="/run/tomcat/tomcat.pid";
|
||||
RuntimeDirectory = "tomcat";
|
||||
User = cfg.user;
|
||||
Environment=[
|
||||
"CATALINA_BASE=${cfg.baseDir}"
|
||||
"CATALINA_PID=/run/tomcat/tomcat.pid"
|
||||
"JAVA_HOME='${cfg.jdk}'"
|
||||
"JAVA_OPTS='${builtins.toString cfg.javaOpts}'"
|
||||
"CATALINA_OPTS='${builtins.toString cfg.catalinaOpts}'"
|
||||
] ++ cfg.extraEnvironment;
|
||||
ExecStart = "${tomcat}/bin/startup.sh";
|
||||
ExecStop = "${tomcat}/bin/shutdown.sh";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ in
|
||||
# Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes.
|
||||
export GTK_DATA_PREFIX=${config.system.path}
|
||||
|
||||
${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc} &
|
||||
${pkgs.runtimeShell} ${pkgs.xfce.xinitrc} &
|
||||
waitPID=$!
|
||||
'';
|
||||
}];
|
||||
|
@ -14,7 +14,7 @@ let
|
||||
default_xserver ${dmcfg.xserverBin}
|
||||
xserver_arguments ${toString dmcfg.xserverArgs}
|
||||
sessiondir ${dmcfg.session.desktops}
|
||||
login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session"
|
||||
login_cmd exec ${pkgs.runtimeShell} ${dmcfg.session.script} "%session"
|
||||
halt_cmd ${config.systemd.package}/sbin/shutdown -h now
|
||||
reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
|
||||
logfile /dev/stderr
|
||||
|
@ -12,6 +12,7 @@ in
|
||||
./afterstep.nix
|
||||
./bspwm.nix
|
||||
./dwm.nix
|
||||
./evilwm.nix
|
||||
./exwm.nix
|
||||
./fluxbox.nix
|
||||
./fvwm.nix
|
||||
|
@ -61,7 +61,7 @@ in
|
||||
apply = set: {
|
||||
script =
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
|
||||
systemConfig=@out@
|
||||
|
||||
|
@ -1,21 +1,22 @@
|
||||
{ config, pkgs, ... }:
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = [ pkgs.kexectools ];
|
||||
config = lib.mkIf (pkgs.kexectools != null) {
|
||||
environment.systemPackages = [ pkgs.kexectools ];
|
||||
|
||||
systemd.services."prepare-kexec" =
|
||||
{ description = "Preparation for kexec";
|
||||
wantedBy = [ "kexec.target" ];
|
||||
before = [ "systemd-kexec.service" ];
|
||||
unitConfig.DefaultDependencies = false;
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.kexectools ];
|
||||
script =
|
||||
''
|
||||
p=$(readlink -f /nix/var/nix/profiles/system)
|
||||
if ! [ -d $p ]; then exit 1; fi
|
||||
exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init"
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
systemd.services."prepare-kexec" =
|
||||
{ description = "Preparation for kexec";
|
||||
wantedBy = [ "kexec.target" ];
|
||||
before = [ "systemd-kexec.service" ];
|
||||
unitConfig.DefaultDependencies = false;
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = [ pkgs.kexectools ];
|
||||
script =
|
||||
''
|
||||
p=$(readlink -f /nix/var/nix/profiles/system)
|
||||
if ! [ -d $p ]; then exit 1; fi
|
||||
exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ let
|
||||
{ splashImage = f cfg.splashImage;
|
||||
grub = f grub;
|
||||
grubTarget = f (grub.grubTarget or "");
|
||||
shell = "${pkgs.stdenv.shell}";
|
||||
shell = "${pkgs.runtimeShell}";
|
||||
fullName = (builtins.parseDrvName realGrub.name).name;
|
||||
fullVersion = (builtins.parseDrvName realGrub.name).version;
|
||||
grubEfi = f grubEfi;
|
||||
@ -536,9 +536,9 @@ in
|
||||
btrfsprogs = pkgs.btrfs-progs;
|
||||
};
|
||||
in pkgs.writeScript "install-grub.sh" (''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
set -e
|
||||
export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])}
|
||||
export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare ])}
|
||||
${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"}
|
||||
'' + flip concatMapStrings cfg.mirroredBoots (args: ''
|
||||
${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@
|
||||
|
@ -182,7 +182,7 @@ sub GrubFs {
|
||||
# Based on the type pull in the identifier from the system
|
||||
my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid -o export @{[$fs->device]}");
|
||||
if ($status != 0) {
|
||||
die "Failed to get blkid info for @{[$fs->mount]} on @{[$fs->device]}";
|
||||
die "Failed to get blkid info (returned $status) for @{[$fs->mount]} on @{[$fs->device]}";
|
||||
}
|
||||
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
||||
if ($#matches != 0) {
|
||||
|
@ -30,6 +30,50 @@ let
|
||||
# mounting `/`, like `/` on a loopback).
|
||||
fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems;
|
||||
|
||||
# A utility for enumerating the shared-library dependencies of a program
|
||||
findLibs = pkgs.writeShellScriptBin "find-libs" ''
|
||||
set -euo pipefail
|
||||
|
||||
declare -A seen
|
||||
declare -a left
|
||||
|
||||
patchelf="${pkgs.buildPackages.patchelf}/bin/patchelf"
|
||||
|
||||
function add_needed {
|
||||
rpath="$($patchelf --print-rpath $1)"
|
||||
dir="$(dirname $1)"
|
||||
for lib in $($patchelf --print-needed $1); do
|
||||
left+=("$lib" "$rpath" "$dir")
|
||||
done
|
||||
}
|
||||
|
||||
add_needed $1
|
||||
|
||||
while [ ''${#left[@]} -ne 0 ]; do
|
||||
next=''${left[0]}
|
||||
rpath=''${left[1]}
|
||||
ORIGIN=''${left[2]}
|
||||
left=("''${left[@]:3}")
|
||||
if [ -z ''${seen[$next]+x} ]; then
|
||||
seen[$next]=1
|
||||
IFS=: read -ra paths <<< $rpath
|
||||
res=
|
||||
for path in "''${paths[@]}"; do
|
||||
path=$(eval "echo $path")
|
||||
if [ -f "$path/$next" ]; then
|
||||
res="$path/$next"
|
||||
echo "$res"
|
||||
add_needed "$res"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -z "$res" ]; then
|
||||
echo "Couldn't satisfy dependency $next" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
# Some additional utilities needed in stage 1, like mount, lvm, fsck
|
||||
# etc. We don't want to bring in all of those packages, so we just
|
||||
@ -37,7 +81,7 @@ let
|
||||
# we just copy what we need from Glibc and use patchelf to make it
|
||||
# work.
|
||||
extraUtils = pkgs.runCommandCC "extra-utils"
|
||||
{ buildInputs = [pkgs.nukeReferences];
|
||||
{ nativeBuildInputs = [pkgs.buildPackages.nukeReferences];
|
||||
allowedReferences = [ "out" ]; # prevent accidents like glibc being included in the initrd
|
||||
}
|
||||
''
|
||||
@ -103,9 +147,7 @@ let
|
||||
# Copy all of the needed libraries
|
||||
find $out/bin $out/lib -type f | while read BIN; do
|
||||
echo "Copying libs for executable $BIN"
|
||||
LDD="$(ldd $BIN)" || continue
|
||||
LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')"
|
||||
for LIB in $LIBS; do
|
||||
for LIB in $(${findLibs}/bin/find-libs $BIN); do
|
||||
TGT="$out/lib/$(basename $LIB)"
|
||||
if [ ! -f "$TGT" ]; then
|
||||
SRC="$(readlink -e $LIB)"
|
||||
@ -132,6 +174,7 @@ let
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "${toString pkgs.stdenv.isCross}" ]; then
|
||||
# Make sure that the patchelf'ed binaries still work.
|
||||
echo "testing patched programs..."
|
||||
$out/bin/ash -c 'echo hello world' | grep "hello world"
|
||||
@ -144,6 +187,7 @@ let
|
||||
$out/bin/mdadm --version
|
||||
|
||||
${config.boot.initrd.extraUtilsCommandsTest}
|
||||
fi
|
||||
''; # */
|
||||
|
||||
|
||||
@ -245,7 +289,7 @@ let
|
||||
{ src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf"; }
|
||||
''
|
||||
target=$out
|
||||
${pkgs.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out
|
||||
${pkgs.buildPackages.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out
|
||||
'';
|
||||
symlink = "/etc/modprobe.d/ubuntu.conf";
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ let
|
||||
bootStage2 = pkgs.substituteAll {
|
||||
src = ./stage-2-init.sh;
|
||||
shellDebug = "${pkgs.bashInteractive}/bin/bash";
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
isExecutable = true;
|
||||
inherit (config.nix) readOnlyStore;
|
||||
inherit (config.networking) useHostResolvConf;
|
||||
|
@ -241,37 +241,37 @@ let
|
||||
}
|
||||
(mkIf (config.preStart != "")
|
||||
{ serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.preStart}
|
||||
'';
|
||||
})
|
||||
(mkIf (config.script != "")
|
||||
{ serviceConfig.ExecStart = makeJobScript "${name}-start" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.script}
|
||||
'' + " " + config.scriptArgs;
|
||||
})
|
||||
(mkIf (config.postStart != "")
|
||||
{ serviceConfig.ExecStartPost = makeJobScript "${name}-post-start" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.postStart}
|
||||
'';
|
||||
})
|
||||
(mkIf (config.reload != "")
|
||||
{ serviceConfig.ExecReload = makeJobScript "${name}-reload" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.reload}
|
||||
'';
|
||||
})
|
||||
(mkIf (config.preStop != "")
|
||||
{ serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.preStop}
|
||||
'';
|
||||
})
|
||||
(mkIf (config.postStop != "")
|
||||
{ serviceConfig.ExecStopPost = makeJobScript "${name}-post-stop" ''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${config.postStop}
|
||||
'';
|
||||
})
|
||||
|
@ -13,7 +13,7 @@ let
|
||||
isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale);
|
||||
|
||||
optimizedKeymap = pkgs.runCommand "keymap" {
|
||||
nativeBuildInputs = [ pkgs.kbd ];
|
||||
nativeBuildInputs = [ pkgs.buildPackages.kbd ];
|
||||
LOADKEYS_KEYMAP_PATH = "${kbdEnv}/share/keymaps/**";
|
||||
} ''
|
||||
loadkeys -b ${optionalString isUnicode "-u"} "${config.i18n.consoleKeyMap}" > $out
|
||||
|
@ -26,7 +26,7 @@ let
|
||||
executable = true;
|
||||
destination = "/bin/bridge-stp";
|
||||
text = ''
|
||||
#!${pkgs.stdenv.shell} -e
|
||||
#!${pkgs.runtimeShell} -e
|
||||
export PATH="${pkgs.mstpd}/bin"
|
||||
|
||||
BRIDGES=(${concatStringsSep " " (attrNames rstpBridges)})
|
||||
@ -64,7 +64,7 @@ let
|
||||
|
||||
# udev script that configures a physical wlan device and adds virtual interfaces
|
||||
wlanDeviceUdevScript = device: interfaceList: pkgs.writeScript "wlan-${device}-udev-script" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
|
||||
# Change the wireless phy device to a predictable name.
|
||||
if [ -e "/sys/class/net/${device}/phy80211/name" ]; then
|
||||
@ -142,7 +142,7 @@ let
|
||||
default = { };
|
||||
example = { mtu = "1492"; window = "524288"; };
|
||||
description = ''
|
||||
Other route options. See the symbol <literal>OPTION</literal>
|
||||
Other route options. See the symbol <literal>OPTIONS</literal>
|
||||
in the <literal>ip-route(8)</literal> manual page for the details.
|
||||
'';
|
||||
};
|
||||
@ -191,7 +191,7 @@ let
|
||||
preferTempAddress = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.enableIPv6;
|
||||
defaultText = literalExample "config.networking.enableIpv6";
|
||||
defaultText = literalExample "config.networking.enableIPv6";
|
||||
description = ''
|
||||
When using SLAAC prefer a temporary (IPv6) address over the EUI-64
|
||||
address for originating connections. This is used to reduce tracking.
|
||||
@ -489,7 +489,7 @@ in
|
||||
networking.interfaces = mkOption {
|
||||
default = {};
|
||||
example =
|
||||
{ eth0.ipv4 = [ {
|
||||
{ eth0.ipv4.addresses = [ {
|
||||
address = "131.211.84.78";
|
||||
prefixLength = 25;
|
||||
} ];
|
||||
@ -1158,7 +1158,7 @@ in
|
||||
# The script creates the required, new WLAN interfaces interfaces and configures the
|
||||
# existing, default interface.
|
||||
curInterfaceScript = device: current: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${device}.sh" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
# Change the wireless phy device to a predictable name.
|
||||
${pkgs.iw}/bin/iw phy `${pkgs.coreutils}/bin/cat /sys/class/net/$INTERFACE/phy80211/name` set name ${device}
|
||||
|
||||
@ -1177,7 +1177,7 @@ in
|
||||
|
||||
# Udev script to execute for a new WLAN interface. The script configures the new WLAN interface.
|
||||
newInterfaceScript = device: new: pkgs.writeScript "udev-run-script-wlan-interfaces-${new._iName}.sh" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
# Configure the new interface
|
||||
${pkgs.iw}/bin/iw dev ${new._iName} set type ${new.type}
|
||||
${optionalString (new.type == "mesh" && new.meshID!=null) "${pkgs.iw}/bin/iw dev ${device} set meshid ${new.meshID}"}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
let
|
||||
script = ''
|
||||
#!${pkgs.stdenv.shell} -eu
|
||||
#!${pkgs.runtimeShell} -eu
|
||||
|
||||
echo "attempting to fetch configuration from EC2 user data..."
|
||||
|
||||
|
@ -47,7 +47,7 @@ let
|
||||
};
|
||||
|
||||
provisionedHook = pkgs.writeScript "provisioned-hook" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
${config.systemd.package}/bin/systemctl start provisioned.target
|
||||
'';
|
||||
|
||||
|
@ -33,7 +33,7 @@ let
|
||||
in
|
||||
pkgs.writeScript "container-init"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
|
||||
# Initialise the container side of the veth pair.
|
||||
if [ "$PRIVATE_NETWORK" = 1 ]; then
|
||||
@ -223,7 +223,7 @@ let
|
||||
serviceDirectives = cfg: {
|
||||
ExecReload = pkgs.writeScript "reload-container"
|
||||
''
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
#! ${pkgs.runtimeShell} -e
|
||||
${pkgs.nixos-container}/bin/nixos-container run "$INSTANCE" -- \
|
||||
bash --login -c "''${SYSTEM_PATH:-/nix/var/nix/profiles/system}/bin/switch-to-configuration test"
|
||||
'';
|
||||
|
@ -119,18 +119,10 @@ in {
|
||||
after = [ "systemd-udev-settle.service" ]
|
||||
++ optional vswitch.enable "vswitchd.service";
|
||||
|
||||
environment = {
|
||||
LIBVIRTD_ARGS = ''--config "${configFile}" ${concatStringsSep " " cfg.extraOptions}'';
|
||||
};
|
||||
environment.LIBVIRTD_ARGS = ''--config "${configFile}" ${concatStringsSep " " cfg.extraOptions}'';
|
||||
|
||||
path = with pkgs; [
|
||||
bridge-utils
|
||||
dmidecode
|
||||
dnsmasq
|
||||
ebtables
|
||||
cfg.qemuPackage # libvirtd requires qemu-img to manage disk images
|
||||
]
|
||||
++ optional vswitch.enable vswitch.package;
|
||||
path = [ cfg.qemuPackage ] # libvirtd requires qemu-img to manage disk images
|
||||
++ optional vswitch.enable vswitch.package;
|
||||
|
||||
preStart = ''
|
||||
mkdir -p /var/log/libvirt/qemu -m 755
|
||||
|
@ -169,7 +169,7 @@ in {
|
||||
mkdir -p ${runDir}/ipsec/{etc/racoon,etc/init.d/,usr/sbin/}
|
||||
ln -fs ${pkgs.ipsecTools}/bin/setkey ${runDir}/ipsec/usr/sbin/setkey
|
||||
ln -fs ${pkgs.writeScript "racoon-restart" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
#!${pkgs.runtimeShell}
|
||||
/var/run/current-system/sw/bin/systemctl $1 racoon
|
||||
''} ${runDir}/ipsec/etc/init.d/racoon
|
||||
'';
|
||||
|
@ -30,7 +30,7 @@ let
|
||||
# Shell script to start the VM.
|
||||
startVM =
|
||||
''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
#! ${pkgs.runtimeShell}
|
||||
|
||||
NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}})
|
||||
|
||||
@ -319,8 +319,8 @@ in
|
||||
networkingOptions =
|
||||
mkOption {
|
||||
default = [
|
||||
"-net nic,vlan=0,model=virtio"
|
||||
"-net user,vlan=0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
|
||||
"-net nic,netdev=user.0,model=virtio"
|
||||
"-netdev user,id=user.0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
|
||||
];
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
@ -434,9 +434,11 @@ in
|
||||
|
||||
virtualisation.pathsInNixDB = [ config.system.build.toplevel ];
|
||||
|
||||
# FIXME: Figure out how to make this work on non-x86
|
||||
virtualisation.qemu.options =
|
||||
mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usbdevice tablet" ];
|
||||
# FIXME: Consolidate this one day.
|
||||
virtualisation.qemu.options = mkMerge [
|
||||
(mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usb" "-device usb-tablet,bus=usb-bus.0" ])
|
||||
(mkIf (pkgs.stdenv.isArm || pkgs.stdenv.isAarch64) [ "-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet" ])
|
||||
];
|
||||
|
||||
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
||||
# of the host into our own filesystem. We use mkVMOverride to
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user