Merge remote-tracking branch 'upstream/master' into sage-8.5
This commit is contained in:
commit
22c16ed300
11
.github/CODEOWNERS
vendored
11
.github/CODEOWNERS
vendored
@ -55,7 +55,7 @@
|
|||||||
/pkgs/top-level/python-packages.nix @FRidh
|
/pkgs/top-level/python-packages.nix @FRidh
|
||||||
/pkgs/development/interpreters/python @FRidh
|
/pkgs/development/interpreters/python @FRidh
|
||||||
/pkgs/development/python-modules @FRidh
|
/pkgs/development/python-modules @FRidh
|
||||||
/doc/languages-frameworks/python.md @FRidh
|
/doc/languages-frameworks/python.section.md @FRidh
|
||||||
|
|
||||||
# Haskell
|
# Haskell
|
||||||
/pkgs/development/compilers/ghc @peti @ryantm @basvandijk
|
/pkgs/development/compilers/ghc @peti @ryantm @basvandijk
|
||||||
@ -64,13 +64,18 @@
|
|||||||
/pkgs/development/haskell-modules/generic-builder.nix @peti @ryantm @basvandijk
|
/pkgs/development/haskell-modules/generic-builder.nix @peti @ryantm @basvandijk
|
||||||
/pkgs/development/haskell-modules/hoogle.nix @peti @ryantm @basvandijk
|
/pkgs/development/haskell-modules/hoogle.nix @peti @ryantm @basvandijk
|
||||||
|
|
||||||
|
# Perl
|
||||||
|
/pkgs/development/interpreters/perl @volth
|
||||||
|
/pkgs/top-level/perl-packages.nix @volth
|
||||||
|
/pkgs/development/perl-modules @volth
|
||||||
|
|
||||||
# R
|
# R
|
||||||
/pkgs/applications/science/math/R @peti
|
/pkgs/applications/science/math/R @peti
|
||||||
/pkgs/development/r-modules @peti
|
/pkgs/development/r-modules @peti
|
||||||
|
|
||||||
# Ruby
|
# Ruby
|
||||||
/pkgs/development/interpreters/ruby @zimbatm
|
/pkgs/development/interpreters/ruby @alyssais @zimbatm
|
||||||
/pkgs/development/ruby-modules @zimbatm
|
/pkgs/development/ruby-modules @alyssais @zimbatm
|
||||||
|
|
||||||
# Rust
|
# Rust
|
||||||
/pkgs/development/compilers/rust @Mic92 @LnL7
|
/pkgs/development/compilers/rust @Mic92 @LnL7
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -13,4 +13,5 @@ result-*
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
/pkgs/development/libraries/qt-5/*/tmp/
|
/pkgs/development/libraries/qt-5/*/tmp/
|
||||||
/pkgs/desktops/kde-5/*/tmp/
|
/pkgs/desktops/kde-5/*/tmp/
|
||||||
|
/pkgs/development/mobile/androidenv/xml/*
|
||||||
|
@ -56,25 +56,30 @@ foo { arg = ...; }
|
|||||||
or list elements should be aligned:
|
or list elements should be aligned:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
# A long list.
|
# A long list.
|
||||||
list =
|
list = [
|
||||||
[ elem1
|
elem1
|
||||||
elem2
|
elem2
|
||||||
elem3
|
elem3
|
||||||
];
|
];
|
||||||
|
|
||||||
# A long attribute set.
|
# A long attribute set.
|
||||||
attrs =
|
|
||||||
{ attr1 = short_expr;
|
|
||||||
attr2 =
|
|
||||||
if true then big_expr else big_expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Alternatively:
|
|
||||||
attrs = {
|
attrs = {
|
||||||
attr1 = short_expr;
|
attr1 = short_expr;
|
||||||
attr2 =
|
attr2 =
|
||||||
if true then big_expr else big_expr;
|
if true then big_expr else big_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Combined
|
||||||
|
listOfAttrs = [
|
||||||
|
{
|
||||||
|
attr1 = 3;
|
||||||
|
attr2 = "fff";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
attr1 = 5;
|
||||||
|
attr2 = "ggg";
|
||||||
|
}
|
||||||
|
];
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -385,7 +385,7 @@ nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).system
|
|||||||
Eventually we would like to make these platform examples an unnecessary
|
Eventually we would like to make these platform examples an unnecessary
|
||||||
convenience so that
|
convenience so that
|
||||||
<programlisting>
|
<programlisting>
|
||||||
nix-build <nixpkgs> --arg crossSystem.config '<arch>-<os>-<vendor>-<abi>' -A whatever</programlisting>
|
nix-build <nixpkgs> --arg crossSystem '{ config = "<arch>-<os>-<vendor>-<abi>"; }' -A whatever</programlisting>
|
||||||
works in the vast majority of cases. The problem today is dependencies on
|
works in the vast majority of cases. The problem today is dependencies on
|
||||||
other sorts of configuration which aren't given proper defaults. We rely on
|
other sorts of configuration which aren't given proper defaults. We rely on
|
||||||
the examples to crudely to set those configuration parameters in some
|
the examples to crudely to set those configuration parameters in some
|
||||||
|
240
doc/languages-frameworks/android.section.md
Normal file
240
doc/languages-frameworks/android.section.md
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
---
|
||||||
|
title: Android
|
||||||
|
author: Sander van der Burg
|
||||||
|
date: 2018-11-18
|
||||||
|
---
|
||||||
|
# Android
|
||||||
|
|
||||||
|
The Android build environment provides three major features and a number of
|
||||||
|
supporting features.
|
||||||
|
|
||||||
|
Deploying an Android SDK installation with plugins
|
||||||
|
--------------------------------------------------
|
||||||
|
The first use case is deploying the SDK with a desired set of plugins or subsets
|
||||||
|
of an SDK.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
let
|
||||||
|
androidComposition = androidenv.composeAndroidPackages {
|
||||||
|
toolsVersion = "25.2.5";
|
||||||
|
platformToolsVersion = "27.0.1";
|
||||||
|
buildToolsVersions = [ "27.0.3" ];
|
||||||
|
includeEmulator = false;
|
||||||
|
emulatorVersion = "27.2.0";
|
||||||
|
platformVersions = [ "24" ];
|
||||||
|
includeSources = false;
|
||||||
|
includeDocs = false;
|
||||||
|
includeSystemImages = false;
|
||||||
|
systemImageTypes = [ "default" ];
|
||||||
|
abiVersions = [ "armeabi-v7a" ];
|
||||||
|
lldbVersions = [ "2.0.2558144" ];
|
||||||
|
cmakeVersions = [ "3.6.4111459" ];
|
||||||
|
includeNDK = false;
|
||||||
|
ndkVersion = "16.1.4479499";
|
||||||
|
useGoogleAPIs = false;
|
||||||
|
useGoogleTVAddOns = false;
|
||||||
|
includeExtras = [
|
||||||
|
"extras;google;gcm"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
androidComposition.androidsdk
|
||||||
|
```
|
||||||
|
|
||||||
|
The above function invocation states that we want an Android SDK with the above
|
||||||
|
specified plugin versions. By default, most plugins are disabled. Notable
|
||||||
|
exceptions are the tools, platform-tools and build-tools sub packages.
|
||||||
|
|
||||||
|
The following parameters are supported:
|
||||||
|
|
||||||
|
* `toolsVersion`, specifies the version of the tools package to use
|
||||||
|
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
|
||||||
|
* `buildToolsVersion` specifies the versions of the `build-tools` plugins to
|
||||||
|
use.
|
||||||
|
* `includeEmulator` specifies whether to deploy the emulator package (`false`
|
||||||
|
by default). When enabled, the version of the emulator to deploy can be
|
||||||
|
specified by setting the `emulatorVersion` parameter.
|
||||||
|
* `includeDocs` specifies whether the documentation catalog should be included.
|
||||||
|
* `lldbVersions` specifies what LLDB versions should be deployed.
|
||||||
|
* `cmakeVersions` specifies which CMake versions should be deployed.
|
||||||
|
* `includeNDK` specifies that the Android NDK bundle should be included.
|
||||||
|
Defaults to: `false`.
|
||||||
|
* `ndkVersion` specifies the NDK version that we want to use.
|
||||||
|
* `includeExtras` is an array of identifier strings referring to arbitrary
|
||||||
|
add-on packages that should be installed.
|
||||||
|
* `platformVersions` specifies which platform SDK versions should be included.
|
||||||
|
|
||||||
|
For each platform version that has been specified, we can apply the following
|
||||||
|
options:
|
||||||
|
|
||||||
|
* `includeSystemImages` specifies whether a system image for each platform SDK
|
||||||
|
should be included.
|
||||||
|
* `includeSources` specifies whether the sources for each SDK version should be
|
||||||
|
included.
|
||||||
|
* `useGoogleAPIs` specifies that for each selected platform version the
|
||||||
|
Google API should be included.
|
||||||
|
* `useGoogleTVAddOns` specifies that for each selected platform version the
|
||||||
|
Google TV add-on should be included.
|
||||||
|
|
||||||
|
For each requested system image we can specify the following options:
|
||||||
|
|
||||||
|
* `systemImageTypes` specifies what kind of system images should be included.
|
||||||
|
Defaults to: `default`.
|
||||||
|
* `abiVersions` specifies what kind of ABI version of each system image should
|
||||||
|
be included. Defaults to: `armeabi-v7a`.
|
||||||
|
|
||||||
|
Most of the function arguments have reasonable default settings.
|
||||||
|
|
||||||
|
When building the above expression with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ nix-build
|
||||||
|
```
|
||||||
|
|
||||||
|
The Android SDK gets deployed with all desired plugin versions.
|
||||||
|
|
||||||
|
We can also deploy subsets of the Android SDK. For example, to only the the
|
||||||
|
`platform-tools` package, you can evaluate the following expression:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
let
|
||||||
|
androidComposition = androidenv.composeAndroidPackages {
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
in
|
||||||
|
androidComposition.platform-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
Using predefine Android package compositions
|
||||||
|
--------------------------------------------
|
||||||
|
In addition to composing an Android package set manually, it is also possible
|
||||||
|
to use a predefined composition that contains all basic packages for a specific
|
||||||
|
Android version, such as version 9.0 (API-level 28).
|
||||||
|
|
||||||
|
The following Nix expression can be used to deploy the entire SDK with all basic
|
||||||
|
plugins:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
androidenv.androidPkgs_9_0.androidsdk
|
||||||
|
```
|
||||||
|
|
||||||
|
It is also possible to use one plugin only:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
androidenv.androidPkgs_9_0.platform-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
Building an Android application
|
||||||
|
-------------------------------
|
||||||
|
In addition to the SDK, it is also possible to build an Ant-based Android
|
||||||
|
project and automatically deploy all the Android plugins that a project
|
||||||
|
requires.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
androidenv.buildApp {
|
||||||
|
name = "MyAndroidApp";
|
||||||
|
src = ./myappsources;
|
||||||
|
release = true;
|
||||||
|
|
||||||
|
# If release is set to true, you need to specify the following parameters
|
||||||
|
keyStore = ./keystore;
|
||||||
|
keyAlias = "myfirstapp";
|
||||||
|
keyStorePassword = "mykeystore";
|
||||||
|
keyAliasPassword = "myfirstapp";
|
||||||
|
|
||||||
|
# Any Android SDK parameters that install all the relevant plugins that a
|
||||||
|
# build requires
|
||||||
|
platformVersions = [ "24" ];
|
||||||
|
|
||||||
|
# When we include the NDK, then ndk-build is invoked before Ant gets invoked
|
||||||
|
includeNDK = true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Aside from the app-specific build parameters (`name`, `src`, `release` and
|
||||||
|
keystore parameters), the `buildApp {}` function supports all the function
|
||||||
|
parameters that the SDK composition function (the function shown in the
|
||||||
|
previous section) supports.
|
||||||
|
|
||||||
|
This build function is particularly useful when it is desired to use
|
||||||
|
[Hydra](http://nixos.org/hydra): the Nix-based continuous integration solution
|
||||||
|
to build Android apps. An Android APK gets exposed as a build product and can be
|
||||||
|
installed on any Android device with a web browser by navigating to the build
|
||||||
|
result page.
|
||||||
|
|
||||||
|
Spawning emulator instances
|
||||||
|
---------------------------
|
||||||
|
For testing purposes, it can also be quite convenient to automatically generate
|
||||||
|
scripts that spawn emulator instances with all desired configuration settings.
|
||||||
|
|
||||||
|
An emulator spawn script can be configured by invoking the `emulateApp {}`
|
||||||
|
function:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
androidenv.emulateApp {
|
||||||
|
name = "emulate-MyAndroidApp";
|
||||||
|
platformVersion = "24";
|
||||||
|
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
|
||||||
|
systemImageType = "default";
|
||||||
|
useGoogleAPIs = false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It is also possible to specify an APK to deploy inside the emulator
|
||||||
|
and the package and activity names to launch it:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
androidenv.emulateApp {
|
||||||
|
name = "emulate-MyAndroidApp";
|
||||||
|
platformVersion = "24";
|
||||||
|
abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
|
||||||
|
systemImageType = "default";
|
||||||
|
useGoogleAPIs = false;
|
||||||
|
app = ./MyApp.apk;
|
||||||
|
package = "MyApp";
|
||||||
|
activity = "MainActivity";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition to prebuilt APKs, you can also bind the APK parameter to a
|
||||||
|
`buildApp {}` function invocation shown in the previous example.
|
||||||
|
|
||||||
|
Querying the available versions of each plugin
|
||||||
|
----------------------------------------------
|
||||||
|
When using any of the previously shown functions, it may be a bit inconvenient
|
||||||
|
to find out what options are supported, since the Android SDK provides many
|
||||||
|
plugins.
|
||||||
|
|
||||||
|
A shell script in the `pkgs/development/mobile/androidenv/` sub directory can be used to retrieve all
|
||||||
|
possible options:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sh ./querypackages.sh packages build-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
The above command-line instruction queries all build-tools versions in the
|
||||||
|
generated `packages.nix` expression.
|
||||||
|
|
||||||
|
Updating the generated expressions
|
||||||
|
----------------------------------
|
||||||
|
Most of the Nix expressions are generated from XML files that the Android
|
||||||
|
package manager uses. To update the expressions run the `generate.sh` script
|
||||||
|
that is stored in the `pkgs/development/mobile/androidenv/` sub directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sh ./generate.sh
|
||||||
|
```
|
@ -935,7 +935,7 @@ The implementation can be found in the
|
|||||||
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
||||||
|
|
||||||
A potential problem with this is that GMP is licensed under the
|
A potential problem with this is that GMP is licensed under the
|
||||||
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
|
[GNU Lesser General Public License (LGPL)](https://www.gnu.org/copyleft/lesser.html),
|
||||||
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
|
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
|
||||||
you may distribute a program that is designed to be compiled and dynamically
|
you may distribute a program that is designed to be compiled and dynamically
|
||||||
linked with the library under the terms of your choice (i.e., commercially) but
|
linked with the library under the terms of your choice (i.e., commercially) but
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
Nixpkgs to easily build packages for other programming languages, such as
|
Nixpkgs to easily build packages for other programming languages, such as
|
||||||
Perl or Haskell. These are described in this chapter.
|
Perl or Haskell. These are described in this chapter.
|
||||||
</para>
|
</para>
|
||||||
|
<xi:include href="android.section.xml" />
|
||||||
<xi:include href="beam.xml" />
|
<xi:include href="beam.xml" />
|
||||||
<xi:include href="bower.xml" />
|
<xi:include href="bower.xml" />
|
||||||
<xi:include href="coq.xml" />
|
<xi:include href="coq.xml" />
|
||||||
<xi:include href="go.xml" />
|
<xi:include href="go.xml" />
|
||||||
<xi:include href="haskell.section.xml" />
|
<xi:include href="haskell.section.xml" />
|
||||||
<xi:include href="idris.section.xml" />
|
<xi:include href="idris.section.xml" />
|
||||||
|
<xi:include href="ios.section.xml" />
|
||||||
<xi:include href="java.xml" />
|
<xi:include href="java.xml" />
|
||||||
<xi:include href="lua.xml" />
|
<xi:include href="lua.xml" />
|
||||||
<xi:include href="node.section.xml" />
|
<xi:include href="node.section.xml" />
|
||||||
@ -27,6 +29,7 @@
|
|||||||
<xi:include href="ruby.xml" />
|
<xi:include href="ruby.xml" />
|
||||||
<xi:include href="rust.section.xml" />
|
<xi:include href="rust.section.xml" />
|
||||||
<xi:include href="texlive.xml" />
|
<xi:include href="texlive.xml" />
|
||||||
|
<xi:include href="titanium.section.xml" />
|
||||||
<xi:include href="vim.section.xml" />
|
<xi:include href="vim.section.xml" />
|
||||||
<xi:include href="emscripten.section.xml" />
|
<xi:include href="emscripten.section.xml" />
|
||||||
</chapter>
|
</chapter>
|
||||||
|
219
doc/languages-frameworks/ios.section.md
Normal file
219
doc/languages-frameworks/ios.section.md
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
---
|
||||||
|
title: iOS
|
||||||
|
author: Sander van der Burg
|
||||||
|
date: 2018-11-18
|
||||||
|
---
|
||||||
|
# iOS
|
||||||
|
|
||||||
|
This component is basically a wrapper/workaround that makes it possible to
|
||||||
|
expose an Xcode installation as a Nix package by means of symlinking to the
|
||||||
|
relevant executables on the host system.
|
||||||
|
|
||||||
|
Since Xcode can't be packaged with Nix, nor we can publish it as a Nix package
|
||||||
|
(because of its license) this is basically the only integration strategy
|
||||||
|
making it possible to do iOS application builds that integrate with other
|
||||||
|
components of the Nix ecosystem
|
||||||
|
|
||||||
|
The primary objective of this project is to use the Nix expression language to
|
||||||
|
specify how iOS apps can be built from source code, and to automatically spawn
|
||||||
|
iOS simulator instances for testing.
|
||||||
|
|
||||||
|
This component also makes it possible to use [Hydra](http://nixos.org/hydra),
|
||||||
|
the Nix-based continuous integration server to regularly build iOS apps and to
|
||||||
|
do wireless ad-hoc installations of enterprise IPAs on iOS devices through
|
||||||
|
Hydra.
|
||||||
|
|
||||||
|
The Xcode build environment implements a number of features.
|
||||||
|
|
||||||
|
Deploying a proxy component wrapper exposing Xcode
|
||||||
|
--------------------------------------------------
|
||||||
|
The first use case is deploying a Nix package that provides symlinks to the Xcode
|
||||||
|
installation on the host system. This package can be used as a build input to
|
||||||
|
any build function implemented in the Nix expression language that requires
|
||||||
|
Xcode.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
|
||||||
|
xcodeenv = import ./xcodeenv {
|
||||||
|
inherit (pkgs) stdenv;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
xcodeenv.composeXcodeWrapper {
|
||||||
|
version = "9.2";
|
||||||
|
xcodeBaseDir = "/Applications/Xcode.app";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
By deploying the above expression with `nix-build` and inspecting its content
|
||||||
|
you will notice that several Xcode-related executables are exposed as a Nix
|
||||||
|
package:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ls result/bin
|
||||||
|
lrwxr-xr-x 1 sander staff 94 1 jan 1970 Simulator -> /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator
|
||||||
|
lrwxr-xr-x 1 sander staff 17 1 jan 1970 codesign -> /usr/bin/codesign
|
||||||
|
lrwxr-xr-x 1 sander staff 17 1 jan 1970 security -> /usr/bin/security
|
||||||
|
lrwxr-xr-x 1 sander staff 21 1 jan 1970 xcode-select -> /usr/bin/xcode-select
|
||||||
|
lrwxr-xr-x 1 sander staff 61 1 jan 1970 xcodebuild -> /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
|
||||||
|
lrwxr-xr-x 1 sander staff 14 1 jan 1970 xcrun -> /usr/bin/xcrun
|
||||||
|
```
|
||||||
|
|
||||||
|
Building an iOS application
|
||||||
|
---------------------------
|
||||||
|
We can build an iOS app executable for the simulator, or an IPA/xcarchive file
|
||||||
|
for release purposes, e.g. ad-hoc, enterprise or store installations, by
|
||||||
|
executing the `xcodeenv.buildApp {}` function:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
|
||||||
|
xcodeenv = import ./xcodeenv {
|
||||||
|
inherit (pkgs) stdenv;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
xcodeenv.buildApp {
|
||||||
|
name = "MyApp";
|
||||||
|
src = ./myappsources;
|
||||||
|
sdkVersion = "11.2";
|
||||||
|
|
||||||
|
target = null; # Corresponds to the name of the app by default
|
||||||
|
configuration = null; # Release for release builds, Debug for debug builds
|
||||||
|
scheme = null; # -scheme will correspond to the app name by default
|
||||||
|
sdk = null; # null will set it to 'iphonesimulator` for simulator builds or `iphoneos` to real builds
|
||||||
|
xcodeFlags = "";
|
||||||
|
|
||||||
|
release = true;
|
||||||
|
certificateFile = ./mycertificate.p12;
|
||||||
|
certificatePassword = "secret";
|
||||||
|
provisioningProfile = ./myprovisioning.profile;
|
||||||
|
signMethod = "ad-hoc"; # 'enterprise' or 'store'
|
||||||
|
generateIPA = true;
|
||||||
|
generateXCArchive = false;
|
||||||
|
|
||||||
|
enableWirelessDistribution = true;
|
||||||
|
installURL = "/installipa.php";
|
||||||
|
bundleId = "mycompany.myapp";
|
||||||
|
appVersion = "1.0";
|
||||||
|
|
||||||
|
# Supports all xcodewrapper parameters as well
|
||||||
|
xcodeBaseDir = "/Applications/Xcode.app";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above function takes a variety of parameters:
|
||||||
|
* The `name` and `src` parameters are mandatory and specify the name of the app
|
||||||
|
and the location where the source code resides
|
||||||
|
* `sdkVersion` specifies which version of the iOS SDK to use.
|
||||||
|
|
||||||
|
It also possile to adjust the `xcodebuild` parameters. This is only needed in
|
||||||
|
rare circumstances. In most cases the default values should suffice:
|
||||||
|
|
||||||
|
* Specifies which `xcodebuild` target to build. By default it takes the target
|
||||||
|
that has the same name as the app.
|
||||||
|
* The `configuration` parameter can be overridden if desired. By default, it
|
||||||
|
will do a debug build for the simulator and a release build for real devices.
|
||||||
|
* The `scheme` parameter specifies which `-scheme` parameter to propagate to
|
||||||
|
`xcodebuild`. By default, it corresponds to the app name.
|
||||||
|
* The `sdk` parameter specifies which SDK to use. By default, it picks
|
||||||
|
`iphonesimulator` for simulator builds and `iphoneos` for release builds.
|
||||||
|
* The `xcodeFlags` parameter specifies arbitrary command line parameters that
|
||||||
|
should be propagated to `xcodebuild`.
|
||||||
|
|
||||||
|
By default, builds are carried out for the iOS simulator. To do release builds
|
||||||
|
(builds for real iOS devices), you must set the `release` parameter to `true`.
|
||||||
|
In addition, you need to set the following parameters:
|
||||||
|
|
||||||
|
* `certificateFile` refers to a P12 certificate file.
|
||||||
|
* `certificatePassword` specifies the password of the P12 certificate.
|
||||||
|
* `provisioningProfile` refers to the provision profile needed to sign the app
|
||||||
|
* `signMethod` should refer to `ad-hoc` for signing the app with an ad-hoc
|
||||||
|
certificate, `enterprise` for enterprise certificates and `app-store` for App
|
||||||
|
store certificates.
|
||||||
|
* `generateIPA` specifies that we want to produce an IPA file (this is probably
|
||||||
|
what you want)
|
||||||
|
* `generateXCArchive` specifies thet we want to produce an xcarchive file.
|
||||||
|
|
||||||
|
When building IPA files on Hydra and when it is desired to allow iOS devices to
|
||||||
|
install IPAs by browsing to the Hydra build products page, you can enable the
|
||||||
|
`enableWirelessDistribution` parameter.
|
||||||
|
|
||||||
|
When enabled, you need to configure the following options:
|
||||||
|
|
||||||
|
* The `installURL` parameter refers to the URL of a PHP script that composes the
|
||||||
|
`itms-services://` URL allowing iOS devices to install the IPA file.
|
||||||
|
* `bundleId` refers to the bundle ID value of the app
|
||||||
|
* `appVersion` refers to the app's version number
|
||||||
|
|
||||||
|
To use wireless adhoc distributions, you must also install the corresponding
|
||||||
|
PHP script on a web server (see section: 'Installing the PHP script for wireless
|
||||||
|
ad hoc installations from Hydra' for more information).
|
||||||
|
|
||||||
|
In addition to the build parameters, you can also specify any parameters that
|
||||||
|
the `xcodeenv.composeXcodeWrapper {}` function takes. For example, the
|
||||||
|
`xcodeBaseDir` parameter can be overridden to refer to a different Xcode
|
||||||
|
version.
|
||||||
|
|
||||||
|
Spawning simulator instances
|
||||||
|
----------------------------
|
||||||
|
In addition to building iOS apps, we can also automatically spawn simulator
|
||||||
|
instances:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
|
||||||
|
xcodeenv = import ./xcodeenv {
|
||||||
|
inherit (pkgs) stdenv;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
xcode.simulateApp {
|
||||||
|
name = "simulate";
|
||||||
|
|
||||||
|
# Supports all xcodewrapper parameters as well
|
||||||
|
xcodeBaseDir = "/Applications/Xcode.app";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above expression produces a script that starts the simulator from the
|
||||||
|
provided Xcode installation. The script can be started as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./result/bin/run-test-simulator
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, the script will show an overview of UDID for all available simulator
|
||||||
|
instances and asks you to pick one. You can also provide a UDID as a
|
||||||
|
command-line parameter to launch an instance automatically:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./result/bin/run-test-simulator 5C93129D-CF39-4B1A-955F-15180C3BD4B8
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also extend the simulator script to automatically deploy and launch an
|
||||||
|
app in the requested simulator instance:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
|
||||||
|
xcodeenv = import ./xcodeenv {
|
||||||
|
inherit (pkgs) stdenv;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
xcode.simulateApp {
|
||||||
|
name = "simulate";
|
||||||
|
bundleId = "mycompany.myapp";
|
||||||
|
app = xcode.buildApp {
|
||||||
|
# ...
|
||||||
|
};
|
||||||
|
|
||||||
|
# Supports all xcodewrapper parameters as well
|
||||||
|
xcodeBaseDir = "/Applications/Xcode.app";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
By providing the result of an `xcode.buildApp {}` function and configuring the
|
||||||
|
app bundle id, the app gets deployed automatically and started.
|
@ -484,10 +484,12 @@ and in this case the `python35` interpreter is automatically used.
|
|||||||
### Interpreters
|
### Interpreters
|
||||||
|
|
||||||
Versions 2.7, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
|
Versions 2.7, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
|
||||||
respectively `python27`, `python35`, `python36`, and `python37`. The PyPy
|
respectively `python27`, `python35`, `python36` and `python37`. The aliases
|
||||||
interpreter is available as `pypy`. The aliases `python2` and `python3`
|
`python2` and `python3` correspond to respectively `python27` and
|
||||||
correspond to respectively `python27` and `python37`. The default interpreter,
|
`python37`. The default interpreter, `python`, maps to `python2`. The PyPy
|
||||||
`python`, maps to `python2`. The Nix expressions for the interpreters can be
|
interpreters compatible with Python 2.7 and 3 are available as `pypy27` and
|
||||||
|
`pypy3`, with aliases `pypy2` mapping to `pypy27` and `pypy` mapping to
|
||||||
|
`pypy2`. The Nix expressions for the interpreters can be
|
||||||
found in `pkgs/development/interpreters/python`.
|
found in `pkgs/development/interpreters/python`.
|
||||||
|
|
||||||
All packages depending on any Python interpreter get appended
|
All packages depending on any Python interpreter get appended
|
||||||
@ -1102,7 +1104,7 @@ on `numpy` will be built with `mkl`.
|
|||||||
The following is an overlay that configures `numpy` to use `mkl`:
|
The following is an overlay that configures `numpy` to use `mkl`:
|
||||||
```nix
|
```nix
|
||||||
self: super: {
|
self: super: {
|
||||||
python36 = super.python36.override {
|
python37 = super.python37.override {
|
||||||
packageOverrides = python-self: python-super: {
|
packageOverrides = python-self: python-super: {
|
||||||
numpy = python-super.numpy.override {
|
numpy = python-super.numpy.override {
|
||||||
blas = super.pkgs.mkl;
|
blas = super.pkgs.mkl;
|
||||||
@ -1112,6 +1114,15 @@ self: super: {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`mkl` requires an `openmp` implementation when running with multiple processors.
|
||||||
|
By default, `mkl` will use Intel's `iomp` implementation if no other is
|
||||||
|
specified, but this is a runtime-only dependency and binary compatible with the
|
||||||
|
LLVM implementation. To use that one instead, Intel recommends users set it with
|
||||||
|
`LD_PRELOAD`.
|
||||||
|
|
||||||
|
Note that `mkl` is only available on `x86_64-{linux,darwin}` platforms;
|
||||||
|
moreover, Hydra is not building and distributing pre-compiled binaries using it.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
### Contributing guidelines
|
### Contributing guidelines
|
||||||
|
@ -50,6 +50,17 @@ bundlerEnv rec {
|
|||||||
future updates can be run easily.
|
future updates can be run easily.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Updating Ruby packages can then be done like this:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
<![CDATA[$ cd pkgs/servers/monitoring/sensu
|
||||||
|
$ nix-shell -p bundler --run 'bundle lock --update'
|
||||||
|
$ nix-shell -p bundix --run 'bundix'
|
||||||
|
]]>
|
||||||
|
</screen>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
For tools written in Ruby - i.e. where the desire is to install a package and
|
For tools written in Ruby - i.e. where the desire is to install a package and
|
||||||
then execute e.g. <command>rake</command> at the command line, there is an
|
then execute e.g. <command>rake</command> at the command line, there is an
|
||||||
|
@ -49,12 +49,12 @@ texlive.combine {
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
You can list packages e.g. by <command>nix-repl</command>.
|
You can list packages e.g. by <command>nix repl</command>.
|
||||||
<programlisting>
|
<programlisting><![CDATA[
|
||||||
$ nix-repl
|
$ nix repl
|
||||||
nix-repl> :l <nixpkgs>
|
nix-repl> :l <nixpkgs>
|
||||||
nix-repl> texlive.collection-<TAB>
|
nix-repl> texlive.collection-<TAB>
|
||||||
</programlisting>
|
]]></programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
115
doc/languages-frameworks/titanium.section.md
Normal file
115
doc/languages-frameworks/titanium.section.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
title: Titanium
|
||||||
|
author: Sander van der Burg
|
||||||
|
date: 2018-11-18
|
||||||
|
---
|
||||||
|
# Titanium
|
||||||
|
|
||||||
|
The Nixpkgs repository contains facilities to deploy a variety of versions of
|
||||||
|
the [Titanium SDK](https://www.appcelerator.com) versions, a cross-platform
|
||||||
|
mobile app development framework using JavaScript as an implementation language,
|
||||||
|
and includes a function abstraction making it possible to build Titanium
|
||||||
|
applications for Android and iOS devices from source code.
|
||||||
|
|
||||||
|
Not all Titanium features supported -- currently, it can only be used to build
|
||||||
|
Android and iOS apps.
|
||||||
|
|
||||||
|
Building a Titanium app
|
||||||
|
-----------------------
|
||||||
|
We can build a Titanium app from source for Android or iOS and for debugging or
|
||||||
|
release purposes by invoking the `titaniumenv.buildApp {}` function:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
titaniumenv.buildApp {
|
||||||
|
name = "myapp";
|
||||||
|
src = ./myappsource;
|
||||||
|
|
||||||
|
preBuild = "";
|
||||||
|
target = "android"; # or 'iphone'
|
||||||
|
tiVersion = "7.1.0.GA";
|
||||||
|
release = true;
|
||||||
|
|
||||||
|
androidsdkArgs = {
|
||||||
|
platformVersions = [ "25" "26" ];
|
||||||
|
};
|
||||||
|
androidKeyStore = ./keystore;
|
||||||
|
androidKeyAlias = "myfirstapp";
|
||||||
|
androidKeyStorePassword = "secret";
|
||||||
|
|
||||||
|
xcodeBaseDir = "/Applications/Xcode.app";
|
||||||
|
xcodewrapperArgs = {
|
||||||
|
version = "9.3";
|
||||||
|
};
|
||||||
|
iosMobileProvisioningProfile = ./myprovisioning.profile;
|
||||||
|
iosCertificateName = "My Company";
|
||||||
|
iosCertificate = ./mycertificate.p12;
|
||||||
|
iosCertificatePassword = "secret";
|
||||||
|
iosVersion = "11.3";
|
||||||
|
iosBuildStore = false;
|
||||||
|
|
||||||
|
enableWirelessDistribution = true;
|
||||||
|
installURL = "/installipa.php";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `titaniumenv.buildApp {}` function takes the following parameters:
|
||||||
|
|
||||||
|
* The `name` parameter refers to the name in the Nix store.
|
||||||
|
* The `src` parameter refers to the source code location of the app that needs
|
||||||
|
to be built.
|
||||||
|
* `preRebuild` contains optional build instructions that are carried out before
|
||||||
|
the build starts.
|
||||||
|
* `target` indicates for which device the app must be built. Currently only
|
||||||
|
'android' and 'iphone' (for iOS) are supported.
|
||||||
|
* `tiVersion` can be used to optionally override the requested Titanium version
|
||||||
|
in `tiapp.xml`. If not specified, it will use the version in `tiapp.xml`.
|
||||||
|
* `release` should be set to true when building an app for submission to the
|
||||||
|
Google Playstore or Apple Appstore. Otherwise, it should be false.
|
||||||
|
|
||||||
|
When the `target` has been set to `android`, we can configure the following
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
* The `androidSdkArgs` parameter refers to an attribute set that propagates all
|
||||||
|
parameters to the `androidenv.composeAndroidPackages {}` function. This can
|
||||||
|
be used to install all relevant Android plugins that may be needed to perform
|
||||||
|
the Android build. If no parameters are given, it will deploy the platform
|
||||||
|
SDKs for API-levels 25 and 26 by default.
|
||||||
|
|
||||||
|
When the `release` parameter has been set to true, you need to provide
|
||||||
|
parameters to sign the app:
|
||||||
|
|
||||||
|
* `androidKeyStore` is the path to the keystore file
|
||||||
|
* `androidKeyAlias` is the key alias
|
||||||
|
* `androidKeyStorePassword` refers to the password to open the keystore file.
|
||||||
|
|
||||||
|
When the `target` has been set to `iphone`, we can configure the following
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
* The `xcodeBaseDir` parameter refers to the location where Xcode has been
|
||||||
|
installed. When none value is given, the above value is the default.
|
||||||
|
* The `xcodewrapperArgs` parameter passes arbitrary parameters to the
|
||||||
|
`xcodeenv.composeXcodeWrapper {}` function. This can, for example, be used
|
||||||
|
to adjust the default version of Xcode.
|
||||||
|
|
||||||
|
When `release` has been set to true, you also need to provide the following
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
* `iosMobileProvisioningProfile` refers to a mobile provisioning profile needed
|
||||||
|
for signing.
|
||||||
|
* `iosCertificateName` refers to the company name in the P12 certificate.
|
||||||
|
* `iosCertificate` refers to the path to the P12 file.
|
||||||
|
* `iosCertificatePassword` contains the password to open the P12 file.
|
||||||
|
* `iosVersion` refers to the iOS SDK version to use. It defaults to the latest
|
||||||
|
version.
|
||||||
|
* `iosBuildStore` should be set to `true` when building for the Apple Appstore
|
||||||
|
submission. For enterprise or ad-hoc builds it should be set to `false`.
|
||||||
|
|
||||||
|
When `enableWirelessDistribution` has been enabled, you must also provide the
|
||||||
|
path of the PHP script (`installURL`) (that is included with the iOS build
|
||||||
|
environment) to enable wireless ad-hoc installations.
|
||||||
|
|
||||||
|
Emulating or simulating the app
|
||||||
|
-------------------------------
|
||||||
|
It is also possible to simulate the correspond iOS simulator build by using
|
||||||
|
`xcodeenv.simulateApp {}` and emulate an Android APK by using
|
||||||
|
`androidenv.emulateApp {}`.
|
@ -48,7 +48,7 @@ neovim.override {
|
|||||||
|
|
||||||
## Managing plugins with Vim packages
|
## Managing plugins with Vim packages
|
||||||
|
|
||||||
To store you plugins in Vim packages the following example can be used:
|
To store you plugins in Vim packages (the native vim plugin manager, see `:help packages`) the following example can be used:
|
||||||
|
|
||||||
```
|
```
|
||||||
vim_configurable.customize {
|
vim_configurable.customize {
|
||||||
@ -56,6 +56,8 @@ vim_configurable.customize {
|
|||||||
# loaded on launch
|
# loaded on launch
|
||||||
start = [ youcompleteme fugitive ];
|
start = [ youcompleteme fugitive ];
|
||||||
# manually loadable by calling `:packadd $plugin-name`
|
# manually loadable by calling `:packadd $plugin-name`
|
||||||
|
# however, if a vim plugin has a dependency that is not explicitly listed in
|
||||||
|
# opt that dependency will always be added to start to avoid confusion.
|
||||||
opt = [ phpCompletion elm-vim ];
|
opt = [ phpCompletion elm-vim ];
|
||||||
# To automatically load a plugin when opening a filetype, add vimrc lines like:
|
# To automatically load a plugin when opening a filetype, add vimrc lines like:
|
||||||
# autocmd FileType php :packadd phpCompletion
|
# autocmd FileType php :packadd phpCompletion
|
||||||
@ -63,6 +65,7 @@ vim_configurable.customize {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`myVimPackage` is an arbitrary name for the generated package. You can choose any name you like.
|
||||||
For Neovim the syntax is:
|
For Neovim the syntax is:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -74,6 +77,8 @@ neovim.override {
|
|||||||
packages.myVimPackage = with pkgs.vimPlugins; {
|
packages.myVimPackage = with pkgs.vimPlugins; {
|
||||||
# see examples below how to use custom packages
|
# see examples below how to use custom packages
|
||||||
start = [ ];
|
start = [ ];
|
||||||
|
# If a vim plugin has a dependency that is not explicitly listed in
|
||||||
|
# opt that dependency will always be added to start to avoid confusion.
|
||||||
opt = [ ];
|
opt = [ ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@ meta = with stdenv.lib; {
|
|||||||
GNU Hello is a program that prints "Hello, world!" when you run it.
|
GNU Hello is a program that prints "Hello, world!" when you run it.
|
||||||
It is fully customizable.
|
It is fully customizable.
|
||||||
'';
|
'';
|
||||||
homepage = http://www.gnu.org/software/hello/manual/;
|
homepage = https://www.gnu.org/software/hello/manual/;
|
||||||
license = licenses.gpl3Plus;
|
license = licenses.gpl3Plus;
|
||||||
maintainers = [ maintainers.eelco ];
|
maintainers = [ maintainers.eelco ];
|
||||||
platforms = platforms.all;
|
platforms = platforms.all;
|
||||||
@ -35,7 +35,7 @@ $ nix-env -qa hello --json
|
|||||||
"hello": {
|
"hello": {
|
||||||
"meta": {
|
"meta": {
|
||||||
"description": "A program that produces a familiar, friendly greeting",
|
"description": "A program that produces a familiar, friendly greeting",
|
||||||
"homepage": "http://www.gnu.org/software/hello/manual/",
|
"homepage": "https://www.gnu.org/software/hello/manual/",
|
||||||
"license": {
|
"license": {
|
||||||
"fullName": "GNU General Public License version 3 or later",
|
"fullName": "GNU General Public License version 3 or later",
|
||||||
"shortName": "GPLv3+",
|
"shortName": "GPLv3+",
|
||||||
@ -135,7 +135,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The package’s homepage. Example:
|
The package’s homepage. Example:
|
||||||
<literal>http://www.gnu.org/software/hello/manual/</literal>
|
<literal>https://www.gnu.org/software/hello/manual/</literal>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -146,7 +146,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The page where a link to the current version can be found. Example:
|
The page where a link to the current version can be found. Example:
|
||||||
<literal>http://ftp.gnu.org/gnu/hello/</literal>
|
<literal>https://ftp.gnu.org/gnu/hello/</literal>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -671,6 +671,43 @@ passthru = {
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>passthru.updateScript</varname>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A script to be run by <filename>maintainers/scripts/update.nix</filename> when
|
||||||
|
the package is matched. It needs to be an executable file, either on the file
|
||||||
|
system:
|
||||||
|
<programlisting>
|
||||||
|
passthru.updateScript = ./update.sh;
|
||||||
|
</programlisting>
|
||||||
|
or inside the expression itself:
|
||||||
|
<programlisting>
|
||||||
|
passthru.updateScript = writeScript "update-zoom-us" ''
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p curl pcre common-updater-scripts
|
||||||
|
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
|
||||||
|
update-source-version zoom-us "$version"
|
||||||
|
'';
|
||||||
|
</programlisting>
|
||||||
|
The attribute can also contain a list, a script followed by arguments to be passed to it:
|
||||||
|
<programlisting>
|
||||||
|
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
|
||||||
|
</programlisting>
|
||||||
|
Note that the update scripts will be run in parallel by default; you should avoid running <command>git commit</command> or any other commands that cannot handle that.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For information about how to run the updates, execute
|
||||||
|
<cmdsynopsis><command>nix-shell</command> <arg>maintainers/scripts/update.nix</arg></cmdsynopsis>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="sec-stdenv-phases">
|
<section xml:id="sec-stdenv-phases">
|
||||||
@ -2463,17 +2500,17 @@ addEnvHooks "$hostOffset" myBashFunction
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
This hook will make a build pause instead of stopping when a failure
|
This hook will make a build pause instead of stopping when a failure
|
||||||
happen. It prevents nix to cleanup the build environment immediatly and
|
happens. It prevents nix from cleaning up the build environment immediately and
|
||||||
allows the user to attach to a build environment using the
|
allows the user to attach to a build environment using the
|
||||||
<command>cntr</command> command. On build error it will print the
|
<command>cntr</command> command. Upon build error it will print
|
||||||
instruction that are neccessary for <command>cntr</command>. Installing
|
instructions on how to use <command>cntr</command>. Installing
|
||||||
cntr and running the command will provide shell access to the build
|
cntr and running the command will provide shell access to the build
|
||||||
sandbox of failed build. At <filename>/var/lib/cntr</filename> the
|
sandbox of failed build. At <filename>/var/lib/cntr</filename> the
|
||||||
sandbox filesystem is mounted. All commands and files of the system are
|
sandboxed filesystem is mounted. All commands and files of the system are
|
||||||
still accessible within the shell. To execute commands from the sandbox
|
still accessible within the shell. To execute commands from the sandbox
|
||||||
use the cntr exec subcommand. Note that <command>cntr</command> also
|
use the cntr exec subcommand. Note that <command>cntr</command> also
|
||||||
needs to be executed on the machine that is doing the build, which might
|
needs to be executed on the machine that is doing the build, which might
|
||||||
be not the case when remote builders are enabled.
|
not be the case when remote builders are enabled.
|
||||||
<command>cntr</command> is only supported on Linux-based platforms. To
|
<command>cntr</command> is only supported on Linux-based platforms. To
|
||||||
use it first add <literal>cntr</literal> to your
|
use it first add <literal>cntr</literal> to your
|
||||||
<literal>environment.systemPackages</literal> on NixOS or alternatively to
|
<literal>environment.systemPackages</literal> on NixOS or alternatively to
|
||||||
@ -2488,6 +2525,23 @@ addEnvHooks "$hostOffset" myBashFunction
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
libiconv, libintl
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A few libraries automatically add to
|
||||||
|
<literal>NIX_LDFLAGS</literal> their library, making their
|
||||||
|
symbols automatically available to the linker. This includes
|
||||||
|
libiconv and libintl (gettext). This is done to provide
|
||||||
|
compatibility between GNU Linux, where libiconv and libintl
|
||||||
|
are bundled in, and other systems where that might not be the
|
||||||
|
case. Sometimes, this behavior is not desired. To disable
|
||||||
|
this behavior, set <literal>dontAddExtraLibs</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
cmake
|
cmake
|
||||||
|
@ -94,6 +94,15 @@ rec {
|
|||||||
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
|
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
|
||||||
|
|
||||||
|
|
||||||
|
/* Given a set of attribute names, return the set of the corresponding
|
||||||
|
attributes from the given set.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
|
||||||
|
=> { a = 1; b = 2; }
|
||||||
|
*/
|
||||||
|
getAttrs = names: attrs: genAttrs names (name: attrs.${name});
|
||||||
|
|
||||||
/* Collect each attribute named `attr' from a list of attribute
|
/* Collect each attribute named `attr' from a list of attribute
|
||||||
sets. Sets that don't contain the named attribute are ignored.
|
sets. Sets that don't contain the named attribute are ignored.
|
||||||
|
|
||||||
|
@ -61,10 +61,10 @@ let
|
|||||||
boolToString mergeAttrs flip mapNullable inNixShell min max
|
boolToString mergeAttrs flip mapNullable inNixShell min max
|
||||||
importJSON warn info nixpkgsVersion version mod compare
|
importJSON warn info nixpkgsVersion version mod compare
|
||||||
splitByAndCompare functionArgs setFunctionArgs isFunction;
|
splitByAndCompare functionArgs setFunctionArgs isFunction;
|
||||||
inherit (fixedPoints) fix fix' extends composeExtensions
|
inherit (fixedPoints) fix fix' converge extends composeExtensions
|
||||||
makeExtensible makeExtensibleWithCustomName;
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||||
getAttrFromPath attrVals attrValues catAttrs filterAttrs
|
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
|
||||||
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
||||||
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||||
genAttrs isDerivation toDerivation optionalAttrs
|
genAttrs isDerivation toDerivation optionalAttrs
|
||||||
|
@ -24,6 +24,16 @@ rec {
|
|||||||
# for a concrete example.
|
# for a concrete example.
|
||||||
fix' = f: let x = f x // { __unfix__ = f; }; in x;
|
fix' = f: let x = f x // { __unfix__ = f; }; in x;
|
||||||
|
|
||||||
|
# Return the fixpoint that `f` converges to when called recursively, starting
|
||||||
|
# with the input `x`.
|
||||||
|
#
|
||||||
|
# nix-repl> converge (x: x / 2) 16
|
||||||
|
# 0
|
||||||
|
converge = f: x:
|
||||||
|
if (f x) == x
|
||||||
|
then x
|
||||||
|
else converge f (f x);
|
||||||
|
|
||||||
# Modify the contents of an explicitly recursive attribute set in a way that
|
# Modify the contents of an explicitly recursive attribute set in a way that
|
||||||
# honors `self`-references. This is accomplished with a function
|
# honors `self`-references. This is accomplished with a function
|
||||||
#
|
#
|
||||||
|
@ -29,13 +29,13 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
agpl3 = spdx {
|
agpl3 = spdx {
|
||||||
spdxId = "AGPL-3.0";
|
spdxId = "AGPL-3.0-only";
|
||||||
fullName = "GNU Affero General Public License v3.0";
|
fullName = "GNU Affero General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
agpl3Plus = {
|
agpl3Plus = spdx {
|
||||||
|
spdxId = "AGPL-3.0-or-later";
|
||||||
fullName = "GNU Affero General Public License v3.0 or later";
|
fullName = "GNU Affero General Public License v3.0 or later";
|
||||||
inherit (agpl3) url;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
amazonsl = {
|
amazonsl = {
|
||||||
@ -266,13 +266,23 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fdl12 = spdx {
|
fdl12 = spdx {
|
||||||
spdxId = "GFDL-1.2";
|
spdxId = "GFDL-1.2-only";
|
||||||
fullName = "GNU Free Documentation License v1.2";
|
fullName = "GNU Free Documentation License v1.2 only";
|
||||||
|
};
|
||||||
|
|
||||||
|
fdl12Plus = spdx {
|
||||||
|
spdxId = "GFDL-1.2-or-later";
|
||||||
|
fullName = "GNU Free Documentation License v1.2 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
fdl13 = spdx {
|
fdl13 = spdx {
|
||||||
spdxId = "GFDL-1.3";
|
spdxId = "GFDL-1.3-only";
|
||||||
fullName = "GNU Free Documentation License v1.3";
|
fullName = "GNU Free Documentation License v1.3 only";
|
||||||
|
};
|
||||||
|
|
||||||
|
fdl13Plus = spdx {
|
||||||
|
spdxId = "GFDL-1.3-or-later";
|
||||||
|
fullName = "GNU Free Documentation License v1.3 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
ffsl = {
|
ffsl = {
|
||||||
@ -297,24 +307,23 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
gpl1 = spdx {
|
gpl1 = spdx {
|
||||||
spdxId = "GPL-1.0";
|
spdxId = "GPL-1.0-only";
|
||||||
fullName = "GNU General Public License v1.0 only";
|
fullName = "GNU General Public License v1.0 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl1Plus = spdx {
|
gpl1Plus = spdx {
|
||||||
spdxId = "GPL-1.0+";
|
spdxId = "GPL-1.0-or-later";
|
||||||
fullName = "GNU General Public License v1.0 or later";
|
fullName = "GNU General Public License v1.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl2 = spdx {
|
gpl2 = spdx {
|
||||||
spdxId = "GPL-2.0";
|
spdxId = "GPL-2.0-only";
|
||||||
fullName = "GNU General Public License v2.0 only";
|
fullName = "GNU General Public License v2.0 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl2Classpath = {
|
gpl2Classpath = spdx {
|
||||||
spdxId = "GPL-2.0-with-classpath-exception";
|
spdxId = "GPL-2.0-with-classpath-exception";
|
||||||
fullName = "GNU General Public License v2.0 only (with Classpath exception)";
|
fullName = "GNU General Public License v2.0 only (with Classpath exception)";
|
||||||
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl2ClasspathPlus = {
|
gpl2ClasspathPlus = {
|
||||||
@ -328,17 +337,17 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
gpl2Plus = spdx {
|
gpl2Plus = spdx {
|
||||||
spdxId = "GPL-2.0+";
|
spdxId = "GPL-2.0-or-later";
|
||||||
fullName = "GNU General Public License v2.0 or later";
|
fullName = "GNU General Public License v2.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl3 = spdx {
|
gpl3 = spdx {
|
||||||
spdxId = "GPL-3.0";
|
spdxId = "GPL-3.0-only";
|
||||||
fullName = "GNU General Public License v3.0 only";
|
fullName = "GNU General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
gpl3Plus = spdx {
|
gpl3Plus = spdx {
|
||||||
spdxId = "GPL-3.0+";
|
spdxId = "GPL-3.0-or-later";
|
||||||
fullName = "GNU General Public License v3.0 or later";
|
fullName = "GNU General Public License v3.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -408,32 +417,32 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
lgpl2 = spdx {
|
lgpl2 = spdx {
|
||||||
spdxId = "LGPL-2.0";
|
spdxId = "LGPL-2.0-only";
|
||||||
fullName = "GNU Library General Public License v2 only";
|
fullName = "GNU Library General Public License v2 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl2Plus = spdx {
|
lgpl2Plus = spdx {
|
||||||
spdxId = "LGPL-2.0+";
|
spdxId = "LGPL-2.0-or-later";
|
||||||
fullName = "GNU Library General Public License v2 or later";
|
fullName = "GNU Library General Public License v2 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl21 = spdx {
|
lgpl21 = spdx {
|
||||||
spdxId = "LGPL-2.1";
|
spdxId = "LGPL-2.1-only";
|
||||||
fullName = "GNU Library General Public License v2.1 only";
|
fullName = "GNU Library General Public License v2.1 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl21Plus = spdx {
|
lgpl21Plus = spdx {
|
||||||
spdxId = "LGPL-2.1+";
|
spdxId = "LGPL-2.1-or-later";
|
||||||
fullName = "GNU Library General Public License v2.1 or later";
|
fullName = "GNU Library General Public License v2.1 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl3 = spdx {
|
lgpl3 = spdx {
|
||||||
spdxId = "LGPL-3.0";
|
spdxId = "LGPL-3.0-only";
|
||||||
fullName = "GNU Lesser General Public License v3.0 only";
|
fullName = "GNU Lesser General Public License v3.0 only";
|
||||||
};
|
};
|
||||||
|
|
||||||
lgpl3Plus = spdx {
|
lgpl3Plus = spdx {
|
||||||
spdxId = "LGPL-3.0+";
|
spdxId = "LGPL-3.0-or-later";
|
||||||
fullName = "GNU Lesser General Public License v3.0 or later";
|
fullName = "GNU Lesser General Public License v3.0 or later";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -505,6 +514,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
free = false;
|
free = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nasa13 = spdx {
|
||||||
|
spdxId = "NASA-1.3";
|
||||||
|
fullName = "NASA Open Source Agreement 1.3";
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
ncsa = spdx {
|
ncsa = spdx {
|
||||||
spdxId = "NCSA";
|
spdxId = "NCSA";
|
||||||
fullName = "University of Illinois/NCSA Open Source License";
|
fullName = "University of Illinois/NCSA Open Source License";
|
||||||
@ -691,7 +706,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
wxWindows = spdx {
|
wxWindows = spdx {
|
||||||
spdxId = "WXwindows";
|
spdxId = "wxWindows";
|
||||||
fullName = "wxWindows Library Licence, Version 3.1";
|
fullName = "wxWindows Library Licence, Version 3.1";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -236,6 +236,26 @@ rec {
|
|||||||
in lenContent >= lenSuffix &&
|
in lenContent >= lenSuffix &&
|
||||||
substring (lenContent - lenSuffix) lenContent content == suffix;
|
substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||||
|
|
||||||
|
/* Determine whether a string contains the given infix
|
||||||
|
|
||||||
|
Type: hasInfix :: string -> string -> bool
|
||||||
|
|
||||||
|
Example:
|
||||||
|
hasInfix "bc" "abcd"
|
||||||
|
=> true
|
||||||
|
hasInfix "ab" "abcd"
|
||||||
|
=> true
|
||||||
|
hasInfix "cd" "abcd"
|
||||||
|
=> true
|
||||||
|
hasInfix "foo" "abcd"
|
||||||
|
=> false
|
||||||
|
*/
|
||||||
|
hasInfix = infix: content:
|
||||||
|
let
|
||||||
|
drop = x: substring 1 (stringLength x) x;
|
||||||
|
in hasPrefix infix content
|
||||||
|
|| content != "" && hasInfix infix (drop content);
|
||||||
|
|
||||||
/* Convert a string to a list of characters (i.e. singleton strings).
|
/* Convert a string to a list of characters (i.e. singleton strings).
|
||||||
This allows you to, e.g., map a function over each character. However,
|
This allows you to, e.g., map a function over each character. However,
|
||||||
note that this will likely be horribly inefficient; Nix is not a
|
note that this will likely be horribly inefficient; Nix is not a
|
||||||
|
@ -66,6 +66,46 @@ rec {
|
|||||||
# uname -r
|
# uname -r
|
||||||
release = null;
|
release = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
qemuArch =
|
||||||
|
if final.isArm then "arm"
|
||||||
|
else if final.isx86_64 then "x86_64"
|
||||||
|
else if final.isx86 then "i386"
|
||||||
|
else {
|
||||||
|
"powerpc" = "ppc";
|
||||||
|
"powerpc64" = "ppc64";
|
||||||
|
"powerpc64le" = "ppc64";
|
||||||
|
"mips64" = "mips";
|
||||||
|
"mipsel64" = "mipsel";
|
||||||
|
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
|
||||||
|
|
||||||
|
emulator = pkgs: let
|
||||||
|
qemu-user = pkgs.qemu.override {
|
||||||
|
smartcardSupport = false;
|
||||||
|
spiceSupport = false;
|
||||||
|
openGLSupport = false;
|
||||||
|
virglSupport = false;
|
||||||
|
vncSupport = false;
|
||||||
|
gtkSupport = false;
|
||||||
|
sdlSupport = false;
|
||||||
|
pulseSupport = false;
|
||||||
|
smbdSupport = false;
|
||||||
|
seccompSupport = false;
|
||||||
|
hostCpuTargets = ["${final.qemuArch}-linux-user"];
|
||||||
|
};
|
||||||
|
wine-name = "wine${toString final.parsed.cpu.bits}";
|
||||||
|
wine = (pkgs.winePackagesFor wine-name).minimal;
|
||||||
|
in
|
||||||
|
if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name &&
|
||||||
|
(final.parsed.cpu.name == pkgs.stdenv.hostPlatform.parsed.cpu.name ||
|
||||||
|
(final.platform.isi686 && pkgs.stdenv.hostPlatform.isx86_64))
|
||||||
|
then pkgs.runtimeShell
|
||||||
|
else if final.isWindows
|
||||||
|
then "${wine}/bin/${wine-name}"
|
||||||
|
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
|
||||||
|
then "${qemu-user}/bin/qemu-${final.qemuArch}"
|
||||||
|
else throw "Don't know how to run ${final.config} executables.";
|
||||||
|
|
||||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
// args;
|
// args;
|
||||||
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||||
|
@ -2,7 +2,14 @@
|
|||||||
# `crossSystem`. They are put here for user convenience, but also used by cross
|
# `crossSystem`. They are put here for user convenience, but also used by cross
|
||||||
# tests and linux cross stdenv building, so handle with care!
|
# tests and linux cross stdenv building, so handle with care!
|
||||||
{ lib }:
|
{ lib }:
|
||||||
let platforms = import ./platforms.nix { inherit lib; }; in
|
let
|
||||||
|
platforms = import ./platforms.nix { inherit lib; };
|
||||||
|
|
||||||
|
riscv = bits: {
|
||||||
|
config = "riscv${bits}-unknown-linux-gnu";
|
||||||
|
platform = platforms.riscv-multiplatform bits;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
#
|
#
|
||||||
@ -40,7 +47,7 @@ rec {
|
|||||||
armv5te-android-prebuilt = rec {
|
armv5te-android-prebuilt = rec {
|
||||||
config = "armv5tel-unknown-linux-androideabi";
|
config = "armv5tel-unknown-linux-androideabi";
|
||||||
sdkVer = "21";
|
sdkVer = "21";
|
||||||
ndkVer = "10e";
|
ndkVer = "18b";
|
||||||
platform = platforms.armv5te-android;
|
platform = platforms.armv5te-android;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
};
|
};
|
||||||
@ -48,7 +55,7 @@ rec {
|
|||||||
armv7a-android-prebuilt = rec {
|
armv7a-android-prebuilt = rec {
|
||||||
config = "armv7a-unknown-linux-androideabi";
|
config = "armv7a-unknown-linux-androideabi";
|
||||||
sdkVer = "24";
|
sdkVer = "24";
|
||||||
ndkVer = "17c";
|
ndkVer = "18b";
|
||||||
platform = platforms.armv7a-android;
|
platform = platforms.armv7a-android;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
};
|
};
|
||||||
@ -56,7 +63,7 @@ rec {
|
|||||||
aarch64-android-prebuilt = rec {
|
aarch64-android-prebuilt = rec {
|
||||||
config = "aarch64-unknown-linux-android";
|
config = "aarch64-unknown-linux-android";
|
||||||
sdkVer = "24";
|
sdkVer = "24";
|
||||||
ndkVer = "17c";
|
ndkVer = "18b";
|
||||||
platform = platforms.aarch64-multiplatform;
|
platform = platforms.aarch64-multiplatform;
|
||||||
useAndroidPrebuilt = true;
|
useAndroidPrebuilt = true;
|
||||||
};
|
};
|
||||||
@ -92,10 +99,6 @@ rec {
|
|||||||
musl64 = { config = "x86_64-unknown-linux-musl"; };
|
musl64 = { config = "x86_64-unknown-linux-musl"; };
|
||||||
musl32 = { config = "i686-unknown-linux-musl"; };
|
musl32 = { config = "i686-unknown-linux-musl"; };
|
||||||
|
|
||||||
riscv = bits: {
|
|
||||||
config = "riscv${bits}-unknown-linux-gnu";
|
|
||||||
platform = platforms.riscv-multiplatform bits;
|
|
||||||
};
|
|
||||||
riscv64 = riscv "64";
|
riscv64 = riscv "64";
|
||||||
riscv32 = riscv "32";
|
riscv32 = riscv "32";
|
||||||
|
|
||||||
@ -107,6 +110,10 @@ rec {
|
|||||||
config = "arm-none-eabi";
|
config = "arm-none-eabi";
|
||||||
libc = "newlib";
|
libc = "newlib";
|
||||||
};
|
};
|
||||||
|
armhf-embedded = {
|
||||||
|
config = "arm-none-eabihf";
|
||||||
|
libc = "newlib";
|
||||||
|
};
|
||||||
|
|
||||||
aarch64-embedded = {
|
aarch64-embedded = {
|
||||||
config = "aarch64-none-elf";
|
config = "aarch64-none-elf";
|
||||||
|
@ -209,8 +209,15 @@ rec {
|
|||||||
abis = setTypes types.openAbi {
|
abis = setTypes types.openAbi {
|
||||||
cygnus = {};
|
cygnus = {};
|
||||||
msvc = {};
|
msvc = {};
|
||||||
eabi = {};
|
|
||||||
elf = {};
|
# Note: eabi is specific to ARM and PowerPC.
|
||||||
|
# On PowerPC, this corresponds to PPCEABI.
|
||||||
|
# On ARM, this corresponds to ARMEABI.
|
||||||
|
eabi = { float = "soft"; };
|
||||||
|
eabihf = { float = "hard"; };
|
||||||
|
|
||||||
|
# Other architectures should use ELF in embedded situations.
|
||||||
|
elf = {};
|
||||||
|
|
||||||
androideabi = {};
|
androideabi = {};
|
||||||
android = {
|
android = {
|
||||||
@ -272,10 +279,8 @@ rec {
|
|||||||
"2" = # We only do 2-part hacks for things Nix already supports
|
"2" = # We only do 2-part hacks for things Nix already supports
|
||||||
if elemAt l 1 == "cygwin"
|
if elemAt l 1 == "cygwin"
|
||||||
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
|
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
|
||||||
else if (elemAt l 1 == "eabi")
|
else if (elemAt l 1) == "elf"
|
||||||
then { cpu = elemAt l 0; vendor = "none"; kernel = "none"; abi = elemAt l 1; }
|
then { cpu = elemAt l 0; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; }
|
||||||
else if (elemAt l 1 == "elf")
|
|
||||||
then { cpu = elemAt l 0; vendor = "none"; kernel = "none"; abi = elemAt l 1; }
|
|
||||||
else { cpu = elemAt l 0; kernel = elemAt l 1; };
|
else { cpu = elemAt l 0; kernel = elemAt l 1; };
|
||||||
"3" = # Awkwards hacks, beware!
|
"3" = # Awkwards hacks, beware!
|
||||||
if elemAt l 1 == "apple"
|
if elemAt l 1 == "apple"
|
||||||
@ -286,10 +291,8 @@ rec {
|
|||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
|
||||||
else if hasPrefix "netbsd" (elemAt l 2)
|
else if hasPrefix "netbsd" (elemAt l 2)
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
|
||||||
else if (elemAt l 2 == "eabi")
|
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "none"; abi = elemAt l 2; }
|
then { cpu = elemAt l 0; vendor = "unknown"; kernel = elemAt l 1; abi = elemAt l 2; }
|
||||||
else if (elemAt l 2 == "elf")
|
|
||||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "none"; abi = elemAt l 2; }
|
|
||||||
else throw "Target specification with 3 components is ambiguous";
|
else throw "Target specification with 3 components is ambiguous";
|
||||||
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
|
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
|
||||||
}.${toString (length l)}
|
}.${toString (length l)}
|
||||||
|
@ -256,6 +256,11 @@
|
|||||||
github = "AndrewMorsillo";
|
github = "AndrewMorsillo";
|
||||||
name = "Andrew Morsillo";
|
name = "Andrew Morsillo";
|
||||||
};
|
};
|
||||||
|
andersk = {
|
||||||
|
email = "andersk@mit.edu";
|
||||||
|
github = "andersk";
|
||||||
|
name = "Anders Kaseorg";
|
||||||
|
};
|
||||||
AndersonTorres = {
|
AndersonTorres = {
|
||||||
email = "torres.anderson.85@protonmail.com";
|
email = "torres.anderson.85@protonmail.com";
|
||||||
github = "AndersonTorres";
|
github = "AndersonTorres";
|
||||||
@ -401,6 +406,11 @@
|
|||||||
github = "aszlig";
|
github = "aszlig";
|
||||||
name = "aszlig";
|
name = "aszlig";
|
||||||
};
|
};
|
||||||
|
atnnn = {
|
||||||
|
email = "etienne@atnnn.com";
|
||||||
|
github = "atnnn";
|
||||||
|
name = "Etienne Laurin";
|
||||||
|
};
|
||||||
auntie = {
|
auntie = {
|
||||||
email = "auntieNeo@gmail.com";
|
email = "auntieNeo@gmail.com";
|
||||||
github = "auntie";
|
github = "auntie";
|
||||||
@ -1319,6 +1329,11 @@
|
|||||||
github = "ellis";
|
github = "ellis";
|
||||||
name = "Ellis Whitehead";
|
name = "Ellis Whitehead";
|
||||||
};
|
};
|
||||||
|
elohmeier = {
|
||||||
|
email = "elo-nixos@nerdworks.de";
|
||||||
|
github = "elohmeier";
|
||||||
|
name = "Enno Lohmeier";
|
||||||
|
};
|
||||||
elseym = {
|
elseym = {
|
||||||
email = "elseym@me.com";
|
email = "elseym@me.com";
|
||||||
github = "elseym";
|
github = "elseym";
|
||||||
@ -1889,6 +1904,11 @@
|
|||||||
github = "ironpinguin";
|
github = "ironpinguin";
|
||||||
name = "Michele Catalano";
|
name = "Michele Catalano";
|
||||||
};
|
};
|
||||||
|
ivan = {
|
||||||
|
email = "ivan@ludios.org";
|
||||||
|
github = "ivan";
|
||||||
|
name = "Ivan Kozik";
|
||||||
|
};
|
||||||
ivan-tkatchev = {
|
ivan-tkatchev = {
|
||||||
email = "tkatchev@gmail.com";
|
email = "tkatchev@gmail.com";
|
||||||
name = "Ivan Tkatchev";
|
name = "Ivan Tkatchev";
|
||||||
@ -1918,6 +1938,11 @@
|
|||||||
github = "jagajaga";
|
github = "jagajaga";
|
||||||
name = "Arseniy Seroka";
|
name = "Arseniy Seroka";
|
||||||
};
|
};
|
||||||
|
jakelogemann = {
|
||||||
|
email = "jake.logemann@gmail.com";
|
||||||
|
github = "jakelogemann";
|
||||||
|
name = "Jake Logemann";
|
||||||
|
};
|
||||||
jammerful = {
|
jammerful = {
|
||||||
email = "jammerful@gmail.com";
|
email = "jammerful@gmail.com";
|
||||||
github = "jammerful";
|
github = "jammerful";
|
||||||
@ -2052,6 +2077,11 @@
|
|||||||
github = "jluttine";
|
github = "jluttine";
|
||||||
name = "Jaakko Luttinen";
|
name = "Jaakko Luttinen";
|
||||||
};
|
};
|
||||||
|
jmagnusj = {
|
||||||
|
email = "jmagnusj@gmail.com";
|
||||||
|
github = "magnusjonsson";
|
||||||
|
name = "Johan Magnus Jonsson";
|
||||||
|
};
|
||||||
jmettes = {
|
jmettes = {
|
||||||
email = "jonathan@jmettes.com";
|
email = "jonathan@jmettes.com";
|
||||||
github = "jmettes";
|
github = "jmettes";
|
||||||
@ -2459,6 +2489,11 @@
|
|||||||
github = "listx";
|
github = "listx";
|
||||||
name = "Linus Arver";
|
name = "Linus Arver";
|
||||||
};
|
};
|
||||||
|
lionello = {
|
||||||
|
email = "lio@lunesu.com";
|
||||||
|
github = "lionello";
|
||||||
|
name = "Lionello Lunesu";
|
||||||
|
};
|
||||||
lluchs = {
|
lluchs = {
|
||||||
email = "lukas.werling@gmail.com";
|
email = "lukas.werling@gmail.com";
|
||||||
github = "lluchs";
|
github = "lluchs";
|
||||||
@ -3404,6 +3439,11 @@
|
|||||||
github = "pkmx";
|
github = "pkmx";
|
||||||
name = "Chih-Mao Chen";
|
name = "Chih-Mao Chen";
|
||||||
};
|
};
|
||||||
|
plchldr = {
|
||||||
|
email = "mail@oddco.de";
|
||||||
|
github = "plchldr";
|
||||||
|
name = "Jonas Beyer";
|
||||||
|
};
|
||||||
plcplc = {
|
plcplc = {
|
||||||
email = "plcplc@gmail.com";
|
email = "plcplc@gmail.com";
|
||||||
github = "plcplc";
|
github = "plcplc";
|
||||||
@ -3856,6 +3896,11 @@
|
|||||||
github = "sboosali";
|
github = "sboosali";
|
||||||
name = "Sam Boosalis";
|
name = "Sam Boosalis";
|
||||||
};
|
};
|
||||||
|
scalavision = {
|
||||||
|
email = "scalavision@gmail.com";
|
||||||
|
github = "scalavision";
|
||||||
|
name = "Tom Sorlie";
|
||||||
|
};
|
||||||
schmitthenner = {
|
schmitthenner = {
|
||||||
email = "development@schmitthenner.eu";
|
email = "development@schmitthenner.eu";
|
||||||
github = "fkz";
|
github = "fkz";
|
||||||
@ -3925,6 +3970,11 @@
|
|||||||
github = "seppeljordan";
|
github = "seppeljordan";
|
||||||
name = "Sebastian Jordan";
|
name = "Sebastian Jordan";
|
||||||
};
|
};
|
||||||
|
seqizz = {
|
||||||
|
email = "seqizz@gmail.com";
|
||||||
|
github = "seqizz";
|
||||||
|
name = "Gurkan Gur";
|
||||||
|
};
|
||||||
sfrijters = {
|
sfrijters = {
|
||||||
email = "sfrijters@gmail.com";
|
email = "sfrijters@gmail.com";
|
||||||
github = "sfrijters";
|
github = "sfrijters";
|
||||||
@ -4258,6 +4308,11 @@
|
|||||||
github = "talyz";
|
github = "talyz";
|
||||||
name = "Kim Lindberger";
|
name = "Kim Lindberger";
|
||||||
};
|
};
|
||||||
|
taneb = {
|
||||||
|
email = "nvd1234@gmail.com";
|
||||||
|
github = "Taneb";
|
||||||
|
name = "Nathan van Doorn";
|
||||||
|
};
|
||||||
tari = {
|
tari = {
|
||||||
email = "peter@taricorp.net";
|
email = "peter@taricorp.net";
|
||||||
github = "tari";
|
github = "tari";
|
||||||
|
@ -1,361 +1,5 @@
|
|||||||
#! /usr/bin/env nix-shell
|
#!/bin/sh
|
||||||
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
|
build=`nix-build -E "with import (fetchTarball "channel:nixpkgs-unstable") {}; python3.withPackages(ps: with ps; [ packaging requests toolz ])"`
|
||||||
|
python=${build}/bin/python
|
||||||
|
exec ${python} pkgs/development/interpreters/python/update-python-libraries/update-python-libraries.py $@
|
||||||
|
|
||||||
"""
|
|
||||||
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
|
||||||
You can pass in multiple files or paths.
|
|
||||||
|
|
||||||
You'll likely want to use
|
|
||||||
``
|
|
||||||
$ ./update-python-libraries ../../pkgs/development/python-modules/*
|
|
||||||
``
|
|
||||||
to update all libraries in that folder.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import requests
|
|
||||||
import toolz
|
|
||||||
from concurrent.futures import ThreadPoolExecutor as Pool
|
|
||||||
from packaging.version import Version as _Version
|
|
||||||
from packaging.version import InvalidVersion
|
|
||||||
from packaging.specifiers import SpecifierSet
|
|
||||||
import collections
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
INDEX = "https://pypi.io/pypi"
|
|
||||||
"""url of PyPI"""
|
|
||||||
|
|
||||||
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip', '.whl']
|
|
||||||
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
|
||||||
|
|
||||||
PRERELEASES = False
|
|
||||||
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
class Version(_Version, collections.abc.Sequence):
|
|
||||||
|
|
||||||
def __init__(self, version):
|
|
||||||
super().__init__(version)
|
|
||||||
# We cannot use `str(Version(0.04.21))` because that becomes `0.4.21`
|
|
||||||
# https://github.com/avian2/unidecode/issues/13#issuecomment-354538882
|
|
||||||
self.raw_version = version
|
|
||||||
|
|
||||||
def __getitem__(self, i):
|
|
||||||
return self._version.release[i]
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._version.release)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
yield from self._version.release
|
|
||||||
|
|
||||||
|
|
||||||
def _get_values(attribute, text):
|
|
||||||
"""Match attribute in text and return all matches.
|
|
||||||
|
|
||||||
:returns: List of matches.
|
|
||||||
"""
|
|
||||||
regex = '{}\s+=\s+"(.*)";'.format(attribute)
|
|
||||||
regex = re.compile(regex)
|
|
||||||
values = regex.findall(text)
|
|
||||||
return values
|
|
||||||
|
|
||||||
def _get_unique_value(attribute, text):
|
|
||||||
"""Match attribute in text and return unique match.
|
|
||||||
|
|
||||||
:returns: Single match.
|
|
||||||
"""
|
|
||||||
values = _get_values(attribute, text)
|
|
||||||
n = len(values)
|
|
||||||
if n > 1:
|
|
||||||
raise ValueError("found too many values for {}".format(attribute))
|
|
||||||
elif n == 1:
|
|
||||||
return values[0]
|
|
||||||
else:
|
|
||||||
raise ValueError("no value found for {}".format(attribute))
|
|
||||||
|
|
||||||
def _get_line_and_value(attribute, text):
|
|
||||||
"""Match attribute in text. Return the line and the value of the attribute."""
|
|
||||||
regex = '({}\s+=\s+"(.*)";)'.format(attribute)
|
|
||||||
regex = re.compile(regex)
|
|
||||||
value = regex.findall(text)
|
|
||||||
n = len(value)
|
|
||||||
if n > 1:
|
|
||||||
raise ValueError("found too many values for {}".format(attribute))
|
|
||||||
elif n == 1:
|
|
||||||
return value[0]
|
|
||||||
else:
|
|
||||||
raise ValueError("no value found for {}".format(attribute))
|
|
||||||
|
|
||||||
|
|
||||||
def _replace_value(attribute, value, text):
|
|
||||||
"""Search and replace value of attribute in text."""
|
|
||||||
old_line, old_value = _get_line_and_value(attribute, text)
|
|
||||||
new_line = old_line.replace(old_value, value)
|
|
||||||
new_text = text.replace(old_line, new_line)
|
|
||||||
return new_text
|
|
||||||
|
|
||||||
def _fetch_page(url):
|
|
||||||
r = requests.get(url)
|
|
||||||
if r.status_code == requests.codes.ok:
|
|
||||||
return r.json()
|
|
||||||
else:
|
|
||||||
raise ValueError("request for {} failed".format(url))
|
|
||||||
|
|
||||||
|
|
||||||
SEMVER = {
|
|
||||||
'major' : 0,
|
|
||||||
'minor' : 1,
|
|
||||||
'patch' : 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _determine_latest_version(current_version, target, versions):
|
|
||||||
"""Determine latest version, given `target`.
|
|
||||||
"""
|
|
||||||
current_version = Version(current_version)
|
|
||||||
|
|
||||||
def _parse_versions(versions):
|
|
||||||
for v in versions:
|
|
||||||
try:
|
|
||||||
yield Version(v)
|
|
||||||
except InvalidVersion:
|
|
||||||
pass
|
|
||||||
|
|
||||||
versions = _parse_versions(versions)
|
|
||||||
|
|
||||||
index = SEMVER[target]
|
|
||||||
|
|
||||||
ceiling = list(current_version[0:index])
|
|
||||||
if len(ceiling) == 0:
|
|
||||||
ceiling = None
|
|
||||||
else:
|
|
||||||
ceiling[-1]+=1
|
|
||||||
ceiling = Version(".".join(map(str, ceiling)))
|
|
||||||
|
|
||||||
# We do not want prereleases
|
|
||||||
versions = SpecifierSet(prereleases=PRERELEASES).filter(versions)
|
|
||||||
|
|
||||||
if ceiling is not None:
|
|
||||||
versions = SpecifierSet(f"<{ceiling}").filter(versions)
|
|
||||||
|
|
||||||
return (max(sorted(versions))).raw_version
|
|
||||||
|
|
||||||
|
|
||||||
def _get_latest_version_pypi(package, extension, current_version, target):
|
|
||||||
"""Get latest version and hash from PyPI."""
|
|
||||||
url = "{}/{}/json".format(INDEX, package)
|
|
||||||
json = _fetch_page(url)
|
|
||||||
|
|
||||||
versions = json['releases'].keys()
|
|
||||||
version = _determine_latest_version(current_version, target, versions)
|
|
||||||
|
|
||||||
try:
|
|
||||||
releases = json['releases'][version]
|
|
||||||
except KeyError as e:
|
|
||||||
raise KeyError('Could not find version {} for {}'.format(version, package)) from e
|
|
||||||
for release in releases:
|
|
||||||
if release['filename'].endswith(extension):
|
|
||||||
# TODO: In case of wheel we need to do further checks!
|
|
||||||
sha256 = release['digests']['sha256']
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
sha256 = None
|
|
||||||
return version, sha256
|
|
||||||
|
|
||||||
|
|
||||||
def _get_latest_version_github(package, extension, current_version, target):
|
|
||||||
raise ValueError("updating from GitHub is not yet supported.")
|
|
||||||
|
|
||||||
|
|
||||||
FETCHERS = {
|
|
||||||
'fetchFromGitHub' : _get_latest_version_github,
|
|
||||||
'fetchPypi' : _get_latest_version_pypi,
|
|
||||||
'fetchurl' : _get_latest_version_pypi,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_SETUPTOOLS_EXTENSION = 'tar.gz'
|
|
||||||
|
|
||||||
|
|
||||||
FORMATS = {
|
|
||||||
'setuptools' : DEFAULT_SETUPTOOLS_EXTENSION,
|
|
||||||
'wheel' : 'whl'
|
|
||||||
}
|
|
||||||
|
|
||||||
def _determine_fetcher(text):
|
|
||||||
# Count occurences of fetchers.
|
|
||||||
nfetchers = sum(text.count('src = {}'.format(fetcher)) for fetcher in FETCHERS.keys())
|
|
||||||
if nfetchers == 0:
|
|
||||||
raise ValueError("no fetcher.")
|
|
||||||
elif nfetchers > 1:
|
|
||||||
raise ValueError("multiple fetchers.")
|
|
||||||
else:
|
|
||||||
# Then we check which fetcher to use.
|
|
||||||
for fetcher in FETCHERS.keys():
|
|
||||||
if 'src = {}'.format(fetcher) in text:
|
|
||||||
return fetcher
|
|
||||||
|
|
||||||
|
|
||||||
def _determine_extension(text, fetcher):
|
|
||||||
"""Determine what extension is used in the expression.
|
|
||||||
|
|
||||||
If we use:
|
|
||||||
- fetchPypi, we check if format is specified.
|
|
||||||
- fetchurl, we determine the extension from the url.
|
|
||||||
- fetchFromGitHub we simply use `.tar.gz`.
|
|
||||||
"""
|
|
||||||
if fetcher == 'fetchPypi':
|
|
||||||
try:
|
|
||||||
src_format = _get_unique_value('format', text)
|
|
||||||
except ValueError as e:
|
|
||||||
src_format = None # format was not given
|
|
||||||
|
|
||||||
try:
|
|
||||||
extension = _get_unique_value('extension', text)
|
|
||||||
except ValueError as e:
|
|
||||||
extension = None # extension was not given
|
|
||||||
|
|
||||||
if extension is None:
|
|
||||||
if src_format is None:
|
|
||||||
src_format = 'setuptools'
|
|
||||||
elif src_format == 'flit':
|
|
||||||
raise ValueError("Don't know how to update a Flit package.")
|
|
||||||
extension = FORMATS[src_format]
|
|
||||||
|
|
||||||
elif fetcher == 'fetchurl':
|
|
||||||
url = _get_unique_value('url', text)
|
|
||||||
extension = os.path.splitext(url)[1]
|
|
||||||
if 'pypi' not in url:
|
|
||||||
raise ValueError('url does not point to PyPI.')
|
|
||||||
|
|
||||||
elif fetcher == 'fetchFromGitHub':
|
|
||||||
raise ValueError('updating from GitHub is not yet implemented.')
|
|
||||||
|
|
||||||
return extension
|
|
||||||
|
|
||||||
|
|
||||||
def _update_package(path, target):
|
|
||||||
|
|
||||||
# Read the expression
|
|
||||||
with open(path, 'r') as f:
|
|
||||||
text = f.read()
|
|
||||||
|
|
||||||
# Determine pname.
|
|
||||||
pname = _get_unique_value('pname', text)
|
|
||||||
|
|
||||||
# Determine version.
|
|
||||||
version = _get_unique_value('version', text)
|
|
||||||
|
|
||||||
# First we check how many fetchers are mentioned.
|
|
||||||
fetcher = _determine_fetcher(text)
|
|
||||||
|
|
||||||
extension = _determine_extension(text, fetcher)
|
|
||||||
|
|
||||||
new_version, new_sha256 = FETCHERS[fetcher](pname, extension, version, target)
|
|
||||||
|
|
||||||
if new_version == version:
|
|
||||||
logging.info("Path {}: no update available for {}.".format(path, pname))
|
|
||||||
return False
|
|
||||||
elif Version(new_version) <= Version(version):
|
|
||||||
raise ValueError("downgrade for {}.".format(pname))
|
|
||||||
if not new_sha256:
|
|
||||||
raise ValueError("no file available for {}.".format(pname))
|
|
||||||
|
|
||||||
text = _replace_value('version', new_version, text)
|
|
||||||
text = _replace_value('sha256', new_sha256, text)
|
|
||||||
|
|
||||||
with open(path, 'w') as f:
|
|
||||||
f.write(text)
|
|
||||||
|
|
||||||
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
|
||||||
|
|
||||||
result = {
|
|
||||||
'path' : path,
|
|
||||||
'target': target,
|
|
||||||
'pname': pname,
|
|
||||||
'old_version' : version,
|
|
||||||
'new_version' : new_version,
|
|
||||||
#'fetcher' : fetcher,
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def _update(path, target):
|
|
||||||
|
|
||||||
# We need to read and modify a Nix expression.
|
|
||||||
if os.path.isdir(path):
|
|
||||||
path = os.path.join(path, 'default.nix')
|
|
||||||
|
|
||||||
# If a default.nix does not exist, we quit.
|
|
||||||
if not os.path.isfile(path):
|
|
||||||
logging.info("Path {}: does not exist.".format(path))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# If file is not a Nix expression, we quit.
|
|
||||||
if not path.endswith(".nix"):
|
|
||||||
logging.info("Path {}: does not end with `.nix`.".format(path))
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
return _update_package(path, target)
|
|
||||||
except ValueError as e:
|
|
||||||
logging.warning("Path {}: {}".format(path, e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _commit(path, pname, old_version, new_version, **kwargs):
|
|
||||||
"""Commit result.
|
|
||||||
"""
|
|
||||||
|
|
||||||
msg = f'python: {pname}: {old_version} -> {new_version}'
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call(['git', 'add', path])
|
|
||||||
subprocess.check_call(['git', 'commit', '-m', msg])
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
subprocess.check_call(['git', 'checkout', path])
|
|
||||||
raise subprocess.CalledProcessError(f'Could not commit {path}') from e
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('package', type=str, nargs='+')
|
|
||||||
parser.add_argument('--target', type=str, choices=SEMVER.keys(), default='major')
|
|
||||||
parser.add_argument('--commit', action='store_true', help='Create a commit for each package update')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
target = args.target
|
|
||||||
|
|
||||||
packages = list(map(os.path.abspath, args.package))
|
|
||||||
|
|
||||||
logging.info("Updating packages...")
|
|
||||||
|
|
||||||
# Use threads to update packages concurrently
|
|
||||||
with Pool() as p:
|
|
||||||
results = list(p.map(lambda pkg: _update(pkg, target), packages))
|
|
||||||
|
|
||||||
logging.info("Finished updating packages.")
|
|
||||||
|
|
||||||
# Commits are created sequentially.
|
|
||||||
if args.commit:
|
|
||||||
logging.info("Committing updates...")
|
|
||||||
list(map(lambda x: _commit(**x), filter(bool, results)))
|
|
||||||
logging.info("Finished committing updates")
|
|
||||||
|
|
||||||
count = sum(map(bool, results))
|
|
||||||
logging.info("{} package(s) updated".format(count))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{ package ? null
|
{ package ? null
|
||||||
, maintainer ? null
|
, maintainer ? null
|
||||||
, path ? null
|
, path ? null
|
||||||
|
, max-workers ? null
|
||||||
|
, keep-going ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
# TODO: add assert statements
|
# TODO: add assert statements
|
||||||
@ -105,26 +107,23 @@ let
|
|||||||
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
|
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
|
||||||
|
|
||||||
to run update script for all package under an attribute path.
|
to run update script for all package under an attribute path.
|
||||||
|
|
||||||
|
You can also add
|
||||||
|
|
||||||
|
--argstr max-workers 8
|
||||||
|
|
||||||
|
to increase the number of jobs in parallel, or
|
||||||
|
|
||||||
|
--argstr keep-going true
|
||||||
|
|
||||||
|
to continue running when a single update fails.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
runUpdateScript = package: ''
|
packageData = package: {
|
||||||
echo -ne " - ${package.name}: UPDATING ..."\\r
|
name = package.name;
|
||||||
${package.updateScript} &> ${(builtins.parseDrvName package.name).name}.log
|
pname = (builtins.parseDrvName package.name).name;
|
||||||
CODE=$?
|
updateScript = pkgs.lib.toList package.updateScript;
|
||||||
if [ "$CODE" != "0" ]; then
|
};
|
||||||
echo " - ${package.name}: ERROR "
|
|
||||||
echo ""
|
|
||||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
|
||||||
echo ""
|
|
||||||
cat ${(builtins.parseDrvName package.name).name}.log
|
|
||||||
echo ""
|
|
||||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
|
||||||
exit $CODE
|
|
||||||
else
|
|
||||||
rm ${(builtins.parseDrvName package.name).name}.log
|
|
||||||
fi
|
|
||||||
echo " - ${package.name}: DONE. "
|
|
||||||
'';
|
|
||||||
|
|
||||||
in pkgs.stdenv.mkDerivation {
|
in pkgs.stdenv.mkDerivation {
|
||||||
name = "nixpkgs-update-script";
|
name = "nixpkgs-update-script";
|
||||||
@ -139,21 +138,7 @@ in pkgs.stdenv.mkDerivation {
|
|||||||
exit 1
|
exit 1
|
||||||
'';
|
'';
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
echo ""
|
unset shellHook # do not contaminate nested shells
|
||||||
echo "Going to be running update for following packages:"
|
exec ${pkgs.python3.interpreter} ${./update.py} ${pkgs.writeText "packages.json" (builtins.toJSON (map packageData packages))}${pkgs.lib.optionalString (max-workers != null) " --max-workers=${max-workers}"}${pkgs.lib.optionalString (keep-going == "true") " --keep-going"}
|
||||||
echo "${builtins.concatStringsSep "\n" (map (x: " - ${x.name}") packages)}"
|
|
||||||
echo ""
|
|
||||||
read -n1 -r -p "Press space to continue..." confirm
|
|
||||||
if [ "$confirm" = "" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "Running update for:"
|
|
||||||
${builtins.concatStringsSep "\n" (map runUpdateScript packages)}
|
|
||||||
echo ""
|
|
||||||
echo "Packages updated!"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "Aborting!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
79
maintainers/scripts/update.py
Normal file
79
maintainers/scripts/update.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import argparse
|
||||||
|
import concurrent.futures
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
updates = {}
|
||||||
|
|
||||||
|
def eprint(*args, **kwargs):
|
||||||
|
print(*args, file=sys.stderr, **kwargs)
|
||||||
|
|
||||||
|
def run_update_script(package):
|
||||||
|
eprint(f" - {package['name']}: UPDATING ...")
|
||||||
|
|
||||||
|
subprocess.run(package['updateScript'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def main(max_workers, keep_going, packages):
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
packages = json.load(f)
|
||||||
|
|
||||||
|
eprint()
|
||||||
|
eprint('Going to be running update for following packages:')
|
||||||
|
for package in packages:
|
||||||
|
eprint(f" - {package['name']}")
|
||||||
|
eprint()
|
||||||
|
|
||||||
|
confirm = input('Press Enter key to continue...')
|
||||||
|
if confirm == '':
|
||||||
|
eprint()
|
||||||
|
eprint('Running update for:')
|
||||||
|
|
||||||
|
with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
|
||||||
|
for package in packages:
|
||||||
|
updates[executor.submit(run_update_script, package)] = package
|
||||||
|
|
||||||
|
for future in concurrent.futures.as_completed(updates):
|
||||||
|
package = updates[future]
|
||||||
|
|
||||||
|
try:
|
||||||
|
future.result()
|
||||||
|
eprint(f" - {package['name']}: DONE.")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
eprint(f" - {package['name']}: ERROR")
|
||||||
|
eprint()
|
||||||
|
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||||
|
eprint()
|
||||||
|
eprint(e.stdout.decode('utf-8'))
|
||||||
|
with open(f"{package['pname']}.log", 'wb') as f:
|
||||||
|
f.write(e.stdout)
|
||||||
|
eprint()
|
||||||
|
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||||
|
|
||||||
|
if not keep_going:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
eprint()
|
||||||
|
eprint('Packages updated!')
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
eprint('Aborting!')
|
||||||
|
sys.exit(130)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Update packages')
|
||||||
|
parser.add_argument('--max-workers', '-j', dest='max_workers', type=int, help='Number of updates to run concurrently', nargs='?', default=4)
|
||||||
|
parser.add_argument('--keep-going', '-k', dest='keep_going', action='store_true', help='Do not stop after first failure')
|
||||||
|
parser.add_argument('packages', help='JSON file containing the list of package names and their update scripts')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
main(args.max_workers, args.keep_going, args.packages)
|
||||||
|
except (KeyboardInterrupt, SystemExit) as e:
|
||||||
|
for update in updates:
|
||||||
|
update.cancel()
|
||||||
|
|
||||||
|
sys.exit(e.code if isinstance(e, SystemExit) else 130)
|
@ -31,7 +31,7 @@ $ cd nixpkgs
|
|||||||
<para>
|
<para>
|
||||||
The second possibility is to add the package outside of the Nixpkgs tree. For
|
The second possibility is to add the package outside of the Nixpkgs tree. For
|
||||||
instance, here is how you specify a build of the
|
instance, here is how you specify a build of the
|
||||||
<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>
|
<link xlink:href="https://www.gnu.org/software/hello/">GNU Hello</link>
|
||||||
package directly in <filename>configuration.nix</filename>:
|
package directly in <filename>configuration.nix</filename>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<xref linkend="opt-environment.systemPackages"/> =
|
<xref linkend="opt-environment.systemPackages"/> =
|
||||||
|
@ -113,12 +113,10 @@ $ nixos-option <xref linkend="opt-boot.kernelModules"/>
|
|||||||
[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ]
|
[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ]
|
||||||
</screen>
|
</screen>
|
||||||
Interactive exploration of the configuration is possible using
|
Interactive exploration of the configuration is possible using
|
||||||
<command
|
<command>nix repl</command>, a read-eval-print loop for Nix expressions.
|
||||||
xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>,
|
A typical use:
|
||||||
a read-eval-print loop for Nix expressions. It’s not installed by default;
|
|
||||||
run <literal>nix-env -i nix-repl</literal> to get it. A typical use:
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-repl '<nixpkgs/nixos>'
|
$ nix repl '<nixpkgs/nixos>'
|
||||||
|
|
||||||
nix-repl> config.<xref linkend="opt-networking.hostName"/>
|
nix-repl> config.<xref linkend="opt-networking.hostName"/>
|
||||||
"mandark"
|
"mandark"
|
||||||
@ -127,4 +125,23 @@ nix-repl> map (x: x.hostName) config.<xref linkend="opt-services.httpd.virtualHo
|
|||||||
[ "example.org" "example.gov" ]
|
[ "example.org" "example.gov" ]
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
While abstracting your configuration, you may find it useful to generate
|
||||||
|
modules using code, instead of writing files. The example
|
||||||
|
below would have the same effect as importing a file which sets those
|
||||||
|
options.
|
||||||
|
<screen>
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let netConfig = { hostName }: {
|
||||||
|
networking.hostName = hostName;
|
||||||
|
networking.useDHCP = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{ imports = [ (netConfig "nixos.localdomain") ]; }
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
@ -19,7 +19,7 @@ starting VDE switch for network 1
|
|||||||
> startAll
|
> startAll
|
||||||
> testScript
|
> testScript
|
||||||
> $machine->succeed("touch /tmp/foo")
|
> $machine->succeed("touch /tmp/foo")
|
||||||
> print($machine->succeed("pwd"), "\n") # Show stdout of command
|
> print($machine->succeed("pwd")) # Show stdout of command
|
||||||
</screen>
|
</screen>
|
||||||
The function <command>testScript</command> executes the entire test script
|
The function <command>testScript</command> executes the entire test script
|
||||||
and drops you back into the test driver command line upon its completion.
|
and drops you back into the test driver command line upon its completion.
|
||||||
|
@ -108,7 +108,7 @@ xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualis
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
$machine->start;
|
$machine->start;
|
||||||
$machine->waitForUnit("default.target");
|
$machine->waitForUnit("default.target");
|
||||||
die unless $machine->succeed("uname") =~ /Linux/;
|
$machine->succeed("uname") =~ /Linux/ or die;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The first line is actually unnecessary; machines are implicitly started when
|
The first line is actually unnecessary; machines are implicitly started when
|
||||||
you first execute an action on them (such as <literal>waitForUnit</literal>
|
you first execute an action on them (such as <literal>waitForUnit</literal>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="http://thread.gmane.org/gmane.linux.distributions.nixos/15165">
|
<link xlink:href="https://www.mail-archive.com/nix-dev@lists.science.uu.nl/msg13957.html">
|
||||||
Nix has been updated to 1.8.</link>
|
Nix has been updated to 1.8.</link>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -39,7 +39,18 @@
|
|||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para />
|
<para>
|
||||||
|
<literal>./programs/nm-applet.nix</literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
There is a new <varname>security.googleOsLogin</varname> module for using
|
||||||
|
<link xlink:href="https://cloud.google.com/compute/docs/instances/managing-instance-access">OS Login</link>
|
||||||
|
to manage SSH access to Google Compute Engine instances, which supersedes
|
||||||
|
the imperative and broken <literal>google-accounts-daemon</literal> used
|
||||||
|
in <literal>nixos/modules/virtualisation/google-compute-config.nix</literal>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
@ -111,6 +122,16 @@
|
|||||||
without Syncthing resetting the permission on every start.
|
without Syncthing resetting the permission on every start.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>ntp</literal> module now has sane default restrictions.
|
||||||
|
If you're relying on the previous defaults, which permitted all queries
|
||||||
|
and commands from all firewall-permitted sources, you can set
|
||||||
|
<varname>services.ntp.restrictDefault</varname> and
|
||||||
|
<varname>services.ntp.restrictSource</varname> to
|
||||||
|
<literal>[]</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Package <varname>rabbitmq_server</varname> is renamed to
|
Package <varname>rabbitmq_server</varname> is renamed to
|
||||||
@ -231,8 +252,97 @@
|
|||||||
(<literal>networking.firewall.interfaces.default.*</literal>), and assigning
|
(<literal>networking.firewall.interfaces.default.*</literal>), and assigning
|
||||||
to this pseudo device will override the (<literal>networking.firewall.allow*</literal>)
|
to this pseudo device will override the (<literal>networking.firewall.allow*</literal>)
|
||||||
options.
|
options.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>nscd</literal> service now disables all caching of
|
||||||
|
<literal>passwd</literal> and <literal>group</literal> databases by
|
||||||
|
default. This was interferring with the correct functioning of the
|
||||||
|
<literal>libnss_systemd.so</literal> module which is used by
|
||||||
|
<literal>systemd</literal> to manage uids and usernames in the presence of
|
||||||
|
<literal>DynamicUser=</literal> in systemd services. This was already the
|
||||||
|
default behaviour in presence of <literal>services.sssd.enable =
|
||||||
|
true</literal> because nscd caching would interfere with
|
||||||
|
<literal>sssd</literal> in unpredictable ways as well. Because we're
|
||||||
|
using nscd not for caching, but for convincing glibc to find NSS modules
|
||||||
|
in the nix store instead of an absolute path, we have decided to disable
|
||||||
|
caching globally now, as it's usually not the behaviour the user wants and
|
||||||
|
can lead to surprising behaviour. Furthermore, negative caching of host
|
||||||
|
lookups is also disabled now by default. This should fix the issue of dns
|
||||||
|
lookups failing in the presence of an unreliable network.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If the old behaviour is desired, this can be restored by setting
|
||||||
|
the <literal>services.nscd.config</literal> option
|
||||||
|
with the desired caching parameters.
|
||||||
|
<programlisting>
|
||||||
|
services.nscd.config =
|
||||||
|
''
|
||||||
|
server-user nscd
|
||||||
|
threads 1
|
||||||
|
paranoia no
|
||||||
|
debug-level 0
|
||||||
|
|
||||||
|
enable-cache passwd yes
|
||||||
|
positive-time-to-live passwd 600
|
||||||
|
negative-time-to-live passwd 20
|
||||||
|
suggested-size passwd 211
|
||||||
|
check-files passwd yes
|
||||||
|
persistent passwd no
|
||||||
|
shared passwd yes
|
||||||
|
|
||||||
|
enable-cache group yes
|
||||||
|
positive-time-to-live group 3600
|
||||||
|
negative-time-to-live group 60
|
||||||
|
suggested-size group 211
|
||||||
|
check-files group yes
|
||||||
|
persistent group no
|
||||||
|
shared group yes
|
||||||
|
|
||||||
|
enable-cache hosts yes
|
||||||
|
positive-time-to-live hosts 600
|
||||||
|
negative-time-to-live hosts 5
|
||||||
|
suggested-size hosts 211
|
||||||
|
check-files hosts yes
|
||||||
|
persistent hosts no
|
||||||
|
shared hosts yes
|
||||||
|
'';
|
||||||
|
</programlisting>
|
||||||
|
See <link xlink:href="https://github.com/NixOS/nixpkgs/pull/50316">#50316</link>
|
||||||
|
for details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
GitLab Shell previously used the nix store paths for the
|
||||||
|
<literal>gitlab-shell</literal> command in its
|
||||||
|
<literal>authorized_keys</literal> file, which might stop working after
|
||||||
|
garbage collection. To circumvent that, we regenerated that file on each
|
||||||
|
startup. As <literal>gitlab-shell</literal> has now been changed to use
|
||||||
|
<literal>/var/run/current-system/sw/bin/gitlab-shell</literal>, this is
|
||||||
|
not necessary anymore, but there might be leftover lines with a nix store
|
||||||
|
path. Regenerate the <literal>authorized_keys</literal> file via
|
||||||
|
<command>sudo -u git -H gitlab-rake gitlab:shell:setup</command> in that
|
||||||
|
case.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>pam_unix</literal> account module is now loaded with its
|
||||||
|
control field set to <literal>required</literal> instead of
|
||||||
|
<literal>sufficient</literal>, so that later pam account modules that
|
||||||
|
might do more extensive checks are being executed.
|
||||||
|
Previously, the whole account module verification was exited prematurely
|
||||||
|
in case a nss module provided the account name to
|
||||||
|
<literal>pam_unix</literal>.
|
||||||
|
The LDAP and SSSD NixOS modules already add their NSS modules when
|
||||||
|
enabled. In case your setup breaks due to some later pam account module
|
||||||
|
previosuly shadowed, or failing NSS lookups, please file a bug. You can
|
||||||
|
get back the old behaviour by manually setting
|
||||||
|
<literal><![CDATA[security.pam.services.<name?>.text]]></literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -273,6 +383,18 @@
|
|||||||
<option>services.kubernetes.addons.dns.replicas</option>.
|
<option>services.kubernetes.addons.dns.replicas</option>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The quassel-webserver package and module was removed from nixpkgs due to the lack
|
||||||
|
of maintainers.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The owncloud server packages and httpd subservice module were removed
|
||||||
|
from nixpkgs due to the lack of maintainers.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
@ -94,5 +94,24 @@ pkgs.stdenv.mkDerivation {
|
|||||||
cat errorlog
|
cat errorlog
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
# Resizes **snugly** to its actual limits (or closer to)
|
||||||
|
free=$(dumpe2fs $out | grep '^Free blocks:')
|
||||||
|
blocksize=$(dumpe2fs $out | grep '^Block size:')
|
||||||
|
blocks=$(dumpe2fs $out | grep '^Block count:')
|
||||||
|
blocks=$((''${blocks##*:})) # format the number.
|
||||||
|
blocksize=$((''${blocksize##*:})) # format the number.
|
||||||
|
# System can't boot with 0 blocks free.
|
||||||
|
# Add 16MiB of free space
|
||||||
|
fudge=$(( 16 * 1024 * 1024 / blocksize ))
|
||||||
|
size=$(( blocks - ''${free##*:} + fudge ))
|
||||||
|
|
||||||
|
echo "Resizing from $blocks blocks to $size blocks. (~ $((size*blocksize/1024/1024))MiB)"
|
||||||
|
EXT2FS_NO_MTAB_OK=yes resize2fs $out -f $size
|
||||||
|
)
|
||||||
|
|
||||||
|
# And a final fsck, because of the previous truncating.
|
||||||
|
fsck.ext4 -n -f $out
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ if test -n "$bootable"; then
|
|||||||
|
|
||||||
isoBootFlags="-eltorito-boot ${bootImage}
|
isoBootFlags="-eltorito-boot ${bootImage}
|
||||||
-eltorito-catalog .boot.cat
|
-eltorito-catalog .boot.cat
|
||||||
-no-emul-boot -boot-load-size 4 -boot-info-table"
|
-no-emul-boot -boot-load-size 4 -boot-info-table
|
||||||
|
--sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$usbBootable"; then
|
if test -n "$usbBootable"; then
|
||||||
@ -112,7 +113,7 @@ xorriso="xorriso
|
|||||||
-r
|
-r
|
||||||
-path-list pathlist
|
-path-list pathlist
|
||||||
--sort-weight 0 /
|
--sort-weight 0 /
|
||||||
--sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
|
"
|
||||||
|
|
||||||
$xorriso -output $out/iso/$isoName
|
$xorriso -output $out/iso/$isoName
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ in rec {
|
|||||||
|
|
||||||
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
|
vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
|
||||||
|
|
||||||
ocrProg = tesseract_4.override { enableLanguages = [ "eng" ]; };
|
ocrProg = tesseract4.override { enableLanguages = [ "eng" ]; };
|
||||||
|
|
||||||
imagemagick_tiff = imagemagick_light.override { inherit libtiff; };
|
imagemagick_tiff = imagemagick_light.override { inherit libtiff; };
|
||||||
|
|
||||||
@ -156,9 +156,23 @@ in rec {
|
|||||||
test = passMeta (runTests driver);
|
test = passMeta (runTests driver);
|
||||||
report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
|
report = passMeta (releaseTools.gcovReport { coverageRuns = [ test ]; });
|
||||||
|
|
||||||
in (if makeCoverageReport then report else test) // {
|
nodeNames = builtins.attrNames nodes;
|
||||||
inherit nodes driver test;
|
invalidNodeNames = lib.filter
|
||||||
};
|
(node: builtins.match "^[A-z_][A-z0-9_]+$" node == null) nodeNames;
|
||||||
|
|
||||||
|
in
|
||||||
|
if lib.length invalidNodeNames > 0 then
|
||||||
|
throw ''
|
||||||
|
Cannot create machines out of (${lib.concatStringsSep ", " invalidNodeNames})!
|
||||||
|
All machines are referenced as perl variables in the testing framework which will break the
|
||||||
|
script when special characters are used.
|
||||||
|
|
||||||
|
Please stick to alphanumeric chars and underscores as separation.
|
||||||
|
''
|
||||||
|
else
|
||||||
|
(if makeCoverageReport then report else test) // {
|
||||||
|
inherit nodes driver test;
|
||||||
|
};
|
||||||
|
|
||||||
runInMachine =
|
runInMachine =
|
||||||
{ drv
|
{ drv
|
||||||
|
@ -7,9 +7,8 @@ rec {
|
|||||||
|| elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ];
|
|| elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ];
|
||||||
|
|
||||||
# Check whenever `b` depends on `a` as a fileSystem
|
# Check whenever `b` depends on `a` as a fileSystem
|
||||||
# FIXME: it's incorrect to simply use hasPrefix here: "/dev/a" is not a parent of "/dev/ab"
|
fsBefore = a: b: a.mountPoint == b.device
|
||||||
fsBefore = a: b: ((any (x: elem x [ "bind" "move" ]) b.options) && (a.mountPoint == b.device))
|
|| hasPrefix "${a.mountPoint}${optionalString (!(hasSuffix "/" a.mountPoint)) "/"}" b.mountPoint;
|
||||||
|| (hasPrefix a.mountPoint b.mountPoint);
|
|
||||||
|
|
||||||
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
|
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
|
||||||
# becomes dev-xyzzy. FIXME: slow.
|
# becomes dev-xyzzy. FIXME: slow.
|
||||||
|
25
nixos/modules/config/appstream.nix
Normal file
25
nixos/modules/config/appstream.nix
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
appstream.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to install files to support the
|
||||||
|
<link xlink:href="https://www.freedesktop.org/software/appstream/docs/index.html">AppStream metadata specification</link>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.appstream.enable {
|
||||||
|
environment.pathsToLink = [
|
||||||
|
# per component metadata
|
||||||
|
"/share/metainfo"
|
||||||
|
# legacy path for above
|
||||||
|
"/share/appdata"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -34,6 +34,17 @@ with lib;
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraLocaleSettings = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = {};
|
||||||
|
example = { LC_MESSAGES = "en_US.UTF-8"; LC_TIME = "de_DE.UTF-8"; };
|
||||||
|
description = ''
|
||||||
|
A set of additional system-wide locale settings other than
|
||||||
|
<literal>LANG</literal> which can be configured with
|
||||||
|
<option>i18n.defaultLocale</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
supportedLocales = mkOption {
|
supportedLocales = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = ["all"];
|
default = ["all"];
|
||||||
@ -129,7 +140,7 @@ with lib;
|
|||||||
environment.sessionVariables =
|
environment.sessionVariables =
|
||||||
{ LANG = config.i18n.defaultLocale;
|
{ LANG = config.i18n.defaultLocale;
|
||||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||||
};
|
} // config.i18n.extraLocaleSettings;
|
||||||
|
|
||||||
systemd.globalEnvironment = mkIf (config.i18n.supportedLocales != []) {
|
systemd.globalEnvironment = mkIf (config.i18n.supportedLocales != []) {
|
||||||
LOCALE_ARCHIVE = "${config.i18n.glibcLocales}/lib/locale/locale-archive";
|
LOCALE_ARCHIVE = "${config.i18n.glibcLocales}/lib/locale/locale-archive";
|
||||||
@ -141,6 +152,7 @@ with lib;
|
|||||||
source = pkgs.writeText "locale.conf"
|
source = pkgs.writeText "locale.conf"
|
||||||
''
|
''
|
||||||
LANG=${config.i18n.defaultLocale}
|
LANG=${config.i18n.defaultLocale}
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (n: v: ''${n}=${v}'') config.i18n.extraLocaleSettings)}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ with lib;
|
|||||||
networkmanager-vpnc = super.networkmanager-vpnc.override { withGnome = false; };
|
networkmanager-vpnc = super.networkmanager-vpnc.override { withGnome = false; };
|
||||||
networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; };
|
networkmanager-iodine = super.networkmanager-iodine.override { withGnome = false; };
|
||||||
pinentry = super.pinentry_ncurses;
|
pinentry = super.pinentry_ncurses;
|
||||||
gobjectIntrospection = super.gobjectIntrospection.override { x11Support = false; };
|
gobject-introspection = super.gobject-introspection.override { x11Support = false; };
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Configuration for the Name Service Switch (/etc/nsswitch.conf).
|
# Configuration for the Name Service Switch (/etc/nsswitch.conf).
|
||||||
|
|
||||||
{ config, lib, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ let
|
|||||||
ldap = canLoadExternalModules && (config.users.ldap.enable && config.users.ldap.nsswitch);
|
ldap = canLoadExternalModules && (config.users.ldap.enable && config.users.ldap.nsswitch);
|
||||||
sssd = canLoadExternalModules && config.services.sssd.enable;
|
sssd = canLoadExternalModules && config.services.sssd.enable;
|
||||||
resolved = canLoadExternalModules && config.services.resolved.enable;
|
resolved = canLoadExternalModules && config.services.resolved.enable;
|
||||||
|
googleOsLogin = canLoadExternalModules && config.security.googleOsLogin.enable;
|
||||||
|
|
||||||
hostArray = [ "files" ]
|
hostArray = [ "files" ]
|
||||||
++ optional mymachines "mymachines"
|
++ optional mymachines "mymachines"
|
||||||
@ -29,6 +30,7 @@ let
|
|||||||
++ optional sssd "sss"
|
++ optional sssd "sss"
|
||||||
++ optional ldap "ldap"
|
++ optional ldap "ldap"
|
||||||
++ optional mymachines "mymachines"
|
++ optional mymachines "mymachines"
|
||||||
|
++ optional googleOsLogin "cache_oslogin oslogin"
|
||||||
++ [ "systemd" ];
|
++ [ "systemd" ];
|
||||||
|
|
||||||
shadowArray = [ "files" ]
|
shadowArray = [ "files" ]
|
||||||
@ -97,7 +99,7 @@ in {
|
|||||||
# configured IP addresses, or ::1 and 127.0.0.2 as
|
# configured IP addresses, or ::1 and 127.0.0.2 as
|
||||||
# fallbacks. Systemd also provides nss-mymachines to return IP
|
# fallbacks. Systemd also provides nss-mymachines to return IP
|
||||||
# addresses of local containers.
|
# addresses of local containers.
|
||||||
system.nssModules = optionals canLoadExternalModules [ config.systemd.package.out ];
|
system.nssModules = (optionals canLoadExternalModules [ config.systemd.package.out ])
|
||||||
|
++ optional googleOsLogin pkgs.google-compute-engine-oslogin.out;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
22
nixos/modules/config/xdg/sounds.nix
Normal file
22
nixos/modules/config/xdg/sounds.nix
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
xdg.sounds.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to install files to support the
|
||||||
|
<link xlink:href="https://www.freedesktop.org/wiki/Specifications/sound-theme-spec/">XDG Sound Theme specification</link>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.xdg.sounds.enable {
|
||||||
|
environment.pathsToLink = [
|
||||||
|
"/share/sounds"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
28
nixos/modules/hardware/bladeRF.nix
Normal file
28
nixos/modules/hardware/bladeRF.nix
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.hardware.bladeRF;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.hardware.bladeRF = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enables udev rules for BladeRF devices. By default grants access
|
||||||
|
to users in the "bladerf" group. You may want to install the
|
||||||
|
libbladeRF package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.udev.packages = [ pkgs.libbladeRF ];
|
||||||
|
users.groups.bladerf = {};
|
||||||
|
};
|
||||||
|
}
|
@ -20,6 +20,8 @@ let
|
|||||||
kernelPackages.nvidia_x11_legacy304
|
kernelPackages.nvidia_x11_legacy304
|
||||||
else if elem "nvidiaLegacy340" drivers then
|
else if elem "nvidiaLegacy340" drivers then
|
||||||
kernelPackages.nvidia_x11_legacy340
|
kernelPackages.nvidia_x11_legacy340
|
||||||
|
else if elem "nvidiaLegacy390" drivers then
|
||||||
|
kernelPackages.nvidia_x11_legacy390
|
||||||
else null;
|
else null;
|
||||||
|
|
||||||
nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
|
nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
|
||||||
@ -101,8 +103,8 @@ in
|
|||||||
config = mkIf enabled {
|
config = mkIf enabled {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = config.services.xserver.displayManager.gdm.wayland;
|
assertion = with config.services.xserver.displayManager; gdm.enable -> !gdm.wayland;
|
||||||
message = "NVIDIA drivers don't support wayland";
|
message = "NVIDIA drivers don't support wayland, set services.xserver.displayManager.gdm.wayland=false";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = !optimusCfg.enable ||
|
assertion = !optimusCfg.enable ||
|
||||||
|
@ -50,7 +50,7 @@ let
|
|||||||
finalCfg = {
|
finalCfg = {
|
||||||
name = "NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}";
|
name = "NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}";
|
||||||
params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}";
|
params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}";
|
||||||
image = "/boot/bzImage";
|
image = "/boot/${config.system.boot.loader.kernelFile}";
|
||||||
initrd = "/boot/initrd";
|
initrd = "/boot/initrd";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
@ -163,7 +163,7 @@ let
|
|||||||
cp -v ${pkgs.refind}/share/refind/refind_x64.efi $out/EFI/boot/
|
cp -v ${pkgs.refind}/share/refind/refind_x64.efi $out/EFI/boot/
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
"# No refind for ia32"
|
"# No refind for ${targetArch}"
|
||||||
;
|
;
|
||||||
|
|
||||||
grubMenuCfg = ''
|
grubMenuCfg = ''
|
||||||
@ -222,18 +222,34 @@ let
|
|||||||
efiDir = pkgs.runCommand "efi-directory" {} ''
|
efiDir = pkgs.runCommand "efi-directory" {} ''
|
||||||
mkdir -p $out/EFI/boot/
|
mkdir -p $out/EFI/boot/
|
||||||
|
|
||||||
|
# ALWAYS required modules.
|
||||||
MODULES="fat iso9660 part_gpt part_msdos \
|
MODULES="fat iso9660 part_gpt part_msdos \
|
||||||
normal boot linux configfile loopback chain halt \
|
normal boot linux configfile loopback chain halt \
|
||||||
efifwsetup efi_gop efi_uga \
|
efifwsetup efi_gop \
|
||||||
ls search search_label search_fs_uuid search_fs_file \
|
ls search search_label search_fs_uuid search_fs_file \
|
||||||
gfxmenu gfxterm gfxterm_background gfxterm_menu test all_video loadenv \
|
gfxmenu gfxterm gfxterm_background gfxterm_menu test all_video loadenv \
|
||||||
exfat ext2 ntfs btrfs hfsplus udf \
|
exfat ext2 ntfs btrfs hfsplus udf \
|
||||||
videoinfo png \
|
videoinfo png \
|
||||||
echo serial \
|
echo serial \
|
||||||
"
|
"
|
||||||
|
|
||||||
|
echo "Building GRUB with modules:"
|
||||||
|
for mod in $MODULES; do
|
||||||
|
echo " - $mod"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Modules that may or may not be available per-platform.
|
||||||
|
echo "Adding additional modules:"
|
||||||
|
for mod in efi_uga; do
|
||||||
|
if [ -f ${pkgs.grub2_efi}/lib/grub/${pkgs.grub2_efi.grubTarget}/$mod.mod ]; then
|
||||||
|
echo " - $mod"
|
||||||
|
MODULES+=" $mod"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Make our own efi program, we can't rely on "grub-install" since it seems to
|
# Make our own efi program, we can't rely on "grub-install" since it seems to
|
||||||
# probe for devices, even with --skip-fs-probe.
|
# probe for devices, even with --skip-fs-probe.
|
||||||
${pkgs.grub2_efi}/bin/grub-mkimage -o $out/EFI/boot/${if targetArch == "x64" then "bootx64" else "bootia32"}.efi -p /EFI/boot -O ${if targetArch == "x64" then "x86_64" else "i386"}-efi \
|
${pkgs.grub2_efi}/bin/grub-mkimage -o $out/EFI/boot/boot${targetArch}.efi -p /EFI/boot -O ${pkgs.grub2_efi.grubTarget} \
|
||||||
$MODULES
|
$MODULES
|
||||||
cp ${pkgs.grub2_efi}/share/grub/unicode.pf2 $out/EFI/boot/
|
cp ${pkgs.grub2_efi}/share/grub/unicode.pf2 $out/EFI/boot/
|
||||||
|
|
||||||
@ -339,15 +355,24 @@ let
|
|||||||
echo "Image size: $image_size"
|
echo "Image size: $image_size"
|
||||||
truncate --size=$image_size "$out"
|
truncate --size=$image_size "$out"
|
||||||
${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
|
${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
|
||||||
mcopy -bpsvm -i "$out" ./* ::
|
mcopy -psvm -i "$out" ./* ::
|
||||||
|
# Verify the FAT partition.
|
||||||
|
${pkgs.dosfstools}/sbin/fsck.vfat -vn "$out"
|
||||||
''; # */
|
''; # */
|
||||||
|
|
||||||
targetArch = if pkgs.stdenv.isi686 then
|
# Name used by UEFI for architectures.
|
||||||
"ia32"
|
targetArch =
|
||||||
else if pkgs.stdenv.isx86_64 then
|
if pkgs.stdenv.isi686 then
|
||||||
"x64"
|
"ia32"
|
||||||
else
|
else if pkgs.stdenv.isx86_64 then
|
||||||
throw "Unsupported architecture";
|
"x64"
|
||||||
|
else if pkgs.stdenv.isAarch64 then
|
||||||
|
"aa64"
|
||||||
|
else
|
||||||
|
throw "Unsupported architecture";
|
||||||
|
|
||||||
|
# Syslinux (and isolinux) only supports x86-based architectures.
|
||||||
|
canx86BiosBoot = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -481,9 +506,9 @@ in
|
|||||||
# here and it causes a cyclic dependency.
|
# here and it causes a cyclic dependency.
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
|
|
||||||
# !!! Hack - attributes expected by other modules.
|
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi ]
|
||||||
system.boot.loader.kernelFile = "bzImage";
|
++ optional canx86BiosBoot pkgs.syslinux
|
||||||
environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
|
;
|
||||||
|
|
||||||
# In stage 1 of the boot, mount the CD as the root FS by label so
|
# In stage 1 of the boot, mount the CD as the root FS by label so
|
||||||
# that we don't need to know its device. We pass the label of the
|
# that we don't need to know its device. We pass the label of the
|
||||||
@ -554,13 +579,7 @@ in
|
|||||||
# Individual files to be included on the CD, outside of the Nix
|
# Individual files to be included on the CD, outside of the Nix
|
||||||
# store on the CD.
|
# store on the CD.
|
||||||
isoImage.contents =
|
isoImage.contents =
|
||||||
[ { source = pkgs.substituteAll {
|
[
|
||||||
name = "isolinux.cfg";
|
|
||||||
src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
|
|
||||||
bootRoot = "/boot";
|
|
||||||
};
|
|
||||||
target = "/isolinux/isolinux.cfg";
|
|
||||||
}
|
|
||||||
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
|
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
|
||||||
target = "/boot/" + config.system.boot.loader.kernelFile;
|
target = "/boot/" + config.system.boot.loader.kernelFile;
|
||||||
}
|
}
|
||||||
@ -570,9 +589,6 @@ in
|
|||||||
{ source = config.system.build.squashfsStore;
|
{ source = config.system.build.squashfsStore;
|
||||||
target = "/nix-store.squashfs";
|
target = "/nix-store.squashfs";
|
||||||
}
|
}
|
||||||
{ source = "${pkgs.syslinux}/share/syslinux";
|
|
||||||
target = "/isolinux";
|
|
||||||
}
|
|
||||||
{ source = config.isoImage.efiSplashImage;
|
{ source = config.isoImage.efiSplashImage;
|
||||||
target = "/EFI/boot/efi-background.png";
|
target = "/EFI/boot/efi-background.png";
|
||||||
}
|
}
|
||||||
@ -582,6 +598,17 @@ in
|
|||||||
{ source = pkgs.writeText "version" config.system.nixos.label;
|
{ source = pkgs.writeText "version" config.system.nixos.label;
|
||||||
target = "/version.txt";
|
target = "/version.txt";
|
||||||
}
|
}
|
||||||
|
] ++ optionals canx86BiosBoot [
|
||||||
|
{ source = pkgs.substituteAll {
|
||||||
|
name = "isolinux.cfg";
|
||||||
|
src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
|
||||||
|
bootRoot = "/boot";
|
||||||
|
};
|
||||||
|
target = "/isolinux/isolinux.cfg";
|
||||||
|
}
|
||||||
|
{ source = "${pkgs.syslinux}/share/syslinux";
|
||||||
|
target = "/isolinux";
|
||||||
|
}
|
||||||
] ++ optionals config.isoImage.makeEfiBootable [
|
] ++ optionals config.isoImage.makeEfiBootable [
|
||||||
{ source = efiImg;
|
{ source = efiImg;
|
||||||
target = "/boot/efi.img";
|
target = "/boot/efi.img";
|
||||||
@ -589,7 +616,7 @@ in
|
|||||||
{ source = "${efiDir}/EFI";
|
{ source = "${efiDir}/EFI";
|
||||||
target = "/EFI";
|
target = "/EFI";
|
||||||
}
|
}
|
||||||
] ++ optionals config.boot.loader.grub.memtest86.enable [
|
] ++ optionals (config.boot.loader.grub.memtest86.enable && canx86BiosBoot) [
|
||||||
{ source = "${pkgs.memtest86plus}/memtest.bin";
|
{ source = "${pkgs.memtest86plus}/memtest.bin";
|
||||||
target = "/boot/memtest.bin";
|
target = "/boot/memtest.bin";
|
||||||
}
|
}
|
||||||
@ -604,9 +631,10 @@ in
|
|||||||
# Create the ISO image.
|
# Create the ISO image.
|
||||||
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
|
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
|
||||||
inherit (config.isoImage) isoName compressImage volumeID contents;
|
inherit (config.isoImage) isoName compressImage volumeID contents;
|
||||||
bootable = true;
|
bootable = canx86BiosBoot;
|
||||||
bootImage = "/isolinux/isolinux.bin";
|
bootImage = "/isolinux/isolinux.bin";
|
||||||
} // optionalAttrs config.isoImage.makeUsbBootable {
|
syslinux = if canx86BiosBoot then pkgs.syslinux else null;
|
||||||
|
} // optionalAttrs (config.isoImage.makeUsbBootable && canx86BiosBoot) {
|
||||||
usbBootable = true;
|
usbBootable = true;
|
||||||
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
|
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
|
||||||
} // optionalAttrs config.isoImage.makeEfiBootable {
|
} // optionalAttrs config.isoImage.makeEfiBootable {
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./sd-image-aarch64.nix ];
|
||||||
|
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
}
|
@ -26,7 +26,6 @@ in
|
|||||||
boot.loader.generic-extlinux-compatible.enable = true;
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
|
||||||
boot.consoleLogLevel = lib.mkDefault 7;
|
boot.consoleLogLevel = lib.mkDefault 7;
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
|
||||||
|
|
||||||
# The serial ports listed here are:
|
# The serial ports listed here are:
|
||||||
# - ttyS0: for Tegra (Jetson TX1)
|
# - ttyS0: for Tegra (Jetson TX1)
|
||||||
|
@ -134,7 +134,9 @@ in
|
|||||||
${config.sdImage.populateBootCommands}
|
${config.sdImage.populateBootCommands}
|
||||||
|
|
||||||
# Copy the populated /boot into the SD image
|
# Copy the populated /boot into the SD image
|
||||||
(cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
|
(cd boot; mcopy -psvm -i ../bootpart.img ./* ::)
|
||||||
|
# Verify the FAT partition before copying it.
|
||||||
|
fsck.vfat -vn bootpart.img
|
||||||
dd conv=notrunc if=bootpart.img of=$img seek=$START count=$SECTORS
|
dd conv=notrunc if=bootpart.img of=$img seek=$START count=$SECTORS
|
||||||
'';
|
'';
|
||||||
}) {};
|
}) {};
|
||||||
|
@ -337,6 +337,7 @@
|
|||||||
alerta = 310;
|
alerta = 310;
|
||||||
minetest = 311;
|
minetest = 311;
|
||||||
rss2email = 312;
|
rss2email = 312;
|
||||||
|
cockroachdb = 313;
|
||||||
|
|
||||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||||
|
|
||||||
@ -634,6 +635,7 @@
|
|||||||
alerta = 310;
|
alerta = 310;
|
||||||
minetest = 311;
|
minetest = 311;
|
||||||
rss2email = 312;
|
rss2email = 312;
|
||||||
|
cockroachdb = 313;
|
||||||
|
|
||||||
# When adding a gid, make sure it doesn't match an existing
|
# When adding a gid, make sure it doesn't match an existing
|
||||||
# uid. Users and groups with the same name should have equal
|
# uid. Users and groups with the same name should have equal
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
./config/xdg/icons.nix
|
./config/xdg/icons.nix
|
||||||
./config/xdg/menus.nix
|
./config/xdg/menus.nix
|
||||||
./config/xdg/mime.nix
|
./config/xdg/mime.nix
|
||||||
|
./config/appstream.nix
|
||||||
|
./config/xdg/sounds.nix
|
||||||
./config/gtk/gtk-icon-cache.nix
|
./config/gtk/gtk-icon-cache.nix
|
||||||
./config/gnu.nix
|
./config/gnu.nix
|
||||||
./config/i18n.nix
|
./config/i18n.nix
|
||||||
@ -34,6 +36,7 @@
|
|||||||
./config/vpnc.nix
|
./config/vpnc.nix
|
||||||
./config/zram.nix
|
./config/zram.nix
|
||||||
./hardware/all-firmware.nix
|
./hardware/all-firmware.nix
|
||||||
|
./hardware/bladeRF.nix
|
||||||
./hardware/brightnessctl.nix
|
./hardware/brightnessctl.nix
|
||||||
./hardware/ckb-next.nix
|
./hardware/ckb-next.nix
|
||||||
./hardware/cpu/amd-microcode.nix
|
./hardware/cpu/amd-microcode.nix
|
||||||
@ -106,6 +109,7 @@
|
|||||||
./programs/mininet.nix
|
./programs/mininet.nix
|
||||||
./programs/mtr.nix
|
./programs/mtr.nix
|
||||||
./programs/nano.nix
|
./programs/nano.nix
|
||||||
|
./programs/nm-applet.nix
|
||||||
./programs/npm.nix
|
./programs/npm.nix
|
||||||
./programs/oblogout.nix
|
./programs/oblogout.nix
|
||||||
./programs/plotinus.nix
|
./programs/plotinus.nix
|
||||||
@ -150,6 +154,7 @@
|
|||||||
./security/chromium-suid-sandbox.nix
|
./security/chromium-suid-sandbox.nix
|
||||||
./security/dhparams.nix
|
./security/dhparams.nix
|
||||||
./security/duosec.nix
|
./security/duosec.nix
|
||||||
|
./security/google_oslogin.nix
|
||||||
./security/hidepid.nix
|
./security/hidepid.nix
|
||||||
./security/lock-kernel-modules.nix
|
./security/lock-kernel-modules.nix
|
||||||
./security/misc.nix
|
./security/misc.nix
|
||||||
@ -212,6 +217,7 @@
|
|||||||
./services/databases/aerospike.nix
|
./services/databases/aerospike.nix
|
||||||
./services/databases/cassandra.nix
|
./services/databases/cassandra.nix
|
||||||
./services/databases/clickhouse.nix
|
./services/databases/clickhouse.nix
|
||||||
|
./services/databases/cockroachdb.nix
|
||||||
./services/databases/couchdb.nix
|
./services/databases/couchdb.nix
|
||||||
./services/databases/firebird.nix
|
./services/databases/firebird.nix
|
||||||
./services/databases/foundationdb.nix
|
./services/databases/foundationdb.nix
|
||||||
@ -246,6 +252,7 @@
|
|||||||
./services/desktops/gnome3/gnome-documents.nix
|
./services/desktops/gnome3/gnome-documents.nix
|
||||||
./services/desktops/gnome3/gnome-keyring.nix
|
./services/desktops/gnome3/gnome-keyring.nix
|
||||||
./services/desktops/gnome3/gnome-online-accounts.nix
|
./services/desktops/gnome3/gnome-online-accounts.nix
|
||||||
|
./services/desktops/gnome3/gnome-remote-desktop.nix
|
||||||
./services/desktops/gnome3/gnome-online-miners.nix
|
./services/desktops/gnome3/gnome-online-miners.nix
|
||||||
./services/desktops/gnome3/gnome-terminal-server.nix
|
./services/desktops/gnome3/gnome-terminal-server.nix
|
||||||
./services/desktops/gnome3/gnome-user-share.nix
|
./services/desktops/gnome3/gnome-user-share.nix
|
||||||
@ -297,6 +304,7 @@
|
|||||||
./services/hardware/usbmuxd.nix
|
./services/hardware/usbmuxd.nix
|
||||||
./services/hardware/thermald.nix
|
./services/hardware/thermald.nix
|
||||||
./services/hardware/undervolt.nix
|
./services/hardware/undervolt.nix
|
||||||
|
./services/hardware/vdr.nix
|
||||||
./services/logging/SystemdJournal2Gelf.nix
|
./services/logging/SystemdJournal2Gelf.nix
|
||||||
./services/logging/awstats.nix
|
./services/logging/awstats.nix
|
||||||
./services/logging/fluentd.nix
|
./services/logging/fluentd.nix
|
||||||
@ -332,11 +340,13 @@
|
|||||||
./services/mail/rspamd.nix
|
./services/mail/rspamd.nix
|
||||||
./services/mail/rss2email.nix
|
./services/mail/rss2email.nix
|
||||||
./services/mail/rmilter.nix
|
./services/mail/rmilter.nix
|
||||||
|
./services/mail/roundcube.nix
|
||||||
./services/mail/nullmailer.nix
|
./services/mail/nullmailer.nix
|
||||||
./services/misc/airsonic.nix
|
./services/misc/airsonic.nix
|
||||||
./services/misc/apache-kafka.nix
|
./services/misc/apache-kafka.nix
|
||||||
./services/misc/autofs.nix
|
./services/misc/autofs.nix
|
||||||
./services/misc/autorandr.nix
|
./services/misc/autorandr.nix
|
||||||
|
./services/misc/bees.nix
|
||||||
./services/misc/bepasty.nix
|
./services/misc/bepasty.nix
|
||||||
./services/misc/canto-daemon.nix
|
./services/misc/canto-daemon.nix
|
||||||
./services/misc/calibre-server.nix
|
./services/misc/calibre-server.nix
|
||||||
@ -710,7 +720,6 @@
|
|||||||
./services/web-apps/restya-board.nix
|
./services/web-apps/restya-board.nix
|
||||||
./services/web-apps/tt-rss.nix
|
./services/web-apps/tt-rss.nix
|
||||||
./services/web-apps/selfoss.nix
|
./services/web-apps/selfoss.nix
|
||||||
./services/web-apps/quassel-webserver.nix
|
|
||||||
./services/web-apps/virtlyst.nix
|
./services/web-apps/virtlyst.nix
|
||||||
./services/web-apps/youtrack.nix
|
./services/web-apps/youtrack.nix
|
||||||
./services/web-servers/apache-httpd/default.nix
|
./services/web-servers/apache-httpd/default.nix
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
# Include support for various filesystems.
|
# Include support for various filesystems.
|
||||||
boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" ];
|
boot.supportedFilesystems = [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "zfs" "ntfs" "cifs" ];
|
||||||
|
|
||||||
# Configure host id for ZFS to work
|
# Configure host id for ZFS to work
|
||||||
networking.hostId = lib.mkDefault "8425e349";
|
networking.hostId = lib.mkDefault "8425e349";
|
||||||
|
@ -20,6 +20,12 @@ with lib;
|
|||||||
|
|
||||||
security.allowUserNamespaces = mkDefault false;
|
security.allowUserNamespaces = mkDefault false;
|
||||||
|
|
||||||
|
security.protectKernelImage = mkDefault true;
|
||||||
|
|
||||||
|
security.allowSimultaneousMultithreading = mkDefault false;
|
||||||
|
|
||||||
|
security.virtualization.flushL1DataCache = mkDefault "always";
|
||||||
|
|
||||||
security.apparmor.enable = mkDefault true;
|
security.apparmor.enable = mkDefault true;
|
||||||
|
|
||||||
boot.kernelParams = [
|
boot.kernelParams = [
|
||||||
@ -28,9 +34,6 @@ with lib;
|
|||||||
|
|
||||||
# Disable legacy virtual syscalls
|
# Disable legacy virtual syscalls
|
||||||
"vsyscall=none"
|
"vsyscall=none"
|
||||||
|
|
||||||
# Disable hibernation (allows replacing the running kernel)
|
|
||||||
"nohibernate"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.blacklistedKernelModules = [
|
boot.blacklistedKernelModules = [
|
||||||
@ -44,9 +47,6 @@ with lib;
|
|||||||
# (e.g., parent/child)
|
# (e.g., parent/child)
|
||||||
boot.kernel.sysctl."kernel.yama.ptrace_scope" = mkOverride 500 1;
|
boot.kernel.sysctl."kernel.yama.ptrace_scope" = mkOverride 500 1;
|
||||||
|
|
||||||
# Prevent replacing the running kernel image w/o reboot
|
|
||||||
boot.kernel.sysctl."kernel.kexec_load_disabled" = mkDefault true;
|
|
||||||
|
|
||||||
# Restrict access to kernel ring buffer (information leaks)
|
# Restrict access to kernel ring buffer (information leaks)
|
||||||
boot.kernel.sysctl."kernel.dmesg_restrict" = mkDefault true;
|
boot.kernel.sysctl."kernel.dmesg_restrict" = mkDefault true;
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ with lib;
|
|||||||
To grant access to a user, it must be part of adbusers group:
|
To grant access to a user, it must be part of adbusers group:
|
||||||
<code>users.users.alice.extraGroups = ["adbusers"];</code>
|
<code>users.users.alice.extraGroups = ["adbusers"];</code>
|
||||||
'';
|
'';
|
||||||
relatedPackages = [ ["androidenv" "platformTools"] ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -24,7 +23,7 @@ with lib;
|
|||||||
###### implementation
|
###### implementation
|
||||||
config = mkIf config.programs.adb.enable {
|
config = mkIf config.programs.adb.enable {
|
||||||
services.udev.packages = [ pkgs.android-udev-rules ];
|
services.udev.packages = [ pkgs.android-udev-rules ];
|
||||||
environment.systemPackages = [ pkgs.androidenv.platformTools ];
|
environment.systemPackages = [ pkgs.androidenv.androidPkgs_9_0.platform-tools ];
|
||||||
users.groups.adbusers = {};
|
users.groups.adbusers = {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,12 @@ in
|
|||||||
if [ "$TERM" != "dumb" -o -n "$INSIDE_EMACS" ]; then
|
if [ "$TERM" != "dumb" -o -n "$INSIDE_EMACS" ]; then
|
||||||
PROMPT_COLOR="1;31m"
|
PROMPT_COLOR="1;31m"
|
||||||
let $UID && PROMPT_COLOR="1;32m"
|
let $UID && PROMPT_COLOR="1;32m"
|
||||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
if [ -n "$INSIDE_EMACS" ]; then
|
||||||
|
# Emacs term mode doesn't support xterm title escape sequence (\e]0;)
|
||||||
|
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||||
|
else
|
||||||
|
PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\$\[\033[0m\] "
|
||||||
|
fi
|
||||||
if test "$TERM" = "xterm"; then
|
if test "$TERM" = "xterm"; then
|
||||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||||
fi
|
fi
|
||||||
|
14
nixos/modules/programs/nm-applet.nix
Normal file
14
nixos/modules/programs/nm-applet.nix
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
options.programs.nm-applet.enable = lib.mkEnableOption "nm-applet";
|
||||||
|
|
||||||
|
config = lib.mkIf config.programs.nm-applet.enable {
|
||||||
|
systemd.user.services.nm-applet = {
|
||||||
|
description = "Network manager applet";
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
partOf = [ "graphical-session.target" ];
|
||||||
|
serviceConfig.ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -7,8 +7,19 @@ let
|
|||||||
swayPackage = cfg.package;
|
swayPackage = cfg.package;
|
||||||
|
|
||||||
swayWrapped = pkgs.writeShellScriptBin "sway" ''
|
swayWrapped = pkgs.writeShellScriptBin "sway" ''
|
||||||
${cfg.extraSessionCommands}
|
set -o errexit
|
||||||
exec ${pkgs.dbus.dbus-launch} --exit-with-session ${swayPackage}/bin/sway
|
|
||||||
|
if [ ! "$_SWAY_WRAPPER_ALREADY_EXECUTED" ]; then
|
||||||
|
export _SWAY_WRAPPER_ALREADY_EXECUTED=1
|
||||||
|
${cfg.extraSessionCommands}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DBUS_SESSION_BUS_ADDRESS" ]; then
|
||||||
|
export DBUS_SESSION_BUS_ADDRESS
|
||||||
|
exec ${swayPackage}/bin/sway "$@"
|
||||||
|
else
|
||||||
|
exec ${pkgs.dbus}/bin/dbus-run-session ${swayPackage}/bin/sway "$@"
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
swayJoined = pkgs.symlinkJoin {
|
swayJoined = pkgs.symlinkJoin {
|
||||||
name = "sway-joined";
|
name = "sway-joined";
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
configuration format of <literal>oh-my-zsh</literal>.
|
configuration format of <literal>oh-my-zsh</literal>.
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
programs.ohMyZsh = {
|
programs.zsh.ohMyZsh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
plugins = [ "git" "python" "man" ];
|
plugins = [ "git" "python" "man" ];
|
||||||
theme = "agnoster";
|
theme = "agnoster";
|
||||||
@ -51,7 +51,7 @@
|
|||||||
The module can do this as well:
|
The module can do this as well:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{
|
{
|
||||||
programs.ohMyZsh.custom = "~/path/to/custom/scripts";
|
programs.zsh.ohMyZsh.custom = "~/path/to/custom/scripts";
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
programs.ohMyZsh.customPkgs = with pkgs; [
|
programs.zsh.ohMyZsh.customPkgs = with pkgs; [
|
||||||
pkgs.nix-zsh-completions
|
pkgs.nix-zsh-completions
|
||||||
# and even more...
|
# and even more...
|
||||||
];
|
];
|
||||||
@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<emphasis>Please keep in mind that this is not compatible with
|
<emphasis>Please keep in mind that this is not compatible with
|
||||||
<literal>programs.ohMyZsh.custom</literal> as it requires an immutable store
|
<literal>programs.zsh.ohMyZsh.custom</literal> as it requires an immutable store
|
||||||
path while <literal>custom</literal> shall remain mutable! An evaluation
|
path while <literal>custom</literal> shall remain mutable! An evaluation
|
||||||
failure will be thrown if both <literal>custom</literal> and
|
failure will be thrown if both <literal>custom</literal> and
|
||||||
<literal>customPkgs</literal> are set.</emphasis>
|
<literal>customPkgs</literal> are set.</emphasis>
|
||||||
|
@ -18,13 +18,13 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
strategy = mkOption {
|
strategy = mkOption {
|
||||||
type = types.enum [ "default" "match_prev_cmd" ];
|
type = types.enum [ "history" "match_prev_cmd" ];
|
||||||
default = "default";
|
default = "history";
|
||||||
description = ''
|
description = ''
|
||||||
Set ZSH_AUTOSUGGEST_STRATEGY to choose the strategy for generating suggestions.
|
Set ZSH_AUTOSUGGEST_STRATEGY to choose the strategy for generating suggestions.
|
||||||
There are currently two to choose from:
|
There are currently two to choose from:
|
||||||
|
|
||||||
* default: Chooses the most recent match.
|
* history: Chooses the most recent match.
|
||||||
* match_prev_cmd: Chooses the most recent match whose preceding history item matches
|
* match_prev_cmd: Chooses the most recent match whose preceding history item matches
|
||||||
the most recently executed command (more info). Note that this strategy won't work as
|
the most recently executed command (more info). Note that this strategy won't work as
|
||||||
expected with ZSH options that don't preserve the history order such as
|
expected with ZSH options that don't preserve the history order such as
|
||||||
@ -51,7 +51,7 @@ in
|
|||||||
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
source ${pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||||||
|
|
||||||
export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.highlightStyle}"
|
export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="${cfg.highlightStyle}"
|
||||||
export ZSH_AUTOSUGGEST_STRATEGY="${cfg.strategy}"
|
export ZSH_AUTOSUGGEST_STRATEGY=("${cfg.strategy}")
|
||||||
|
|
||||||
${concatStringsSep "\n" (mapAttrsToList (key: value: ''export ${key}="${value}"'') cfg.extraConfig)}
|
${concatStringsSep "\n" (mapAttrsToList (key: value: ''export ${key}="${value}"'') cfg.extraConfig)}
|
||||||
'';
|
'';
|
||||||
|
68
nixos/modules/security/google_oslogin.nix
Normal file
68
nixos/modules/security/google_oslogin.nix
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.security.googleOsLogin;
|
||||||
|
package = pkgs.google-compute-engine-oslogin;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
security.googleOsLogin.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable Google OS Login
|
||||||
|
|
||||||
|
The OS Login package enables the following components:
|
||||||
|
AuthorizedKeysCommand to query valid SSH keys from the user's OS Login
|
||||||
|
profile during ssh authentication phase.
|
||||||
|
NSS Module to provide user and group information
|
||||||
|
PAM Module for the sshd service, providing authorization and
|
||||||
|
authentication support, allowing the system to use data stored in
|
||||||
|
Google Cloud IAM permissions to control both, the ability to log into
|
||||||
|
an instance, and to perform operations as root (sudo).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
security.pam.services.sshd = {
|
||||||
|
makeHomeDir = true;
|
||||||
|
googleOsLoginAccountVerification = true;
|
||||||
|
# disabled for now: googleOsLoginAuthentication = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.sudo.extraConfig = ''
|
||||||
|
#includedir /run/google-sudoers.d
|
||||||
|
'';
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /run/google-sudoers.d 750 root root -"
|
||||||
|
"d /var/google-users.d 750 root root -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# enable the nss module, so user lookups etc. work
|
||||||
|
system.nssModules = [ package ];
|
||||||
|
|
||||||
|
# Ugly: sshd refuses to start if a store path is given because /nix/store is group-writable.
|
||||||
|
# So indirect by a symlink.
|
||||||
|
environment.etc."ssh/authorized_keys_command_google_oslogin" = {
|
||||||
|
mode = "0755";
|
||||||
|
text = ''
|
||||||
|
#!/bin/sh
|
||||||
|
exec ${package}/bin/google_authorized_keys "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
services.openssh.extraConfig = ''
|
||||||
|
AuthorizedKeysCommand /etc/ssh/authorized_keys_command_google_oslogin %u
|
||||||
|
AuthorizedKeysCommandUser nobody
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -22,18 +22,104 @@ with lib;
|
|||||||
a user namespace fails with "no space left on device" (ENOSPC).
|
a user namespace fails with "no space left on device" (ENOSPC).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
security.protectKernelImage = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to prevent replacing the running kernel image.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
security.allowSimultaneousMultithreading = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to allow SMT/hyperthreading. Disabling SMT means that only
|
||||||
|
physical CPU cores will be usable at runtime, potentially at
|
||||||
|
significant performance cost.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The primary motivation for disabling SMT is to mitigate the risk of
|
||||||
|
leaking data between threads running on the same CPU core (due to
|
||||||
|
e.g., shared caches). This attack vector is unproven.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Disabling SMT is a supplement to the L1 data cache flushing mitigation
|
||||||
|
(see <xref linkend="opt-security.virtualization.flushL1DataCache"/>)
|
||||||
|
versus malicious VM guests (SMT could "bring back" previously flushed
|
||||||
|
data).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
security.virtualization.flushL1DataCache = mkOption {
|
||||||
|
type = types.nullOr (types.enum [ "never" "cond" "always" ]);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Whether the hypervisor should flush the L1 data cache before
|
||||||
|
entering guests.
|
||||||
|
See also <xref linkend="opt-security.allowSimultaneousMultithreading"/>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>null</literal></term>
|
||||||
|
<listitem><para>uses the kernel default</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>"never"</literal></term>
|
||||||
|
<listitem><para>disables L1 data cache flushing entirely.
|
||||||
|
May be appropriate if all guests are trusted.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>"cond"</literal></term>
|
||||||
|
<listitem><para>flushes L1 data cache only for pre-determined
|
||||||
|
code paths. May leak information about the host address space
|
||||||
|
layout.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>"always"</literal></term>
|
||||||
|
<listitem><para>flushes L1 data cache every time the hypervisor
|
||||||
|
enters the guest. May incur significant performance cost.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (!config.security.allowUserNamespaces) {
|
config = mkMerge [
|
||||||
# Setting the number of allowed user namespaces to 0 effectively disables
|
(mkIf (!config.security.allowUserNamespaces) {
|
||||||
# the feature at runtime. Note that root may raise the limit again
|
# Setting the number of allowed user namespaces to 0 effectively disables
|
||||||
# at any time.
|
# the feature at runtime. Note that root may raise the limit again
|
||||||
boot.kernel.sysctl."user.max_user_namespaces" = 0;
|
# at any time.
|
||||||
|
boot.kernel.sysctl."user.max_user_namespaces" = 0;
|
||||||
|
|
||||||
assertions = [
|
assertions = [
|
||||||
{ assertion = config.nix.useSandbox -> config.security.allowUserNamespaces;
|
{ assertion = config.nix.useSandbox -> config.security.allowUserNamespaces;
|
||||||
message = "`nix.useSandbox = true` conflicts with `!security.allowUserNamespaces`.";
|
message = "`nix.useSandbox = true` conflicts with `!security.allowUserNamespaces`.";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
})
|
||||||
|
|
||||||
|
(mkIf config.security.protectKernelImage {
|
||||||
|
# Disable hibernation (allows replacing the running kernel)
|
||||||
|
boot.kernelParams = [ "nohibernate" ];
|
||||||
|
# Prevent replacing the running kernel image w/o reboot
|
||||||
|
boot.kernel.sysctl."kernel.kexec_load_disabled" = mkDefault true;
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (!config.security.allowSimultaneousMultithreading) {
|
||||||
|
boot.kernelParams = [ "nosmt" ];
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (config.security.virtualization.flushL1DataCache != null) {
|
||||||
|
boot.kernelParams = [ "kvm-intel.vmentry_l1d_flush=${config.security.virtualization.flushL1DataCache}" ];
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,30 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
googleOsLoginAccountVerification = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
If set, will use the Google OS Login PAM modules
|
||||||
|
(<literal>pam_oslogin_login</literal>,
|
||||||
|
<literal>pam_oslogin_admin</literal>) to verify possible OS Login
|
||||||
|
users and set sudoers configuration accordingly.
|
||||||
|
This only makes sense to enable for the <literal>sshd</literal> PAM
|
||||||
|
service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
googleOsLoginAuthentication = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
If set, will use the <literal>pam_oslogin_login</literal>'s user
|
||||||
|
authentication methods to authenticate users using 2FA.
|
||||||
|
This only makes sense to enable for the <literal>sshd</literal> PAM
|
||||||
|
service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
fprintAuth = mkOption {
|
fprintAuth = mkOption {
|
||||||
default = config.services.fprintd.enable;
|
default = config.services.fprintd.enable;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
@ -269,7 +293,7 @@ let
|
|||||||
text = mkDefault
|
text = mkDefault
|
||||||
(''
|
(''
|
||||||
# Account management.
|
# Account management.
|
||||||
account ${if cfg.sssdStrictAccess then "required" else "sufficient"} pam_unix.so
|
account required pam_unix.so
|
||||||
${optionalString use_ldap
|
${optionalString use_ldap
|
||||||
"account sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
|
"account sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
|
||||||
${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess==false)
|
${optionalString (config.services.sssd.enable && cfg.sssdStrictAccess==false)
|
||||||
@ -278,8 +302,14 @@ let
|
|||||||
"account [default=bad success=ok user_unknown=ignore] ${pkgs.sssd}/lib/security/pam_sss.so"}
|
"account [default=bad success=ok user_unknown=ignore] ${pkgs.sssd}/lib/security/pam_sss.so"}
|
||||||
${optionalString config.krb5.enable
|
${optionalString config.krb5.enable
|
||||||
"account sufficient ${pam_krb5}/lib/security/pam_krb5.so"}
|
"account sufficient ${pam_krb5}/lib/security/pam_krb5.so"}
|
||||||
|
${optionalString cfg.googleOsLoginAccountVerification ''
|
||||||
|
account [success=ok ignore=ignore default=die] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so
|
||||||
|
account [success=ok default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so
|
||||||
|
''}
|
||||||
|
|
||||||
# Authentication management.
|
# Authentication management.
|
||||||
|
${optionalString cfg.googleOsLoginAuthentication
|
||||||
|
"auth [success=done perm_denied=bad default=ignore] ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so"}
|
||||||
${optionalString cfg.rootOK
|
${optionalString cfg.rootOK
|
||||||
"auth sufficient pam_rootok.so"}
|
"auth sufficient pam_rootok.so"}
|
||||||
${optionalString cfg.requireWheel
|
${optionalString cfg.requireWheel
|
||||||
|
@ -191,7 +191,7 @@ in {
|
|||||||
options = {
|
options = {
|
||||||
|
|
||||||
paths = mkOption {
|
paths = mkOption {
|
||||||
type = with types; either path (nonEmptyListOf path);
|
type = with types; either path (listOf str);
|
||||||
description = "Path(s) to back up.";
|
description = "Path(s) to back up.";
|
||||||
example = "/home/user";
|
example = "/home/user";
|
||||||
apply = x: if isList x then x else [ x ];
|
apply = x: if isList x then x else [ x ];
|
||||||
|
@ -46,7 +46,7 @@ let
|
|||||||
# in the same directory as slurm.conf
|
# in the same directory as slurm.conf
|
||||||
etcSlurm = pkgs.symlinkJoin {
|
etcSlurm = pkgs.symlinkJoin {
|
||||||
name = "etc-slurm";
|
name = "etc-slurm";
|
||||||
paths = [ configFile cgroupConfig plugStackConfig ];
|
paths = [ configFile cgroupConfig plugStackConfig ] ++ cfg.extraConfigPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -239,6 +239,17 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraConfigPaths = mkOption {
|
||||||
|
type = with types; listOf path;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Slurm expects config files for plugins in the same path
|
||||||
|
as <literal>slurm.conf</literal>. Add extra nix store
|
||||||
|
paths that should be merged into same directory as
|
||||||
|
<literal>slurm.conf</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -303,6 +314,7 @@ in
|
|||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
|
KillMode = "process";
|
||||||
ExecStart = "${wrappedSlurm}/bin/slurmd";
|
ExecStart = "${wrappedSlurm}/bin/slurmd";
|
||||||
PIDFile = "/run/slurmd.pid";
|
PIDFile = "/run/slurmd.pid";
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
@ -42,6 +42,18 @@ in {
|
|||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
User token in Jenkins used to reload config.
|
User token in Jenkins used to reload config.
|
||||||
|
WARNING: This token will be world readable in the Nix store. To keep
|
||||||
|
it secret, use the <option>accessTokenFile</option> option instead.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
accessTokenFile = mkOption {
|
||||||
|
default = "";
|
||||||
|
type = types.str;
|
||||||
|
example = "/run/keys/jenkins-job-builder-access-token";
|
||||||
|
description = ''
|
||||||
|
File containing the API token for the <option>accessUser</option>
|
||||||
|
user.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,6 +115,21 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (jenkinsCfg.enable && cfg.enable) {
|
config = mkIf (jenkinsCfg.enable && cfg.enable) {
|
||||||
|
assertions = [
|
||||||
|
{ assertion =
|
||||||
|
if cfg.accessUser != ""
|
||||||
|
then (cfg.accessToken != "" && cfg.accessTokenFile == "") ||
|
||||||
|
(cfg.accessToken == "" && cfg.accessTokenFile != "")
|
||||||
|
else true;
|
||||||
|
message = ''
|
||||||
|
One of accessToken and accessTokenFile options must be non-empty
|
||||||
|
strings, but not both. Current values:
|
||||||
|
services.jenkins.jobBuilder.accessToken = "${cfg.accessToken}"
|
||||||
|
services.jenkins.jobBuilder.accessTokenFile = "${cfg.accessTokenFile}"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
systemd.services.jenkins-job-builder = {
|
systemd.services.jenkins-job-builder = {
|
||||||
description = "Jenkins Job Builder Service";
|
description = "Jenkins Job Builder Service";
|
||||||
# JJB can run either before or after jenkins. We chose after, so we can
|
# JJB can run either before or after jenkins. We chose after, so we can
|
||||||
@ -128,8 +155,13 @@ in {
|
|||||||
ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder";
|
ownerStamp = ".config-xml-managed-by-nixos-jenkins-job-builder";
|
||||||
reloadScript = ''
|
reloadScript = ''
|
||||||
echo "Asking Jenkins to reload config"
|
echo "Asking Jenkins to reload config"
|
||||||
CRUMB=$(curl -s 'http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
|
curl_opts="--silent --fail --show-error"
|
||||||
curl --silent -X POST -H "$CRUMB" http://${cfg.accessUser}:${cfg.accessToken}@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}/reload
|
access_token=${if cfg.accessTokenFile != ""
|
||||||
|
then "$(cat '${cfg.accessTokenFile}')"
|
||||||
|
else cfg.accessToken}
|
||||||
|
jenkins_url="http://${cfg.accessUser}:$access_token@${jenkinsCfg.listenAddress}:${toString jenkinsCfg.port}${jenkinsCfg.prefix}"
|
||||||
|
crumb=$(curl $curl_opts "$jenkins_url"'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
|
||||||
|
curl $curl_opts -X POST -H "$crumb" "$jenkins_url"/reload
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
|
@ -43,6 +43,7 @@ in
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
default = pkgs.aerospike;
|
default = pkgs.aerospike;
|
||||||
|
defaultText = "pkgs.aerospike";
|
||||||
type = types.package;
|
type = types.package;
|
||||||
description = "Which Aerospike derivation to use";
|
description = "Which Aerospike derivation to use";
|
||||||
};
|
};
|
||||||
|
@ -70,6 +70,11 @@ with lib;
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.clickhouse ];
|
||||||
|
|
||||||
|
# startup requires a `/etc/localtime` which only if exists if `time.timeZone != null`
|
||||||
|
time.timeZone = mkDefault "UTC";
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
217
nixos/modules/services/databases/cockroachdb.nix
Normal file
217
nixos/modules/services/databases/cockroachdb.nix
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.cockroachdb;
|
||||||
|
crdb = cfg.package;
|
||||||
|
|
||||||
|
escape = builtins.replaceStrings ["%"] ["%%"];
|
||||||
|
ifNotNull = v: s: optionalString (!isNull v) s;
|
||||||
|
|
||||||
|
startupCommand = lib.concatStringsSep " "
|
||||||
|
[ # Basic startup
|
||||||
|
"${crdb}/bin/cockroach start"
|
||||||
|
"--logtostderr"
|
||||||
|
"--store=/var/lib/cockroachdb"
|
||||||
|
(ifNotNull cfg.locality "--locality='${cfg.locality}'")
|
||||||
|
|
||||||
|
# WebUI settings
|
||||||
|
"--http-addr='${cfg.http.address}:${toString cfg.http.port}'"
|
||||||
|
|
||||||
|
# Cluster listen address
|
||||||
|
"--listen-addr='${cfg.listen.address}:${toString cfg.listen.port}'"
|
||||||
|
|
||||||
|
# Cluster configuration
|
||||||
|
(ifNotNull cfg.join "--join=${cfg.join}")
|
||||||
|
|
||||||
|
# Cache and memory settings. Must be escaped.
|
||||||
|
"--cache='${escape cfg.cache}'"
|
||||||
|
"--max-sql-memory='${escape cfg.maxSqlMemory}'"
|
||||||
|
|
||||||
|
# Certificate/security settings.
|
||||||
|
(if cfg.insecure then "--insecure" else "--certs-dir=${cfg.certsDir}")
|
||||||
|
];
|
||||||
|
|
||||||
|
addressOption = descr: defaultPort: {
|
||||||
|
address = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Address to bind to for ${descr}";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = defaultPort;
|
||||||
|
description = "Port to bind to for ${descr}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.cockroachdb = {
|
||||||
|
enable = mkEnableOption "CockroachDB Server";
|
||||||
|
|
||||||
|
listen = addressOption "intra-cluster communication" 26257;
|
||||||
|
|
||||||
|
http = addressOption "http-based Admin UI" 8080;
|
||||||
|
|
||||||
|
locality = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
An ordered, comma-separated list of key-value pairs that describe the
|
||||||
|
topography of the machine. Topography might include country,
|
||||||
|
datacenter or rack designations. Data is automatically replicated to
|
||||||
|
maximize diversities of each tier. The order of tiers is used to
|
||||||
|
determine the priority of the diversity, so the more inclusive
|
||||||
|
localities like country should come before less inclusive localities
|
||||||
|
like datacenter. The tiers and order must be the same on all nodes.
|
||||||
|
Including more tiers is better than including fewer. For example:
|
||||||
|
|
||||||
|
<literal>
|
||||||
|
country=us,region=us-west,datacenter=us-west-1b,rack=12
|
||||||
|
country=ca,region=ca-east,datacenter=ca-east-2,rack=4
|
||||||
|
|
||||||
|
planet=earth,province=manitoba,colo=secondary,power=3
|
||||||
|
</literal>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
join = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "The addresses for connecting the node to a cluster.";
|
||||||
|
};
|
||||||
|
|
||||||
|
insecure = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Run in insecure mode.";
|
||||||
|
};
|
||||||
|
|
||||||
|
certsDir = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = "The path to the certificate directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "cockroachdb";
|
||||||
|
description = "User account under which CockroachDB runs";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "cockroachdb";
|
||||||
|
description = "User account under which CockroachDB runs";
|
||||||
|
};
|
||||||
|
|
||||||
|
openPorts = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Open firewall ports for cluster communication by default";
|
||||||
|
};
|
||||||
|
|
||||||
|
cache = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "25%";
|
||||||
|
description = ''
|
||||||
|
The total size for caches.
|
||||||
|
|
||||||
|
This can be a percentage, expressed with a fraction sign or as a
|
||||||
|
decimal-point number, or any bytes-based unit. For example,
|
||||||
|
<literal>"25%"</literal>, <literal>"0.25"</literal> both represent
|
||||||
|
25% of the available system memory. The values
|
||||||
|
<literal>"1000000000"</literal> and <literal>"1GB"</literal> both
|
||||||
|
represent 1 gigabyte of memory.
|
||||||
|
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maxSqlMemory = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "25%";
|
||||||
|
description = ''
|
||||||
|
The maximum in-memory storage capacity available to store temporary
|
||||||
|
data for SQL queries.
|
||||||
|
|
||||||
|
This can be a percentage, expressed with a fraction sign or as a
|
||||||
|
decimal-point number, or any bytes-based unit. For example,
|
||||||
|
<literal>"25%"</literal>, <literal>"0.25"</literal> both represent
|
||||||
|
25% of the available system memory. The values
|
||||||
|
<literal>"1000000000"</literal> and <literal>"1GB"</literal> both
|
||||||
|
represent 1 gigabyte of memory.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.cockroachdb;
|
||||||
|
defaultText = "pkgs.cockroachdb";
|
||||||
|
description = ''
|
||||||
|
The CockroachDB derivation to use for running the service.
|
||||||
|
|
||||||
|
This would primarily be useful to enable Enterprise Edition features
|
||||||
|
in your own custom CockroachDB build (Nixpkgs CockroachDB binaries
|
||||||
|
only contain open source features and open source code).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.services.cockroachdb.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = !cfg.insecure -> !(isNull cfg.certsDir);
|
||||||
|
message = "CockroachDB must have a set of SSL certificates (.certsDir), or run in Insecure Mode (.insecure = true)";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = [ crdb ];
|
||||||
|
|
||||||
|
users.users = optionalAttrs (cfg.user == "cockroachdb") (singleton
|
||||||
|
{ name = "cockroachdb";
|
||||||
|
description = "CockroachDB Server User";
|
||||||
|
uid = config.ids.uids.cockroachdb;
|
||||||
|
group = cfg.group;
|
||||||
|
});
|
||||||
|
|
||||||
|
users.groups = optionalAttrs (cfg.group == "cockroachdb") (singleton
|
||||||
|
{ name = "cockroachdb";
|
||||||
|
gid = config.ids.gids.cockroachdb;
|
||||||
|
});
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = lib.optionals cfg.openPorts
|
||||||
|
[ cfg.http.port cfg.listen.port ];
|
||||||
|
|
||||||
|
systemd.services.cockroachdb =
|
||||||
|
{ description = "CockroachDB Server";
|
||||||
|
documentation = [ "man:cockroach(1)" "https://www.cockroachlabs.com" ];
|
||||||
|
|
||||||
|
after = [ "network.target" "time-sync.target" ];
|
||||||
|
requires = [ "time-sync.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
unitConfig.RequiresMountsFor = "/var/lib/cockroachdb";
|
||||||
|
|
||||||
|
serviceConfig =
|
||||||
|
{ ExecStart = startupCommand;
|
||||||
|
Type = "notify";
|
||||||
|
User = cfg.user;
|
||||||
|
StateDirectory = "cockroachdb";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
|
||||||
|
Restart = "always";
|
||||||
|
|
||||||
|
# A conservative-ish timeout is alright here, because for Type=notify
|
||||||
|
# cockroach will send systemd pings during startup to keep it alive
|
||||||
|
TimeoutStopSec = 60;
|
||||||
|
RestartSec = 10;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ thoughtpolice ];
|
||||||
|
}
|
@ -29,21 +29,6 @@ let
|
|||||||
installOptions =
|
installOptions =
|
||||||
"${mysqldAndInstallOptions} ${lib.optionalString isMysqlAtLeast57 "--insecure"}";
|
"${mysqldAndInstallOptions} ${lib.optionalString isMysqlAtLeast57 "--insecure"}";
|
||||||
|
|
||||||
myCnf = pkgs.writeText "my.cnf"
|
|
||||||
''
|
|
||||||
[mysqld]
|
|
||||||
port = ${toString cfg.port}
|
|
||||||
datadir = ${cfg.dataDir}
|
|
||||||
${optionalString (cfg.bind != null) "bind-address = ${cfg.bind}" }
|
|
||||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
|
|
||||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
|
|
||||||
${optionalString (cfg.ensureUsers != [])
|
|
||||||
''
|
|
||||||
plugin-load-add = auth_socket.so
|
|
||||||
''}
|
|
||||||
${cfg.extraOptions}
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -242,6 +227,21 @@ in
|
|||||||
|
|
||||||
environment.systemPackages = [mysql];
|
environment.systemPackages = [mysql];
|
||||||
|
|
||||||
|
environment.etc."my.cnf".text =
|
||||||
|
''
|
||||||
|
[mysqld]
|
||||||
|
port = ${toString cfg.port}
|
||||||
|
datadir = ${cfg.dataDir}
|
||||||
|
${optionalString (cfg.bind != null) "bind-address = ${cfg.bind}" }
|
||||||
|
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
|
||||||
|
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
|
||||||
|
${optionalString (cfg.ensureUsers != [])
|
||||||
|
''
|
||||||
|
plugin-load-add = auth_socket.so
|
||||||
|
''}
|
||||||
|
${cfg.extraOptions}
|
||||||
|
'';
|
||||||
|
|
||||||
systemd.services.mysql = let
|
systemd.services.mysql = let
|
||||||
hasNotify = (cfg.package == pkgs.mariadb);
|
hasNotify = (cfg.package == pkgs.mariadb);
|
||||||
in {
|
in {
|
||||||
@ -263,7 +263,7 @@ in
|
|||||||
if ! test -e ${cfg.dataDir}/mysql; then
|
if ! test -e ${cfg.dataDir}/mysql; then
|
||||||
mkdir -m 0700 -p ${cfg.dataDir}
|
mkdir -m 0700 -p ${cfg.dataDir}
|
||||||
chown -R ${cfg.user} ${cfg.dataDir}
|
chown -R ${cfg.user} ${cfg.dataDir}
|
||||||
${mysql}/bin/mysql_install_db ${installOptions}
|
${mysql}/bin/mysql_install_db --defaults-file=/etc/my.cnf ${installOptions}
|
||||||
touch /tmp/mysql_init
|
touch /tmp/mysql_init
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ in
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = if hasNotify then "notify" else "simple";
|
Type = if hasNotify then "notify" else "simple";
|
||||||
RuntimeDirectory = "mysqld";
|
RuntimeDirectory = "mysqld";
|
||||||
ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
|
ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions}";
|
||||||
};
|
};
|
||||||
|
|
||||||
postStart = ''
|
postStart = ''
|
||||||
|
@ -54,6 +54,13 @@ in
|
|||||||
description = "The database directory.";
|
description = "The database directory.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0";
|
||||||
|
example = "acl trace";
|
||||||
|
description = "The log level selector of slapd.";
|
||||||
|
};
|
||||||
|
|
||||||
configDir = mkOption {
|
configDir = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
@ -139,7 +146,7 @@ in
|
|||||||
chown -R "${cfg.user}:${cfg.group}" "${cfg.dataDir}"
|
chown -R "${cfg.user}:${cfg.group}" "${cfg.dataDir}"
|
||||||
'';
|
'';
|
||||||
serviceConfig.ExecStart =
|
serviceConfig.ExecStart =
|
||||||
"${openldap.out}/libexec/slapd -d 0 " +
|
"${openldap.out}/libexec/slapd -d ${cfg.logLevel} " +
|
||||||
"-u '${cfg.user}' -g '${cfg.group}' " +
|
"-u '${cfg.user}' -g '${cfg.group}' " +
|
||||||
"-h '${concatStringsSep " " cfg.urlList}' " +
|
"-h '${concatStringsSep " " cfg.urlList}' " +
|
||||||
"${configOpts}";
|
"${configOpts}";
|
||||||
|
@ -238,6 +238,9 @@ in
|
|||||||
User = "postgres";
|
User = "postgres";
|
||||||
Group = "postgres";
|
Group = "postgres";
|
||||||
PermissionsStartOnly = true;
|
PermissionsStartOnly = true;
|
||||||
|
Type = if lib.versionAtLeast cfg.package.version "9.6"
|
||||||
|
then "notify"
|
||||||
|
else "simple";
|
||||||
|
|
||||||
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
||||||
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
||||||
|
@ -61,6 +61,8 @@ in
|
|||||||
wantedBy = [ "default.target" ];
|
wantedBy = [ "default.target" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
environment.etc."geoclue/geoclue.conf".source = "${package}/etc/geoclue/geoclue.conf";
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Remote desktop daemon using Pipewire.
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
###### interface
|
||||||
|
options = {
|
||||||
|
services.gnome3.gnome-remote-desktop = {
|
||||||
|
enable = mkEnableOption "Remote Desktop support using Pipewire";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
config = mkIf config.services.gnome3.gnome-remote-desktop.enable {
|
||||||
|
systemd.packages = [ pkgs.gnome3.gnome-remote-desktop ];
|
||||||
|
};
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
Rodney Lorrimar @rvl
|
Rodney Lorrimar @rvl
|
||||||
-->
|
-->
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="http://www.gnu.org/software/emacs/">Emacs</link> is an
|
<link xlink:href="https://www.gnu.org/software/emacs/">Emacs</link> is an
|
||||||
extensible, customizable, self-documenting real-time display editor — and
|
extensible, customizable, self-documenting real-time display editor — and
|
||||||
more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp
|
more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp
|
||||||
programming language with extensions to support text editing.
|
programming language with extensions to support text editing.
|
||||||
|
@ -25,9 +25,14 @@ in {
|
|||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.bluez;
|
default = pkgs.bluez;
|
||||||
defaultText = "pkgs.bluez";
|
defaultText = "pkgs.bluez";
|
||||||
example = "pkgs.bluez.override { enableMidi = true; }";
|
example = "pkgs.bluezFull";
|
||||||
description = ''
|
description = ''
|
||||||
Which BlueZ package to use.
|
Which BlueZ package to use.
|
||||||
|
|
||||||
|
<note><para>
|
||||||
|
Use the <literal>pkgs.bluezFull</literal> package to enable all
|
||||||
|
bluez plugins.
|
||||||
|
</para></note>
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ in {
|
|||||||
description = "LIRC daemon socket";
|
description = "LIRC daemon socket";
|
||||||
wantedBy = [ "sockets.target" ];
|
wantedBy = [ "sockets.target" ];
|
||||||
socketConfig = {
|
socketConfig = {
|
||||||
|
# default search path
|
||||||
ListenStream = "/run/lirc/lircd";
|
ListenStream = "/run/lirc/lircd";
|
||||||
SocketUser = "lirc";
|
SocketUser = "lirc";
|
||||||
SocketMode = "0660";
|
SocketMode = "0660";
|
||||||
@ -66,9 +67,19 @@ in {
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
RuntimeDirectory = "lirc";
|
RuntimeDirectory = "lirc";
|
||||||
|
|
||||||
# socket lives in runtime directory; we have to keep is available
|
# Service runtime directory and socket share same folder.
|
||||||
|
# Following hacks are necessary to get everything right:
|
||||||
|
|
||||||
|
# 1. prevent socket deletion during stop and restart
|
||||||
RuntimeDirectoryPreserve = true;
|
RuntimeDirectoryPreserve = true;
|
||||||
|
|
||||||
|
# 2. fix runtime folder owner-ship, happens when socket activation
|
||||||
|
# creates the folder
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
ExecStartPre = [
|
||||||
|
"${pkgs.coreutils}/bin/chown lirc /run/lirc/"
|
||||||
|
];
|
||||||
|
|
||||||
ExecStart = ''
|
ExecStart = ''
|
||||||
${pkgs.lirc}/bin/lircd --nodaemon \
|
${pkgs.lirc}/bin/lircd --nodaemon \
|
||||||
${escapeShellArgs cfg.extraArguments} \
|
${escapeShellArgs cfg.extraArguments} \
|
||||||
|
71
nixos/modules/services/hardware/vdr.nix
Normal file
71
nixos/modules/services/hardware/vdr.nix
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.vdr;
|
||||||
|
libDir = "/var/lib/vdr";
|
||||||
|
in {
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.vdr = {
|
||||||
|
enable = mkEnableOption "enable VDR. Please put config into ${libDir}.";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.vdr;
|
||||||
|
defaultText = "pkgs.vdr";
|
||||||
|
example = literalExample "pkgs.wrapVdr.override { plugins = with pkgs.vdrPlugins; [ hello ]; }";
|
||||||
|
description = "Package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
videoDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/srv/vdr/video";
|
||||||
|
description = "Recording directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArguments = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "Additional command line arguments to pass to VDR.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${cfg.videoDir} 0755 vdr vdr -"
|
||||||
|
"Z ${cfg.videoDir} - vdr vdr -"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.vdr = {
|
||||||
|
description = "VDR";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''
|
||||||
|
${cfg.package}/bin/vdr \
|
||||||
|
--video="${cfg.videoDir}" \
|
||||||
|
--config="${libDir}" \
|
||||||
|
${escapeShellArgs cfg.extraArguments}
|
||||||
|
'';
|
||||||
|
User = "vdr";
|
||||||
|
CacheDirectory = "vdr";
|
||||||
|
StateDirectory = "vdr";
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.vdr = {
|
||||||
|
group = "vdr";
|
||||||
|
home = libDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.vdr = {};
|
||||||
|
};
|
||||||
|
}
|
153
nixos/modules/services/mail/roundcube.nix
Normal file
153
nixos/modules/services/mail/roundcube.nix
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.roundcube;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.roundcube = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable roundcube.
|
||||||
|
|
||||||
|
Also enables nginx virtual host management.
|
||||||
|
Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.<name></literal>.
|
||||||
|
See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hostName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "webmail.example.com";
|
||||||
|
description = "Hostname to use for the nginx vhost";
|
||||||
|
};
|
||||||
|
|
||||||
|
database = {
|
||||||
|
username = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "roundcube";
|
||||||
|
description = "Username for the postgresql connection";
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = ''
|
||||||
|
Host of the postgresql server. If this is not set to
|
||||||
|
<literal>localhost</literal>, you have to create the
|
||||||
|
postgresql user and database yourself, with appropriate
|
||||||
|
permissions.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
password = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Password for the postgresql connection";
|
||||||
|
};
|
||||||
|
dbname = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "roundcube";
|
||||||
|
description = "Name of the postgresql database";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of roundcube plugins to enable. Currently, only those directly shipped with Roundcube are supported.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = "Extra configuration for roundcube webmail instance";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.etc."roundcube/config.inc.php".text = ''
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$config = array();
|
||||||
|
$config['db_dsnw'] = 'pgsql://${cfg.database.username}:${cfg.database.password}@${cfg.database.host}/${cfg.database.dbname}';
|
||||||
|
$config['log_driver'] = 'syslog';
|
||||||
|
$config['max_message_size'] = '25M';
|
||||||
|
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
||||||
|
${cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
${cfg.hostName} = {
|
||||||
|
forceSSL = mkDefault true;
|
||||||
|
enableACME = mkDefault true;
|
||||||
|
locations."/" = {
|
||||||
|
root = pkgs.roundcube;
|
||||||
|
index = "index.php";
|
||||||
|
extraConfig = ''
|
||||||
|
location ~* \.php$ {
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
fastcgi_pass unix:/run/phpfpm/roundcube;
|
||||||
|
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||||
|
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = mkIf (cfg.database.host == "localhost") {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.phpfpm.poolConfigs.roundcube = ''
|
||||||
|
listen = /run/phpfpm/roundcube
|
||||||
|
listen.owner = nginx
|
||||||
|
listen.group = nginx
|
||||||
|
listen.mode = 0660
|
||||||
|
user = nginx
|
||||||
|
pm = dynamic
|
||||||
|
pm.max_children = 75
|
||||||
|
pm.start_servers = 2
|
||||||
|
pm.min_spare_servers = 1
|
||||||
|
pm.max_spare_servers = 20
|
||||||
|
pm.max_requests = 500
|
||||||
|
php_admin_value[error_log] = 'stderr'
|
||||||
|
php_admin_flag[log_errors] = on
|
||||||
|
php_admin_value[post_max_size] = 25M
|
||||||
|
php_admin_value[upload_max_filesize] = 25M
|
||||||
|
catch_workers_output = yes
|
||||||
|
'';
|
||||||
|
systemd.services.phpfpm-roundcube.after = [ "roundcube-setup.service" ];
|
||||||
|
|
||||||
|
systemd.services.roundcube-setup = let
|
||||||
|
pgSuperUser = config.services.postgresql.superUser;
|
||||||
|
in {
|
||||||
|
requires = [ "postgresql.service" ];
|
||||||
|
after = [ "postgresql.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = [ config.services.postgresql.package ];
|
||||||
|
script = ''
|
||||||
|
mkdir -p /var/lib/roundcube
|
||||||
|
if [ ! -f /var/lib/roundcube/db-created ]; then
|
||||||
|
if [ "${cfg.database.host}" = "localhost" ]; then
|
||||||
|
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create role ${cfg.database.username} with login password '${cfg.database.password}'";
|
||||||
|
${pkgs.sudo}/bin/sudo -u ${pgSuperUser} psql postgres -c "create database ${cfg.database.dbname} with owner ${cfg.database.username}";
|
||||||
|
fi
|
||||||
|
PGPASSWORD=${cfg.database.password} ${pkgs.postgresql}/bin/psql -U ${cfg.database.username} \
|
||||||
|
-f ${pkgs.roundcube}/SQL/postgres.initial.sql \
|
||||||
|
-h ${cfg.database.host} ${cfg.database.dbname}
|
||||||
|
touch /var/lib/roundcube/db-created
|
||||||
|
fi
|
||||||
|
|
||||||
|
${pkgs.php}/bin/php ${pkgs.roundcube}/bin/update.sh
|
||||||
|
'';
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
123
nixos/modules/services/misc/bees.nix
Normal file
123
nixos/modules/services/misc/bees.nix
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.beesd;
|
||||||
|
|
||||||
|
logLevels = { emerg = 0; alert = 1; crit = 2; err = 3; warning = 4; notice = 5; info = 6; debug = 7; };
|
||||||
|
|
||||||
|
fsOptions = with types; {
|
||||||
|
options.spec = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = ''
|
||||||
|
Description of how to identify the filesystem to be duplicated by this
|
||||||
|
instance of bees. Note that deduplication crosses subvolumes; one must
|
||||||
|
not configure multiple instances for subvolumes of the same filesystem
|
||||||
|
(or block devices which are part of the same filesystem), but only for
|
||||||
|
completely independent btrfs filesystems.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This must be in a format usable by findmnt; that could be a key=value
|
||||||
|
pair, or a bare path to a mount point.
|
||||||
|
'';
|
||||||
|
example = "LABEL=MyBulkDataDrive";
|
||||||
|
};
|
||||||
|
options.hashTableSizeMB = mkOption {
|
||||||
|
type = types.addCheck types.int (n: mod n 16 == 0);
|
||||||
|
default = 1024; # 1GB; default from upstream beesd script
|
||||||
|
description = ''
|
||||||
|
Hash table size in MB; must be a multiple of 16.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A larger ratio of index size to storage size means smaller blocks of
|
||||||
|
duplicate content are recognized.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If you have 1TB of data, a 4GB hash table (which is to say, a value of
|
||||||
|
4096) will permit 4KB extents (the smallest possible size) to be
|
||||||
|
recognized, whereas a value of 1024 -- creating a 1GB hash table --
|
||||||
|
will recognize only aligned duplicate blocks of 16KB.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.verbosity = mkOption {
|
||||||
|
type = types.enum (attrNames logLevels ++ attrValues logLevels);
|
||||||
|
apply = v: if isString v then logLevels.${v} else v;
|
||||||
|
default = "info";
|
||||||
|
description = "Log verbosity (syslog keyword/level).";
|
||||||
|
};
|
||||||
|
options.workDir = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = ".beeshome";
|
||||||
|
description = ''
|
||||||
|
Name (relative to the root of the filesystem) of the subvolume where
|
||||||
|
the hash table will be stored.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
options.extraOptions = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Extra command-line options passed to the daemon. See upstream bees documentation.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
[ "--thread-count" "4" ]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.beesd = {
|
||||||
|
filesystems = mkOption {
|
||||||
|
type = with types; attrsOf (submodule fsOptions);
|
||||||
|
description = "BTRFS filesystems to run block-level deduplication on.";
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
root = {
|
||||||
|
spec = "LABEL=root";
|
||||||
|
hashTableSizeMB = 2048;
|
||||||
|
verbosity = "crit";
|
||||||
|
extraOptions = [ "--loadavg-target" "5.0" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
systemd.services = mapAttrs' (name: fs: nameValuePair "beesd@${name}" {
|
||||||
|
description = "Block-level BTRFS deduplication for %i";
|
||||||
|
after = [ "sysinit.target" ];
|
||||||
|
|
||||||
|
serviceConfig = let
|
||||||
|
configOpts = [
|
||||||
|
fs.spec
|
||||||
|
"verbosity=${toString fs.verbosity}"
|
||||||
|
"idxSizeMB=${toString fs.hashTableSizeMB}"
|
||||||
|
"workDir=${fs.workDir}"
|
||||||
|
];
|
||||||
|
configOptsStr = escapeShellArgs configOpts;
|
||||||
|
in {
|
||||||
|
# Values from https://github.com/Zygo/bees/blob/v0.6.1/scripts/beesd%40.service.in
|
||||||
|
ExecStart = "${pkgs.bees}/bin/bees-service-wrapper run ${configOptsStr} -- --no-timestamps ${escapeShellArgs fs.extraOptions}";
|
||||||
|
ExecStopPost = "${pkgs.bees}/bin/bees-service-wrapper cleanup ${configOptsStr}";
|
||||||
|
CPUAccounting = true;
|
||||||
|
CPUWeight = 12;
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
IOSchedulingPriority = 7;
|
||||||
|
IOWeight = 10;
|
||||||
|
KillMode = "control-group";
|
||||||
|
KillSignal = "SIGTERM";
|
||||||
|
MemoryAccounting = true;
|
||||||
|
Nice = 19;
|
||||||
|
Restart = "on-abnormal";
|
||||||
|
StartupCPUWeight = 25;
|
||||||
|
StartupIOWeight = 25;
|
||||||
|
SyslogIdentifier = "bees"; # would otherwise be "bees-service-wrapper"
|
||||||
|
};
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
|
}) cfg.filesystems;
|
||||||
|
};
|
||||||
|
}
|
@ -609,10 +609,6 @@ in {
|
|||||||
touch "${cfg.statePath}/db-seeded"
|
touch "${cfg.statePath}/db-seeded"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The gitlab:shell:setup regenerates the authorized_keys file so that
|
|
||||||
# the store path to the gitlab-shell in it gets updated
|
|
||||||
${pkgs.sudo}/bin/sudo -u ${cfg.user} -H force=yes ${gitlab-rake}/bin/gitlab-rake gitlab:shell:setup
|
|
||||||
|
|
||||||
# The gitlab:shell:create_hooks task seems broken for fixing links
|
# The gitlab:shell:create_hooks task seems broken for fixing links
|
||||||
# so we instead delete all the hooks and create them anew
|
# so we instead delete all the hooks and create them anew
|
||||||
rm -f ${cfg.statePath}/repositories/**/*.git/hooks
|
rm -f ${cfg.statePath}/repositories/**/*.git/hooks
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
server-user nscd
|
|
||||||
threads 1
|
|
||||||
paranoia no
|
|
||||||
debug-level 0
|
|
||||||
|
|
||||||
enable-cache passwd yes
|
|
||||||
positive-time-to-live passwd 0
|
|
||||||
negative-time-to-live passwd 0
|
|
||||||
suggested-size passwd 211
|
|
||||||
check-files passwd yes
|
|
||||||
persistent passwd no
|
|
||||||
shared passwd yes
|
|
||||||
|
|
||||||
enable-cache group yes
|
|
||||||
positive-time-to-live group 0
|
|
||||||
negative-time-to-live group 0
|
|
||||||
suggested-size group 211
|
|
||||||
check-files group yes
|
|
||||||
persistent group no
|
|
||||||
shared group yes
|
|
||||||
|
|
||||||
enable-cache hosts yes
|
|
||||||
positive-time-to-live hosts 600
|
|
||||||
negative-time-to-live hosts 5
|
|
||||||
suggested-size hosts 211
|
|
||||||
check-files hosts yes
|
|
||||||
persistent hosts no
|
|
||||||
shared hosts yes
|
|
||||||
|
|
||||||
enable-cache services yes
|
|
||||||
positive-time-to-live services 0
|
|
||||||
negative-time-to-live services 0
|
|
||||||
suggested-size services 211
|
|
||||||
check-files services yes
|
|
||||||
persistent services no
|
|
||||||
shared services yes
|
|
@ -75,7 +75,6 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
system.nssModules = optional cfg.enable pkgs.sssd;
|
system.nssModules = optional cfg.enable pkgs.sssd;
|
||||||
services.nscd.config = builtins.readFile ./nscd-sssd.conf;
|
|
||||||
services.dbus.packages = [ pkgs.sssd ];
|
services.dbus.packages = [ pkgs.sssd ];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -169,8 +169,9 @@ in {
|
|||||||
Sets the maximum amount of time (in seconds) a connection may be reused.
|
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.
|
For MySQL this setting should be shorter than the `wait_timeout' variable.
|
||||||
'';
|
'';
|
||||||
default = 14400;
|
default = "unlimited";
|
||||||
type = types.int;
|
example = 14400;
|
||||||
|
type = types.either types.int (types.enum [ "unlimited" ]);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ let
|
|||||||
serviceConfig.Restart = mkDefault "always";
|
serviceConfig.Restart = mkDefault "always";
|
||||||
serviceConfig.PrivateTmp = mkDefault true;
|
serviceConfig.PrivateTmp = mkDefault true;
|
||||||
serviceConfig.WorkingDirectory = mkDefault /tmp;
|
serviceConfig.WorkingDirectory = mkDefault /tmp;
|
||||||
} serviceOpts ] ++ optional (serviceOpts.serviceConfig.DynamicUser or false) {
|
} serviceOpts ] ++ optional (!(serviceOpts.serviceConfig.DynamicUser or false)) {
|
||||||
serviceConfig.User = conf.user;
|
serviceConfig.User = conf.user;
|
||||||
serviceConfig.Group = conf.group;
|
serviceConfig.Group = conf.group;
|
||||||
});
|
});
|
||||||
|
@ -36,5 +36,10 @@ in
|
|||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# CPython requires a process to either have $HOME defined or run as a UID
|
||||||
|
# defined in /etc/passwd. The latter is false with DynamicUser, so define a
|
||||||
|
# dummy $HOME. https://bugs.python.org/issue10496
|
||||||
|
environment = { HOME = "/var/empty"; };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ in {
|
|||||||
|
|
||||||
services.ipfs = {
|
services.ipfs = {
|
||||||
|
|
||||||
enable = mkEnableOption "Interplanetary File System";
|
enable = mkEnableOption "Interplanetary File System (WARNING: may cause severe network degredation)";
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -12,7 +12,7 @@ let
|
|||||||
${concatMapStringsSep "\n" (server: "server " + server) cfg.servers}
|
${concatMapStringsSep "\n" (server: "server " + server) cfg.servers}
|
||||||
|
|
||||||
${optionalString
|
${optionalString
|
||||||
cfg.initstepslew.enabled
|
(cfg.initstepslew.enabled && (cfg.servers != []))
|
||||||
"initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}"
|
"initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +113,7 @@ in
|
|||||||
chown chrony:chrony ${stateDir} ${keyFile}
|
chown chrony:chrony ${stateDir} ${keyFile}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
unitConfig.ConditionCapability = "CAP_SYS_TIME";
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
{ Type = "forking";
|
{ Type = "forking";
|
||||||
ExecStart = "${pkgs.chrony}/bin/chronyd ${chronyFlags}";
|
ExecStart = "${pkgs.chrony}/bin/chronyd ${chronyFlags}";
|
||||||
@ -121,8 +122,8 @@ in
|
|||||||
ProtectSystem = "full";
|
ProtectSystem = "full";
|
||||||
PrivateTmp = "yes";
|
PrivateTmp = "yes";
|
||||||
|
|
||||||
ConditionCapability = "CAP_SYS_TIME";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ let
|
|||||||
# anything ever again ("couldn't resolve ..., giving up on
|
# anything ever again ("couldn't resolve ..., giving up on
|
||||||
# it"), so we silently lose time synchronisation. This also
|
# it"), so we silently lose time synchronisation. This also
|
||||||
# applies to openntpd.
|
# applies to openntpd.
|
||||||
${config.systemd.package}/bin/systemctl try-reload-or-restart ntpd.service openntpd.service || true
|
${config.systemd.package}/bin/systemctl try-reload-or-restart ntpd.service openntpd.service chronyd.service || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${cfg.runHook}
|
${cfg.runHook}
|
||||||
|
@ -488,7 +488,7 @@ in {
|
|||||||
'') cfg.dynamicHosts.hostsDirs);
|
'') cfg.dynamicHosts.hostsDirs);
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExist = true;
|
RemainAfterExit = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ let
|
|||||||
configFile = pkgs.writeText "ntp.conf" ''
|
configFile = pkgs.writeText "ntp.conf" ''
|
||||||
driftfile ${stateDir}/ntp.drift
|
driftfile ${stateDir}/ntp.drift
|
||||||
|
|
||||||
|
restrict default ${toString cfg.restrictDefault}
|
||||||
|
restrict -6 default ${toString cfg.restrictDefault}
|
||||||
|
restrict source ${toString cfg.restrictSource}
|
||||||
|
|
||||||
restrict 127.0.0.1
|
restrict 127.0.0.1
|
||||||
restrict -6 ::1
|
restrict -6 ::1
|
||||||
|
|
||||||
@ -36,11 +40,40 @@ in
|
|||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Whether to synchronise your machine's time using the NTP
|
Whether to synchronise your machine's time using ntpd, as a peer in
|
||||||
protocol.
|
the NTP network.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Disables <literal>systemd.timesyncd</literal> if enabled.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
restrictDefault = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = ''
|
||||||
|
The restriction flags to be set by default.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The default flags prevent external hosts from using ntpd as a DDoS
|
||||||
|
reflector, setting system time, and querying OS/ntpd version. As
|
||||||
|
recommended in section 6.5.1.1.3, answer "No" of
|
||||||
|
http://support.ntp.org/bin/view/Support/AccessRestrictions
|
||||||
|
'';
|
||||||
|
default = [ "limited" "kod" "nomodify" "notrap" "noquery" "nopeer" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
restrictSource = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = ''
|
||||||
|
The restriction flags to be set on source.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The default flags allow peers to be added by ntpd from configured
|
||||||
|
pool(s), but not by other means.
|
||||||
|
'';
|
||||||
|
default = [ "limited" "kod" "nomodify" "notrap" "noquery" ];
|
||||||
|
};
|
||||||
|
|
||||||
servers = mkOption {
|
servers = mkOption {
|
||||||
default = config.networking.timeServers;
|
default = config.networking.timeServers;
|
||||||
description = ''
|
description = ''
|
||||||
@ -51,6 +84,7 @@ in
|
|||||||
extraFlags = mkOption {
|
extraFlags = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "Extra flags passed to the ntpd command.";
|
description = "Extra flags passed to the ntpd command.";
|
||||||
|
example = literalExample ''[ "--interface=eth0" ]'';
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,6 +228,7 @@ let
|
|||||||
|
|
||||||
createSSLOptsStr = o: ''
|
createSSLOptsStr = o: ''
|
||||||
ssl = {
|
ssl = {
|
||||||
|
cafile = "/etc/ssl/certs/ca-bundle.crt";
|
||||||
key = "${o.key}";
|
key = "${o.key}";
|
||||||
certificate = "${o.cert}";
|
certificate = "${o.cert}";
|
||||||
${concatStringsSep "\n" (mapAttrsToList (name: value: "${name} = ${toLua value};") o.extraOptions)}
|
${concatStringsSep "\n" (mapAttrsToList (name: value: "${name} = ${toLua value};") o.extraOptions)}
|
||||||
|
@ -27,7 +27,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
arguments = mkOption {
|
arguments = mkOption {
|
||||||
default = "-v -d pulse";
|
default = "-v pulse";
|
||||||
description = ''
|
description = ''
|
||||||
Arguments to pass to the daemon. Defaults to a local pulseaudio
|
Arguments to pass to the daemon. Defaults to a local pulseaudio
|
||||||
server.
|
server.
|
||||||
|
@ -202,7 +202,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
modprobe wireguard
|
${optionalString (!config.boot.isContainer) "modprobe wireguard"}
|
||||||
|
|
||||||
${values.preSetup}
|
${values.preSetup}
|
||||||
|
|
||||||
|
@ -149,7 +149,10 @@ in {
|
|||||||
after = [ "network.target" "elasticsearch.service" ];
|
after = [ "network.target" "elasticsearch.service" ];
|
||||||
environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; };
|
environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; };
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/kibana --config ${cfgFile}";
|
ExecStart =
|
||||||
|
"${cfg.package}/bin/kibana" +
|
||||||
|
" --config ${cfgFile}" +
|
||||||
|
" --path.data ${cfg.dataDir}";
|
||||||
User = "kibana";
|
User = "kibana";
|
||||||
WorkingDirectory = cfg.dataDir;
|
WorkingDirectory = cfg.dataDir;
|
||||||
};
|
};
|
||||||
|
@ -1,28 +1,52 @@
|
|||||||
|
# We basically use nscd as a proxy for forwarding nss requests to appropriate
|
||||||
|
# nss modules, as we run nscd with LD_LIBRARY_PATH set to the directory
|
||||||
|
# containing all such modules
|
||||||
|
# Note that we can not use `enable-cache no` As this will actually cause nscd
|
||||||
|
# to just reject the nss requests it receives, which then causes glibc to
|
||||||
|
# fallback to trying to handle the request by itself. Which won't work as glibc
|
||||||
|
# is not aware of the path in which the nss modules live. As a workaround, we
|
||||||
|
# have `enable-cache yes` with an explicit ttl of 0
|
||||||
server-user nscd
|
server-user nscd
|
||||||
threads 1
|
threads 1
|
||||||
paranoia no
|
paranoia no
|
||||||
debug-level 0
|
debug-level 0
|
||||||
|
|
||||||
enable-cache passwd yes
|
enable-cache passwd yes
|
||||||
positive-time-to-live passwd 600
|
positive-time-to-live passwd 0
|
||||||
negative-time-to-live passwd 20
|
negative-time-to-live passwd 0
|
||||||
suggested-size passwd 211
|
suggested-size passwd 211
|
||||||
check-files passwd yes
|
check-files passwd yes
|
||||||
persistent passwd no
|
persistent passwd no
|
||||||
shared passwd yes
|
shared passwd yes
|
||||||
|
|
||||||
enable-cache group yes
|
enable-cache group yes
|
||||||
positive-time-to-live group 3600
|
positive-time-to-live group 0
|
||||||
negative-time-to-live group 60
|
negative-time-to-live group 0
|
||||||
suggested-size group 211
|
suggested-size group 211
|
||||||
check-files group yes
|
check-files group yes
|
||||||
persistent group no
|
persistent group no
|
||||||
shared group yes
|
shared group yes
|
||||||
|
|
||||||
|
enable-cache netgroup yes
|
||||||
|
positive-time-to-live netgroup 0
|
||||||
|
negative-time-to-live netgroup 0
|
||||||
|
suggested-size netgroup 211
|
||||||
|
check-files netgroup yes
|
||||||
|
persistent netgroup no
|
||||||
|
shared netgroup yes
|
||||||
|
|
||||||
enable-cache hosts yes
|
enable-cache hosts yes
|
||||||
positive-time-to-live hosts 600
|
positive-time-to-live hosts 600
|
||||||
negative-time-to-live hosts 5
|
negative-time-to-live hosts 0
|
||||||
suggested-size hosts 211
|
suggested-size hosts 211
|
||||||
check-files hosts yes
|
check-files hosts yes
|
||||||
persistent hosts no
|
persistent hosts no
|
||||||
shared hosts yes
|
shared hosts yes
|
||||||
|
|
||||||
|
enable-cache services yes
|
||||||
|
positive-time-to-live services 0
|
||||||
|
negative-time-to-live services 0
|
||||||
|
suggested-size services 211
|
||||||
|
check-files services yes
|
||||||
|
persistent services no
|
||||||
|
shared services yes
|
||||||
|
@ -484,4 +484,6 @@ in {
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
meta.doc = ./nextcloud.xml;
|
||||||
}
|
}
|
||||||
|
99
nixos/modules/services/web-apps/nextcloud.xml
Normal file
99
nixos/modules/services/web-apps/nextcloud.xml
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<chapter 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="module-services-nextcloud">
|
||||||
|
<title>Nextcloud</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://nextcloud.com/">Nextcloud</link> is an open-source, self-hostable cloud
|
||||||
|
platform. The server setup can be automated using
|
||||||
|
<link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. A desktop client is packaged
|
||||||
|
at <literal>pkgs.nextcloud-client</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="module-services-nextcloud-basic-usage">
|
||||||
|
<title>Basic usage</title>
|
||||||
|
<para>
|
||||||
|
Nextcloud is a PHP-based application which requires an HTTP server
|
||||||
|
(<literal><link linkend="opt-services.nextcloud.enable">services.nextcloud</link></literal> optionally supports
|
||||||
|
<literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>) and a database
|
||||||
|
(it's recommended to use <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A very basic configuration may look like this:
|
||||||
|
<programlisting>{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.nextcloud = {
|
||||||
|
<link linkend="opt-services.nextcloud.enable">enable</link> = true;
|
||||||
|
<link linkend="opt-services.nextcloud.hostName">hostName</link> = "nextcloud.tld";
|
||||||
|
<link linkend="opt-services.nextcloud.nginx.enable">nginx.enable</link> = true;
|
||||||
|
config = {
|
||||||
|
<link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql";
|
||||||
|
<link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud";
|
||||||
|
<link linkend="opt-services.nextcloud.config.dbhost">dbhost</link> = "/tmp"; # nextcloud will add /.s.PGSQL.5432 by itself
|
||||||
|
<link linkend="opt-services.nextcloud.config.dbname">dbname</link> = "nextcloud";
|
||||||
|
<link linkend="opt-services.nextcloud.config.adminpassFile">adminpassFile</link> = "/path/to/admin-pass-file";
|
||||||
|
<link linkend="opt-services.nextcloud.config.adminuser">adminuser</link> = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
<link linkend="opt-services.postgresql.enable">enable</link> = true;
|
||||||
|
<link linkend="opt-services.postgresql.initialScript">initialScript</link> = pkgs.writeText "psql-init" ''
|
||||||
|
CREATE ROLE nextcloud WITH LOGIN;
|
||||||
|
CREATE DATABASE nextcloud WITH OWNER nextcloud;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# ensure that postgres is running *before* running the setup
|
||||||
|
systemd.services."nextcloud-setup" = {
|
||||||
|
requires = ["postgresql.service"];
|
||||||
|
after = ["postgresql.service"];
|
||||||
|
};
|
||||||
|
|
||||||
|
<link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
|
||||||
|
}</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The options <literal>hostName</literal> and <literal>nginx.enable</literal> are used internally to configure an
|
||||||
|
HTTP server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> and <literal>nginx</literal>.
|
||||||
|
The <literal>config</literal> attribute set is used for the <literal>config.php</literal> which is used
|
||||||
|
for the application's configuration.
|
||||||
|
<emphasis>Beware: this isn't entirely pure since the config is modified by the application's runtime!</emphasis>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
In case the application serves multiple hosts (those are checked with
|
||||||
|
<literal><link xlink:href="http://php.net/manual/en/reserved.variables.server.php">$_SERVER['HTTP_HOST']</link></literal>)
|
||||||
|
those can be added using
|
||||||
|
<literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="module-services-nextcloud-pitfalls-during-upgrade">
|
||||||
|
<title>Pitfalls</title>
|
||||||
|
<para>
|
||||||
|
Unfortunately Nextcloud appears to be very stateful when it comes to managing its own configuration. The
|
||||||
|
config file lives in the home directory of the <literal>nextcloud</literal> user (by default
|
||||||
|
<literal>/var/lib/nextcloud/config/config.php</literal>) and is also used to track several
|
||||||
|
states of the application (e.g. whether installed or not).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Right now changes to the <literal>services.nextcloud.config</literal> attribute set won't take effect
|
||||||
|
after the first install
|
||||||
|
(except <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>) since the actual configuration
|
||||||
|
file is generated by the NextCloud installer which also sets up critical parts such as the database
|
||||||
|
structure.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
<emphasis>Warning: don't delete <literal>config.php</literal>! This file tracks the application's state and a deletion can cause unwanted side-effects!</emphasis>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
<emphasis>Warning: don't rerun <literal>nextcloud-occ maintenance:install</literal>! This command tries to install the application and can cause unwanted side-effects!</emphasis>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The issues are known and reported in <link xlink:href="https://github.com/NixOS/nixpkgs/issues/49783">#49783</link>, for now it's unfortunately necessary to manually work around these issues.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</chapter>
|
@ -1,101 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.quassel-webserver;
|
|
||||||
quassel-webserver = cfg.pkg;
|
|
||||||
settings = ''
|
|
||||||
module.exports = {
|
|
||||||
default: {
|
|
||||||
host: '${cfg.quasselCoreHost}', // quasselcore host
|
|
||||||
port: ${toString cfg.quasselCorePort}, // quasselcore port
|
|
||||||
initialBacklogLimit: ${toString cfg.initialBacklogLimit}, // Amount of backlogs to fetch per buffer on connection
|
|
||||||
backlogLimit: ${toString cfg.backlogLimit}, // Amount of backlogs to fetch per buffer after first retrieval
|
|
||||||
securecore: ${boolToString cfg.secureCore}, // Connect to the core using SSL
|
|
||||||
theme: '${cfg.theme}' // Default UI theme
|
|
||||||
},
|
|
||||||
themes: ['default', 'darksolarized'], // Available themes
|
|
||||||
forcedefault: ${boolToString cfg.forceHostAndPort}, // Will force default host and port to be used, and will hide the corresponding fields in the UI
|
|
||||||
prefixpath: '${cfg.prefixPath}' // Configure this if you use a reverse proxy
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
settingsFile = pkgs.writeText "settings-user.js" settings;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.quassel-webserver = {
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Whether to enable the quassel webclient service";
|
|
||||||
};
|
|
||||||
pkg = mkOption {
|
|
||||||
default = pkgs.quassel-webserver;
|
|
||||||
defaultText = "pkgs.quassel-webserver";
|
|
||||||
type = types.package;
|
|
||||||
description = "The quassel-webserver package";
|
|
||||||
};
|
|
||||||
quasselCoreHost = mkOption {
|
|
||||||
default = "";
|
|
||||||
type = types.str;
|
|
||||||
description = "The default host of the quassel core";
|
|
||||||
};
|
|
||||||
quasselCorePort = mkOption {
|
|
||||||
default = 4242;
|
|
||||||
type = types.int;
|
|
||||||
description = "The default quassel core port";
|
|
||||||
};
|
|
||||||
initialBacklogLimit = mkOption {
|
|
||||||
default = 20;
|
|
||||||
type = types.int;
|
|
||||||
description = "Amount of backlogs to fetch per buffer on connection";
|
|
||||||
};
|
|
||||||
backlogLimit = mkOption {
|
|
||||||
default = 100;
|
|
||||||
type = types.int;
|
|
||||||
description = "Amount of backlogs to fetch per buffer after first retrieval";
|
|
||||||
};
|
|
||||||
secureCore = mkOption {
|
|
||||||
default = true;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Connect to the core using SSL";
|
|
||||||
};
|
|
||||||
theme = mkOption {
|
|
||||||
default = "default";
|
|
||||||
type = types.str;
|
|
||||||
description = "default or darksolarized";
|
|
||||||
};
|
|
||||||
prefixPath = mkOption {
|
|
||||||
default = "";
|
|
||||||
type = types.str;
|
|
||||||
description = "Configure this if you use a reverse proxy. Must start with a '/'";
|
|
||||||
example = "/quassel";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
default = 60443;
|
|
||||||
type = types.int;
|
|
||||||
description = "The port the quassel webserver should listen on";
|
|
||||||
};
|
|
||||||
useHttps = mkOption {
|
|
||||||
default = true;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Whether the quassel webserver connection should be a https connection";
|
|
||||||
};
|
|
||||||
forceHostAndPort = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = "Force the users to use the quasselCoreHost and quasselCorePort defaults";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
systemd.services.quassel-webserver = {
|
|
||||||
description = "A web server/client for Quassel";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${quassel-webserver}/lib/node_modules/quassel-webserver/bin/www -p ${toString cfg.port} -m ${if cfg.useHttps == true then "https" else "http"} -c ${settingsFile}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -85,7 +85,7 @@ in rec {
|
|||||||
id = mkOption {
|
id = mkOption {
|
||||||
default = "main";
|
default = "main";
|
||||||
description = ''
|
description = ''
|
||||||
A unique identifier necessary to keep multiple owncloud server
|
A unique identifier necessary to keep multiple Limesurvey server
|
||||||
instances on the same machine apart. This is used to
|
instances on the same machine apart. This is used to
|
||||||
disambiguate the administrative scripts, which get names like
|
disambiguate the administrative scripts, which get names like
|
||||||
mediawiki-$id-change-password.
|
mediawiki-$id-change-password.
|
||||||
|
@ -83,11 +83,11 @@ let
|
|||||||
|
|
||||||
# Unpack Mediawiki and put the config file in its root directory.
|
# Unpack Mediawiki and put the config file in its root directory.
|
||||||
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
mediawikiRoot = pkgs.stdenv.mkDerivation rec {
|
||||||
name= "mediawiki-1.29.1";
|
name= "mediawiki-1.31.1";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = pkgs.fetchurl {
|
||||||
url = "https://releases.wikimedia.org/mediawiki/1.29/${name}.tar.gz";
|
url = "https://releases.wikimedia.org/mediawiki/1.31/${name}.tar.gz";
|
||||||
sha256 = "03mpazbxvb011s2nmlw5p6dc43yjgl5yrsilmj1imyykm57bwb3m";
|
sha256 = "13x48clij21cmysjkpnx68vggchrdasqp7b290j87xlfgjhdhnnf";
|
||||||
};
|
};
|
||||||
|
|
||||||
skins = config.skins;
|
skins = config.skins;
|
||||||
@ -111,7 +111,7 @@ let
|
|||||||
sed -i \
|
sed -i \
|
||||||
-e 's|/bin/bash|${pkgs.bash}/bin/bash|g' \
|
-e 's|/bin/bash|${pkgs.bash}/bin/bash|g' \
|
||||||
-e 's|/usr/bin/timeout|${pkgs.coreutils}/bin/timeout|g' \
|
-e 's|/usr/bin/timeout|${pkgs.coreutils}/bin/timeout|g' \
|
||||||
$out/includes/limit.sh \
|
$out/includes/shell/limit.sh \
|
||||||
$out/includes/GlobalFunctions.php
|
$out/includes/GlobalFunctions.php
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -1,608 +0,0 @@
|
|||||||
{ config, lib, pkgs, serverInfo, php, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
owncloudConfig = pkgs.writeText "config.php"
|
|
||||||
''
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/* Only enable this for local development and not in productive environments */
|
|
||||||
/* This will disable the minifier and outputs some additional debug informations */
|
|
||||||
define("DEBUG", false);
|
|
||||||
|
|
||||||
$CONFIG = array(
|
|
||||||
/* Flag to indicate ownCloud is successfully installed (true = installed) */
|
|
||||||
"installed" => true,
|
|
||||||
|
|
||||||
/* Type of database, can be sqlite, mysql or pgsql */
|
|
||||||
"dbtype" => "${config.dbType}",
|
|
||||||
|
|
||||||
/* Name of the ownCloud database */
|
|
||||||
"dbname" => "${config.dbName}",
|
|
||||||
|
|
||||||
/* User to access the ownCloud database */
|
|
||||||
"dbuser" => "${config.dbUser}",
|
|
||||||
|
|
||||||
/* Password to access the ownCloud database */
|
|
||||||
"dbpassword" => "${config.dbPassword}",
|
|
||||||
|
|
||||||
/* Host running the ownCloud database. To specify a port use "HOSTNAME:####"; to specify a unix sockets use "localhost:/path/to/socket". */
|
|
||||||
"dbhost" => "${config.dbServer}",
|
|
||||||
|
|
||||||
/* Prefix for the ownCloud tables in the database */
|
|
||||||
"dbtableprefix" => "",
|
|
||||||
|
|
||||||
/* Force use of HTTPS connection (true = use HTTPS) */
|
|
||||||
"forcessl" => ${config.forceSSL},
|
|
||||||
|
|
||||||
/* Blacklist a specific file and disallow the upload of files with this name - WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING. */
|
|
||||||
"blacklisted_files" => array('.htaccess'),
|
|
||||||
|
|
||||||
/* The automatic hostname detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */
|
|
||||||
"overwritehost" => "${config.overwriteHost}",
|
|
||||||
|
|
||||||
/* The automatic protocol detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the protocol detection. For example "https" */
|
|
||||||
"overwriteprotocol" => "${config.overwriteProtocol}",
|
|
||||||
|
|
||||||
/* The automatic webroot detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. For example "/domain.tld/ownCloud". The value "/" can be used to remove the root. */
|
|
||||||
"overwritewebroot" => "${config.overwriteWebRoot}",
|
|
||||||
|
|
||||||
/* The automatic detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to define a manually override condition as regular expression for the remote ip address. For example "^10\.0\.0\.[1-3]$" */
|
|
||||||
"overwritecondaddr" => "",
|
|
||||||
|
|
||||||
/* A proxy to use to connect to the internet. For example "myproxy.org:88" */
|
|
||||||
"proxy" => "",
|
|
||||||
|
|
||||||
/* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */
|
|
||||||
"proxyuserpwd" => "",
|
|
||||||
|
|
||||||
/* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */
|
|
||||||
${if config.trustedDomain != "" then "'trusted_domains' => array('${config.trustedDomain}')," else ""}
|
|
||||||
|
|
||||||
/* Theme to use for ownCloud */
|
|
||||||
"theme" => "",
|
|
||||||
|
|
||||||
/* Optional ownCloud default language - overrides automatic language detection on public pages like login or shared items. This has no effect on the user's language preference configured under "personal -> language" once they have logged in */
|
|
||||||
"default_language" => "${config.defaultLang}",
|
|
||||||
|
|
||||||
/* Path to the parent directory of the 3rdparty directory */
|
|
||||||
"3rdpartyroot" => "",
|
|
||||||
|
|
||||||
/* URL to the parent directory of the 3rdparty directory, as seen by the browser */
|
|
||||||
"3rdpartyurl" => "",
|
|
||||||
|
|
||||||
/* Default app to open on login.
|
|
||||||
* This can be a comma-separated list of app ids.
|
|
||||||
* If the first app is not enabled for the current user,
|
|
||||||
* it will try with the second one and so on. If no enabled app could be found,
|
|
||||||
* the "files" app will be displayed instead. */
|
|
||||||
"defaultapp" => "${config.defaultApp}",
|
|
||||||
|
|
||||||
/* Enable the help menu item in the settings */
|
|
||||||
"knowledgebaseenabled" => true,
|
|
||||||
|
|
||||||
/* Enable installing apps from the appstore */
|
|
||||||
"appstoreenabled" => ${config.appStoreEnable},
|
|
||||||
|
|
||||||
/* URL of the appstore to use, server should understand OCS */
|
|
||||||
"appstoreurl" => "https://api.owncloud.com/v1",
|
|
||||||
|
|
||||||
/* Domain name used by ownCloud for the sender mail address, e.g. no-reply@example.com */
|
|
||||||
"mail_domain" => "${config.mailFromDomain}",
|
|
||||||
|
|
||||||
/* FROM address used by ownCloud for the sender mail address, e.g. owncloud@example.com
|
|
||||||
This setting overwrites the built in 'sharing-noreply' and 'lostpassword-noreply'
|
|
||||||
FROM addresses, that ownCloud uses
|
|
||||||
*/
|
|
||||||
"mail_from_address" => "${config.mailFrom}",
|
|
||||||
|
|
||||||
/* Enable SMTP class debugging */
|
|
||||||
"mail_smtpdebug" => false,
|
|
||||||
|
|
||||||
/* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
|
|
||||||
"mail_smtpmode" => "${config.SMTPMode}",
|
|
||||||
|
|
||||||
/* Host to use for sending mail, depends on mail_smtpmode if this is used */
|
|
||||||
"mail_smtphost" => "${config.SMTPHost}",
|
|
||||||
|
|
||||||
/* Port to use for sending mail, depends on mail_smtpmode if this is used */
|
|
||||||
"mail_smtpport" => ${config.SMTPPort},
|
|
||||||
|
|
||||||
/* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */
|
|
||||||
"mail_smtptimeout" => ${config.SMTPTimeout},
|
|
||||||
|
|
||||||
/* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used.
|
|
||||||
Can be "", ssl or tls */
|
|
||||||
"mail_smtpsecure" => "${config.SMTPSecure}",
|
|
||||||
|
|
||||||
/* authentication needed to send mail, depends on mail_smtpmode if this is used
|
|
||||||
* (false = disable authentication)
|
|
||||||
*/
|
|
||||||
"mail_smtpauth" => ${config.SMTPAuth},
|
|
||||||
|
|
||||||
/* authentication type needed to send mail, depends on mail_smtpmode if this is used
|
|
||||||
* Can be LOGIN (default), PLAIN or NTLM */
|
|
||||||
"mail_smtpauthtype" => "${config.SMTPAuthType}",
|
|
||||||
|
|
||||||
/* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
|
|
||||||
"mail_smtpname" => "${config.SMTPUser}",
|
|
||||||
|
|
||||||
/* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
|
|
||||||
"mail_smtppassword" => "${config.SMTPPass}",
|
|
||||||
|
|
||||||
/* memcached servers (Only used when xCache, APC and APCu are absent.) */
|
|
||||||
"memcached_servers" => array(
|
|
||||||
// hostname, port and optional weight. Also see:
|
|
||||||
// http://www.php.net/manual/en/memcached.addservers.php
|
|
||||||
// http://www.php.net/manual/en/memcached.addserver.php
|
|
||||||
//array('localhost', 11211),
|
|
||||||
//array('other.host.local', 11211),
|
|
||||||
),
|
|
||||||
|
|
||||||
/* How long should ownCloud keep deleted files in the trash bin, default value: 30 days */
|
|
||||||
'trashbin_retention_obligation' => 30,
|
|
||||||
|
|
||||||
/* Disable/Enable auto expire for the trash bin, by default auto expire is enabled */
|
|
||||||
'trashbin_auto_expire' => true,
|
|
||||||
|
|
||||||
/* allow user to change his display name, if it is supported by the back-end */
|
|
||||||
'allow_user_to_change_display_name' => true,
|
|
||||||
|
|
||||||
/* Check 3rdparty apps for malicious code fragments */
|
|
||||||
"appcodechecker" => true,
|
|
||||||
|
|
||||||
/* Check if ownCloud is up to date */
|
|
||||||
"updatechecker" => true,
|
|
||||||
|
|
||||||
/* Are we connected to the internet or are we running in a closed network? */
|
|
||||||
"has_internet_connection" => true,
|
|
||||||
|
|
||||||
/* Check if the ownCloud WebDAV server is working correctly. Can be disabled if not needed in special situations*/
|
|
||||||
"check_for_working_webdav" => true,
|
|
||||||
|
|
||||||
/* Check if .htaccess protection of data is working correctly. Can be disabled if not needed in special situations*/
|
|
||||||
"check_for_working_htaccess" => true,
|
|
||||||
|
|
||||||
/* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
|
|
||||||
"log_type" => "owncloud",
|
|
||||||
|
|
||||||
/* File for the owncloud logger to log to, (default is ownloud.log in the data dir) */
|
|
||||||
"logfile" => "${config.dataDir}/owncloud.log",
|
|
||||||
|
|
||||||
/* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
|
|
||||||
"loglevel" => "2",
|
|
||||||
|
|
||||||
/* date format to be used while writing to the owncloud logfile */
|
|
||||||
'logdateformat' => 'F d, Y H:i:s',
|
|
||||||
|
|
||||||
${tzSetting}
|
|
||||||
|
|
||||||
/* Append all database queries and parameters to the log file.
|
|
||||||
(watch out, this option can increase the size of your log file)*/
|
|
||||||
"log_query" => false,
|
|
||||||
|
|
||||||
/* Whether ownCloud should log the last successfull cron exec */
|
|
||||||
"cron_log" => true,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
|
|
||||||
* This rotates the current owncloud logfile to a new name, this way the total log usage
|
|
||||||
* will stay limited and older entries are available for a while longer. The
|
|
||||||
* total disk usage is twice the configured size.
|
|
||||||
* WARNING: When you use this, the log entries will eventually be lost.
|
|
||||||
*/
|
|
||||||
'log_rotate_size' => "104857600", // 104857600, // 100 MiB
|
|
||||||
|
|
||||||
/* Lifetime of the remember login cookie, default is 15 days */
|
|
||||||
"remember_login_cookie_lifetime" => 1296000,
|
|
||||||
|
|
||||||
/* Life time of a session after inactivity */
|
|
||||||
"session_lifetime" => 86400,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable/disable session keep alive when a user is logged in in the Web UI.
|
|
||||||
* This is achieved by sending a "heartbeat" to the server to prevent
|
|
||||||
* the session timing out.
|
|
||||||
*/
|
|
||||||
"session_keepalive" => true,
|
|
||||||
|
|
||||||
/* Custom CSP policy, changing this will overwrite the standard policy */
|
|
||||||
"custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *",
|
|
||||||
|
|
||||||
/* Enable/disable X-Frame-Restriction */
|
|
||||||
/* HIGH SECURITY RISK IF DISABLED*/
|
|
||||||
"xframe_restriction" => true,
|
|
||||||
|
|
||||||
/* The directory where the user data is stored, default to data in the owncloud
|
|
||||||
* directory. The sqlite database is also stored here, when sqlite is used.
|
|
||||||
*/
|
|
||||||
"datadirectory" => "${config.dataDir}/storage",
|
|
||||||
|
|
||||||
/* The directory where the skeleton files are located. These files will be copied to the data
|
|
||||||
* directory of new users. Leave empty to not copy any skeleton files.
|
|
||||||
*/
|
|
||||||
// "skeletondirectory" => "",
|
|
||||||
|
|
||||||
/* Enable maintenance mode to disable ownCloud
|
|
||||||
If you want to prevent users to login to ownCloud before you start doing some maintenance work,
|
|
||||||
you need to set the value of the maintenance parameter to true.
|
|
||||||
Please keep in mind that users who are already logged-in are kicked out of ownCloud instantly.
|
|
||||||
*/
|
|
||||||
"maintenance" => false,
|
|
||||||
|
|
||||||
"apps_paths" => array(
|
|
||||||
|
|
||||||
/* Set an array of path for your apps directories
|
|
||||||
key 'path' is for the fs path and the key 'url' is for the http path to your
|
|
||||||
applications paths. 'writable' indicates whether the user can install apps in this folder.
|
|
||||||
You must have at least 1 app folder writable or you must set the parameter 'appstoreenabled' to false
|
|
||||||
*/
|
|
||||||
array(
|
|
||||||
'path'=> '${config.dataDir}/apps',
|
|
||||||
'url' => '/apps',
|
|
||||||
'writable' => true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'user_backends'=>array(
|
|
||||||
/*
|
|
||||||
array(
|
|
||||||
'class'=>'OC_User_IMAP',
|
|
||||||
'arguments'=>array('{imap.gmail.com:993/imap/ssl}INBOX')
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
),
|
|
||||||
//links to custom clients
|
|
||||||
'customclient_desktop' => ''', //http://owncloud.org/sync-clients/
|
|
||||||
'customclient_android' => ''', //https://play.google.com/store/apps/details?id=com.owncloud.android
|
|
||||||
'customclient_ios' => ''', //https://itunes.apple.com/us/app/owncloud/id543672169?mt=8
|
|
||||||
|
|
||||||
// PREVIEW
|
|
||||||
'enable_previews' => true,
|
|
||||||
/* the max width of a generated preview, if value is null, there is no limit */
|
|
||||||
'preview_max_x' => null,
|
|
||||||
/* the max height of a generated preview, if value is null, there is no limit */
|
|
||||||
'preview_max_y' => null,
|
|
||||||
/* the max factor to scale a preview, default is set to 10 */
|
|
||||||
'preview_max_scale_factor' => 10,
|
|
||||||
/* custom path for libreoffice / openoffice binary */
|
|
||||||
'preview_libreoffice_path' => '${config.libreofficePath}',
|
|
||||||
/* cl parameters for libreoffice / openoffice */
|
|
||||||
'preview_office_cl_parameters' => ''',
|
|
||||||
|
|
||||||
/* whether avatars should be enabled */
|
|
||||||
'enable_avatars' => true,
|
|
||||||
|
|
||||||
// Extra SSL options to be used for configuration
|
|
||||||
'openssl' => array(
|
|
||||||
'config' => '/etc/ssl/openssl.cnf',
|
|
||||||
),
|
|
||||||
|
|
||||||
// default cipher used for file encryption, currently we support AES-128-CFB and AES-256-CFB
|
|
||||||
'cipher' => 'AES-256-CFB',
|
|
||||||
|
|
||||||
/* whether usage of the instance should be restricted to admin users only */
|
|
||||||
'singleuser' => false,
|
|
||||||
|
|
||||||
/* all css and js files will be served by the web server statically in one js file and ons css file*/
|
|
||||||
'asset-pipeline.enabled' => false,
|
|
||||||
|
|
||||||
/* where mount.json file should be stored, defaults to data/mount.json */
|
|
||||||
'mount_file' => ''',
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user.
|
|
||||||
*
|
|
||||||
* When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured
|
|
||||||
* cache directory and "$user" is the user.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
'cache_path' => ''',
|
|
||||||
|
|
||||||
/* EXPERIMENTAL: option whether to include external storage in quota calculation, defaults to false */
|
|
||||||
'quota_include_external_storage' => false,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* specifies how often the filesystem is checked for changes made outside owncloud
|
|
||||||
* 0 -> never check the filesystem for outside changes, provides a performance increase when it's certain that no changes are made directly to the filesystem
|
|
||||||
* 1 -> check each file or folder at most once per request, recomended for general use if outside changes might happen
|
|
||||||
* 2 -> check every time the filesystem is used, causes a performance hit when using external storages, not recomended for regular use
|
|
||||||
*/
|
|
||||||
'filesystem_check_changes' => 1,
|
|
||||||
|
|
||||||
/* If true, prevent owncloud from changing the cache due to changes in the filesystem for all storage */
|
|
||||||
'filesystem_cache_readonly' => false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* define default folder for shared files and folders
|
|
||||||
*/
|
|
||||||
'share_folder' => '/',
|
|
||||||
|
|
||||||
'version' => '${config.package.version}',
|
|
||||||
|
|
||||||
'openssl' => '${pkgs.openssl.bin}/bin/openssl'
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
'';
|
|
||||||
|
|
||||||
tzSetting = let tz = serverInfo.fullConfig.time.timeZone; in optionalString (!isNull tz) ''
|
|
||||||
/* timezone used while writing to the owncloud logfile (default: UTC) */
|
|
||||||
'logtimezone' => '${tz}',
|
|
||||||
'';
|
|
||||||
|
|
||||||
postgresql = serverInfo.fullConfig.services.postgresql.package;
|
|
||||||
|
|
||||||
setupDb = pkgs.writeScript "setup-owncloud-db" ''
|
|
||||||
#!${pkgs.runtimeShell}
|
|
||||||
PATH="${postgresql}/bin"
|
|
||||||
createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
|
|
||||||
createdb "${config.dbName}" -O "${config.dbUser}" || true
|
|
||||||
psql -U postgres -d postgres -c "alter user ${config.dbUser} with password '${config.dbPassword}';" || true
|
|
||||||
|
|
||||||
QUERY="CREATE TABLE appconfig
|
|
||||||
( appid VARCHAR( 255 ) NOT NULL
|
|
||||||
, configkey VARCHAR( 255 ) NOT NULL
|
|
||||||
, configvalue VARCHAR( 255 ) NOT NULL
|
|
||||||
);
|
|
||||||
GRANT ALL ON appconfig TO ${config.dbUser};
|
|
||||||
ALTER TABLE appconfig OWNER TO ${config.dbUser};"
|
|
||||||
|
|
||||||
psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
rec {
|
|
||||||
|
|
||||||
extraConfig =
|
|
||||||
''
|
|
||||||
${if config.urlPrefix != "" then "Alias ${config.urlPrefix} ${config.package}" else ''
|
|
||||||
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
|
|
||||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
|
|
||||||
''}
|
|
||||||
|
|
||||||
<Directory ${config.package}>
|
|
||||||
Include ${config.package}/.htaccess
|
|
||||||
</Directory>
|
|
||||||
'';
|
|
||||||
|
|
||||||
globalEnvVars = [
|
|
||||||
{ name = "OC_CONFIG_PATH"; value = "${config.dataDir}/config/"; }
|
|
||||||
];
|
|
||||||
|
|
||||||
documentRoot = if config.urlPrefix == "" then config.package else null;
|
|
||||||
|
|
||||||
enablePHP = true;
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.owncloud70;
|
|
||||||
defaultText = "pkgs.owncloud70";
|
|
||||||
example = literalExample "pkgs.owncloud70";
|
|
||||||
description = ''
|
|
||||||
ownCloud package to use.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
urlPrefix = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "/owncloud";
|
|
||||||
description = ''
|
|
||||||
The URL prefix under which the owncloud service appears.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
id = mkOption {
|
|
||||||
default = "main";
|
|
||||||
description = ''
|
|
||||||
A unique identifier necessary to keep multiple owncloud server
|
|
||||||
instances on the same machine apart. This is used to
|
|
||||||
disambiguate the administrative scripts, which get names like
|
|
||||||
mediawiki-$id-change-password.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
adminUser = mkOption {
|
|
||||||
default = "owncloud";
|
|
||||||
description = "The admin user name for accessing owncloud.";
|
|
||||||
};
|
|
||||||
|
|
||||||
adminPassword = mkOption {
|
|
||||||
description = "The admin password for accessing owncloud.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbType = mkOption {
|
|
||||||
default = "pgsql";
|
|
||||||
description = "Type of database, in NixOS, for now, only pgsql.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbName = mkOption {
|
|
||||||
default = "owncloud";
|
|
||||||
description = "Name of the database that holds the owncloud data.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbServer = mkOption {
|
|
||||||
default = "localhost:5432";
|
|
||||||
description = ''
|
|
||||||
The location of the database server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dbUser = mkOption {
|
|
||||||
default = "owncloud";
|
|
||||||
description = "The user name for accessing the database.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbPassword = mkOption {
|
|
||||||
example = "foobar";
|
|
||||||
description = ''
|
|
||||||
The password of the database user. Warning: this is stored in
|
|
||||||
cleartext in the Nix store!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
forceSSL = mkOption {
|
|
||||||
default = "false";
|
|
||||||
description = "Force use of HTTPS connection.";
|
|
||||||
};
|
|
||||||
|
|
||||||
adminAddr = mkOption {
|
|
||||||
default = serverInfo.serverConfig.adminAddr;
|
|
||||||
example = "admin@example.com";
|
|
||||||
description = ''
|
|
||||||
Emergency contact e-mail address. Defaults to the Apache
|
|
||||||
admin address.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
siteName = mkOption {
|
|
||||||
default = "owncloud";
|
|
||||||
example = "Foobar owncloud";
|
|
||||||
description = "Name of the owncloud";
|
|
||||||
};
|
|
||||||
|
|
||||||
trustedDomain = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "Trusted domain";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultLang = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "Default language";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultApp = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "Default application";
|
|
||||||
};
|
|
||||||
|
|
||||||
appStoreEnable = mkOption {
|
|
||||||
default = "true";
|
|
||||||
description = "Enable app store";
|
|
||||||
};
|
|
||||||
|
|
||||||
mailFrom = mkOption {
|
|
||||||
default = "no-reply";
|
|
||||||
description = "Mail from";
|
|
||||||
};
|
|
||||||
|
|
||||||
mailFromDomain = mkOption {
|
|
||||||
default = "example.xyz";
|
|
||||||
description = "Mail from domain";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPMode = mkOption {
|
|
||||||
default = "smtp";
|
|
||||||
description = "Which mode to use for sending mail: sendmail, smtp, qmail or php.";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPHost = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "SMTP host";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPPort = mkOption {
|
|
||||||
default = "25";
|
|
||||||
description = "SMTP port";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPTimeout = mkOption {
|
|
||||||
default = "10";
|
|
||||||
description = "SMTP mode";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPSecure = mkOption {
|
|
||||||
default = "ssl";
|
|
||||||
description = "SMTP secure";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPAuth = mkOption {
|
|
||||||
default = "true";
|
|
||||||
description = "SMTP auth";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPAuthType = mkOption {
|
|
||||||
default = "LOGIN";
|
|
||||||
description = "SMTP auth type";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPUser = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "SMTP user";
|
|
||||||
};
|
|
||||||
|
|
||||||
SMTPPass = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "SMTP pass";
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
default = "/var/lib/owncloud";
|
|
||||||
description = "Data dir";
|
|
||||||
};
|
|
||||||
|
|
||||||
libreofficePath = mkOption {
|
|
||||||
default = "/usr/bin/libreoffice";
|
|
||||||
description = "Path for LibreOffice/OpenOffice binary.";
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteHost = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "The automatic hostname detection of ownCloud can fail in
|
|
||||||
certain reverse proxy and CLI/cron situations. This option allows to
|
|
||||||
manually override the automatic detection. You can also add a port.";
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteProtocol = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "The automatic protocol detection of ownCloud can fail in
|
|
||||||
certain reverse proxy and CLI/cron situations. This option allows to
|
|
||||||
manually override the protocol detection.";
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteWebRoot = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "The automatic webroot detection of ownCloud can fail in
|
|
||||||
certain reverse proxy and CLI/cron situations. This option allows to
|
|
||||||
manually override the automatic detection.";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
startupScript = pkgs.writeScript "owncloud_startup.sh" ''
|
|
||||||
|
|
||||||
if [ ! -d ${config.dataDir}/config ]; then
|
|
||||||
mkdir -p ${config.dataDir}/config
|
|
||||||
cp ${owncloudConfig} ${config.dataDir}/config/config.php
|
|
||||||
mkdir -p ${config.dataDir}/storage
|
|
||||||
mkdir -p ${config.dataDir}/apps
|
|
||||||
cp -r ${config.package}/apps/* ${config.dataDir}/apps/
|
|
||||||
chmod -R ug+rw ${config.dataDir}
|
|
||||||
chmod -R o-rwx ${config.dataDir}
|
|
||||||
chown -R wwwrun:wwwrun ${config.dataDir}
|
|
||||||
|
|
||||||
${pkgs.sudo}/bin/sudo -u postgres ${setupDb}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e ${config.package}/config/ca-bundle.crt ]; then
|
|
||||||
cp -f ${config.package}/config/ca-bundle.crt ${config.dataDir}/config/
|
|
||||||
fi
|
|
||||||
|
|
||||||
${php}/bin/php ${config.package}/occ upgrade >> ${config.dataDir}/upgrade.log || true
|
|
||||||
|
|
||||||
chown wwwrun:wwwrun ${config.dataDir}/owncloud.log || true
|
|
||||||
|
|
||||||
QUERY="INSERT INTO groups (gid) values('admin');
|
|
||||||
INSERT INTO users (uid,password)
|
|
||||||
values('${config.adminUser}','${builtins.hashString "sha1" config.adminPassword}');
|
|
||||||
INSERT INTO group_user (gid,uid)
|
|
||||||
values('admin','${config.adminUser}');"
|
|
||||||
${pkgs.sudo}/bin/sudo -u postgres ${postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
|
|
||||||
'';
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user