Update all legacy-style modules

I.e., modules that use "require = [options]".  Nowadays that should be
written as

  {
    options = { ... };
    config = { ... };
  };

Also, use "imports" instead of "require" in places where we actually
import another module.
This commit is contained in:
Eelco Dolstra 2013-09-04 13:05:09 +02:00
parent 3a23e6dd31
commit 17457297cb
54 changed files with 1827 additions and 1934 deletions

View File

@ -2,11 +2,20 @@
with pkgs.lib; with pkgs.lib;
###### interface
let let
glibcLocales = pkgs.glibcLocales.override {
allLocales = any (x: x == "all") config.i18n.supportedLocales;
locales = config.i18n.supportedLocales;
};
in
{
###### interface
options = { options = {
i18n = { i18n = {
defaultLocale = mkOption { defaultLocale = mkOption {
default = "en_US.UTF-8"; default = "en_US.UTF-8";
@ -53,31 +62,26 @@ let
}; };
###### implementation
glibcLocales = pkgs.glibcLocales.override { ###### implementation
allLocales = any (x: x == "all") config.i18n.supportedLocales;
locales = config.i18n.supportedLocales; config = {
environment.systemPackages = [ glibcLocales ];
environment.shellInit =
''
export LANG=${config.i18n.defaultLocale}
'';
# /etc/locale.conf is used by systemd.
environment.etc = singleton
{ target = "locale.conf";
source = pkgs.writeText "locale.conf"
''
LANG=${config.i18n.defaultLocale}
'';
};
}; };
in
{
require = options;
environment.systemPackages = [ glibcLocales ];
environment.shellInit =
''
export LANG=${config.i18n.defaultLocale}
'';
# /etc/locale.conf is used by systemd.
environment.etc = singleton
{ target = "locale.conf";
source = pkgs.writeText "locale.conf"
''
LANG=${config.i18n.defaultLocale}
'';
};
} }

View File

@ -1,12 +1,18 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.krb5; cfg = config.krb5;
in
{
###### interface
options = { options = {
krb5 = { krb5 = {
enable = mkOption { enable = mkOption {
@ -35,171 +41,164 @@ let
}; };
}; };
}; };
in
###### implementation ###### implementation
mkIf config.krb5.enable { config = mkIf config.krb5.enable {
require = [
options
];
environment = { environment.systemPackages = [ pkgs.krb5 ];
systemPackages = [ pkgs.krb5 ];
etc = [
{ source = pkgs.writeText "krb5.conf"
''
[libdefaults]
default_realm = ${cfg.defaultRealm}
encrypt = true
# The following krb5.conf variables are only for MIT Kerberos. environment.etc."krb5.conf".text =
krb4_config = /etc/krb.conf ''
krb4_realms = /etc/krb.realms [libdefaults]
kdc_timesync = 1 default_realm = ${cfg.defaultRealm}
ccache_type = 4 encrypt = true
forwardable = true
proxiable = true
# The following encryption type specification will be used by MIT Kerberos # The following krb5.conf variables are only for MIT Kerberos.
# if uncommented. In general, the defaults in the MIT Kerberos code are krb4_config = /etc/krb.conf
# correct and overriding these specifications only serves to disable new krb4_realms = /etc/krb.realms
# encryption types as they are added, creating interoperability problems. kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
# default_tgs_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5 # The following encryption type specification will be used by MIT Kerberos
# default_tkt_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5 # if uncommented. In general, the defaults in the MIT Kerberos code are
# permitted_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5 # correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
# The following libdefaults parameters are only for Heimdal Kerberos. # default_tgs_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5
v4_instance_resolve = false # default_tkt_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5
v4_name_convert = { # permitted_enctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5
host = {
rcmd = host
ftp = ftp
}
plain = {
something = something-else
}
}
fcc-mit-ticketflags = true
[realms] # The following libdefaults parameters are only for Heimdal Kerberos.
${cfg.defaultRealm} = { v4_instance_resolve = false
kdc = ${cfg.kdc} v4_name_convert = {
admin_server = ${cfg.kerberosAdminServer} host = {
# kpasswd_server = ${cfg.kerberosAdminServer} rcmd = host
} ftp = ftp
ATHENA.MIT.EDU = { }
kdc = kerberos.mit.edu:88 plain = {
kdc = kerberos-1.mit.edu:88 something = something-else
kdc = kerberos-2.mit.edu:88 }
admin_server = kerberos.mit.edu }
default_domain = mit.edu fcc-mit-ticketflags = true
}
MEDIA-LAB.MIT.EDU = {
kdc = kerberos.media.mit.edu
admin_server = kerberos.media.mit.edu
}
ZONE.MIT.EDU = {
kdc = casio.mit.edu
kdc = seiko.mit.edu
admin_server = casio.mit.edu
}
MOOF.MIT.EDU = {
kdc = three-headed-dogcow.mit.edu:88
kdc = three-headed-dogcow-1.mit.edu:88
admin_server = three-headed-dogcow.mit.edu
}
CSAIL.MIT.EDU = {
kdc = kerberos-1.csail.mit.edu
kdc = kerberos-2.csail.mit.edu
admin_server = kerberos.csail.mit.edu
default_domain = csail.mit.edu
krb524_server = krb524.csail.mit.edu
}
IHTFP.ORG = {
kdc = kerberos.ihtfp.org
admin_server = kerberos.ihtfp.org
}
GNU.ORG = {
kdc = kerberos.gnu.org
kdc = kerberos-2.gnu.org
kdc = kerberos-3.gnu.org
admin_server = kerberos.gnu.org
}
1TS.ORG = {
kdc = kerberos.1ts.org
admin_server = kerberos.1ts.org
}
GRATUITOUS.ORG = {
kdc = kerberos.gratuitous.org
admin_server = kerberos.gratuitous.org
}
DOOMCOM.ORG = {
kdc = kerberos.doomcom.org
admin_server = kerberos.doomcom.org
}
ANDREW.CMU.EDU = {
kdc = vice28.fs.andrew.cmu.edu
kdc = vice2.fs.andrew.cmu.edu
kdc = vice11.fs.andrew.cmu.edu
kdc = vice12.fs.andrew.cmu.edu
admin_server = vice28.fs.andrew.cmu.edu
default_domain = andrew.cmu.edu
}
CS.CMU.EDU = {
kdc = kerberos.cs.cmu.edu
kdc = kerberos-2.srv.cs.cmu.edu
admin_server = kerberos.cs.cmu.edu
}
DEMENTIA.ORG = {
kdc = kerberos.dementia.org
kdc = kerberos2.dementia.org
admin_server = kerberos.dementia.org
}
stanford.edu = {
kdc = krb5auth1.stanford.edu
kdc = krb5auth2.stanford.edu
kdc = krb5auth3.stanford.edu
admin_server = krb5-admin.stanford.edu
default_domain = stanford.edu
}
[domain_realm] [realms]
.${cfg.domainRealm} = ${cfg.defaultRealm} ${cfg.defaultRealm} = {
${cfg.domainRealm} = ${cfg.defaultRealm} kdc = ${cfg.kdc}
.mit.edu = ATHENA.MIT.EDU admin_server = ${cfg.kerberosAdminServer}
mit.edu = ATHENA.MIT.EDU #kpasswd_server = ${cfg.kerberosAdminServer}
.media.mit.edu = MEDIA-LAB.MIT.EDU }
media.mit.edu = MEDIA-LAB.MIT.EDU ATHENA.MIT.EDU = {
.csail.mit.edu = CSAIL.MIT.EDU kdc = kerberos.mit.edu:88
csail.mit.edu = CSAIL.MIT.EDU kdc = kerberos-1.mit.edu:88
.whoi.edu = ATHENA.MIT.EDU kdc = kerberos-2.mit.edu:88
whoi.edu = ATHENA.MIT.EDU admin_server = kerberos.mit.edu
.stanford.edu = stanford.edu default_domain = mit.edu
}
MEDIA-LAB.MIT.EDU = {
kdc = kerberos.media.mit.edu
admin_server = kerberos.media.mit.edu
}
ZONE.MIT.EDU = {
kdc = casio.mit.edu
kdc = seiko.mit.edu
admin_server = casio.mit.edu
}
MOOF.MIT.EDU = {
kdc = three-headed-dogcow.mit.edu:88
kdc = three-headed-dogcow-1.mit.edu:88
admin_server = three-headed-dogcow.mit.edu
}
CSAIL.MIT.EDU = {
kdc = kerberos-1.csail.mit.edu
kdc = kerberos-2.csail.mit.edu
admin_server = kerberos.csail.mit.edu
default_domain = csail.mit.edu
krb524_server = krb524.csail.mit.edu
}
IHTFP.ORG = {
kdc = kerberos.ihtfp.org
admin_server = kerberos.ihtfp.org
}
GNU.ORG = {
kdc = kerberos.gnu.org
kdc = kerberos-2.gnu.org
kdc = kerberos-3.gnu.org
admin_server = kerberos.gnu.org
}
1TS.ORG = {
kdc = kerberos.1ts.org
admin_server = kerberos.1ts.org
}
GRATUITOUS.ORG = {
kdc = kerberos.gratuitous.org
admin_server = kerberos.gratuitous.org
}
DOOMCOM.ORG = {
kdc = kerberos.doomcom.org
admin_server = kerberos.doomcom.org
}
ANDREW.CMU.EDU = {
kdc = vice28.fs.andrew.cmu.edu
kdc = vice2.fs.andrew.cmu.edu
kdc = vice11.fs.andrew.cmu.edu
kdc = vice12.fs.andrew.cmu.edu
admin_server = vice28.fs.andrew.cmu.edu
default_domain = andrew.cmu.edu
}
CS.CMU.EDU = {
kdc = kerberos.cs.cmu.edu
kdc = kerberos-2.srv.cs.cmu.edu
admin_server = kerberos.cs.cmu.edu
}
DEMENTIA.ORG = {
kdc = kerberos.dementia.org
kdc = kerberos2.dementia.org
admin_server = kerberos.dementia.org
}
stanford.edu = {
kdc = krb5auth1.stanford.edu
kdc = krb5auth2.stanford.edu
kdc = krb5auth3.stanford.edu
admin_server = krb5-admin.stanford.edu
default_domain = stanford.edu
}
[logging] [domain_realm]
kdc = SYSLOG:INFO:DAEMON .${cfg.domainRealm} = ${cfg.defaultRealm}
admin_server = SYSLOG:INFO:DAEMON ${cfg.domainRealm} = ${cfg.defaultRealm}
default = SYSLOG:INFO:DAEMON .mit.edu = ATHENA.MIT.EDU
krb4_convert = true mit.edu = ATHENA.MIT.EDU
krb4_get_tickets = false .media.mit.edu = MEDIA-LAB.MIT.EDU
media.mit.edu = MEDIA-LAB.MIT.EDU
.csail.mit.edu = CSAIL.MIT.EDU
csail.mit.edu = CSAIL.MIT.EDU
.whoi.edu = ATHENA.MIT.EDU
whoi.edu = ATHENA.MIT.EDU
.stanford.edu = stanford.edu
[logging]
kdc = SYSLOG:INFO:DAEMON
admin_server = SYSLOG:INFO:DAEMON
default = SYSLOG:INFO:DAEMON
krb4_convert = true
krb4_get_tickets = false
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
max_timeout = 30
timeout_shift = 2
initial_timeout = 1
}
'';
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
max_timeout = 30
timeout_shift = 2
initial_timeout = 1
}
'';
target = "krb5.conf";
}
];
}; };
} }

View File

@ -1,150 +1,12 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib; with pkgs.lib;
with pkgs; with pkgs;
###### interface
let let
inherit mkOption mkIf optionalString stringAfter singleton;
cfg = config.users.ldap; cfg = config.users.ldap;
options = {
users = {
ldap = {
enable = mkOption {
default = false;
description = "
Whether to enable authentication against an LDAP server.
";
};
server = mkOption {
example = "ldap://ldap.example.org/";
description = "
The URL of the LDAP server.
";
};
base = mkOption {
example = "dc=example,dc=org";
description = "
The distinguished name of the search base.
";
};
useTLS = mkOption {
default = false;
description = "
If enabled, use TLS (encryption) over an LDAP (port 389)
connection. The alternative is to specify an LDAPS server (port
636) in <option>users.ldap.server</option> or to forego
security.
";
};
timeLimit = mkOption {
default = 0;
type = types.int;
description = "
Specifies the time limit (in seconds) to use when performing
searches. A value of zero (0), which is the default, is to
wait indefinitely for searches to be completed.
";
};
daemon = {
enable = mkOption {
default = false;
description = ''
Whether to let the nslcd daemon (nss-pam-ldapd) handle the
LDAP lookups for NSS and PAM. This can improve performance,
and if you need to bind to the LDAP server with a password,
it increases security, since only the nslcd user needs to
have access to the bindpw file, not everyone that uses NSS
and/or PAM. If this option is enabled, a local nscd user is
created automatically, and the nslcd service is started
automatically when the network get up.
'';
};
extraConfig = mkOption {
default = "";
type = types.string;
description = ''
Extra configuration options that will be added verbatim at
the end of the nslcd configuration file (nslcd.conf).
'' ;
} ;
};
bind = {
distinguishedName = mkOption {
default = "";
example = "cn=admin,dc=example,dc=com";
type = types.string;
description = "
The distinguished name to bind to the LDAP server with. If this
is not specified, an anonymous bind will be done.
";
};
password = mkOption {
default = "/etc/ldap/bind.password";
type = types.string;
description = "
The path to a file containing the credentials to use when binding
to the LDAP server (if not binding anonymously).
";
};
timeLimit = mkOption {
default = 30;
type = types.int;
description = "
Specifies the time limit (in seconds) to use when connecting
to the directory server. This is distinct from the time limit
specified in <literal>users.ldap.timeLimit</literal> and affects
the initial server connection only.
";
};
policy = mkOption {
default = "hard_open";
type = types.string;
description = "
Specifies the policy to use for reconnecting to an unavailable
LDAP server. The default is <literal>hard_open</literal>, which
reconnects if opening the connection to the directory server
failed. By contrast, <literal>hard_init</literal> reconnects if
initializing the connection failed. Initializing may not
actually contact the directory server, and it is possible that
a malformed configuration file will trigger reconnection. If
<literal>soft</literal> is specified, then
<literal>nss_ldap</literal> will return immediately on server
failure. All hard reconnect policies block with exponential
backoff before retrying.
";
};
};
extraConfig = mkOption {
default = "" ;
type = types.string ;
description = ''
Extra configuration options that will be added verbatim at
the end of the ldap configuration file (ldap.conf).
If <literal>users.ldap.daemon</literal> is enabled, this
configuration will not be used. In that case, use
<literal>users.ldap.daemon.extraConfig</literal> instead.
'' ;
};
};
};
};
# Careful: OpenLDAP seems to be very picky about the indentation of # Careful: OpenLDAP seems to be very picky about the indentation of
# this file. Directives HAVE to start in the first column! # this file. Directives HAVE to start in the first column!
ldapConfig = { ldapConfig = {
@ -186,63 +48,199 @@ let
in in
###### implementation {
mkIf cfg.enable {
require = [
options
];
environment.etc = if cfg.daemon.enable then [nslcdConfig] else [ldapConfig]; ###### interface
system.activationScripts = mkIf insertLdapPassword { options = {
ldap = stringAfter [ "etc" "groups" "users" ] ''
if test -f "${cfg.bind.password}" ; then
echo "bindpw "$(cat ${cfg.bind.password})"" | cat ${ldapConfig} - > /etc/ldap.conf.bindpw
mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf
chmod 600 /etc/ldap.conf
fi
'';
};
system.nssModules = singleton ( users.ldap = {
if cfg.daemon.enable then nss_pam_ldapd else nss_ldap
); enable = mkOption {
default = false;
description = "Whether to enable authentication against an LDAP server.";
};
server = mkOption {
example = "ldap://ldap.example.org/";
description = "The URL of the LDAP server.";
};
base = mkOption {
example = "dc=example,dc=org";
description = "The distinguished name of the search base.";
};
useTLS = mkOption {
default = false;
description = ''
If enabled, use TLS (encryption) over an LDAP (port 389)
connection. The alternative is to specify an LDAPS server (port
636) in <option>users.ldap.server</option> or to forego
security.
'';
};
timeLimit = mkOption {
default = 0;
type = types.int;
description = ''
Specifies the time limit (in seconds) to use when performing
searches. A value of zero (0), which is the default, is to
wait indefinitely for searches to be completed.
'';
};
daemon = {
enable = mkOption {
default = false;
description = ''
Whether to let the nslcd daemon (nss-pam-ldapd) handle the
LDAP lookups for NSS and PAM. This can improve performance,
and if you need to bind to the LDAP server with a password,
it increases security, since only the nslcd user needs to
have access to the bindpw file, not everyone that uses NSS
and/or PAM. If this option is enabled, a local nscd user is
created automatically, and the nslcd service is started
automatically when the network get up.
'';
};
extraConfig = mkOption {
default = "";
type = types.string;
description = ''
Extra configuration options that will be added verbatim at
the end of the nslcd configuration file (nslcd.conf).
'' ;
} ;
};
bind = {
distinguishedName = mkOption {
default = "";
example = "cn=admin,dc=example,dc=com";
type = types.string;
description = ''
The distinguished name to bind to the LDAP server with. If this
is not specified, an anonymous bind will be done.
'';
};
password = mkOption {
default = "/etc/ldap/bind.password";
type = types.string;
description = ''
The path to a file containing the credentials to use when binding
to the LDAP server (if not binding anonymously).
'';
};
timeLimit = mkOption {
default = 30;
type = types.int;
description = ''
Specifies the time limit (in seconds) to use when connecting
to the directory server. This is distinct from the time limit
specified in <literal>users.ldap.timeLimit</literal> and affects
the initial server connection only.
'';
};
policy = mkOption {
default = "hard_open";
type = types.string;
description = ''
Specifies the policy to use for reconnecting to an unavailable
LDAP server. The default is <literal>hard_open</literal>, which
reconnects if opening the connection to the directory server
failed. By contrast, <literal>hard_init</literal> reconnects if
initializing the connection failed. Initializing may not
actually contact the directory server, and it is possible that
a malformed configuration file will trigger reconnection. If
<literal>soft</literal> is specified, then
<literal>nss_ldap</literal> will return immediately on server
failure. All hard reconnect policies block with exponential
backoff before retrying.
'';
};
};
extraConfig = mkOption {
default = "";
type = types.string;
description = ''
Extra configuration options that will be added verbatim at
the end of the ldap configuration file (ldap.conf).
If <literal>users.ldap.daemon</literal> is enabled, this
configuration will not be used. In that case, use
<literal>users.ldap.daemon.extraConfig</literal> instead.
'' ;
};
users = mkIf cfg.daemon.enable {
extraGroups.nslcd = {
gid = config.ids.gids.nslcd;
}; };
extraUsers.nslcd = {
uid = config.ids.uids.nslcd;
description = "nslcd user.";
group = "nslcd";
};
}; };
systemd.services = mkIf cfg.daemon.enable { ###### implementation
nslcd = {
wantedBy = [ "nss-user-lookup.target" ];
before = [ "nss-user-lookup.target" ];
after = [ "network.target" ];
preStart = '' config = mkIf cfg.enable {
mkdir -p /run/nslcd
rm -f /run/nslcd/nslcd.pid; environment.etc = if cfg.daemon.enable then [nslcdConfig] else [ldapConfig];
chown nslcd.nslcd /run/nslcd
${optionalString (cfg.bind.distinguishedName != "") '' system.activationScripts = mkIf insertLdapPassword {
if test -s "${cfg.bind.password}" ; then ldap = stringAfter [ "etc" "groups" "users" ] ''
ln -sfT "${cfg.bind.password}" /run/nslcd/bindpw if test -f "${cfg.bind.password}" ; then
fi echo "bindpw "$(cat ${cfg.bind.password})"" | cat ${ldapConfig} - > /etc/ldap.conf.bindpw
''} mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf
chmod 600 /etc/ldap.conf
fi
''; '';
};
serviceConfig = { system.nssModules = singleton (
ExecStart = "${nss_pam_ldapd}/sbin/nslcd"; if cfg.daemon.enable then nss_pam_ldapd else nss_ldap
Type = "forking"; );
PIDFile = "/run/nslcd/nslcd.pid";
Restart = "always"; users = mkIf cfg.daemon.enable {
extraGroups.nslcd = {
gid = config.ids.gids.nslcd;
};
extraUsers.nslcd = {
uid = config.ids.uids.nslcd;
description = "nslcd user.";
group = "nslcd";
}; };
}; };
systemd.services = mkIf cfg.daemon.enable {
nslcd = {
wantedBy = [ "nss-user-lookup.target" ];
before = [ "nss-user-lookup.target" ];
after = [ "network.target" ];
preStart = ''
mkdir -p /run/nslcd
rm -f /run/nslcd/nslcd.pid;
chown nslcd.nslcd /run/nslcd
${optionalString (cfg.bind.distinguishedName != "") ''
if test -s "${cfg.bind.password}" ; then
ln -sfT "${cfg.bind.password}" /run/nslcd/bindpw
fi
''}
'';
serviceConfig = {
ExecStart = "${nss_pam_ldapd}/sbin/nslcd";
Type = "forking";
PIDFile = "/run/nslcd/nslcd.pid";
Restart = "always";
};
};
};
}; };
} }

View File

@ -1,6 +1,6 @@
# /etc files related to networking, such as /etc/services. # /etc files related to networking, such as /etc/services.
{config, pkgs, ...}: { config, pkgs, ... }:
with pkgs.lib; with pkgs.lib;
@ -8,6 +8,10 @@ let
cfg = config.networking; cfg = config.networking;
in
{
options = { options = {
networking.extraHosts = pkgs.lib.mkOption { networking.extraHosts = pkgs.lib.mkOption {
@ -32,53 +36,53 @@ let
}; };
in config = {
{ environment.etc =
require = [options]; { # /etc/services: TCP/UDP port assignments.
"services".source = pkgs.iana_etc + "/etc/services";
environment.etc = # /etc/protocols: IP protocol numbers.
{ # /etc/services: TCP/UDP port assignments. "protocols".source = pkgs.iana_etc + "/etc/protocols";
"services".source = pkgs.iana_etc + "/etc/services";
# /etc/protocols: IP protocol numbers. # /etc/rpc: RPC program numbers.
"protocols".source = pkgs.iana_etc + "/etc/protocols"; "rpc".source = pkgs.glibc + "/etc/rpc";
# /etc/rpc: RPC program numbers. # /etc/hosts: Hostname-to-IP mappings.
"rpc".source = pkgs.glibc + "/etc/rpc"; "hosts".text =
# /etc/hosts: Hostname-to-IP mappings.
"hosts".text =
''
127.0.0.1 localhost
${optionalString cfg.enableIPv6 ''
::1 localhost
''}
${cfg.extraHosts}
'';
# /etc/resolvconf.conf: Configuration for openresolv.
"resolvconf.conf".text =
'' ''
# This is the default, but we must set it here to prevent 127.0.0.1 localhost
# a collision with an apparently unrelated environment ${optionalString cfg.enableIPv6 ''
# variable with the same name exported by dhcpcd. ::1 localhost
interface_order='lo lo[0-9]*' ''}
'' + optionalString config.services.nscd.enable '' ${cfg.extraHosts}
# Invalidate the nscd cache whenever resolv.conf is
# regenerated.
libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service'
'' + optionalString cfg.dnsSingleRequest ''
# only send one DNS request at a time
resolv_conf_options='single-request'
'' + optionalString config.services.bind.enable ''
# This hosts runs a full-blown DNS resolver.
name_servers='127.0.0.1'
''; '';
};
# The ip-up target is started when we have IP connectivity. So # /etc/resolvconf.conf: Configuration for openresolv.
# services that depend on IP connectivity (like ntpd) should be "resolvconf.conf".text =
# pulled in by this target. ''
systemd.targets.ip-up.description = "Services Requiring IP Connectivity"; # This is the default, but we must set it here to prevent
# a collision with an apparently unrelated environment
# variable with the same name exported by dhcpcd.
interface_order='lo lo[0-9]*'
'' + optionalString config.services.nscd.enable ''
# Invalidate the nscd cache whenever resolv.conf is
# regenerated.
libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service'
'' + optionalString cfg.dnsSingleRequest ''
# only send one DNS request at a time
resolv_conf_options='single-request'
'' + optionalString config.services.bind.enable ''
# This hosts runs a full-blown DNS resolver.
name_servers='127.0.0.1'
'';
};
# The ip-up target is started when we have IP connectivity. So
# services that depend on IP connectivity (like ntpd) should be
# pulled in by this target.
systemd.targets.ip-up.description = "Services Requiring IP Connectivity";
};
} }

View File

@ -6,17 +6,22 @@ with pkgs.lib;
let let
inherit (config.services.avahi) nssmdns;
in
{
options = { options = {
# NSS modules. Hacky! # NSS modules. Hacky!
system.nssModules = mkOption { system.nssModules = mkOption {
internal = true; internal = true;
default = []; default = [];
description = " description = ''
Search path for NSS (Name Service Switch) modules. This allows Search path for NSS (Name Service Switch) modules. This allows
several DNS resolution methods to be specified via several DNS resolution methods to be specified via
<filename>/etc/nsswitch.conf</filename>. <filename>/etc/nsswitch.conf</filename>.
"; '';
merge = mergeListOption; merge = mergeListOption;
apply = list: apply = list:
{ {
@ -27,34 +32,31 @@ let
}; };
inherit (config.services.avahi) nssmdns; config = {
in environment.etc =
[ # Name Service Switch configuration file. Required by the C library.
# !!! Factor out the mdns stuff. The avahi module should define
# an option used by this module.
{ source = pkgs.writeText "nsswitch.conf"
''
passwd: files ldap
group: files ldap
shadow: files ldap
hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} myhostname
networks: files dns
ethers: files
services: files
protocols: files
'';
target = "nsswitch.conf";
}
];
{ # Use nss-myhostname to ensure that our hostname always resolves to
require = [ options ]; # a valid IP address. It returns all locally configured IP
# addresses, or ::1 and 127.0.0.2 as fallbacks.
system.nssModules = [ pkgs.systemd ];
environment.etc = };
[ # Name Service Switch configuration file. Required by the C library.
# !!! Factor out the mdns stuff. The avahi module should define
# an option used by this module.
{ source = pkgs.writeText "nsswitch.conf"
''
passwd: files ldap
group: files ldap
shadow: files ldap
hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} myhostname
networks: files dns
ethers: files
services: files
protocols: files
'';
target = "nsswitch.conf";
}
];
# Use nss-myhostname to ensure that our hostname always resolves to
# a valid IP address. It returns all locally configured IP
# addresses, or ::1 and 127.0.0.2 as fallbacks.
system.nssModules = [ pkgs.systemd ];
} }

View File

@ -54,7 +54,9 @@ let
extraManpages extraManpages
]; ];
in
{
options = { options = {
environment = { environment = {
@ -78,9 +80,7 @@ let
# to work. # to work.
default = []; default = [];
example = ["/"]; example = ["/"];
description = " description = "List of directories to be symlinked in `/run/current-system/sw'.";
Lists directories to be symlinked in `/run/current-system/sw'.
";
}; };
}; };
@ -120,24 +120,23 @@ let
}; };
config = {
in environment.systemPackages = requiredPackages;
{ environment.pathsToLink =
require = [ options ]; [ "/bin"
"/etc/xdg"
"/info"
"/lib"
"/man"
"/sbin"
"/share/emacs"
"/share/org"
"/share/info"
"/share/terminfo"
"/share/man"
];
environment.systemPackages = requiredPackages; };
environment.pathsToLink = [
"/bin"
"/etc/xdg"
"/info"
"/lib"
"/man"
"/sbin"
"/share/emacs"
"/share/org"
"/share/info"
"/share/terminfo"
"/share/man"
];
} }

View File

@ -1,43 +1,34 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = {
environment = {
unixODBCDrivers = mkOption {
default = [];
example = "map (x : x.ini) (with pkgs.unixODBCDrivers; [ mysql psql psqlng ] )";
description = ''
specifies unix odbc drivers to be registered at /etc/odbcinst.ini.
Maybe you also want to add pkgs.unixODBC to the system path to get a
command line client t connnect to odbc databases.
'';
};
};
};
in
###### implementation
with pkgs.lib;
# unixODBC drivers (this solution is not perfect.. Because the user has to # unixODBC drivers (this solution is not perfect.. Because the user has to
# ask the admin to add a driver.. but it's simple and works # ask the admin to add a driver.. but it's simple and works
mkIf (config.environment.unixODBCDrivers != []) { {
###### interface
require = [ options = {
options environment.unixODBCDrivers = mkOption {
]; default = [];
example = literalExample "map (x : x.ini) (with pkgs.unixODBCDrivers; [ mysql psql psqlng ] )";
environment = { description = ''
etc = [ Specifies Unix ODBC drivers to be registered in
{ source = <filename>/etc/odbcinst.ini</filename>. You may also want to
let inis = config.environment.unixODBCDrivers; add <literal>pkgs.unixODBC</literal> to the system path to get
in pkgs.writeText "odbcinst.ini" (pkgs.lib.concatStringsSep "\n" inis); a command line client to connnect to ODBC databases.
target = "odbcinst.ini"; '';
} };
];
}; };
###### implementation
config = mkIf (config.environment.unixODBCDrivers != []) {
environment.etc."odbcinst.ini".text =
let inis = config.environment.unixODBCDrivers;
in pkgs.lib.concatStringsSep "\n" inis;
};
} }

View File

@ -1,61 +1,59 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption
mergeEnableOption mergeListOption;
options = {
hardware = {
pcmcia = {
enable = mkOption {
default = false;
merge = mergeEnableOption;
description = ''
Enable this option to support PCMCIA card.
'';
};
firmware = mkOption {
default = [];
merge = mergeListOption;
description = ''
List of firmware used to handle specific PCMCIA card.
'';
};
config = mkOption {
default = null;
description = ''
Path to the configuration file which map the memory, irq
and ports used by the PCMCIA hardware.
'';
};
};
};
};
in
###### implementation
let
inherit (pkgs.lib) mkIf;
pcmciaUtils = pkgs.pcmciaUtils.passthru.function { pcmciaUtils = pkgs.pcmciaUtils.passthru.function {
inherit (config.hardware.pcmcia) firmware config; inherit (config.hardware.pcmcia) firmware config;
}; };
in in
mkIf config.hardware.pcmcia.enable { {
require = [ ###### interface
# ../upstart-jobs/udev.nix
# ? # config.environment.extraPackages
options
];
boot.kernelModules = [ "pcmcia" ]; options = {
services.udev.packages = [ pcmciaUtils ]; hardware.pcmcia = {
enable = mkOption {
default = false;
merge = mergeEnableOption;
description = ''
Enable this option to support PCMCIA card.
'';
};
firmware = mkOption {
default = [];
merge = mergeListOption;
description = ''
List of firmware used to handle specific PCMCIA card.
'';
};
config = mkOption {
default = null;
description = ''
Path to the configuration file which map the memory, irq
and ports used by the PCMCIA hardware.
'';
};
};
};
###### implementation
config = mkIf config.hardware.pcmcia.enable {
boot.kernelModules = [ "pcmcia" ];
services.udev.packages = [ pcmciaUtils ];
environment.systemPackages = [ pcmciaUtils ];
};
environment.systemPackages = [ pcmciaUtils ];
} }

View File

@ -6,7 +6,7 @@
with pkgs.lib; with pkgs.lib;
{ {
require = imports =
[ ./memtest.nix [ ./memtest.nix
./channel.nix ./channel.nix
./iso-image.nix ./iso-image.nix

View File

@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [ ./installation-cd-minimal.nix ]; imports = [ ./installation-cd-minimal.nix ];
boot.kernelPackages = pkgs.linuxPackages_3_9; boot.kernelPackages = pkgs.linuxPackages_3_9;
boot.vesa = false; boot.vesa = false;

View File

@ -6,10 +6,7 @@
with pkgs.lib; with pkgs.lib;
{ {
require = [ imports = [ ./installation-cd-base.nix ../../profiles/graphical.nix ];
./installation-cd-base.nix
../../profiles/graphical.nix
];
# Provide wicd for easy wireless configuration. # Provide wicd for easy wireless configuration.
#networking.wicd.enable = true; #networking.wicd.enable = true;

View File

@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [ ./installation-cd-minimal.nix ]; imports = [ ./installation-cd-minimal.nix ];
boot.kernelPackages = pkgs.linuxPackages_3_10; boot.kernelPackages = pkgs.linuxPackages_3_10;
boot.vesa = false; boot.vesa = false;

View File

@ -4,7 +4,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = imports =
[ ./installation-cd-base.nix [ ./installation-cd-base.nix
../../profiles/minimal.nix ../../profiles/minimal.nix
]; ];

View File

@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [ ./installation-cd-graphical.nix ]; imports = [ ./installation-cd-graphical.nix ];
boot.kernelPackages = pkgs.linuxPackages_3_10; boot.kernelPackages = pkgs.linuxPackages_3_10;
boot.vesa = false; boot.vesa = false;

View File

@ -8,6 +8,79 @@ with pkgs.lib;
let let
# The Grub image.
grubImage = pkgs.runCommand "grub_eltorito" {}
''
${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
''; # */
# The configuration file for Grub.
grubCfg =
''
set default=${builtins.toString config.boot.loader.grub.default}
set timeout=${builtins.toString config.boot.loader.grub.timeout}
if loadfont /boot/grub/unicode.pf2; then
set gfxmode=640x480
insmod gfxterm
insmod vbe
terminal_output gfxterm
insmod png
if background_image /boot/grub/splash.png; then
set color_normal=white/black
set color_highlight=black/white
else
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue
fi
fi
${config.boot.loader.grub.extraEntries}
'';
# The efi boot image
efiImg = pkgs.runCommand "efi-image_eltorito" {}
''
#Let's hope 10M is enough
dd bs=2048 count=5120 if=/dev/zero of="$out"
${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
${pkgs.mtools}/bin/mmd -i "$out" efi
${pkgs.mtools}/bin/mmd -i "$out" efi/boot
${pkgs.mtools}/bin/mmd -i "$out" efi/nixos
${pkgs.mtools}/bin/mmd -i "$out" loader
${pkgs.mtools}/bin/mmd -i "$out" loader/entries
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi \
::efi/boot/boot${targetArch}.efi
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${config.boot.kernelPackages.kernel + "/bzImage"} ::bzImage
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${config.system.build.initialRamdisk + "/initrd"} ::efi/nixos/initrd
echo "title NixOS LiveCD" > boot-params
echo "linux /bzImage" >> boot-params
echo "initrd /efi/nixos/initrd" >> boot-params
echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> boot-params
${pkgs.mtools}/bin/mcopy -v -i "$out" boot-params ::loader/entries/nixos-livecd.conf
echo "default nixos-livecd" > boot-params
echo "timeout 5" >> boot-params
${pkgs.mtools}/bin/mcopy -v -i "$out" boot-params ::loader/loader.conf
'';
targetArch = if pkgs.stdenv.isi686 then
"ia32"
else if pkgs.stdenv.isx86_64 then
"x64"
else
throw "Unsupported architecture";
in
{
options = { options = {
isoImage.isoName = mkOption { isoImage.isoName = mkOption {
@ -84,228 +157,157 @@ let
}; };
# The Grub image. config = {
grubImage = pkgs.runCommand "grub_eltorito" {}
''
${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
''; # */
boot.loader.grub.version = 2;
# The configuration file for Grub. # Don't build the GRUB menu builder script, since we don't need it
grubCfg = # here and it causes a cyclic dependency.
'' boot.loader.grub.enable = false;
set default=${builtins.toString config.boot.loader.grub.default}
set timeout=${builtins.toString config.boot.loader.grub.timeout}
if loadfont /boot/grub/unicode.pf2; then # !!! Hack - attributes expected by other modules.
set gfxmode=640x480 system.boot.loader.kernelFile = "bzImage";
insmod gfxterm environment.systemPackages = [ pkgs.grub2 ];
insmod vbe
terminal_output gfxterm
insmod png # In stage 1 of the boot, mount the CD as the root FS by label so
if background_image /boot/grub/splash.png; then # that we don't need to know its device. We pass the label of the
set color_normal=white/black # root filesystem on the kernel command line, rather than in
set color_highlight=black/white # `fileSystems' below. This allows CD-to-USB converters such as
else # UNetbootin to rewrite the kernel command line to pass the label or
set menu_color_normal=cyan/blue # UUID of the USB stick. It would be nicer to write
set menu_color_highlight=white/blue # `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
fi # recognise that.
boot.kernelParams = [ "root=LABEL=${config.isoImage.volumeID}" ];
fi # Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1 init
# script.
fileSystems."/".device = "/dev/root";
${config.boot.loader.grub.extraEntries} fileSystems."/nix/store" =
''; { fsType = "squashfs";
device = "/nix-store.squashfs";
options = "loop";
};
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
# The efi boot image boot.initrd.kernelModules = [ "loop" ];
efiImg = pkgs.runCommand "efi-image_eltorito" {}
''
#Let's hope 10M is enough
dd bs=2048 count=5120 if=/dev/zero of="$out"
${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
${pkgs.mtools}/bin/mmd -i "$out" efi
${pkgs.mtools}/bin/mmd -i "$out" efi/boot
${pkgs.mtools}/bin/mmd -i "$out" efi/nixos
${pkgs.mtools}/bin/mmd -i "$out" loader
${pkgs.mtools}/bin/mmd -i "$out" loader/entries
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi \
::efi/boot/boot${targetArch}.efi
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${config.boot.kernelPackages.kernel + "/bzImage"} ::bzImage
${pkgs.mtools}/bin/mcopy -v -i "$out" \
${config.system.build.initialRamdisk + "/initrd"} ::efi/nixos/initrd
echo "title NixOS LiveCD" > boot-params
echo "linux /bzImage" >> boot-params
echo "initrd /efi/nixos/initrd" >> boot-params
echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> boot-params
${pkgs.mtools}/bin/mcopy -v -i "$out" boot-params ::loader/entries/nixos-livecd.conf
echo "default nixos-livecd" > boot-params
echo "timeout 5" >> boot-params
${pkgs.mtools}/bin/mcopy -v -i "$out" boot-params ::loader/loader.conf
'';
targetArch = if pkgs.stdenv.isi686 then boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars";
"ia32"
else if pkgs.stdenv.isx86_64 then
"x64"
else
throw "Unsupported architecture";
in # In stage 1, mount a tmpfs on top of / (the ISO image) and
# /nix/store (the squashfs image) to make this a live CD.
boot.initrd.postMountCommands =
''
mkdir -p /unionfs-chroot/ro-root
mount --rbind $targetRoot /unionfs-chroot/ro-root
{ mkdir /unionfs-chroot/rw-root
require = options; mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-root
mkdir /mnt-root-union
unionfs -o allow_other,cow,chroot=/unionfs-chroot,max_files=32768 /rw-root=RW:/ro-root=RO /mnt-root-union
oldTargetRoot=$targetRoot
targetRoot=/mnt-root-union
boot.loader.grub.version = 2; mkdir /unionfs-chroot/rw-store
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store
mkdir -p $oldTargetRoot/nix/store
unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-store=RW:/ro-root/nix/store=RO /mnt-root-union/nix/store
'';
# Don't build the GRUB menu builder script, since we don't need it # Closures to be copied to the Nix store on the CD, namely the init
# here and it causes a cyclic dependency. # script and the top-level system configuration directory.
boot.loader.grub.enable = false; isoImage.storeContents =
[ config.system.build.toplevel ] ++
optional config.isoImage.includeSystemBuildDependencies
config.system.build.toplevel.drvPath;
# !!! Hack - attributes expected by other modules. # Create the squashfs image that contains the Nix store.
system.boot.loader.kernelFile = "bzImage"; system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
environment.systemPackages = [ pkgs.grub2 ]; inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
storeContents = config.isoImage.storeContents;
# 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
# root filesystem on the kernel command line, rather than in
# `fileSystems' below. This allows CD-to-USB converters such as
# UNetbootin to rewrite the kernel command line to pass the label or
# UUID of the USB stick. It would be nicer to write
# `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
# recognise that.
boot.kernelParams = [ "root=LABEL=${config.isoImage.volumeID}" ];
# Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1 init
# script.
fileSystems."/".device = "/dev/root";
fileSystems."/nix/store" =
{ fsType = "squashfs";
device = "/nix-store.squashfs";
options = "loop";
}; };
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ]; # Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
[ { source = grubImage;
target = "/boot/grub/grub_eltorito";
}
{ source = pkgs.writeText "grub.cfg" grubCfg;
target = "/boot/grub/grub.cfg";
}
{ source = config.boot.kernelPackages.kernel + "/bzImage";
target = "/boot/bzImage";
}
{ source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
{ source = "${pkgs.grub2}/share/grub/unicode.pf2";
target = "/boot/grub/unicode.pf2";
}
{ source = config.boot.loader.grub.splashImage;
target = "/boot/grub/splash.png";
}
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
}
{ # Quick hack: need a mount point for the store.
source = pkgs.runCommand "empty" {} "ensureDir $out";
target = "/nix/store";
}
] ++ pkgs.stdenv.lib.optionals config.isoImage.makeEfiBootable [
{ source = efiImg;
target = "/boot/efi.img";
}
];
boot.initrd.kernelModules = [ "loop" ]; # The Grub menu.
boot.loader.grub.extraEntries =
''
menuentry "NixOS Installer / Rescue" {
linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
initrd /boot/initrd
}
boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars"; menuentry "Boot from hard disk" {
set root=(hd0)
chainloader +1
}
'';
# In stage 1, mount a tmpfs on top of / (the ISO image) and boot.loader.grub.timeout = 10;
# /nix/store (the squashfs image) to make this a live CD.
boot.initrd.postMountCommands =
''
mkdir -p /unionfs-chroot/ro-root
mount --rbind $targetRoot /unionfs-chroot/ro-root
mkdir /unionfs-chroot/rw-root # Create the ISO image.
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-root system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
mkdir /mnt-root-union inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
unionfs -o allow_other,cow,chroot=/unionfs-chroot,max_files=32768 /rw-root=RW:/ro-root=RO /mnt-root-union
oldTargetRoot=$targetRoot
targetRoot=/mnt-root-union
mkdir /unionfs-chroot/rw-store inherit (config.isoImage) isoName compressImage volumeID contents;
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store
mkdir -p $oldTargetRoot/nix/store
unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-store=RW:/ro-root/nix/store=RO /mnt-root-union/nix/store
'';
# Closures to be copied to the Nix store on the CD, namely the init bootable = true;
# script and the top-level system configuration directory. bootImage = "/boot/grub/grub_eltorito";
isoImage.storeContents = } // pkgs.stdenv.lib.optionalAttrs config.isoImage.makeEfiBootable {
[ config.system.build.toplevel ] ++ efiBootable = true;
optional config.isoImage.includeSystemBuildDependencies efiBootImage = "boot/efi.img";
config.system.build.toplevel.drvPath; });
boot.postBootCommands =
''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
${config.environment.nix}/bin/nix-store --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# Add vfat support to the initrd to enable people to copy the
# contents of the CD to a bootable USB stick. Need unionfs-fuse for union mounts
boot.initrd.supportedFilesystems = [ "vfat" "unionfs-fuse" ];
# Create the squashfs image that contains the Nix store.
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
storeContents = config.isoImage.storeContents;
}; };
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
[ { source = grubImage;
target = "/boot/grub/grub_eltorito";
}
{ source = pkgs.writeText "grub.cfg" grubCfg;
target = "/boot/grub/grub.cfg";
}
{ source = config.boot.kernelPackages.kernel + "/bzImage";
target = "/boot/bzImage";
}
{ source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
{ source = "${pkgs.grub2}/share/grub/unicode.pf2";
target = "/boot/grub/unicode.pf2";
}
{ source = config.boot.loader.grub.splashImage;
target = "/boot/grub/splash.png";
}
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
}
{ # Quick hack: need a mount point for the store.
source = pkgs.runCommand "empty" {} "ensureDir $out";
target = "/nix/store";
}
] ++ pkgs.stdenv.lib.optionals config.isoImage.makeEfiBootable [
{ source = efiImg;
target = "/boot/efi.img";
}
];
# The Grub menu.
boot.loader.grub.extraEntries =
''
menuentry "NixOS Installer / Rescue" {
linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
initrd /boot/initrd
}
menuentry "Boot from hard disk" {
set root=(hd0)
chainloader +1
}
'';
boot.loader.grub.timeout = 10;
# Create the ISO image.
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = true;
bootImage = "/boot/grub/grub_eltorito";
} // pkgs.stdenv.lib.optionalAttrs config.isoImage.makeEfiBootable {
efiBootable = true;
efiBootImage = "boot/efi.img";
});
boot.postBootCommands =
''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
${config.environment.nix}/bin/nix-store --load-db < /nix/store/nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
# Add vfat support to the initrd to enable people to copy the
# contents of the CD to a bootable USB stick. Need unionfs-fuse for union mounts
boot.initrd.supportedFilesystems = [ "vfat" "unionfs-fuse" ];
} }

View File

@ -1,11 +1,11 @@
{config, pkgs, ...}: { config, pkgs, ... }:
{ {
require = [./installation-cd-base.nix]; imports = [ ./installation-cd-base.nix ];
# Build the build-time dependencies of this configuration on the DVD # Build the build-time dependencies of this configuration on the DVD
# to speed up installation. # to speed up installation.
isoImage.storeContents = [config.system.build.toplevel.drvPath]; isoImage.storeContents = [ config.system.build.toplevel.drvPath ];
# Include lots of packages. # Include lots of packages.
environment.systemPackages = environment.systemPackages =

View File

@ -12,15 +12,10 @@ let
# evaluated. So we'll just hope for the best. # evaluated. So we'll just hope for the best.
dummyConfiguration = pkgs.writeText "configuration.nix" dummyConfiguration = pkgs.writeText "configuration.nix"
'' ''
{config, pkgs, ...}: { config, pkgs, ... }:
{ { # Add your own options below, e.g.:
require = [ ];
# Add your own options below
# E.g.,
# services.openssh.enable = true; # services.openssh.enable = true;
nixpkgs.config.platform = pkgs.platforms.fuloong2f_n32; nixpkgs.config.platform = pkgs.platforms.fuloong2f_n32;
} }
''; '';
@ -45,11 +40,7 @@ let
in in
{ {
require = imports = [ ./system-tarball.nix ];
[
./system-tarball.nix
];
# Disable some other stuff we don't need. # Disable some other stuff we don't need.
security.sudo.enable = false; security.sudo.enable = false;

View File

@ -65,7 +65,7 @@ let
in in
{ {
require = imports =
[ ./system-tarball.nix [ ./system-tarball.nix
# Profiles of this basic installation. # Profiles of this basic installation.

View File

@ -15,11 +15,9 @@ let
# evaluated. So we'll just hope for the best. # evaluated. So we'll just hope for the best.
dummyConfiguration = pkgs.writeText "configuration.nix" dummyConfiguration = pkgs.writeText "configuration.nix"
'' ''
{config, pkgs, ...}: { config, pkgs, ... }:
{ {
require = [ ];
# Add your own options below and run "nixos-rebuild switch". # Add your own options below and run "nixos-rebuild switch".
# E.g., # E.g.,
# services.openssh.enable = true; # services.openssh.enable = true;
@ -39,10 +37,7 @@ let
in in
{ {
require = imports = [ ./system-tarball.nix ];
[
./system-tarball.nix
];
# Disable some other stuff we don't need. # Disable some other stuff we don't need.
security.sudo.enable = false; security.sudo.enable = false;

View File

@ -8,6 +8,11 @@ with pkgs.lib;
let let
versionFile = pkgs.writeText "nixos-version" config.system.nixosVersion;
in
{
options = { options = {
tarball.contents = mkOption { tarball.contents = mkOption {
example = example =
@ -31,59 +36,57 @@ let
}; };
versionFile = pkgs.writeText "nixos-version" config.system.nixosVersion; config = {
in # In stage 1 of the boot, mount the CD/DVD as the root FS by label
# so that we don't need to know its device.
fileSystems = [ ];
{ # boot.initrd.availableKernelModules = [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ext4" ];
require = options;
# In stage 1 of the boot, mount the CD/DVD as the root FS by label # boot.initrd.kernelModules = [ "rtc_mv" ];
# so that we don't need to know its device.
fileSystems = [ ];
# boot.initrd.availableKernelModules = [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ext4" ]; # Closures to be copied to the Nix store on the CD, namely the init
# script and the top-level system configuration directory.
tarball.storeContents =
[ { object = config.system.build.toplevel;
symlink = "/run/current-system";
}
];
# boot.initrd.kernelModules = [ "rtc_mv" ]; # Individual files to be included on the CD, outside of the Nix
# store on the CD.
tarball.contents =
[ { source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
{ source = versionFile;
target = "/nixos-version.txt";
}
];
# Closures to be copied to the Nix store on the CD, namely the init # Create the tarball
# script and the top-level system configuration directory. system.build.tarball = import ../../../lib/make-system-tarball.nix {
tarball.storeContents = inherit (pkgs) stdenv perl xz pathsFromGraph;
[ { object = config.system.build.toplevel;
symlink = "/run/current-system";
}
];
# Individual files to be included on the CD, outside of the Nix inherit (config.tarball) contents storeContents;
# store on the CD. };
tarball.contents =
[ { source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
{ source = versionFile;
target = "/nixos-version.txt";
}
];
# Create the tarball boot.postBootCommands =
system.build.tarball = import ../../../lib/make-system-tarball.nix { ''
inherit (pkgs) stdenv perl xz pathsFromGraph; # After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
if [ -f /nix-path-registration ]; then
${config.environment.nix}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
inherit (config.tarball) contents storeContents;
}; };
boot.postBootCommands =
''
# After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs.
if [ -f /nix-path-registration ]; then
${config.environment.nix}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
} }

View File

@ -8,7 +8,7 @@ my @attrs = ();
my @kernelModules = (); my @kernelModules = ();
my @initrdKernelModules = (); my @initrdKernelModules = ();
my @modulePackages = (); my @modulePackages = ();
my @requires = ("<nixos/modules/installer/scan/not-detected.nix>"); my @imports = ("<nixos/modules/installer/scan/not-detected.nix>");
sub debug { sub debug {
@ -227,7 +227,7 @@ my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
my $kernelModules = toNixExpr(removeDups @kernelModules); my $kernelModules = toNixExpr(removeDups @kernelModules);
my $modulePackages = toNixExpr(removeDups @modulePackages); my $modulePackages = toNixExpr(removeDups @modulePackages);
my $attrs = multiLineList(" ", removeDups @attrs); my $attrs = multiLineList(" ", removeDups @attrs);
my $requires = multiLineList(" ", removeDups @requires); my $imports = multiLineList(" ", removeDups @imports);
print <<EOF ; print <<EOF ;
@ -236,7 +236,7 @@ print <<EOF ;
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [$requires ]; imports = [$imports ];
boot.initrd.kernelModules = [$initrdKernelModules ]; boot.initrd.kernelModules = [$initrdKernelModules ];
boot.kernelModules = [$kernelModules ]; boot.kernelModules = [$kernelModules ];

View File

@ -215,7 +215,7 @@ if $generate; then
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = imports =
[ # Include the results of the hardware scan. [ # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
]; ];

View File

@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = imports =
[ ../virtualisation/virtualbox-image.nix [ ../virtualisation/virtualbox-image.nix
../installer/cd-dvd/channel.nix ../installer/cd-dvd/channel.nix
../profiles/demo.nix ../profiles/demo.nix

View File

@ -1,10 +1,9 @@
# This module defines the global list of uids and gids. We keep a # This module defines the global list of uids and gids. We keep a
# central list to prevent id collisions. # central list to prevent id collisions.
{config, pkgs, ...}: { config, pkgs, ... }:
let
{
options = { options = {
ids.uids = pkgs.lib.mkOption { ids.uids = pkgs.lib.mkOption {
@ -21,181 +20,181 @@ let
}; };
in
{ config = {
require = options;
ids.uids = { ids.uids = {
root = 0; root = 0;
nscd = 1; nscd = 1;
sshd = 2; sshd = 2;
ntp = 3; ntp = 3;
messagebus = 4; # D-Bus messagebus = 4; # D-Bus
haldaemon = 5; haldaemon = 5;
nagios = 6; nagios = 6;
vsftpd = 7; vsftpd = 7;
ftp = 8; ftp = 8;
bitlbee = 9; bitlbee = 9;
avahi = 10; avahi = 10;
portmap = 11; portmap = 11;
atd = 12; atd = 12;
zabbix = 13; zabbix = 13;
postfix = 14; postfix = 14;
dovecot = 15; dovecot = 15;
tomcat = 16; tomcat = 16;
pulseaudio = 22; # must match `pulseaudio' GID pulseaudio = 22; # must match `pulseaudio' GID
gpsd = 23; gpsd = 23;
polkituser = 28; polkituser = 28;
uptimed = 29; uptimed = 29;
ddclient = 30; ddclient = 30;
davfs2 = 31; davfs2 = 31;
privoxy = 32; privoxy = 32;
osgi = 34; osgi = 34;
tor = 35; tor = 35;
cups = 36; cups = 36;
foldingAtHome = 37; foldingAtHome = 37;
sabnzbd = 38; sabnzbd = 38;
kdm = 39; kdm = 39;
ghostOne = 40; ghostOne = 40;
git = 41; git = 41;
fourStore = 42; fourStore = 42;
fourStoreEndpoint = 43; fourStoreEndpoint = 43;
virtuoso = 44; virtuoso = 44;
rtkit = 45; rtkit = 45;
dovecot2 = 46; dovecot2 = 46;
dovenull2 = 47; dovenull2 = 47;
unbound = 48; unbound = 48;
prayer = 49; prayer = 49;
mpd = 50; mpd = 50;
clamav = 51; clamav = 51;
fprot = 52; fprot = 52;
bind = 53; bind = 53;
wwwrun = 54; wwwrun = 54;
spamd = 56; spamd = 56;
nslcd = 58; nslcd = 58;
nginx = 60; nginx = 60;
chrony = 61; chrony = 61;
smtpd = 63; smtpd = 63;
smtpq = 64; smtpq = 64;
supybot = 65; supybot = 65;
iodined = 66; iodined = 66;
graphite = 68; graphite = 68;
statsd = 69; statsd = 69;
transmission = 70; transmission = 70;
postgres = 71; postgres = 71;
smbguest = 74; smbguest = 74;
varnish = 75; varnish = 75;
dd-agent = 76; dd-agent = 76;
lighttpd = 77; lighttpd = 77;
lightdm = 78; lightdm = 78;
freenet = 79; freenet = 79;
ircd = 80; ircd = 80;
bacula = 81; bacula = 81;
almir = 82; almir = 82;
deluge = 83; deluge = 83;
mysql = 84; mysql = 84;
rabbitmq = 85; rabbitmq = 85;
activemq = 86; activemq = 86;
gnunet = 87; gnunet = 87;
oidentd = 88; oidentd = 88;
quassel = 89; quassel = 89;
amule = 90; amule = 90;
minidlna = 91; minidlna = 91;
elasticsearch = 92; elasticsearch = 92;
# When adding a uid, make sure it doesn't match an existing gid. # When adding a uid, make sure it doesn't match an existing gid.
nixbld = 30000; # start of range of uids nixbld = 30000; # start of range of uids
nobody = 65534; nobody = 65534;
}; };
ids.gids = { ids.gids = {
root = 0; root = 0;
wheel = 1; wheel = 1;
kmem = 2; kmem = 2;
tty = 3; tty = 3;
messagebus = 4; # D-Bus messagebus = 4; # D-Bus
haldaemon = 5; haldaemon = 5;
disk = 6; disk = 6;
vsftpd = 7; vsftpd = 7;
ftp = 8; ftp = 8;
bitlbee = 9; bitlbee = 9;
avahi = 10; avahi = 10;
portmap = 11; portmap = 11;
atd = 12; atd = 12;
postfix = 13; postfix = 13;
postdrop = 14; postdrop = 14;
dovecot = 15; dovecot = 15;
audio = 17; audio = 17;
floppy = 18; floppy = 18;
uucp = 19; uucp = 19;
lp = 20; lp = 20;
tomcat = 21; tomcat = 21;
pulseaudio = 22; # must match `pulseaudio' UID pulseaudio = 22; # must match `pulseaudio' UID
gpsd = 23; gpsd = 23;
cdrom = 24; cdrom = 24;
tape = 25; tape = 25;
video = 26; video = 26;
dialout = 27; dialout = 27;
polkituser = 28; polkituser = 28;
utmp = 29; utmp = 29;
davfs2 = 31; davfs2 = 31;
privoxy = 32; privoxy = 32;
disnix = 33; disnix = 33;
osgi = 34; osgi = 34;
ghostOne = 40; ghostOne = 40;
git = 41; git = 41;
fourStore = 42; fourStore = 42;
fourStoreEndpoint = 43; fourStoreEndpoint = 43;
virtuoso = 44; virtuoso = 44;
dovecot2 = 46; dovecot2 = 46;
prayer = 49; prayer = 49;
mpd = 50; mpd = 50;
clamav = 51; clamav = 51;
fprot = 52; fprot = 52;
wwwrun = 54; wwwrun = 54;
adm = 55; adm = 55;
spamd = 56; spamd = 56;
networkmanager = 57; networkmanager = 57;
nslcd = 58; nslcd = 58;
scanner = 59; scanner = 59;
nginx = 60; nginx = 60;
systemd-journal = 62; systemd-journal = 62;
smtpd = 63; smtpd = 63;
smtpq = 64; smtpq = 64;
supybot = 65; supybot = 65;
iodined = 66; iodined = 66;
libvirtd = 67; libvirtd = 67;
graphite = 68; graphite = 68;
transmission = 70; transmission = 70;
postgres = 71; postgres = 71;
vboxusers = 72; vboxusers = 72;
vboxsf = 73; vboxsf = 73;
smbguest = 74; smbguest = 74;
varnish = 75; varnish = 75;
dd-agent = 76; dd-agent = 76;
lighttpd = 77; lighttpd = 77;
lightdm = 78; lightdm = 78;
freenet = 79; freenet = 79;
ircd = 80; ircd = 80;
bacula = 81; bacula = 81;
almir = 82; almir = 82;
deluge = 83; deluge = 83;
mysql = 84; mysql = 84;
rabbitmq = 85; rabbitmq = 85;
activemq = 86; activemq = 86;
gnunet = 87; gnunet = 87;
oidentd = 88; oidentd = 88;
quassel = 89; quassel = 89;
amule = 90; amule = 90;
minidlna = 91; minidlna = 91;
# When adding a gid, make sure it doesn't match an existing uid. # When adding a gid, make sure it doesn't match an existing uid.
users = 100;
nixbld = 30000;
nogroup = 65534;
};
users = 100;
nixbld = 30000;
nogroup = 65534;
}; };
} }

View File

@ -1,21 +1,15 @@
# This module allows you to export something from configuration # This module allows you to export something from configuration
# Use case: export kernel source expression for ease of configuring # Use case: export kernel source expression for ease of configuring
{config, pkgs, ...}: { config, pkgs, ... }:
let
options = {
passthru = pkgs.lib.mkOption {
description = ''
This attribute set will be exported as a system attribute.
You can put whatever you want here.
'';
};
};
in
{ {
require = options; options = {
passthru = pkgs.lib.mkOption {
description = ''
This attribute set will be exported as a system attribute.
You can put whatever you want here.
'';
};
};
} }

View File

@ -224,7 +224,6 @@
#./services/x11/window-managers/compiz.nix #./services/x11/window-managers/compiz.nix
./services/x11/window-managers/default.nix ./services/x11/window-managers/default.nix
./services/x11/window-managers/icewm.nix ./services/x11/window-managers/icewm.nix
./services/x11/window-managers/kwm.nix
./services/x11/window-managers/metacity.nix ./services/x11/window-managers/metacity.nix
./services/x11/window-managers/none.nix ./services/x11/window-managers/none.nix
./services/x11/window-managers/twm.nix ./services/x11/window-managers/twm.nix

View File

@ -49,7 +49,7 @@
# Include lots of firmware. # Include lots of firmware.
hardware.enableAllFirmware = true; hardware.enableAllFirmware = true;
require = imports =
[ ../hardware/network/zydas-zd1211.nix ]; [ ../hardware/network/zydas-zd1211.nix ];
} }

View File

@ -47,7 +47,7 @@ let
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [ ${toString config.installer.cloneConfigIncludes} ]; imports = [ ${toString config.installer.cloneConfigIncludes} ];
} }
''; '';

View File

@ -1,7 +1,7 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
require = [ ./graphical.nix ]; imports = [ ./graphical.nix ];
users.extraUsers.demo = users.extraUsers.demo =
{ description = "Demo user account"; { description = "Demo user account";

View File

@ -31,6 +31,9 @@ let
mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases
); );
in
{
options = { options = {
environment.promptInit = mkOption { environment.promptInit = mkOption {
@ -87,70 +90,65 @@ let
}; };
in
{ config = {
require = [options];
environment.etc = # Script executed when the shell starts as a login shell.
[ { # Script executed when the shell starts as a login shell. environment.etc."profile".source =
source = pkgs.substituteAll { pkgs.substituteAll {
src = ./profile.sh; src = ./profile.sh;
wrapperDir = config.security.wrapperDir; wrapperDir = config.security.wrapperDir;
inherit (cfg) shellInit; inherit (cfg) shellInit;
}; };
target = "profile";
}
{ # /etc/bashrc: executed every time an interactive bash # /etc/bashrc: executed every time an interactive bash
# starts. Sources /etc/profile to ensure that the system # starts. Sources /etc/profile to ensure that the system
# environment is configured properly. # environment is configured properly.
source = pkgs.substituteAll { environment.etc."bashrc".source =
src = ./bashrc.sh; pkgs.substituteAll {
inherit (cfg) interactiveShellInit; src = ./bashrc.sh;
}; inherit (cfg) interactiveShellInit;
target = "bashrc"; };
}
{ # Configuration for readline in bash. # Configuration for readline in bash.
source = ./inputrc; environment.etc."inputrc".source = ./inputrc;
target = "inputrc";
} environment.shellAliases =
{ ls = "ls --color=tty";
ll = "ls -l";
l = "ls -alh";
which = "type -P";
};
environment.interactiveShellInit =
''
# Check the window size after every command.
shopt -s checkwinsize
${cfg.promptInit}
${initBashCompletion}
${shellAliases}
# Disable hashing (i.e. caching) of command lookups.
set +h
'';
system.build.binsh = pkgs.bashInteractive;
system.activationScripts.binsh = stringAfter [ "stdio" ]
''
# Create the required /bin/sh symlink; otherwise lots of things
# (notably the system() function) won't work.
mkdir -m 0755 -p /bin
ln -sfn "${cfg.binsh}" /bin/.sh.tmp
mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh
'';
environment.pathsToLink = optionals cfg.enableBashCompletion [
"/etc/bash_completion.d"
"/share/bash-completion"
]; ];
environment.shellAliases = };
{ ls = "ls --color=tty";
ll = "ls -l";
l = "ls -alh";
which = "type -P";
};
environment.interactiveShellInit =
''
# Check the window size after every command.
shopt -s checkwinsize
${cfg.promptInit}
${initBashCompletion}
${shellAliases}
# Disable hashing (i.e. caching) of command lookups.
set +h
'';
system.build.binsh = pkgs.bashInteractive;
system.activationScripts.binsh = stringAfter [ "stdio" ]
''
# Create the required /bin/sh symlink; otherwise lots of things
# (notably the system() function) won't work.
mkdir -m 0755 -p /bin
ln -sfn "${cfg.binsh}" /bin/.sh.tmp
mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh
'';
environment.pathsToLink = optionals cfg.enableBashCompletion [
"/etc/bash_completion.d"
"/share/bash-completion"
];
} }

View File

@ -3,12 +3,18 @@
# directly to an SMTP server defined in its configuration file, wihout # directly to an SMTP server defined in its configuration file, wihout
# queueing mail locally. # queueing mail locally.
{config, pkgs, ...}: { config, pkgs, ... }:
with pkgs.lib; with pkgs.lib;
let let
cfg = config.networking.defaultMailServer;
in
{
options = { options = {
networking.defaultMailServer = { networking.defaultMailServer = {
@ -16,94 +22,90 @@ let
directDelivery = mkOption { directDelivery = mkOption {
default = false; default = false;
example = true; example = true;
description = " description = ''
Use the trivial Mail Transfer Agent (MTA) Use the trivial Mail Transfer Agent (MTA)
<command>ssmtp</command> package to allow programs to send <command>ssmtp</command> package to allow programs to send
e-mail. If you don't want to run a ``real'' MTA like e-mail. If you don't want to run a real MTA like
<command>sendmail</command> or <command>postfix</command> on <command>sendmail</command> or <command>postfix</command> on
your machine, set this option to <literal>true</literal>, and your machine, set this option to <literal>true</literal>, and
set the option set the option
<option>networking.defaultMailServer.hostName</option> to the <option>networking.defaultMailServer.hostName</option> to the
host name of your preferred mail server. host name of your preferred mail server.
"; '';
}; };
hostName = mkOption { hostName = mkOption {
example = "mail.example.org"; example = "mail.example.org";
description = " description = ''
The host name of the default mail server to use to deliver The host name of the default mail server to use to deliver
e-mail. e-mail.
"; '';
}; };
domain = mkOption { domain = mkOption {
default = ""; default = "";
example = "example.org"; example = "example.org";
description = " description = ''
The domain from which mail will appear to be sent. The domain from which mail will appear to be sent.
"; '';
}; };
useTLS = mkOption { useTLS = mkOption {
default = false; default = false;
example = true; example = true;
description = " description = ''
Whether TLS should be used to connect to the default mail Whether TLS should be used to connect to the default mail
server. server.
"; '';
}; };
useSTARTTLS = mkOption { useSTARTTLS = mkOption {
default = false; default = false;
example = true; example = true;
description = " description = ''
Whether the STARTTLS should be used to connect to the default Whether the STARTTLS should be used to connect to the default
mail server. (This is needed for TLS-capable mail servers mail server. (This is needed for TLS-capable mail servers
running on the default SMTP port 25.) running on the default SMTP port 25.)
"; '';
}; };
authUser = mkOption { authUser = mkOption {
default = ""; default = "";
example = "foo@example.org"; example = "foo@example.org";
description = " description = ''
Username used for SMTP auth. Leave blank to disable. Username used for SMTP auth. Leave blank to disable.
"; '';
}; };
authPass = mkOption { authPass = mkOption {
default = ""; default = "";
example = "correctHorseBatteryStaple"; example = "correctHorseBatteryStaple";
description = " description = ''
Password used for SMTP auth. (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE) Password used for SMTP auth. (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)
"; '';
}; };
}; };
}; };
cfg = config.networking.defaultMailServer;
in config = mkIf cfg.directDelivery {
mkIf cfg.directDelivery { environment.etc."ssmtp/ssmtp.conf".text =
require = [options]; ''
MailHub=${cfg.hostName}
FromLineOverride=YES
${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""}
UseTLS=${if cfg.useTLS then "YES" else "NO"}
UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"}
#Debug=YES
${if cfg.authUser != "" then "AuthUser=${cfg.authUser}" else ""}
${if cfg.authPass != "" then "AuthPass=${cfg.authPass}" else ""}
'';
environment.etc = environment.systemPackages = [pkgs.ssmtp];
[ { source = pkgs.writeText "ssmtp.conf" ''
MailHub=${cfg.hostName} };
FromLineOverride=YES
${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""}
UseTLS=${if cfg.useTLS then "YES" else "NO"}
UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"}
#Debug=YES
${if cfg.authUser != "" then "AuthUser=${cfg.authUser}" else ""}
${if cfg.authPass != "" then "AuthPass=${cfg.authPass}" else ""}
'';
target = "ssmtp/ssmtp.conf";
}
];
environment.systemPackages = [pkgs.ssmtp];
} }

View File

@ -1,47 +1,42 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.services.xserver.desktopManager.gnome; cfg = config.services.xserver.desktopManager.gnome;
gnome = pkgs.gnome; gnome = pkgs.gnome;
options = { services = { xserver = { desktopManager = {
gnome = {
enable = mkOption {
default = false;
example = true;
description = "Enable a gnome terminal as a desktop manager.";
};
};
}; }; }; };
in in
mkIf cfg.enable { {
require = options;
services = { options = {
xserver = {
desktopManager = { services.xserver.desktopManager.gnome.enable = mkOption {
session = [{ default = false;
name = "gnome"; example = true;
start = '' description = "Enable a gnome terminal as a desktop manager.";
${gnome.gnometerminal}/bin/gnome-terminal -ls & };
waitPID=$!
''; };
}];
config = mkIf cfg.enable {
services.xserver.desktopManager.session = singleton
{ name = "gnome";
start = ''
${gnome.gnometerminal}/bin/gnome-terminal -ls &
waitPID=$!
'';
}; };
}; environment.systemPackages =
[ gnome.gnometerminal
gnome.GConf
gnome.gconfeditor
];
}; };
environment = {
x11Packages = [
gnome.gnometerminal
gnome.GConf
gnome.gconfeditor
];
};
} }

View File

@ -1,10 +1,14 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.services.xserver.desktopManager.xterm; cfg = config.services.xserver.desktopManager.xterm;
in
{
options = { options = {
services.xserver.desktopManager.xterm.enable = mkOption { services.xserver.desktopManager.xterm.enable = mkOption {
@ -15,30 +19,18 @@ let
}; };
in config = mkIf cfg.enable {
mkIf cfg.enable { services.xserver.desktopManager.session = singleton
require = options; { name = "xterm";
start = ''
services = { ${pkgs.xterm}/bin/xterm -ls &
xserver = { waitPID=$!
'';
desktopManager = {
session = [{
name = "xterm";
start = ''
${pkgs.xterm}/bin/xterm -ls &
waitPID=$!
'';
}];
}; };
}; environment.systemPackages = [ pkgs.xterm ];
}; };
environment = {
x11Packages = [
pkgs.xterm
];
};
} }

View File

@ -1,25 +1,26 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mergeOneOption any;
cfg = config.services.xserver.windowManager; cfg = config.services.xserver.windowManager;
in in
{ {
imports = [ imports =
./compiz.nix [ ./compiz.nix
./openbox.nix ./openbox.nix
./kwm.nix ./metacity.nix
./metacity.nix ./none.nix
./none.nix ./twm.nix
./twm.nix ./wmii.nix
./wmii.nix ./xmonad.nix
./xmonad.nix ./i3.nix
./i3.nix ./xbmc.nix
./xbmc.nix ];
];
options = { options = {
services.xserver.windowManager = { services.xserver.windowManager = {
session = mkOption { session = mkOption {
@ -28,11 +29,11 @@ in
name = "wmii"; name = "wmii";
start = "..."; start = "...";
}]; }];
description = " description = ''
Internal option used to add some common line to window manager Internal option used to add some common line to window manager
scripts before forwarding the value to the scripts before forwarding the value to the
<varname>displayManager</varname>. <varname>displayManager</varname>.
"; '';
apply = map (d: d // { apply = map (d: d // {
manage = "window"; manage = "window";
}); });
@ -41,9 +42,7 @@ in
default = mkOption { default = mkOption {
default = "none"; default = "none";
example = "wmii"; example = "wmii";
description = " description = "Default window manager loaded if none have been chosen.";
Default window manager loaded if none have been chosen.
";
merge = mergeOneOption; merge = mergeOneOption;
apply = defaultWM: apply = defaultWM:
if any (w: w.name == defaultWM) cfg.session then if any (w: w.name == defaultWM) cfg.session then
@ -53,6 +52,7 @@ in
}; };
}; };
}; };
config = { config = {

View File

@ -1,46 +0,0 @@
{pkgs, config, ...}:
let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.services.xserver.windowManager.kwm;
option = { services = { xserver = { windowManager = {
kwm = {
enable = mkOption {
default = false;
example = true;
description = "Enable the kwm window manager.";
};
};
}; }; }; };
in
mkIf cfg.enable {
require = option;
services = {
xserver = {
windowManager = {
session = [{
name = "kwm";
start = "
${pkgs.kde3.kdebase}/bin/kwin &
waitPID=$!
";
}];
};
};
};
environment = {
x11Packages = [
pkgs.kde3.kdelibs
pkgs.kde3.kdebase
];
};
}

View File

@ -1,49 +1,42 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.services.xserver.windowManager.metacity; cfg = config.services.xserver.windowManager.metacity;
xorg = config.services.xserver.package; xorg = config.services.xserver.package;
gnome = pkgs.gnome; gnome = pkgs.gnome;
option = { services = { xserver = { windowManager = {
metacity = {
enable = mkOption {
default = false;
example = true;
description = "Enable the metacity window manager.";
};
};
}; }; }; };
in in
mkIf cfg.enable { {
require = option; options = {
services = { services.xserver.windowManager.metacity.enable = mkOption {
xserver = { default = false;
example = true;
description = "Enable the metacity window manager.";
};
windowManager = { };
session = [{
name = "metacity"; config = mkIf cfg.enable {
start = ''
env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/ services.xserver.windowManager.session = singleton
# !!! Hack: load the schemas for Metacity. { name = "metacity";
GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \ start = ''
--makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */ env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/
${gnome.metacity}/bin/metacity & # !!! Hack: load the schemas for Metacity.
waitPID=$! GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
''; --makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */
}]; ${gnome.metacity}/bin/metacity &
waitPID=$!
'';
}; };
}; environment.systemPackages = [ gnome.metacity ];
}; };
environment = {
x11Packages = [ gnome.metacity ];
};
} }

View File

@ -1,27 +1,27 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mkIf;
cfg = config.services.xserver.windowManager.wmii; cfg = config.services.xserver.windowManager.wmii;
option = { services = { xserver = { windowManager = {
wmii = {
enable = mkOption {
default = false;
example = true;
description = "Enable the wmii window manager.";
};
};
}; }; }; };
in in
mkIf cfg.enable { {
require = option; options = {
services = { services.xserver.windowManager.wmii.enable = mkOption {
xserver = { default = false;
example = true;
description = "Enable the wmii window manager.";
};
};
config = mkIf cfg.enable {
services.xserver.windowManager.session = singleton
# stop wmii by # stop wmii by
# $wmiir xwrite /ctl quit # $wmiir xwrite /ctl quit
# this will cause wmii exiting with exit code 0 # this will cause wmii exiting with exit code 0
@ -32,23 +32,16 @@ mkIf cfg.enable {
# lost and all applications running on X will terminate. # lost and all applications running on X will terminate.
# Another use case is kill -9 wmii; after rotating screen. # Another use case is kill -9 wmii; after rotating screen.
# Note: we don't like kill for that purpose. But it works (-> subject "wmii and xrandr" on mailinglist) # Note: we don't like kill for that purpose. But it works (-> subject "wmii and xrandr" on mailinglist)
windowManager = { { name = "wmii";
session = [{ start = ''
name = "wmii"; while :; do
start = " ${pkgs.wmiiSnap}/bin/wmii && break
while :; do done
${pkgs.wmiiSnap}/bin/wmii && break '';
done
";
}];
}; };
}; environment.systemPackages = [ pkgs.wmiiSnap ];
}; };
environment = {
x11Packages = [
pkgs.wmiiSnap
];
};
} }

View File

@ -4,66 +4,6 @@ with pkgs.lib;
let let
options = {
system.build = mkOption {
default = {};
description = ''
Attribute set of derivations used to setup the system.
'';
};
nesting.children = mkOption {
default = [];
description = ''
Additional configurations to build.
'';
};
nesting.clone = mkOption {
default = [];
description = ''
Additional configurations to build based on the current
configuration which is has a lower priority.
'';
};
system.boot.loader.id = mkOption {
default = "";
description = ''
Id string of the used bootloader.
'';
};
system.boot.loader.kernelFile = mkOption {
default = pkgs.stdenv.platform.kernelTarget;
type = types.uniq types.string;
description = ''
Name of the kernel file to be passed to the bootloader.
'';
};
system.copySystemConfiguration = mkOption {
default = false;
description = ''
If enabled, copies the NixOS configuration file
<literal>$NIXOS_CONFIG</literal> (usually
<filename>/etc/nixos/configuration.nix</filename>)
to the system store path.
'';
};
system.extraSystemBuilderCmds = mkOption {
default = "";
internal = true;
merge = concatStringsSep "\n";
description = ''
This code will be added to the builder creating the system store path.
'';
};
};
# This attribute is responsible for creating boot entries for # This attribute is responsible for creating boot entries for
# child configuration. They are only (directly) accessible # child configuration. They are only (directly) accessible
@ -176,13 +116,79 @@ let
}; };
in { in
require = [options];
system.extraSystemBuilderCmds = {
optionalString options = {
config.system.copySystemConfiguration
"cp ${maybeEnv "NIXOS_CONFIG" "/etc/nixos/configuration.nix"} $out"; system.build = mkOption {
default = {};
description = ''
Attribute set of derivations used to setup the system.
'';
};
nesting.children = mkOption {
default = [];
description = ''
Additional configurations to build.
'';
};
nesting.clone = mkOption {
default = [];
description = ''
Additional configurations to build based on the current
configuration which is has a lower priority.
'';
};
system.boot.loader.id = mkOption {
default = "";
description = ''
Id string of the used bootloader.
'';
};
system.boot.loader.kernelFile = mkOption {
default = pkgs.stdenv.platform.kernelTarget;
type = types.uniq types.string;
description = ''
Name of the kernel file to be passed to the bootloader.
'';
};
system.copySystemConfiguration = mkOption {
default = false;
description = ''
If enabled, copies the NixOS configuration file
<literal>$NIXOS_CONFIG</literal> (usually
<filename>/etc/nixos/configuration.nix</filename>)
to the system store path.
'';
};
system.extraSystemBuilderCmds = mkOption {
default = "";
internal = true;
merge = concatStringsSep "\n";
description = ''
This code will be added to the builder creating the system store path.
'';
};
};
config = {
system.extraSystemBuilderCmds =
optionalString
config.system.copySystemConfiguration
"cp ${maybeEnv "NIXOS_CONFIG" "/etc/nixos/configuration.nix"} $out";
system.build.toplevel = system;
};
system.build.toplevel = system;
} }

View File

@ -1,48 +1,9 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
options = {
boot = {
loader = {
generationsDir = {
enable = mkOption {
default = false;
description = ''
Whether to create symlinks to the system generations under
<literal>/boot</literal>. When enabled,
<literal>/boot/default/kernel</literal>,
<literal>/boot/default/initrd</literal>, etc., are updated to
point to the current generation's kernel image, initial RAM
disk, and other bootstrap files.
This optional is not necessary with boot loaders such as GNU GRUB
for which the menu is updated to point to the latest bootstrap
files. However, it is needed for U-Boot on platforms where the
boot command line is stored in flash memory rather than in a
menu file.
'';
};
copyKernels = mkOption {
default = false;
description = "
Whether copy the necessary boot files into /boot, so
/nix/store is not needed by the boot loader.
";
};
};
};
};
};
in
###### implementation
let
generationsDirBuilder = pkgs.substituteAll { generationsDirBuilder = pkgs.substituteAll {
src = ./generations-dir-builder.sh; src = ./generations-dir-builder.sh;
isExecutable = true; isExecutable = true;
@ -53,18 +14,50 @@ let
# Temporary check, for nixos to cope both with nixpkgs stdenv-updates and trunk # Temporary check, for nixos to cope both with nixpkgs stdenv-updates and trunk
platform = pkgs.stdenv.platform; platform = pkgs.stdenv.platform;
in in
{ {
require = [ options = {
options
# config.system.build boot.loader.generationsDir = {
# ../system/system-options.nix
]; enable = mkOption {
default = false;
description = ''
Whether to create symlinks to the system generations under
<literal>/boot</literal>. When enabled,
<literal>/boot/default/kernel</literal>,
<literal>/boot/default/initrd</literal>, etc., are updated to
point to the current generation's kernel image, initial RAM
disk, and other bootstrap files.
This optional is not necessary with boot loaders such as GNU GRUB
for which the menu is updated to point to the latest bootstrap
files. However, it is needed for U-Boot on platforms where the
boot command line is stored in flash memory rather than in a
menu file.
'';
};
copyKernels = mkOption {
default = false;
description = "
Whether copy the necessary boot files into /boot, so
/nix/store is not needed by the boot loader.
";
};
};
};
config = mkIf config.boot.loader.generationsDir.enable {
system.build.installBootLoader = generationsDirBuilder;
system.boot.loader.id = "generationsDir";
system.boot.loader.kernelFile = platform.kernelTarget;
system = mkIf config.boot.loader.generationsDir.enable {
build.installBootLoader = generationsDirBuilder;
boot.loader.id = "generationsDir";
boot.loader.kernelFile = platform.kernelTarget;
}; };
} }

View File

@ -1,30 +1,9 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
options = {
boot = {
loader = {
raspberryPi = {
enable = mkOption {
default = false;
description = ''
Whether to create files with the system generations in
<literal>/boot</literal>.
<literal>/boot/old</literal> will hold files from old generations.
'';
};
};
};
};
};
in
###### implementation
let
builder = pkgs.substituteAll { builder = pkgs.substituteAll {
src = ./builder.sh; src = ./builder.sh;
isExecutable = true; isExecutable = true;
@ -34,18 +13,26 @@ let
}; };
platform = pkgs.stdenv.platform; platform = pkgs.stdenv.platform;
in in
{ {
require = [ options = {
options
# config.system.build boot.loader.raspberryPi.enable = mkOption {
# ../system/system-options.nix default = false;
]; description = ''
Whether to create files with the system generations in
<literal>/boot</literal>.
<literal>/boot/old</literal> will hold files from old generations.
'';
};
system = mkIf config.boot.loader.raspberryPi.enable { };
build.installBootLoader = builder;
boot.loader.id = "raspberrypi"; config = mkIf config.boot.loader.raspberryPi.enable {
boot.loader.kernelFile = platform.kernelTarget; system.build.installBootLoader = builder;
system.boot.loader.id = "raspberrypi";
system.boot.loader.kernelFile = platform.kernelTarget;
}; };
} }

View File

@ -11,116 +11,6 @@ let
udev = config.systemd.package; udev = config.systemd.package;
options = {
boot.resumeDevice = mkOption {
default = "";
example = "0:0";
description = "
Device for manual resume attempt during boot. Looks like
major:minor. ls -l /dev/SWAP_PARTION shows them.
";
};
boot.initrd.enableSplashScreen = mkOption {
default = true;
description = "
Whether to show a nice splash screen while booting.
";
};
boot.initrd.checkJournalingFS = mkOption {
default = true;
type = types.bool;
description = ''
Whether to run fsck on journaling filesystems such as ext3.
'';
};
boot.initrd.mdadmConf = mkOption {
default = "";
type = with types; string;
description = ''
Contents of /etc/mdadm.conf at initrd.
'';
};
boot.initrd.preLVMCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately before lvm discovery.
'';
};
boot.initrd.postDeviceCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately after stage 1 of the
boot has loaded kernel modules and created device nodes in
/dev.
'';
};
boot.initrd.postMountCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately after the stage 1
filesystems have been mounted.
'';
};
boot.initrd.extraUtilsCommands = mkOption {
internal = true;
default = "";
type = with types; string;
description = ''
Shell commands to be executed in the builder of the
extra-utils derivation. This can be used to provide
additional utilities in the initial ramdisk.
'';
};
boot.initrd.extraUtilsCommandsTest = mkOption {
internal = true;
default = "";
type = with types; string;
description = ''
Shell commands to be executed in the builder of the
extra-utils derivation after patchelf has done its
job. This can be used to test additional utilities
copied in extraUtilsCommands.
'';
};
boot.initrd.compressor = mkOption {
default = "gzip -9";
type = types.string;
description = "The compressor to use on the initrd";
example = "xz";
};
fileSystems = mkOption {
options.neededForBoot = mkOption {
default = false;
type = types.bool;
description = ''
If set, this file system will be mounted in the initial
ramdisk. By default, this applies to the root file system
and to the file system containing
<filename>/nix/store</filename>.
'';
};
};
};
kernelPackages = config.boot.kernelPackages; kernelPackages = config.boot.kernelPackages;
modulesTree = config.system.modulesTree; modulesTree = config.system.modulesTree;
@ -141,14 +31,15 @@ let
&& kernelPackages.kernel.features.needsCifsUtils && kernelPackages.kernel.features.needsCifsUtils
&& any (fs: fs.fsType == "cifs") fileSystems; && any (fs: fs.fsType == "cifs") fileSystems;
busybox = if needsCifsUtils busybox =
then pkgs.busybox.override { if needsCifsUtils
extraConfig = '' then pkgs.busybox.override {
CONFIG_FEATURE_MOUNT_CIFS n extraConfig = ''
CONFIG_FEATURE_MOUNT_HELPERS y CONFIG_FEATURE_MOUNT_CIFS n
''; CONFIG_FEATURE_MOUNT_HELPERS y
} '';
else pkgs.busybox; }
else pkgs.busybox;
# Some additional utilities needed in stage 1, like mount, lvm, fsck # Some additional utilities needed in stage 1, like mount, lvm, fsck
@ -351,16 +242,128 @@ let
]; ];
}; };
in { in
require = [options]; {
options = {
system.build.bootStage1 = bootStage1; boot.resumeDevice = mkOption {
system.build.initialRamdisk = initialRamdisk; default = "";
system.build.extraUtils = extraUtils; example = "0:0";
description = "
Device for manual resume attempt during boot. Looks like
major:minor. ls -l /dev/SWAP_PARTION shows them.
";
};
system.requiredKernelConfig = with config.lib.kernelConfig; [ boot.initrd.enableSplashScreen = mkOption {
(isYes "TMPFS") default = true;
(isYes "BLK_DEV_INITRD") description = "
]; Whether to show a nice splash screen while booting.
";
};
boot.initrd.checkJournalingFS = mkOption {
default = true;
type = types.bool;
description = ''
Whether to run fsck on journaling filesystems such as ext3.
'';
};
boot.initrd.mdadmConf = mkOption {
default = "";
type = with types; string;
description = ''
Contents of /etc/mdadm.conf at initrd.
'';
};
boot.initrd.preLVMCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately before lvm discovery.
'';
};
boot.initrd.postDeviceCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately after stage 1 of the
boot has loaded kernel modules and created device nodes in
/dev.
'';
};
boot.initrd.postMountCommands = mkOption {
default = "";
type = with types; string;
description = ''
Shell commands to be executed immediately after the stage 1
filesystems have been mounted.
'';
};
boot.initrd.extraUtilsCommands = mkOption {
internal = true;
default = "";
type = with types; string;
description = ''
Shell commands to be executed in the builder of the
extra-utils derivation. This can be used to provide
additional utilities in the initial ramdisk.
'';
};
boot.initrd.extraUtilsCommandsTest = mkOption {
internal = true;
default = "";
type = with types; string;
description = ''
Shell commands to be executed in the builder of the
extra-utils derivation after patchelf has done its
job. This can be used to test additional utilities
copied in extraUtilsCommands.
'';
};
boot.initrd.compressor = mkOption {
default = "gzip -9";
type = types.string;
description = "The compressor to use on the initrd";
example = "xz";
};
fileSystems = mkOption {
options.neededForBoot = mkOption {
default = false;
type = types.bool;
description = ''
If set, this file system will be mounted in the initial
ramdisk. By default, this applies to the root file system
and to the file system containing
<filename>/nix/store</filename>.
'';
};
};
};
config = {
system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk;
system.build.extraUtils = extraUtils;
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "TMPFS")
(isYes "BLK_DEV_INITRD")
];
};
} }

View File

@ -4,6 +4,38 @@ with pkgs.lib;
let let
kernel = config.boot.kernelPackages.kernel;
activateConfiguration = config.system.activationScripts.script;
readonlyMountpoint = pkgs.runCommand "readonly-mountpoint" {} ''
mkdir -p $out/bin
cc -O3 ${./readonly-mountpoint.c} -o $out/bin/readonly-mountpoint
strip -s $out/bin/readonly-mountpoint
'';
bootStage2 = pkgs.substituteAll {
src = ./stage-2-init.sh;
shellDebug = "${pkgs.bashInteractive}/bin/bash";
isExecutable = true;
inherit (config.boot) devShmSize runSize cleanTmpDir;
inherit (config.nix) readOnlyStore;
ttyGid = config.ids.gids.tty;
path =
[ pkgs.coreutils
pkgs.utillinux
pkgs.sysvtools
] ++ (optional config.boot.cleanTmpDir pkgs.findutils)
++ optional config.nix.readOnlyStore readonlyMountpoint;
postBootCommands = pkgs.writeText "local-cmds"
''
${config.boot.postBootCommands}
${config.powerManagement.powerUpCommands}
'';
};
in
{
options = { options = {
boot = { boot = {
@ -59,39 +91,10 @@ let
}; };
kernel = config.boot.kernelPackages.kernel;
activateConfiguration = config.system.activationScripts.script;
readonlyMountpoint = pkgs.runCommand "readonly-mountpoint" {} '' config = {
mkdir -p $out/bin
cc -O3 ${./readonly-mountpoint.c} -o $out/bin/readonly-mountpoint system.build.bootStage2 = bootStage2;
strip -s $out/bin/readonly-mountpoint
'';
bootStage2 = pkgs.substituteAll {
src = ./stage-2-init.sh;
shellDebug = "${pkgs.bashInteractive}/bin/bash";
isExecutable = true;
inherit (config.boot) devShmSize runSize cleanTmpDir;
inherit (config.nix) readOnlyStore;
ttyGid = config.ids.gids.tty;
path =
[ pkgs.coreutils
pkgs.utillinux
pkgs.sysvtools
] ++ (optional config.boot.cleanTmpDir pkgs.findutils)
++ optional config.nix.readOnlyStore readonlyMountpoint;
postBootCommands = pkgs.writeText "local-cmds"
''
${config.boot.postBootCommands}
${config.powerManagement.powerUpCommands}
'';
}; };
in
{
require = [options];
system.build.bootStage2 = bootStage2;
} }

View File

@ -1,5 +1,5 @@
{ config, pkgs, modulesPath, ... }: { config, pkgs, modulesPath, ... }:
{ {
require = [ "${modulesPath}/virtualisation/amazon-image.nix" ]; imports = [ "${modulesPath}/virtualisation/amazon-image.nix" ];
} }

View File

@ -3,7 +3,7 @@
with pkgs.lib; with pkgs.lib;
{ {
require = [ ../profiles/headless.nix ./ec2-data.nix ]; imports = [ ../profiles/headless.nix ./ec2-data.nix ];
system.build.amazonImage = system.build.amazonImage =
pkgs.vmTools.runInLinuxVM ( pkgs.vmTools.runInLinuxVM (

View File

@ -5,7 +5,8 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
with pkgs.lib; with pkgs.lib;
let
{
options = { options = {
ec2.metadata = mkOption { ec2.metadata = mkOption {
type = types.bool; type = types.bool;
@ -15,84 +16,84 @@ let
''; '';
}; };
}; };
in
{
require = [options];
systemd.services."fetch-ec2-data" = config = {
{ description = "Fetch EC2 Data";
wantedBy = [ "multi-user.target" ]; systemd.services."fetch-ec2-data" =
before = [ "sshd.service" ]; { description = "Fetch EC2 Data";
after = [ "network.target" ];
path = [ pkgs.curl pkgs.iproute ]; wantedBy = [ "multi-user.target" ];
before = [ "sshd.service" ];
after = [ "network.target" ];
script = path = [ pkgs.curl pkgs.iproute ];
''
ip route del blackhole 169.254.169.254/32 || true
curl="curl --retry 3 --retry-delay 0 --fail" script =
''
ip route del blackhole 169.254.169.254/32 || true
echo "setting host name..." curl="curl --retry 3 --retry-delay 0 --fail"
${optionalString (config.networking.hostName == "") ''
${pkgs.nettools}/bin/hostname $($curl http://169.254.169.254/1.0/meta-data/hostname)
''}
# Don't download the SSH key if it has already been injected echo "setting host name..."
# into the image (a Nova feature). ${optionalString (config.networking.hostName == "") ''
if ! [ -e /root/.ssh/authorized_keys ]; then ${pkgs.nettools}/bin/hostname $($curl http://169.254.169.254/1.0/meta-data/hostname)
echo "obtaining SSH key..." ''}
mkdir -p /root/.ssh
$curl -o /root/key.pub http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
if [ $? -eq 0 -a -e /root/key.pub ]; then
if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then
cat /root/key.pub >> /root/.ssh/authorized_keys
echo "new key added to authorized_keys"
fi
chmod 600 /root/.ssh/authorized_keys
rm -f /root/key.pub
fi
fi
# Extract the intended SSH host key for this machine from # Don't download the SSH key if it has already been injected
# the supplied user data, if available. Otherwise sshd will # into the image (a Nova feature).
# generate one normally. if ! [ -e /root/.ssh/authorized_keys ]; then
$curl http://169.254.169.254/2011-01-01/user-data > /root/user-data || true echo "obtaining SSH key..."
key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' /root/user-data)" mkdir -p /root/.ssh
key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' /root/user-data)" $curl -o /root/key.pub http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_dsa_key ]; then if [ $? -eq 0 -a -e /root/key.pub ]; then
mkdir -m 0755 -p /etc/ssh if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then
(umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key) cat /root/key.pub >> /root/.ssh/authorized_keys
echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub echo "new key added to authorized_keys"
fi fi
chmod 600 /root/.ssh/authorized_keys
rm -f /root/key.pub
fi
fi
${optionalString (! config.ec2.metadata) '' # Extract the intended SSH host key for this machine from
# Since the user data is sensitive, prevent it from being # the supplied user data, if available. Otherwise sshd will
# accessed from now on. # generate one normally.
ip route add blackhole 169.254.169.254/32 $curl http://169.254.169.254/2011-01-01/user-data > /root/user-data || true
''} key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' /root/user-data)"
''; key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' /root/user-data)"
if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_dsa_key ]; then
mkdir -m 0755 -p /etc/ssh
(umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key)
echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
fi
serviceConfig.Type = "oneshot"; ${optionalString (! config.ec2.metadata) ''
serviceConfig.RemainAfterExit = true; # Since the user data is sensitive, prevent it from being
}; # accessed from now on.
ip route add blackhole 169.254.169.254/32
''}
'';
systemd.services."print-host-key" = serviceConfig.Type = "oneshot";
{ description = "Print SSH Host Key"; serviceConfig.RemainAfterExit = true;
wantedBy = [ "multi-user.target" ]; };
after = [ "sshd.service" ];
script =
''
# Print the host public key on the console so that the user
# can obtain it securely by parsing the output of
# ec2-get-console-output.
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console
${pkgs.openssh}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console
echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
};
systemd.services."print-host-key" =
{ description = "Print SSH Host Key";
wantedBy = [ "multi-user.target" ];
after = [ "sshd.service" ];
script =
''
# Print the host public key on the console so that the user
# can obtain it securely by parsing the output of
# ec2-get-console-output.
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console
${pkgs.openssh}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console
echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
};
};
} }

View File

@ -1,5 +1,5 @@
{ config, pkgs, modulesPath, ... }: { config, pkgs, modulesPath, ... }:
{ {
require = [ "${modulesPath}/virtualisation/nova-image.nix" ]; imports = [ "${modulesPath}/virtualisation/nova-image.nix" ];
} }

View File

@ -3,7 +3,7 @@
with pkgs.lib; with pkgs.lib;
{ {
require = [ ../profiles/qemu-guest.nix ../profiles/headless.nix ./ec2-data.nix ]; imports = [ ../profiles/qemu-guest.nix ../profiles/headless.nix ./ec2-data.nix ];
system.build.novaImage = system.build.novaImage =
pkgs.vmTools.runInLinuxVM ( pkgs.vmTools.runInLinuxVM (

View File

@ -18,6 +18,123 @@ let
then "noname" then "noname"
else config.networking.hostName; else config.networking.hostName;
cfg = config.virtualisation;
qemuGraphics = if cfg.graphics then "" else "-nographic";
kernelConsole = if cfg.graphics then "" else "console=ttyS0";
ttys = [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ];
# Shell script to start the VM.
startVM =
''
#! ${pkgs.stdenv.shell}
NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}})
if ! test -e "$NIX_DISK_IMAGE"; then
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" \
${toString config.virtualisation.diskSize}M || exit 1
fi
# Create a directory for exchanging data with the VM.
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
fi
cd $TMPDIR
mkdir -p $TMPDIR/xchg
idx=2
extraDisks=""
${flip concatMapStrings cfg.emptyDiskImages (size: ''
${pkgs.qemu_kvm}/bin/qemu-img create -f raw "empty$idx" "${toString size}M"
extraDisks="$extraDisks -drive index=$idx,file=$(pwd)/empty$idx,if=virtio,werror=report"
idx=$((idx + 1))
'')}
# Start QEMU.
# "-boot menu=on" is there, because I don't know how to make qemu boot from 2nd hd.
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \
-name ${vmName} \
-m ${toString config.virtualisation.memorySize} \
${optionalString (pkgs.stdenv.system == "x86_64-linux") "-cpu kvm64"} \
-net nic,vlan=0,model=virtio \
-net user,vlan=0''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
-virtfs local,path=/nix/store,security_model=none,mount_tag=store \
-virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
${if cfg.useBootLoader then ''
-drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
-drive index=1,id=drive2,file=${bootDisk}/disk.img,if=virtio,readonly \
-boot menu=on
'' else ''
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
-kernel ${config.system.build.toplevel}/kernel \
-initrd ${config.system.build.toplevel}/initrd \
-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo} ${kernelConsole} $QEMU_KERNEL_PARAMS" \
''} \
$extraDisks \
${qemuGraphics} \
${toString config.virtualisation.qemu.options} \
$QEMU_OPTS
'';
regInfo = pkgs.runCommand "reginfo"
{ exportReferencesGraph =
map (x: [("closure-" + baseNameOf x) x]) config.virtualisation.pathsInNixDB;
buildInputs = [ pkgs.perl ];
preferLocalBuild = true;
}
''
printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > $out
'';
# Generate a hard disk image containing a /boot partition and GRUB
# in the MBR. Used when the `useBootLoader' option is set.
bootDisk =
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "nixos-boot-disk"
{ preVM =
''
mkdir $out
diskImage=$out/disk.img
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "32M"
'';
buildInputs = [ pkgs.utillinux ];
}
''
# Create a single /boot partition.
${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
. /sys/class/block/vda1/uevent
mknod /dev/vda1 b $MAJOR $MINOR
. /sys/class/block/vda/uevent
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
# Mount /boot.
mkdir /boot
mount /dev/vda1 /boot
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
mkdir /boot/grub
echo '(hd0) /dev/vda' > /boot/grub/device.map
# Install GRUB and generate the GRUB boot menu.
touch /etc/NIXOS
mkdir -p /nix/var/nix/profiles
${config.system.build.toplevel}/bin/switch-to-configuration boot
umount /boot
''
);
in
{
imports = [ ../profiles/qemu-guest.nix ];
options = { options = {
virtualisation.memorySize = virtualisation.memorySize =
@ -154,264 +271,151 @@ let
}; };
cfg = config.virtualisation; config = {
qemuGraphics = if cfg.graphics then "" else "-nographic"; boot.loader.grub.device = mkOverride 50 "/dev/vda";
kernelConsole = if cfg.graphics then "" else "console=ttyS0";
ttys = [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ];
# Shell script to start the VM. boot.initrd.supportedFilesystems = optional cfg.writableStore "unionfs-fuse";
startVM =
''
#! ${pkgs.stdenv.shell}
NIX_DISK_IMAGE=$(readlink -f ''${NIX_DISK_IMAGE:-${config.virtualisation.diskImage}}) boot.initrd.extraUtilsCommands =
''
# We need mke2fs in the initrd.
cp ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin
'';
if ! test -e "$NIX_DISK_IMAGE"; then boot.initrd.postDeviceCommands =
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 "$NIX_DISK_IMAGE" \ ''
${toString config.virtualisation.diskSize}M || exit 1 # If the disk image appears to be empty, run mke2fs to
fi # initialise.
FSTYPE=$(blkid -o value -s TYPE /dev/vda || true)
if test -z "$FSTYPE"; then
mke2fs -t ext4 /dev/vda
fi
'';
# Create a directory for exchanging data with the VM. boot.initrd.postMountCommands =
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then ''
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir) # Mark this as a NixOS machinex.
fi mkdir -p $targetRoot/etc
cd $TMPDIR echo -n > $targetRoot/etc/NIXOS
mkdir -p $TMPDIR/xchg
idx=2 # Fix the permissions on /tmp.
extraDisks="" chmod 1777 $targetRoot/tmp
${flip concatMapStrings cfg.emptyDiskImages (size: ''
${pkgs.qemu_kvm}/bin/qemu-img create -f raw "empty$idx" "${toString size}M"
extraDisks="$extraDisks -drive index=$idx,file=$(pwd)/empty$idx,if=virtio,werror=report"
idx=$((idx + 1))
'')}
# Start QEMU. mkdir -p $targetRoot/boot
# "-boot menu=on" is there, because I don't know how to make qemu boot from 2nd hd. mount -o remount,ro $targetRoot/nix/store
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \ ${optionalString cfg.writableStore ''
-name ${vmName} \ mkdir -p /unionfs-chroot/ro-store
-m ${toString config.virtualisation.memorySize} \ mount --rbind $targetRoot/nix/store /unionfs-chroot/ro-store
${optionalString (pkgs.stdenv.system == "x86_64-linux") "-cpu kvm64"} \
-net nic,vlan=0,model=virtio \ mkdir /unionfs-chroot/rw-store
-net user,vlan=0''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \ ${if cfg.writableStoreUseTmpfs then ''
-virtfs local,path=/nix/store,security_model=none,mount_tag=store \ mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store
-virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
${if cfg.useBootLoader then ''
-drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
-drive index=1,id=drive2,file=${bootDisk}/disk.img,if=virtio,readonly \
-boot menu=on
'' else '' '' else ''
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \ mkdir $targetRoot/.nix-rw-store
-kernel ${config.system.build.toplevel}/kernel \ mount --bind $targetRoot/.nix-rw-store /unionfs-chroot/rw-store
-initrd ${config.system.build.toplevel}/initrd \ ''}
-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo} ${kernelConsole} $QEMU_KERNEL_PARAMS" \
''} \
$extraDisks \
${qemuGraphics} \
${toString config.virtualisation.qemu.options} \
$QEMU_OPTS
'';
unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768,hide_meta_files /rw-store=RW:/ro-store=RO $targetRoot/nix/store
regInfo = pkgs.runCommand "reginfo"
{ exportReferencesGraph =
map (x: [("closure-" + baseNameOf x) x]) config.virtualisation.pathsInNixDB;
buildInputs = [ pkgs.perl ];
preferLocalBuild = true;
}
''
printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > $out
'';
# Generate a hard disk image containing a /boot partition and GRUB
# in the MBR. Used when the `useBootLoader' option is set.
bootDisk =
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "nixos-boot-disk"
{ preVM =
''
mkdir $out
diskImage=$out/disk.img
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "32M"
'';
buildInputs = [ pkgs.utillinux ];
}
''
# Create a single /boot partition.
${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
. /sys/class/block/vda1/uevent
mknod /dev/vda1 b $MAJOR $MINOR
. /sys/class/block/vda/uevent
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
# Mount /boot.
mkdir /boot
mount /dev/vda1 /boot
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
mkdir /boot/grub
echo '(hd0) /dev/vda' > /boot/grub/device.map
# Install GRUB and generate the GRUB boot menu.
touch /etc/NIXOS
mkdir -p /nix/var/nix/profiles
${config.system.build.toplevel}/bin/switch-to-configuration boot
umount /boot
''
);
in
{
require = [ options ../profiles/qemu-guest.nix ];
boot.loader.grub.device = mkOverride 50 "/dev/vda";
boot.initrd.supportedFilesystems = optional cfg.writableStore "unionfs-fuse";
boot.initrd.extraUtilsCommands =
''
# We need mke2fs in the initrd.
cp ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin
'';
boot.initrd.postDeviceCommands =
''
# If the disk image appears to be empty, run mke2fs to
# initialise.
FSTYPE=$(blkid -o value -s TYPE /dev/vda || true)
if test -z "$FSTYPE"; then
mke2fs -t ext4 /dev/vda
fi
'';
boot.initrd.postMountCommands =
''
# Mark this as a NixOS machinex.
mkdir -p $targetRoot/etc
echo -n > $targetRoot/etc/NIXOS
# Fix the permissions on /tmp.
chmod 1777 $targetRoot/tmp
mkdir -p $targetRoot/boot
mount -o remount,ro $targetRoot/nix/store
${optionalString cfg.writableStore ''
mkdir -p /unionfs-chroot/ro-store
mount --rbind $targetRoot/nix/store /unionfs-chroot/ro-store
mkdir /unionfs-chroot/rw-store
${if cfg.writableStoreUseTmpfs then ''
mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store
'' else ''
mkdir $targetRoot/.nix-rw-store
mount --bind $targetRoot/.nix-rw-store /unionfs-chroot/rw-store
''} ''}
'';
unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768,hide_meta_files /rw-store=RW:/ro-store=RO $targetRoot/nix/store # After booting, register the closure of the paths in
''} # `virtualisation.pathsInNixDB' in the Nix database in the VM. This
''; # allows Nix operations to work in the VM. The path to the
# registration file is passed through the kernel command line to
# allow `system.build.toplevel' to be included. (If we had a direct
# reference to ${regInfo} here, then we would get a cyclic
# dependency.)
boot.postBootCommands =
''
if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then
${config.environment.nix}/bin/nix-store --load-db < ''${BASH_REMATCH[1]}
fi
'';
# After booting, register the closure of the paths in virtualisation.pathsInNixDB = [ config.system.build.toplevel ];
# `virtualisation.pathsInNixDB' in the Nix database in the VM. This
# allows Nix operations to work in the VM. The path to the
# registration file is passed through the kernel command line to
# allow `system.build.toplevel' to be included. (If we had a direct
# reference to ${regInfo} here, then we would get a cyclic
# dependency.)
boot.postBootCommands =
''
if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then
${config.environment.nix}/bin/nix-store --load-db < ''${BASH_REMATCH[1]}
fi
'';
virtualisation.pathsInNixDB = [ config.system.build.toplevel ]; virtualisation.qemu.options = [ "-vga std" "-usbdevice tablet" ];
virtualisation.qemu.options = [ "-vga std" "-usbdevice tablet" ]; # Mount the host filesystem via 9P, and bind-mount the Nix store of
# the host into our own filesystem. We use mkOverride to allow this
# module to be applied to "normal" NixOS system configuration, where
# the regular value for the `fileSystems' attribute should be
# disregarded for the purpose of building a VM test image (since
# those filesystems don't exist in the VM).
fileSystems = mkOverride 10
{ "/".device = "/dev/vda";
"/nix/store" =
{ device = "store";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576,cache=loose";
};
"/tmp/xchg" =
{ device = "xchg";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576,cache=loose";
neededForBoot = true;
};
"/tmp/shared" =
{ device = "shared";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576";
neededForBoot = true;
};
} // optionalAttrs cfg.useBootLoader
{ "/boot" =
{ device = "/dev/disk/by-label/boot";
fsType = "ext4";
options = "ro";
noCheck = true; # fsck fails on a r/o filesystem
};
};
# Mount the host filesystem via 9P, and bind-mount the Nix store of swapDevices = mkOverride 50 [ ];
# the host into our own filesystem. We use mkOverride to allow this
# module to be applied to "normal" NixOS system configuration, where
# the regular value for the `fileSystems' attribute should be
# disregarded for the purpose of building a VM test image (since
# those filesystems don't exist in the VM).
fileSystems = mkOverride 10
{ "/".device = "/dev/vda";
"/nix/store" =
{ device = "store";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576,cache=loose";
};
"/tmp/xchg" =
{ device = "xchg";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576,cache=loose";
neededForBoot = true;
};
"/tmp/shared" =
{ device = "shared";
fsType = "9p";
options = "trans=virtio,version=9p2000.L,msize=1048576";
neededForBoot = true;
};
} // optionalAttrs cfg.useBootLoader
{ "/boot" =
{ device = "/dev/disk/by-label/boot";
fsType = "ext4";
options = "ro";
noCheck = true; # fsck fails on a r/o filesystem
};
};
swapDevices = mkOverride 50 [ ]; # Don't run ntpd in the guest. It should get the correct time from KVM.
services.ntp.enable = false;
# Don't run ntpd in the guest. It should get the correct time from KVM. system.build.vm = pkgs.runCommand "nixos-vm" { preferLocalBuild = true; }
services.ntp.enable = false; ''
ensureDir $out/bin
ln -s ${config.system.build.toplevel} $out/system
ln -s ${pkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${vmName}-vm
'';
system.build.vm = pkgs.runCommand "nixos-vm" { preferLocalBuild = true; } # When building a regular system configuration, override whatever
'' # video driver the host uses.
ensureDir $out/bin services.xserver.videoDriver = mkOverride 50 null;
ln -s ${config.system.build.toplevel} $out/system services.xserver.videoDrivers = mkOverride 50 [ "vesa" ];
ln -s ${pkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${vmName}-vm services.xserver.defaultDepth = mkOverride 50 0;
''; services.xserver.resolutions = mkOverride 50 [ { x = 1024; y = 768; } ];
services.xserver.monitorSection =
''
# Set a higher refresh rate so that resolutions > 800x600 work.
HorizSync 30-140
VertRefresh 50-160
'';
# When building a regular system configuration, override whatever # Wireless won't work in the VM.
# video driver the host uses. networking.wireless.enable = mkOverride 50 false;
services.xserver.videoDriver = mkOverride 50 null;
services.xserver.videoDrivers = mkOverride 50 [ "vesa" ];
services.xserver.defaultDepth = mkOverride 50 0;
services.xserver.resolutions = mkOverride 50 [ { x = 1024; y = 768; } ];
services.xserver.monitorSection =
''
# Set a higher refresh rate so that resolutions > 800x600 work.
HorizSync 30-140
VertRefresh 50-160
'';
# Wireless won't work in the VM. system.requiredKernelConfig = with config.lib.kernelConfig;
networking.wireless.enable = mkOverride 50 false; [ (isEnabled "VIRTIO_BLK")
(isEnabled "VIRTIO_PCI")
(isEnabled "VIRTIO_NET")
(isEnabled "EXT4_FS")
(isYes "BLK_DEV")
(isYes "PCI")
(isYes "EXPERIMENTAL")
(isYes "NETDEVICES")
(isYes "NET_CORE")
(isYes "INET")
(isYes "NETWORK_FILESYSTEMS")
] ++ optional (!cfg.graphics) [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
];
system.requiredKernelConfig = with config.lib.kernelConfig; };
[ (isEnabled "VIRTIO_BLK")
(isEnabled "VIRTIO_PCI")
(isEnabled "VIRTIO_NET")
(isEnabled "EXT4_FS")
(isYes "BLK_DEV")
(isYes "PCI")
(isYes "EXPERIMENTAL")
(isYes "NETDEVICES")
(isYes "NET_CORE")
(isYes "INET")
(isYes "NETWORK_FILESYSTEMS")
] ++ optional (!cfg.graphics) [
(isYes "SERIAL_8250_CONSOLE")
(isYes "SERIAL_8250")
];
} }

View File

@ -5,7 +5,7 @@
machine = machine =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ require = [ ./common/x11.nix ]; { imports = [ ./common/x11.nix ];
environment.systemPackages = [ pkgs.firefox ]; environment.systemPackages = [ pkgs.firefox ];
}; };

View File

@ -37,7 +37,7 @@ let
'' ''
{ config, pkgs, modulesPath, ... }: { config, pkgs, modulesPath, ... }:
{ require = { imports =
[ ./hardware.nix [ ./hardware.nix
"''${modulesPath}/testing/test-instrumentation.nix" "''${modulesPath}/testing/test-instrumentation.nix"
]; ];

View File

@ -5,7 +5,7 @@
machine = machine =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ require = [ ./common/user-account.nix ]; { imports = [ ./common/user-account.nix ];
virtualisation.memorySize = 768; virtualisation.memorySize = 768;

View File

@ -17,7 +17,7 @@ rec {
client = client =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ require = [ ./common/x11.nix ]; { imports = [ ./common/x11.nix ];
services.xserver.driSupport = true; services.xserver.driSupport = true;
services.xserver.defaultDepth = pkgs.lib.mkOverride 0 16; services.xserver.defaultDepth = pkgs.lib.mkOverride 0 16;
environment.systemPackages = [ pkgs.quake3demo ]; environment.systemPackages = [ pkgs.quake3demo ];

View File

@ -3,9 +3,8 @@
{ {
nodes = { nodes = {
storage = storage =
{pkgs, config, ...}: { config, pkgs, ... }:
{ { services.nfs.server.enable = true;
services.nfs.server.enable = true;
services.nfs.server.exports = '' services.nfs.server.exports = ''
/repos 192.168.1.0/255.255.255.0(rw,no_root_squash) /repos 192.168.1.0/255.255.255.0(rw,no_root_squash)
''; '';
@ -13,10 +12,8 @@
}; };
postgresql = postgresql =
{config, pkgs, ...}: { config, pkgs, ... }:
{ { services.postgresql.enable = true;
services.openssh.enable = true;
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql92; services.postgresql.package = pkgs.postgresql92;
services.postgresql.enableTCPIP = true; services.postgresql.enableTCPIP = true;
services.postgresql.authentication = '' services.postgresql.authentication = ''
@ -29,15 +26,13 @@
}; };
webserver = webserver =
{config, pkgs, ...}: { config, pkgs, ... }:
{ { fileSystems = pkgs.lib.mkOverride 50
fileSystems = pkgs.lib.mkOverride 50
[ { mountPoint = "/repos"; [ { mountPoint = "/repos";
device = "storage:/repos"; device = "storage:/repos";
fsType = "nfs"; fsType = "nfs";
} }
]; ];
services.httpd.enable = true; services.httpd.enable = true;
services.httpd.adminAddr = "root@localhost"; services.httpd.adminAddr = "root@localhost";
services.httpd.extraSubservices = [ { serviceType = "trac"; } ]; services.httpd.extraSubservices = [ { serviceType = "trac"; } ];
@ -45,9 +40,8 @@
}; };
client = client =
{config, pkgs, ...}: { config, pkgs, ... }:
{ { imports = [ ./common/x11.nix ];
require = [ ./common/x11.nix ];
services.xserver.desktopManager.kde4.enable = true; services.xserver.desktopManager.kde4.enable = true;
}; };
}; };

View File

@ -5,7 +5,7 @@
machine = machine =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ require = [ ./common/user-account.nix ]; { imports = [ ./common/user-account.nix ];
services.xserver.enable = true; services.xserver.enable = true;