Merge branch 'master'
This commit is contained in:
commit
565bd805e6
@ -53,7 +53,7 @@ $ nix-env -qa hello --json
|
|||||||
"x86_64-linux",
|
"x86_64-linux",
|
||||||
"armv5tel-linux",
|
"armv5tel-linux",
|
||||||
"armv7l-linux",
|
"armv7l-linux",
|
||||||
"mips64el-linux",
|
"mips32-linux",
|
||||||
"x86_64-darwin",
|
"x86_64-darwin",
|
||||||
"i686-cygwin",
|
"i686-cygwin",
|
||||||
"i686-freebsd",
|
"i686-freebsd",
|
||||||
|
@ -155,12 +155,6 @@ rec {
|
|||||||
outPath = assert condition; drv.outPath;
|
outPath = assert condition; drv.outPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Add attributes to each output of a derivation without changing
|
|
||||||
the derivation itself. */
|
|
||||||
addPassthru =
|
|
||||||
lib.warn "`addPassthru drv passthru` is deprecated, replace with `extendDerivation true passthru drv`"
|
|
||||||
(drv: passthru: extendDerivation true passthru drv);
|
|
||||||
|
|
||||||
/* Strip a derivation of all non-essential attributes, returning
|
/* Strip a derivation of all non-essential attributes, returning
|
||||||
only those needed by hydra-eval-jobs. Also strictly evaluate the
|
only those needed by hydra-eval-jobs. Also strictly evaluate the
|
||||||
result to ensure that there are no thunks kept alive to prevent
|
result to ensure that there are no thunks kept alive to prevent
|
||||||
|
@ -21,10 +21,10 @@ let
|
|||||||
|
|
||||||
# packaging
|
# packaging
|
||||||
customisation = callLibs ./customisation.nix;
|
customisation = callLibs ./customisation.nix;
|
||||||
maintainers = callLibs ./maintainers.nix;
|
maintainers = import ./maintainers-list.nix;
|
||||||
meta = callLibs ./meta.nix;
|
meta = callLibs ./meta.nix;
|
||||||
sources = callLibs ./sources.nix;
|
sources = callLibs ./sources.nix;
|
||||||
|
versions = callLibs ./versions.nix;
|
||||||
|
|
||||||
# module system
|
# module system
|
||||||
modules = callLibs ./modules.nix;
|
modules = callLibs ./modules.nix;
|
||||||
@ -88,7 +88,7 @@ let
|
|||||||
inherit (stringsWithDeps) textClosureList textClosureMap
|
inherit (stringsWithDeps) textClosureList textClosureMap
|
||||||
noDepEntry fullDepEntry packEntry stringAfter;
|
noDepEntry fullDepEntry packEntry stringAfter;
|
||||||
inherit (customisation) overrideDerivation makeOverridable
|
inherit (customisation) overrideDerivation makeOverridable
|
||||||
callPackageWith callPackagesWith extendDerivation addPassthru
|
callPackageWith callPackagesWith extendDerivation
|
||||||
hydraJob makeScope;
|
hydraJob makeScope;
|
||||||
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
||||||
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
||||||
|
3955
lib/maintainers-list.nix
Normal file
3955
lib/maintainers-list.nix
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,799 +0,0 @@
|
|||||||
{ ...}:
|
|
||||||
/* List of NixOS maintainers. The format is:
|
|
||||||
|
|
||||||
handle = "Real Name <address@example.org>";
|
|
||||||
|
|
||||||
where <handle> is preferred to be your GitHub username (so it's easy
|
|
||||||
to ping a package @<handle>), and <Real Name> is your real name, not
|
|
||||||
a pseudonym. Please keep the list alphabetically sorted. */
|
|
||||||
{
|
|
||||||
a1russell = "Adam Russell <adamlr6+pub@gmail.com>";
|
|
||||||
aaronschif = "Aaron Schif <aaronschif@gmail.com>";
|
|
||||||
abaldeau = "Andreas Baldeau <andreas@baldeau.net>";
|
|
||||||
abbradar = "Nikolay Amiantov <ab@fmap.me>";
|
|
||||||
abigailbuccaneer = "Abigail Bunyan <abigailbuccaneer@gmail.com>";
|
|
||||||
aboseley = "Adam Boseley <adam.boseley@gmail.com>";
|
|
||||||
abuibrahim = "Ruslan Babayev <ruslan@babayev.com>";
|
|
||||||
acowley = "Anthony Cowley <acowley@gmail.com>";
|
|
||||||
adelbertc = "Adelbert Chang <adelbertc@gmail.com>";
|
|
||||||
adev = "Adrien Devresse <adev@adev.name>";
|
|
||||||
adisbladis = "Adam Hose <adis@blad.is>";
|
|
||||||
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
|
||||||
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
|
||||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
|
||||||
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
|
|
||||||
aflatter = "Alexander Flatter <flatter@fastmail.fm>";
|
|
||||||
afldcr = "James Alexander Feldman-Crough <alex@fldcr.com>";
|
|
||||||
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
|
|
||||||
afranchuk = "Alex Franchuk <alex.franchuk@gmail.com>";
|
|
||||||
aherrmann = "Andreas Herrmann <andreash87@gmx.ch>";
|
|
||||||
ahmedtd = "Taahir Ahmed <ahmed.taahir@gmail.com>";
|
|
||||||
aij = "Ivan Jager <aij+git@mrph.org>";
|
|
||||||
ajgrf = "Alex Griffin <a@ajgrf.com>";
|
|
||||||
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
|
||||||
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
|
||||||
akc = "Anders Claesson <akc@akc.is>";
|
|
||||||
alexvorobiev = "Alex Vorobiev <alexander.vorobiev@gmail.com";
|
|
||||||
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
|
||||||
alibabzo = "Alistair Bill <alistair.bill@gmail.com>";
|
|
||||||
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
|
||||||
alunduil = "Alex Brandt <alunduil@alunduil.com>";
|
|
||||||
ambrop72 = "Ambroz Bizjak <ambrop7@gmail.com>";
|
|
||||||
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
|
||||||
amiloradovsky = "Andrew Miloradovsky <miloradovsky@gmail.com>";
|
|
||||||
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
|
||||||
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
|
|
||||||
anderspapitto = "Anders Papitto <anderspapitto@gmail.com>";
|
|
||||||
andir = "Andreas Rammhold <andreas@rammhold.de>";
|
|
||||||
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
|
||||||
andrestylianos = "Andre S. Ramos <andre.stylianos@gmail.com>";
|
|
||||||
andrew-d = "Andrew Dunham <andrew@du.nham.ca>";
|
|
||||||
andrewrk = "Andrew Kelley <superjoe30@gmail.com>";
|
|
||||||
andsild = "Anders Sildnes <andsild@gmail.com>";
|
|
||||||
aneeshusa = "Aneesh Agrawal <aneeshusa@gmail.com>";
|
|
||||||
ankhers = "Justin Wood <justin.k.wood@gmail.com>";
|
|
||||||
antono = "Antono Vasiljev <self@antono.info>";
|
|
||||||
antonxy = "Anton Schirg <anton.schirg@posteo.de>";
|
|
||||||
apeschar = "Albert Peschar <albert@peschar.net>";
|
|
||||||
apeyroux = "Alexandre Peyroux <alex@px.io>";
|
|
||||||
arcadio = "Arcadio Rubio García <arc@well.ox.ac.uk>";
|
|
||||||
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
|
|
||||||
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
|
|
||||||
arobyn = "Alexei Robyn <shados@shados.net>";
|
|
||||||
artuuge = "Artur E. Ruuge <artuuge@gmail.com>";
|
|
||||||
ashalkhakov = "Artyom Shalkhakov <artyom.shalkhakov@gmail.com>";
|
|
||||||
ashgillman = "Ashley Gillman <gillmanash@gmail.com>";
|
|
||||||
aske = "Kirill Boltaev <aske@fmap.me>";
|
|
||||||
asppsa = "Alastair Pharo <asppsa@gmail.com>";
|
|
||||||
astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>";
|
|
||||||
asymmetric = "Lorenzo Manacorda <lorenzo@mailbox.org>";
|
|
||||||
aszlig = "aszlig <aszlig@nix.build>";
|
|
||||||
auntie = "Jonathan Glines <auntieNeo@gmail.com>";
|
|
||||||
avnik = "Alexander V. Nikolaev <avn@avnik.info>";
|
|
||||||
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
|
|
||||||
bachp = "Pascal Bach <pascal.bach@nextrem.ch>";
|
|
||||||
backuitist = "Bruno Bieth";
|
|
||||||
badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>";
|
|
||||||
balajisivaraman = "Balaji Sivaraman <sivaraman.balaji@gmail.com>";
|
|
||||||
barrucadu = "Michael Walker <mike@barrucadu.co.uk>";
|
|
||||||
basvandijk = "Bas van Dijk <v.dijk.bas@gmail.com>";
|
|
||||||
Baughn = "Svein Ove Aas <sveina@gmail.com>";
|
|
||||||
bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>";
|
|
||||||
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
|
|
||||||
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
|
|
||||||
bendlas = "Herwig Hochleitner <herwig@bendlas.net>";
|
|
||||||
benley = "Benjamin Staffin <benley@gmail.com>";
|
|
||||||
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
|
||||||
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
|
||||||
berce = "Bert Moens <bert.moens@gmail.com>";
|
|
||||||
berdario = "Dario Bertini <berdario@gmail.com>";
|
|
||||||
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
|
||||||
bhipple = "Benjamin Hipple <bhipple@protonmail.com>";
|
|
||||||
binarin = "Alexey Lebedeff <binarin@binarin.ru>";
|
|
||||||
bjg = "Brian Gough <bjg@gnu.org>";
|
|
||||||
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
|
||||||
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
|
||||||
bobakker = "Bo Bakker <bobakk3r@gmail.com>";
|
|
||||||
bobvanderlinden = "Bob van der Linden <bobvanderlinden@gmail.com>";
|
|
||||||
bodil = "Bodil Stokke <nix@bodil.org>";
|
|
||||||
boothead = "Ben Ford <ben@perurbis.com>";
|
|
||||||
bosu = "Boris Sukholitko <boriss@gmail.com>";
|
|
||||||
bradediger = "Brad Ediger <brad@bradediger.com>";
|
|
||||||
bramd = "Bram Duvigneau <bram@bramd.nl>";
|
|
||||||
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
|
||||||
bugworm = "Roman Gerasimenko <bugworm@zoho.com>";
|
|
||||||
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
|
||||||
c0bw3b = "Renaud <c0bw3b@gmail.com>";
|
|
||||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
|
||||||
calbrecht = "Christian Albrecht <christian.albrecht@mayflower.de>";
|
|
||||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
|
||||||
calvertvl = "Victor Calvert <calvertvl@gmail.com>";
|
|
||||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
|
||||||
canndrew = "Andrew Cann <shum@canndrew.org>";
|
|
||||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
|
||||||
casey = "Casey Rodarmor <casey@rodarmor.net>";
|
|
||||||
catern = "Spencer Baugh <sbaugh@catern.com>";
|
|
||||||
caugner = "Claas Augner <nixos@caugner.de>";
|
|
||||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
|
||||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
|
||||||
changlinli = "Changlin Li <mail@changlinli.com>";
|
|
||||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
|
||||||
chattered = "Phil Scott <me@philscotted.com>";
|
|
||||||
ChengCat = "Yucheng Zhang <yu@cheng.cat>";
|
|
||||||
chiiruno = "Okina Matara <okinan@protonmail.com>";
|
|
||||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
|
||||||
chpatrick = "Patrick Chilton <chpatrick@gmail.com>";
|
|
||||||
chreekat = "Bryan Richter <b@chreekat.net>";
|
|
||||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
|
||||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
|
||||||
chrisrosset = "Christopher Rosset <chris@rosset.org.uk>";
|
|
||||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
|
||||||
ciil = "Simon Lackerbauer <simon@lackerbauer.com>";
|
|
||||||
ck3d = "Christian Kögler <ck3d@gmx.de>";
|
|
||||||
ckampka = "Christian Kampka <christian@kampka.net>";
|
|
||||||
ckauhaus = "Christian Kauhaus <kc@flyingcircus.io>";
|
|
||||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
|
||||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
|
||||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
|
||||||
cmfwyp = "cmfwyp <cmfwyp@riseup.net>";
|
|
||||||
cobbal = "Andrew Cobb <andrew.cobb@gmail.com>";
|
|
||||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
|
||||||
codsl = "codsl <codsl@riseup.net>";
|
|
||||||
codyopel = "Cody Opel <codyopel@gmail.com>";
|
|
||||||
colemickens = "Cole Mickens <cole.mickens@gmail.com>";
|
|
||||||
colescott = "Cole Scott <colescottsf@gmail.com>";
|
|
||||||
copumpkin = "Dan Peebles <pumpkingod@gmail.com>";
|
|
||||||
corngood = "David McFarland <corngood@gmail.com>";
|
|
||||||
coroa = "Jonas Hörsch <jonas@chaoflow.net>";
|
|
||||||
couchemar = "Andrey Pavlov <couchemar@yandex.ru>";
|
|
||||||
cpages = "Carles Pagès <page@ruiec.cat>";
|
|
||||||
cransom = "Casey Ransom <cransom@hubns.net>";
|
|
||||||
cryptix = "Henry Bubert <cryptix@riseup.net>";
|
|
||||||
CrystalGamma = "Jona Stubbe <nixos@crystalgamma.de>";
|
|
||||||
cstrahan = "Charles Strahan <charles@cstrahan.com>";
|
|
||||||
csingley = "Christopher Singley <csingley@gmail.com>";
|
|
||||||
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
|
||||||
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
|
||||||
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
|
||||||
dancek = "Hannu Hartikainen <hannu.hartikainen@gmail.com>";
|
|
||||||
danharaj = "Dan Haraj <dan@obsidian.systems>";
|
|
||||||
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
|
|
||||||
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
|
||||||
david50407 = "David Kuo <me@davy.tw>";
|
|
||||||
davidak = "David Kleuker <post@davidak.de>";
|
|
||||||
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
|
|
||||||
davorb = "Davor Babic <davor@davor.se>";
|
|
||||||
dbohdan = "Danyil Bohdan <danyil.bohdan@gmail.com>";
|
|
||||||
dbrock = "Daniel Brockman <daniel@brockman.se>";
|
|
||||||
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
|
||||||
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
|
||||||
derchris = "Christian Gerbrandt <derchris@me.com>";
|
|
||||||
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
|
||||||
dermetfan = "Robin Stumm <serverkorken@gmail.com>";
|
|
||||||
DerTim1 = "Tim Digel <tim.digel@active-group.de>";
|
|
||||||
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
|
||||||
devhell = "devhell <\"^\"@regexmail.net>";
|
|
||||||
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
|
||||||
dfordivam = "Divam <dfordivam+nixpkgs@gmail.com>";
|
|
||||||
dfoxfranke = "Daniel Fox Franke <dfoxfranke@gmail.com>";
|
|
||||||
dgonyeo = "Derek Gonyeo <derek@gonyeo.com>";
|
|
||||||
dipinhora = "Dipin Hora <dipinhora+github@gmail.com>";
|
|
||||||
disassembler = "Samuel Leathers <disasm@gmail.com>";
|
|
||||||
dizfer = "David Izquierdo <david@izquierdofernandez.com>";
|
|
||||||
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
|
|
||||||
DmitryTsygankov = "Dmitry Tsygankov <dmitry.tsygankov@gmail.com>";
|
|
||||||
dmjio = "David Johnson <djohnson.m@gmail.com>";
|
|
||||||
dochang = "Desmond O. Chang <dochang@gmail.com>";
|
|
||||||
domenkozar = "Domen Kozar <domen@dev.si>";
|
|
||||||
dotlambda = "Robert Schütz <rschuetz17@gmail.com>";
|
|
||||||
doublec = "Chris Double <chris.double@double.co.nz>";
|
|
||||||
dpaetzel = "David Pätzel <david.a.paetzel@gmail.com>";
|
|
||||||
dpflug = "David Pflug <david@pflug.email>";
|
|
||||||
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
|
||||||
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
|
||||||
dsferruzza = "David Sferruzza <david.sferruzza@gmail.com>";
|
|
||||||
dtzWill = "Will Dietz <nix@wdtz.org>";
|
|
||||||
dupgit = "Olivier Delhomme <olivier.delhomme@free.fr>";
|
|
||||||
dywedir = "Vladyslav M. <dywedir@protonmail.ch>";
|
|
||||||
dzabraev = "Maksim Dzabraev <dzabraew@gmail.com>";
|
|
||||||
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
|
||||||
earldouglas = "James Earl Douglas <james@earldouglas.com>";
|
|
||||||
ebzzry = "Rommel Martinez <ebzzry@ebzzry.io>";
|
|
||||||
edanaher = "Evan Danaher <nixos@edanaher.net>";
|
|
||||||
edef = "edef <edef@edef.eu>";
|
|
||||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
|
||||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
|
||||||
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
|
||||||
eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
|
|
||||||
ehegnes = "Eric Hegnes <eric.hegnes@gmail.com>";
|
|
||||||
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
|
||||||
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
|
||||||
ekleog = "Leo Gaspard <leo@gaspard.io>";
|
|
||||||
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
|
||||||
eleanor = "Dejan Lukan <dejan@proteansec.com>";
|
|
||||||
elijahcaine = "Elijah Caine <elijahcainemv@gmail.com>";
|
|
||||||
elitak = "Eric Litak <elitak@gmail.com>";
|
|
||||||
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
|
||||||
enzime = "Michael Hoang <enzime@users.noreply.github.com>";
|
|
||||||
eperuffo = "Emanuele Peruffo <info@emanueleperuffo.com>";
|
|
||||||
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
|
||||||
eqyiel = "Ruben Maher <r@rkm.id.au>";
|
|
||||||
ericbmerritt = "Eric Merritt <eric@afiniate.com>";
|
|
||||||
ericsagnes = "Eric Sagnes <eric.sagnes@gmail.com>";
|
|
||||||
ericson2314 = "John Ericson <John.Ericson@Obsidian.Systems>";
|
|
||||||
erictapen = "Justin Humm <justin.humm@posteo.de>";
|
|
||||||
erikryb = "Erik Rybakken <erik.rybakken@math.ntnu.no>";
|
|
||||||
ertes = "Ertugrul Söylemez <esz@posteo.de>";
|
|
||||||
ethercrow = "Dmitry Ivanov <ethercrow@gmail.com>";
|
|
||||||
etu = "Elis Hirwing <elis@hirwing.se>";
|
|
||||||
exfalso = "Andras Slemmer <0slemi0@gmail.com>";
|
|
||||||
exi = "Reno Reckling <nixos@reckling.org>";
|
|
||||||
exlevan = "Alexey Levan <exlevan@gmail.com>";
|
|
||||||
expipiplus1 = "Joe Hermaszewski <nix@monoid.al>";
|
|
||||||
fadenb = "Tristan Helmich <tristan.helmich+nixos@gmail.com>";
|
|
||||||
falsifian = "James Cook <james.cook@utoronto.ca>";
|
|
||||||
fare = "Francois-Rene Rideau <fahree@gmail.com>";
|
|
||||||
f-breidenstein = "Felix Breidenstein <mail@felixbreidenstein.de>";
|
|
||||||
fgaz = "Francesco Gazzetta <francygazz@gmail.com>";
|
|
||||||
FireyFly = "Jonas Höglund <nix@firefly.nu>";
|
|
||||||
flokli = "Florian Klink <flokli@flokli.de>";
|
|
||||||
florianjacob = "Florian Jacob <projects+nixos@florianjacob.de>";
|
|
||||||
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
|
||||||
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
|
||||||
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
|
||||||
forkk = "Andrew Okin <forkk@forkk.net>";
|
|
||||||
fornever = "Friedrich von Never <friedrich@fornever.me>";
|
|
||||||
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
|
|
||||||
fps = "Florian Paul Schmidt <mista.tapas@gmx.net>";
|
|
||||||
fridh = "Frederik Rietdijk <fridh@fridh.nl>";
|
|
||||||
frlan = "Frank Lanitz <frank@frank.uvena.de>";
|
|
||||||
fro_ozen = "fro_ozen <fro_ozen@gmx.de>";
|
|
||||||
ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>";
|
|
||||||
funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>";
|
|
||||||
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
|
|
||||||
fuzzy-id = "Thomas Bach <hacking+nixos@babibo.de>";
|
|
||||||
fxfactorial = "Edgar Aroutiounian <edgar.factorial@gmail.com>";
|
|
||||||
gabesoft = "Gabriel Adomnicai <gabesoft@gmail.com>";
|
|
||||||
gal_bolle = "Florent Becker <florent.becker@ens-lyon.org>";
|
|
||||||
garbas = "Rok Garbas <rok@garbas.si>";
|
|
||||||
garrison = "Jim Garrison <jim@garrison.cc>";
|
|
||||||
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
|
|
||||||
gebner = "Gabriel Ebner <gebner@gebner.org>";
|
|
||||||
geistesk = "Alvar Penning <post@0x21.biz>";
|
|
||||||
genesis = "Ronan Bignaux <ronan@aimao.org>";
|
|
||||||
georgewhewell = "George Whewell <georgerw@gmail.com>";
|
|
||||||
gilligan = "Tobias Pflug <tobias.pflug@gmail.com>";
|
|
||||||
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
|
|
||||||
gleber = "Gleb Peregud <gleber.p@gmail.com>";
|
|
||||||
glenns = "Glenn Searby <glenn.searby@gmail.com>";
|
|
||||||
globin = "Robin Gloster <mail@glob.in>";
|
|
||||||
gnidorah = "Alex Ivanov <yourbestfriend@opmbx.org>";
|
|
||||||
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
|
||||||
Gonzih = "Max Gonzih <gonzih@gmail.com>";
|
|
||||||
goodrone = "Andrew Trachenko <goodrone@gmail.com>";
|
|
||||||
gpyh = "Yacine Hmito <yacine.hmito@gmail.com>";
|
|
||||||
grahamc = "Graham Christensen <graham@grahamc.com>";
|
|
||||||
grburst = "Julius Elias <grburst@openmailbox.org>";
|
|
||||||
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
|
||||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
|
||||||
guibou = "Guillaume Bouchard <guillaum.bouchard@gmail.com>";
|
|
||||||
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
|
||||||
guyonvarch = "Joris Guyonvarch <joris@guyonvarch.me>";
|
|
||||||
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
|
||||||
hamhut1066 = "Hamish Hutchings <github@hamhut1066.com>";
|
|
||||||
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
|
||||||
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
|
||||||
hce = "Hans-Christian Esperer <hc@hcesperer.org>";
|
|
||||||
hectorj = "Hector Jusforgues <hector.jusforgues+nixos@gmail.com>";
|
|
||||||
hedning = "Tor Hedin Brønner <torhedinbronner@gmail.com>";
|
|
||||||
heel = "Sergii Paryzhskyi <parizhskiy@gmail.com>";
|
|
||||||
henrytill = "Henry Till <henrytill@gmail.com>";
|
|
||||||
hhm = "hhm <heehooman+nixpkgs@gmail.com>";
|
|
||||||
hinton = "Tom Hinton <t@larkery.com>";
|
|
||||||
hodapp = "Chris Hodapp <hodapp87@gmail.com>";
|
|
||||||
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
|
||||||
htr = "Hugo Tavares Reis <hugo@linux.com>";
|
|
||||||
hyphon81 = "Masato Yonekawa <zero812n@gmail.com>";
|
|
||||||
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
|
||||||
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
|
||||||
iblech = "Ingo Blechschmidt <iblech@speicherleck.de>";
|
|
||||||
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
|
||||||
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
|
||||||
ilya-kolpakov = "Ilya Kolpakov <ilya.kolpakov@gmail.com>";
|
|
||||||
infinisil = "Silvan Mosberger <infinisil@icloud.com>";
|
|
||||||
ironpinguin = "Michele Catalano <michele@catalano.de>";
|
|
||||||
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
|
|
||||||
ixmatus = "Parnell Springmeyer <parnell@digitalmentat.com>";
|
|
||||||
izorkin = "Yurii Izorkin <Izorkin@gmail.com>";
|
|
||||||
ixxie = "Matan Bendix Shenhav <matan@fluxcraft.net>";
|
|
||||||
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
|
||||||
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
|
||||||
jammerful = "jammerful <jammerful@gmail.com>";
|
|
||||||
jansol = "Jan Solanti <jan.solanti@paivola.fi>";
|
|
||||||
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
|
||||||
jb55 = "William Casarin <jb55@jb55.com>";
|
|
||||||
jbedo = "Justin Bedő <cu@cua0.org>";
|
|
||||||
jcumming = "Jack Cummings <jack@mudshark.org>";
|
|
||||||
jdagilliland = "Jason Gilliland <jdagilliland@gmail.com>";
|
|
||||||
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
|
||||||
jensbin = "Jens Binkert <jensbin@protonmail.com>";
|
|
||||||
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
|
|
||||||
jfb = "James Felix Black <james@yamtime.com>";
|
|
||||||
jfrankenau = "Johannes Frankenau <johannes@frankenau.net>";
|
|
||||||
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
|
||||||
jgertm = "Tim Jaeger <jger.tm@gmail.com>";
|
|
||||||
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
|
||||||
jhhuh = "Ji-Haeng Huh <jhhuh.note@gmail.com>";
|
|
||||||
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
|
|
||||||
jlesquembre = "José Luis Lafuente <jl@lafuente.me>";
|
|
||||||
jluttine = "Jaakko Luttinen <jaakko.luttinen@iki.fi>";
|
|
||||||
Jo = "Joachim Ernst <0x4A6F@shackspace.de>";
|
|
||||||
joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
|
|
||||||
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
|
||||||
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
|
||||||
joelteon = "Joel Taylor <me@joelt.io>";
|
|
||||||
johbo = "Johannes Bornhold <johannes@bornhold.name>";
|
|
||||||
johnazoidberg = "Daniel Schäfer <git@danielschaefer.me>";
|
|
||||||
johnmh = "John M. Harris, Jr. <johnmh@openblox.org>";
|
|
||||||
johnramsden = "John Ramsden <johnramsden@riseup.net>";
|
|
||||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
|
||||||
jonafato = "Jon Banafato <jon@jonafato.com>";
|
|
||||||
joncojonathan = "Jonathan Haddock <joncojonathan@gmail.com>";
|
|
||||||
jpdoyle = "Joe Doyle <joethedoyle@gmail.com>";
|
|
||||||
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
|
||||||
jpotier = "Martin Potier <jpo.contributes.to.nixos@marvid.fr>";
|
|
||||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
|
||||||
jtojnar = "Jan Tojnar <jtojnar@gmail.com>";
|
|
||||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
|
||||||
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
|
||||||
jwilberding = "Jordan Wilberding <jwilberding@afiniate.com>";
|
|
||||||
jyp = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
|
||||||
jzellner = "Jeff Zellner <jeffz@eml.cc>";
|
|
||||||
kaiha = "Kai Harries <kai.harries@gmail.com>";
|
|
||||||
kamilchm = "Kamil Chmielewski <kamil.chm@gmail.com>";
|
|
||||||
kampfschlaefer = "Arnold Krille <arnold@arnoldarts.de>";
|
|
||||||
karolchmist = "karolchmist <info+nix@chmist.com>";
|
|
||||||
kentjames = "James Kent <jameschristopherkent@gmail.com";
|
|
||||||
kevincox = "Kevin Cox <kevincox@kevincox.ca>";
|
|
||||||
khumba = "Bryan Gardiner <bog@khumba.net>";
|
|
||||||
KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>";
|
|
||||||
kierdavis = "Kier Davis <kierdavis@gmail.com>";
|
|
||||||
kiloreux = "Kiloreux Emperex <kiloreux@gmail.com>";
|
|
||||||
kini = "Keshav Kini <keshav.kini@gmail.com>";
|
|
||||||
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
|
||||||
knedlsepp = "Josef Kemetmüller <josef.kemetmueller@gmail.com>";
|
|
||||||
konimex = "Muhammad Herdiansyah <herdiansyah@netc.eu>";
|
|
||||||
koral = "Koral <koral@mailoo.org>";
|
|
||||||
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
|
|
||||||
kquick = "Kevin Quick <quick@sparq.org>";
|
|
||||||
kragniz = "Louis Taylor <louis@kragniz.eu>";
|
|
||||||
kristoff3r = "Kristoffer Søholm <k.soeholm@gmail.com>";
|
|
||||||
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
|
||||||
kuznero = "Roman Kuznetsov <roman@kuznero.com>";
|
|
||||||
lasandell = "Luke Sandell <lasandell@gmail.com>";
|
|
||||||
lassulus = "Lassulus <lassulus@gmail.com>";
|
|
||||||
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
|
||||||
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
|
||||||
league = "Christopher League <league@contrapunctus.net>";
|
|
||||||
lebastr = "Alexander Lebedev <lebastr@gmail.com>";
|
|
||||||
ledif = "Adam Fidel <refuse@gmail.com>";
|
|
||||||
leemachin = "Lee Machin <me@mrl.ee>";
|
|
||||||
leenaars = "Michiel Leenaars <ml.software@leenaa.rs>";
|
|
||||||
leonardoce = "Leonardo Cecchi <leonardo.cecchi@gmail.com>";
|
|
||||||
lethalman = "Luca Bruno <lucabru@src.gnome.org>";
|
|
||||||
lewo = "Antoine Eiche <lewo@abesis.fr>";
|
|
||||||
lheckemann = "Linus Heckemann <git@sphalerite.org>";
|
|
||||||
lhvwb = "Nathaniel Baxter <nathaniel.baxter@gmail.com>";
|
|
||||||
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
|
||||||
limeytexan = "Michael Brantley <limeytexan@gmail.com>";
|
|
||||||
linquize = "Linquize <linquize@yahoo.com.hk>";
|
|
||||||
linus = "Linus Arver <linusarver@gmail.com>";
|
|
||||||
lluchs = "Lukas Werling <lukas.werling@gmail.com>";
|
|
||||||
lnl7 = "Daiderd Jordan <daiderd@gmail.com>";
|
|
||||||
lo1tuma = "Mathias Schreck <schreck.mathias@gmail.com>";
|
|
||||||
loskutov = "Ignat Loskutov <ignat.loskutov@gmail.com>";
|
|
||||||
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
|
||||||
lowfatcomputing = "Andreas Wagner <andreas.wagner@lowfatcomputing.org>";
|
|
||||||
lsix = "Lancelot SIX <lsix@lancelotsix.com>";
|
|
||||||
lschuermann = "Leon Schuermann <leon.git@is.currently.online>";
|
|
||||||
ltavard = "Laure Tavard <laure.tavard@univ-grenoble-alpes.fr>";
|
|
||||||
lucas8 = "Luc Chabassier <luc.linux@mailoo.org>";
|
|
||||||
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
|
||||||
lufia = "Kyohei Kadota <lufia@lufia.org>";
|
|
||||||
luispedro = "Luis Pedro Coelho <luis@luispedro.org>";
|
|
||||||
lukego = "Luke Gorrie <luke@snabb.co>";
|
|
||||||
luz = "Luz <luz666@daum.net>";
|
|
||||||
lw = "Sergey Sofeychuk <lw@fmap.me>";
|
|
||||||
lyt = "Tim Liou <wheatdoge@gmail.com>";
|
|
||||||
m3tti = "Mathaeus Sander <mathaeus.peter.sander@gmail.com>";
|
|
||||||
ma27 = "Maximilian Bosch <maximilian@mbosch.me>";
|
|
||||||
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
|
||||||
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
|
|
||||||
mahe = "Matthias Herrmann <matthias.mh.herrmann@gmail.com>";
|
|
||||||
makefu = "Felix Richter <makefu@syntax-fehler.de>";
|
|
||||||
malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>";
|
|
||||||
manveru = "Michael Fellinger <m.fellinger@gmail.com>";
|
|
||||||
marcweber = "Marc Weber <marco-oweber@gmx.de>";
|
|
||||||
markus1189 = "Markus Hauck <markus1189@gmail.com>";
|
|
||||||
markuskowa = "Markus Kowalewski <markus.kowalewski@gmail.com>";
|
|
||||||
markWot = "Markus Wotringer <markus@wotringer.de>";
|
|
||||||
martijnvermaat = "Martijn Vermaat <martijn@vermaat.name>";
|
|
||||||
martingms = "Martin Gammelsæter <martin@mg.am>";
|
|
||||||
matejc = "Matej Cotman <cotman.matej@gmail.com>";
|
|
||||||
mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>";
|
|
||||||
matthewbauer = "Matthew Bauer <mjbauer95@gmail.com>";
|
|
||||||
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
|
|
||||||
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
|
|
||||||
mbakke = "Marius Bakke <mbakke@fastmail.com>";
|
|
||||||
mbbx6spp = "Susan Potter <me@susanpotter.net>";
|
|
||||||
mbe = "Brandon Edens <brandonedens@gmail.com>";
|
|
||||||
mbode = "Maximilian Bode <maxbode@gmail.com>";
|
|
||||||
mboes = "Mathieu Boespflug <mboes@tweag.net>";
|
|
||||||
mbrgm = "Marius Bergmann <marius@yeai.de>";
|
|
||||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
|
||||||
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
|
||||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
|
||||||
mehandes = "Matt Deming <niewskici@gmail.com>";
|
|
||||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
|
||||||
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
|
||||||
mgdelacroix = "Miguel de la Cruz <mgdelacroix@gmail.com>";
|
|
||||||
mgttlinger = "Merlin Göttlinger <megoettlinger@gmail.com";
|
|
||||||
mguentner = "Maximilian Güntner <code@klandest.in>";
|
|
||||||
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
|
||||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
|
||||||
michalrus = "Michal Rus <m@michalrus.com>";
|
|
||||||
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
|
||||||
mickours = "Michael Mercier <mickours@gmail.com<";
|
|
||||||
midchildan = "midchildan <midchildan+nix@gmail.com>";
|
|
||||||
mikefaille = "Michaël Faille <michael@faille.io>";
|
|
||||||
mikoim = "Eshin Kunishima <ek@esh.ink>";
|
|
||||||
miltador = "Vasiliy Solovey <miltador@yandex.ua>";
|
|
||||||
mimadrid = "Miguel Madrid <mimadrid@ucm.es>";
|
|
||||||
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
|
||||||
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
|
||||||
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
|
||||||
mjp = "Mike Playle <mike@mythik.co.uk>"; # github = "MikePlayle";
|
|
||||||
mkg = "Mark K Gardner <mkg@vt.edu>";
|
|
||||||
mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>";
|
|
||||||
mmahut = "Marek Mahut <marek.mahut@gmail.com>";
|
|
||||||
moaxcp = "John Mercier <moaxcp@gmail.com>";
|
|
||||||
modulistic = "Pablo Costa <modulistic@gmail.com>";
|
|
||||||
mog = "Matthew O'Gorman <mog-lists@rldn.net>";
|
|
||||||
montag451 = "montag451 <montag451@laposte.net>";
|
|
||||||
moosingin3space = "Nathan Moos <moosingin3space@gmail.com>";
|
|
||||||
moredread = "André-Patrick Bubel <code@apb.name>";
|
|
||||||
moretea = "Maarten Hoogendoorn <maarten@moretea.nl>";
|
|
||||||
mornfall = "Petr Ročkai <me@mornfall.net>";
|
|
||||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
|
||||||
mounium = "Katona László <muoniurn@gmail.com>";
|
|
||||||
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
|
||||||
mpcsh = "Mark Cohen <m@mpc.sh>";
|
|
||||||
mpickering = "Matthew Pickering <matthewtpickering@gmail.com>";
|
|
||||||
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
|
||||||
mpsyco = "Francis St-Amour <fr.st-amour@gmail.com>";
|
|
||||||
mrVanDalo = "Ingolf Wanger <contact@ingolf-wagner.de>";
|
|
||||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
|
||||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
|
||||||
mstarzyk = "Maciek Starzyk <mstarzyk@gmail.com>";
|
|
||||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
|
||||||
mt-caret = "Masayuki Takeda <mtakeda.enigsol@gmail.com>";
|
|
||||||
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
|
||||||
mudri = "James Wood <lamudri@gmail.com>";
|
|
||||||
muflax = "Stefan Dorn <mail@muflax.com>";
|
|
||||||
myrl = "Myrl Hex <myrl.0xf@gmail.com>";
|
|
||||||
nadrieril = "Nadrieril Feneanar <nadrieril@gmail.com>";
|
|
||||||
namore = "Roman Naumann <namor@hemio.de>";
|
|
||||||
nand0p = "Fernando Jose Pando <nando@hex7.com>";
|
|
||||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
|
||||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
|
||||||
nckx = "Tobias Geerinckx-Rice <github@tobias.gr>";
|
|
||||||
ndowens = "Nathan Owens <ndowens04@gmail.com>";
|
|
||||||
neeasade = "Nathan Isom <nathanisom27@gmail.com>";
|
|
||||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
|
||||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
|
||||||
nh2 = "Niklas Hambüchen <mail@nh2.me>";
|
|
||||||
nhooyr = "Anmol Sethi <anmol@aubble.com>";
|
|
||||||
nickhu = "Nick Hu <me@nickhu.co.uk>";
|
|
||||||
nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>";
|
|
||||||
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
|
||||||
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
|
||||||
ninjatrappeur = "Félix Baylac-Jacqué <felix@alternativebit.fr>";
|
|
||||||
nipav = "Niko Pavlinek <niko.pavlinek@gmail.com>";
|
|
||||||
nixy = "Andrew R. M. <nixy@nixy.moe>";
|
|
||||||
nmattia = "Nicolas Mattia <nicolas@nmattia.com>";
|
|
||||||
nocoolnametom = "Tom Doggett <nocoolnametom@gmail.com>";
|
|
||||||
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
|
||||||
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
|
||||||
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
|
||||||
nthorne = "Niklas Thörne <notrupertthorne@gmail.com>";
|
|
||||||
nyarly = "Judson Lester <nyarly@gmail.com>";
|
|
||||||
obadz = "obadz <obadz-nixos@obadz.com>";
|
|
||||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
|
||||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
|
||||||
offline = "Jaka Hudoklin <jakahudoklin@gmail.com>";
|
|
||||||
oida = "oida <oida@posteo.de>";
|
|
||||||
okasu = "Okasu <oka.sux@gmail.com>";
|
|
||||||
olcai = "Erik Timan <dev@timan.info>";
|
|
||||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
|
||||||
olynch = "Owen Lynch <owen@olynch.me>";
|
|
||||||
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
|
||||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
|
||||||
orivej = "Orivej Desh <orivej@gmx.fr>";
|
|
||||||
osener = "Ozan Sener <ozan@ozansener.com>";
|
|
||||||
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
|
|
||||||
oxij = "Jan Malakhovski <oxij@oxij.org>";
|
|
||||||
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
|
||||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
|
||||||
panaeon = "Vitalii Voloshyn <vitalii.voloshyn@gmail.com";
|
|
||||||
paperdigits = "Mica Semrick <mica@silentumbrella.com>";
|
|
||||||
paraseba = "Sebastian Galkin <paraseba@gmail.com>";
|
|
||||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
|
||||||
patternspandemic = "Brad Christensen <patternspandemic@live.com>";
|
|
||||||
pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>";
|
|
||||||
pbogdan = "Piotr Bogdan <ppbogdan@gmail.com>";
|
|
||||||
pcarrier = "Pierre Carrier <pc@rrier.ca>";
|
|
||||||
periklis = "theopompos@gmail.com";
|
|
||||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
|
||||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
|
||||||
peterromfeldhk = "Peter Romfeld <peter.romfeld.hk@gmail.com>";
|
|
||||||
peti = "Peter Simons <simons@cryp.to>";
|
|
||||||
philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
|
|
||||||
phile314 = "Philipp Hausmann <nix@314.ch>";
|
|
||||||
Phlogistique = "Noé Rubinstein <noe.rubinstein@gmail.com>";
|
|
||||||
phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>";
|
|
||||||
phunehehe = "Hoang Xuan Phu <phunehehe@gmail.com>";
|
|
||||||
pierrechevalier83 = "Pierre Chevalier <pierrechevalier83@gmail.com>";
|
|
||||||
pierrer = "Pierre Radermecker <pierrer@pi3r.be>";
|
|
||||||
pierron = "Nicolas B. Pierron <nixos@nbp.name>";
|
|
||||||
piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>";
|
|
||||||
pjbarnoy = "Perry Barnoy <pjbarnoy@gmail.com>";
|
|
||||||
pjones = "Peter Jones <pjones@devalot.com>";
|
|
||||||
pkmx = "Chih-Mao Chen <pkmx.tw@gmail.com>";
|
|
||||||
plcplc = "Philip Lykke Carlsen <plcplc@gmail.com>";
|
|
||||||
plumps = "Maksim Bronsky <maks.bronsky@web.de";
|
|
||||||
pmahoney = "Patrick Mahoney <pat@polycrystal.org>";
|
|
||||||
pmeunier = "Pierre-Étienne Meunier <pierre-etienne.meunier@inria.fr>";
|
|
||||||
pmiddend = "Philipp Middendorf <pmidden@secure.mailbox.org>";
|
|
||||||
pneumaticat = "Kevin Liu <kevin@potatofrom.space>";
|
|
||||||
polyrod = "Maurizio Di Pietro <dc1mdp@gmail.com>";
|
|
||||||
pradeepchhetri = "Pradeep Chhetri <pradeep.chhetri89@gmail.com>";
|
|
||||||
prikhi = "Pavan Rikhi <pavan.rikhi@gmail.com>";
|
|
||||||
primeos = "Michael Weiss <dev.primeos@gmail.com>";
|
|
||||||
Profpatsch = "Profpatsch <mail@profpatsch.de>";
|
|
||||||
proglodyte = "Proglodyte <proglodyte23@gmail.com>";
|
|
||||||
pshendry = "Paul Hendry <paul@pshendry.com>";
|
|
||||||
psibi = "Sibi <sibi@psibi.in>";
|
|
||||||
pstn = "Philipp Steinpaß <philipp@xndr.de>";
|
|
||||||
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
|
|
||||||
puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
|
|
||||||
pxc = "Patrick Callahan <patrick.callahan@latitudeengineering.com>";
|
|
||||||
qknight = "Joachim Schiele <js@lastlog.de>";
|
|
||||||
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
|
|
||||||
ralith = "Benjamin Saunders <ben.e.saunders@gmail.com>";
|
|
||||||
ramkromberg = "Ram Kromberg <ramkromberg@mail.com>";
|
|
||||||
rardiol = "Ricardo Ardissone <ricardo.ardissone@gmail.com>";
|
|
||||||
rasendubi = "Alexey Shmalko <rasen.dubi@gmail.com>";
|
|
||||||
raskin = "Michael Raskin <7c6f434c@mail.ru>";
|
|
||||||
ravloony = "Tom Macdonald <ravloony@gmail.com>";
|
|
||||||
razvan = "Răzvan Flavius Panda <razvan.panda@gmail.com>";
|
|
||||||
rbasso = "Rafael Basso <rbasso@sharpgeeks.net>";
|
|
||||||
redbaron = "Maxim Ivanov <ivanov.maxim@gmail.com>";
|
|
||||||
redvers = "Redvers Davies <red@infect.me>";
|
|
||||||
refnil = "Martin Lavoie <broemartino@gmail.com>";
|
|
||||||
regnat = "Théophane Hufschmitt <regnat@regnat.ovh>";
|
|
||||||
relrod = "Ricky Elrod <ricky@elrod.me>";
|
|
||||||
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
|
|
||||||
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
|
||||||
rht = "rht <rhtbot@protonmail.com>";
|
|
||||||
richardipsum = "Richard Ipsum <richardipsum@fastmail.co.uk>";
|
|
||||||
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
|
||||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
|
||||||
ris = "Robert Scott <code@humanleg.org.uk>";
|
|
||||||
rlupton20 = "Richard Lupton <richard.lupton@gmail.com>";
|
|
||||||
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
|
||||||
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
|
||||||
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
|
||||||
robbinch = "Robbin C. <robbinch33@gmail.com>";
|
|
||||||
roberth = "Robert Hensing <nixpkgs@roberthensing.nl>";
|
|
||||||
robertodr = "Roberto Di Remigio <roberto.diremigio@gmail.com>";
|
|
||||||
robgssp = "Rob Glossop <robgssp@gmail.com>";
|
|
||||||
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
|
||||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
|
||||||
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
|
||||||
rongcuid = "Rongcui Dong <rongcuid@outlook.com>";
|
|
||||||
rszibele = "Richard Szibele <richard@szibele.com>";
|
|
||||||
rtreffer = "Rene Treffer <treffer+nixos@measite.de>";
|
|
||||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
|
||||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
|
||||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
|
||||||
rvolosatovs = "Roman Volosatovs <rvolosatovs@riseup.net>";
|
|
||||||
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
|
||||||
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
|
||||||
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
|
||||||
ryantrinkle = "Ryan Trinkle <ryan.trinkle@gmail.com>";
|
|
||||||
rybern = "Ryan Bernstein <ryan.bernstein@columbia.edu>";
|
|
||||||
rycee = "Robert Helgesson <robert@rycee.net>";
|
|
||||||
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
|
||||||
rzetterberg = "Richard Zetterberg <richard.zetterberg@gmail.com>";
|
|
||||||
s1lvester = "Markus Silvester <s1lvester@bockhacker.me>";
|
|
||||||
samdroid-apps = "Sam Parkinson <sam@sam.today>";
|
|
||||||
samueldr = "Samuel Dionne-Riel <samuel@dionne-riel.com>";
|
|
||||||
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
|
|
||||||
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
|
||||||
sargon = "Daniel Ehlers <danielehlers@mindeye.net>";
|
|
||||||
sauyon = "Sauyon Lee <s@uyon.co>";
|
|
||||||
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
|
|
||||||
schneefux = "schneefux <schneefux+nixos_pkg@schneefux.xyz>";
|
|
||||||
schristo = "Scott Christopher <schristopher@konputa.com>";
|
|
||||||
scode = "Peter Schuller <peter.schuller@infidyne.com>";
|
|
||||||
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
|
|
||||||
sdll = "Sasha Illarionov <sasha.delly@gmail.com>";
|
|
||||||
SeanZicari = "Sean Zicari <sean.zicari@gmail.com>";
|
|
||||||
sellout = "Greg Pfeil <greg@technomadic.org>";
|
|
||||||
sepi = "Raffael Mancini <raffael@mancini.lu>";
|
|
||||||
seppeljordan = "Sebastian Jordan <sebastian.jordan.mail@googlemail.com>";
|
|
||||||
sfrijters = "Stefan Frijters <sfrijters@gmail.com>";
|
|
||||||
shanemikel = "Shane Pearlman <shanemikel1@gmail.com>";
|
|
||||||
shawndellysse = "Shawn Dellysse <sdellysse@gmail.com>";
|
|
||||||
sheenobu = "Sheena Artrip <sheena.artrip@gmail.com>";
|
|
||||||
sheganinans = "Aistis Raulinaitis <sheganinans@gmail.com>";
|
|
||||||
shell = "Shell Turner <cam.turn@gmail.com>";
|
|
||||||
shlevy = "Shea Levy <shea@shealevy.com>";
|
|
||||||
siddharthist = "Langston Barrett <langston.barrett@gmail.com>";
|
|
||||||
sifmelcara = "Ming Chuan <ming@culpring.com>";
|
|
||||||
sigma = "Yann Hodique <yann.hodique@gmail.com>";
|
|
||||||
simonvandel = "Simon Vandel Sillesen <simon.vandel@gmail.com>";
|
|
||||||
sivteck = "Sivaram Balakrishnan <sivaram1992@gmail.com>";
|
|
||||||
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
|
|
||||||
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
|
|
||||||
sjourdois = "Stéphane ‘kwisatz’ Jourdois <sjourdois@gmail.com>";
|
|
||||||
skeidel = "Sven Keidel <svenkeidel@gmail.com>";
|
|
||||||
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
|
||||||
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
|
||||||
smironov = "Sergey Mironov <grrwlf@gmail.com>";
|
|
||||||
snyh = "Xia Bin <snyh@snyh.org>";
|
|
||||||
solson = "Scott Olson <scott@solson.me>";
|
|
||||||
sorpaas = "Wei Tang <hi@that.world>";
|
|
||||||
sorki = "Richard Marko <srk@48.io>";
|
|
||||||
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
|
||||||
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
|
||||||
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
|
||||||
sprock = "Roger Mason <rmason@mun.ca>";
|
|
||||||
spwhitt = "Spencer Whitt <sw@swhitt.me>";
|
|
||||||
srhb = "Sarah Brofeldt <sbrofeldt@gmail.com>";
|
|
||||||
SShrike = "Severen Redwood <severen@shrike.me>";
|
|
||||||
stephenmw = "Stephen Weinberg <stephen@q5comm.com>";
|
|
||||||
sternenseemann = "Lukas Epple <post@lukasepple.de>";
|
|
||||||
stesie = "Stefan Siegl <stesie@brokenpipe.de>";
|
|
||||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
|
||||||
StijnDW = "Stijn DW <stekke@airmail.cc>";
|
|
||||||
StillerHarpo = "Florian Engel <florianengel39@gmail.com>";
|
|
||||||
stumoss = "Stuart Moss <samoss@gmail.com>";
|
|
||||||
SuprDewd = "Bjarki Ágúst Guðmundsson <suprdewd@gmail.com>";
|
|
||||||
suvash = "Suvash Thapaliya <suvash+nixpkgs@gmail.com>";
|
|
||||||
svsdep = "Vasyl Solovei <svsdep@gmail.com>";
|
|
||||||
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
|
||||||
swflint = "Samuel W. Flint <swflint@flintfam.org>";
|
|
||||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
|
||||||
symphorien = "Guillaume Girol <symphorien_nixpkgs@xlumurb.eu>";
|
|
||||||
szczyp = "Szczyp <qb@szczyp.com>";
|
|
||||||
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
|
|
||||||
tadfisher = "Tad Fisher <tadfisher@gmail.com>";
|
|
||||||
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
|
|
||||||
tailhook = "Paul Colomiets <paul@colomiets.name>";
|
|
||||||
taketwo = "Sergey Alexandrov <alexandrov88@gmail.com>";
|
|
||||||
takikawa = "Asumu Takikawa <asumu@igalia.com>";
|
|
||||||
taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
|
|
||||||
taku0 = "Takuo Yonezawa <mxxouy6x3m_github@tatapa.org>";
|
|
||||||
tari = "Peter Marheine <peter@taricorp.net>";
|
|
||||||
tavyc = "Octavian Cerna <octavian.cerna@gmail.com>";
|
|
||||||
TealG = "Teal Gaure <~@Teal.Gr>";
|
|
||||||
teh = "Tom Hunger <tehunger@gmail.com>";
|
|
||||||
telotortium = "Robert Irelan <rirelan@gmail.com>";
|
|
||||||
teto = "Matthieu Coudron <mcoudron@hotmail.com>";
|
|
||||||
tex = "Milan Svoboda <milan.svoboda@centrum.cz>";
|
|
||||||
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
|
||||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
|
||||||
thanegill = "Thane Gill <me@thanegill.com>";
|
|
||||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
|
||||||
theuni = "Christian Theune <ct@flyingcircus.io>";
|
|
||||||
ThomasMader = "Thomas Mader <thomas.mader@gmail.com>";
|
|
||||||
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
|
||||||
thpham = "Thomas Pham <thomas.pham@ithings.ch>";
|
|
||||||
tilpner = "Till Höppner <till@hoeppner.ws>";
|
|
||||||
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
|
||||||
timokau = "Timo Kaufmann <timokau@zoho.com>";
|
|
||||||
tiramiseb = "Sébastien Maccagnoni <sebastien@maccagnoni.eu>";
|
|
||||||
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
|
||||||
tnias = "Philipp Bartsch <phil@grmr.de>";
|
|
||||||
tohl = "Tomas Hlavaty <tom@logand.com>";
|
|
||||||
tokudan = "Daniel Frank <git@danielfrank.net>";
|
|
||||||
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
|
||||||
tomsmeets = "Tom Smeets <tom@tsmeets.nl>";
|
|
||||||
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
|
||||||
treemo = "Matthieu Chevrier <matthieu.chevrier@treemo.fr>";
|
|
||||||
trevorj = "Trevor Joynson <nix@trevor.joynson.io>";
|
|
||||||
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
|
||||||
troydm = "Dmitry Geurkov <d.geurkov@gmail.com>";
|
|
||||||
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
|
||||||
ttuegel = "Thomas Tuegel <ttuegel@mailbox.org>";
|
|
||||||
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
|
||||||
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
|
||||||
tvorog = "Marsel Zaripov <marszaripov@gmail.com>";
|
|
||||||
tweber = "Thorsten Weber <tw+nixpkgs@360vier.de>";
|
|
||||||
twey = "James ‘Twey’ Kay <twey@twey.co.uk>";
|
|
||||||
unode = "Renato Alves <alves.rjc@gmail.com>";
|
|
||||||
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
|
|
||||||
utdemir = "Utku Demir <me@utdemir.com>";
|
|
||||||
#urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; inactive since 2012
|
|
||||||
uwap = "uwap <me@uwap.name>";
|
|
||||||
va1entin = "Valentin Heidelberger <github@valentinsblog.com>";
|
|
||||||
vaibhavsagar = "Vaibhav Sagar <vaibhavsagar@gmail.com>";
|
|
||||||
valeriangalliat = "Valérian Galliat <val@codejam.info>";
|
|
||||||
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
|
|
||||||
vanschelven = "Klaas van Schelven <klaas@vanschelven.com>";
|
|
||||||
vanzef = "Ivan Solyankin <vanzef@gmail.com>";
|
|
||||||
varunpatro = "Varun Patro <varun.kumar.patro@gmail.com>";
|
|
||||||
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
|
||||||
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
|
||||||
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
|
|
||||||
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
|
||||||
velovix = "Tyler Compton <xaviosx@gmail.com>";
|
|
||||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
|
||||||
vidbina = "David Asabina <vid@bina.me>";
|
|
||||||
vifino = "Adrian Pistol <vifino@tty.sh>";
|
|
||||||
vinymeuh = "VinyMeuh <vinymeuh@gmail.com>";
|
|
||||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
|
||||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
|
||||||
vklquevs = "vklquevs <vklquevs@gmail.com>";
|
|
||||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
|
||||||
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
|
||||||
vmchale = "Vanessa McHale <tmchale@wisc.edu>";
|
|
||||||
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
|
||||||
volth = "Jaroslavas Pocepko <jaroslavas@volth.com>";
|
|
||||||
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
|
||||||
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
|
||||||
vyp = "vyp <elisp.vim@gmail.com>";
|
|
||||||
wedens = "wedens <kirill.wedens@gmail.com>";
|
|
||||||
willibutz = "Willi Butz <willibutz@posteo.de>";
|
|
||||||
willtim = "Tim Philip Williams <tim.williams.public@gmail.com>";
|
|
||||||
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
|
||||||
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
|
|
||||||
wjlroe = "William Roe <willroe@gmail.com>";
|
|
||||||
wkennington = "William A. Kennington III <william@wkennington.com>";
|
|
||||||
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
|
|
||||||
woffs = "Frank Doepper <github@woffs.de>";
|
|
||||||
womfoo = "Kranium Gikos Mendoza <kranium@gikos.net>";
|
|
||||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
|
||||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
|
||||||
xaverdh = "Dominik Xaver Hörl <hoe.dom@gmx.de>";
|
|
||||||
xeji = "xeji <xeji@cat3.de>";
|
|
||||||
xnwdd = "Guillermo NWDD <nwdd+nixos@no.team>";
|
|
||||||
xurei = "Olivier Bourdoux <olivier.bourdoux@gmail.com>";
|
|
||||||
xvapx = "Marti Serra <marti.serra.coscollano@gmail.com>";
|
|
||||||
xwvvvvwx = "David Terry <davidterry@posteo.de>";
|
|
||||||
xzfc = "Albert Safin <xzfcpw@gmail.com>";
|
|
||||||
y0no = "Yoann Ono <y0no@y0no.fr>";
|
|
||||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
|
||||||
yegortimoshenko = "Yegor Timoshenko <yegortimoshenko@gmail.com>";
|
|
||||||
yesbox = "Jesper Geertsen Jonsson <jesper.geertsen.jonsson@gmail.com>";
|
|
||||||
ylwghst = "Burim Augustin Berisa <ylwghst@onionmail.info>";
|
|
||||||
yochai = "Yochai <yochai@titat.info>";
|
|
||||||
yorickvp = "Yorick van Pelt <yorickvanpelt@gmail.com>";
|
|
||||||
yrashk = "Yurii Rashkovskii <yrashk@gmail.com>";
|
|
||||||
yuriaisaka = "Yuri Aisaka <yuri.aisaka+nix@gmail.com>";
|
|
||||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
|
||||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
|
||||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
|
||||||
zalakain = "Unai Zalakain <contact@unaizalakain.info>";
|
|
||||||
zarelit = "David Costa <david@zarel.net>";
|
|
||||||
zauberpony = "Elmar Athmer <elmar@athmer.org>";
|
|
||||||
zef = "Zef Hemel <zef@zef.me>";
|
|
||||||
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
|
||||||
Zimmi48 = "Théo Zimmermann <theo.zimmermann@univ-paris-diderot.fr>";
|
|
||||||
zohl = "Al Zohali <zohl@fmap.me>";
|
|
||||||
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
|
||||||
zraexy = "David Mell <zraexy@gmail.com>";
|
|
||||||
zx2c4 = "Jason A. Donenfeld <Jason@zx2c4.com>";
|
|
||||||
zzamboni = "Diego Zamboni <diego@zzamboni.org>";
|
|
||||||
}
|
|
@ -23,10 +23,12 @@ rec {
|
|||||||
config = parse.tripleFromSystem final.parsed;
|
config = parse.tripleFromSystem final.parsed;
|
||||||
# Just a guess, based on `system`
|
# Just a guess, based on `system`
|
||||||
platform = platforms.selectBySystem final.system;
|
platform = platforms.selectBySystem final.system;
|
||||||
|
# Derived meta-data
|
||||||
libc =
|
libc =
|
||||||
/**/ if final.isDarwin then "libSystem"
|
/**/ if final.isDarwin then "libSystem"
|
||||||
else if final.isMinGW then "msvcrt"
|
else if final.isMinGW then "msvcrt"
|
||||||
else if final.isMusl then "musl"
|
else if final.isMusl then "musl"
|
||||||
|
else if final.isAndroid then "bionic"
|
||||||
else if final.isLinux /* default */ then "glibc"
|
else if final.isLinux /* default */ then "glibc"
|
||||||
# TODO(@Ericson2314) think more about other operating systems
|
# TODO(@Ericson2314) think more about other operating systems
|
||||||
else "native/impure";
|
else "native/impure";
|
||||||
@ -39,7 +41,10 @@ rec {
|
|||||||
/**/ if final.isWindows then ".exe"
|
/**/ if final.isWindows then ".exe"
|
||||||
else "";
|
else "";
|
||||||
};
|
};
|
||||||
|
# Misc boolean options
|
||||||
|
useAndroidPrebuilt = false;
|
||||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
// args;
|
// args;
|
||||||
in final;
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||||
|
final;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ let
|
|||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
||||||
|
|
||||||
"mips64el-linux"
|
"mipsel-linux"
|
||||||
|
|
||||||
"i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd"
|
"i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd"
|
||||||
|
|
||||||
|
@ -38,6 +38,13 @@ rec {
|
|||||||
platform = platforms.aarch64-multiplatform;
|
platform = platforms.aarch64-multiplatform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
aarch64-android-prebuilt = rec {
|
||||||
|
config = "aarch64-unknown-linux-android";
|
||||||
|
arch = "aarch64";
|
||||||
|
platform = platforms.aarch64-multiplatform;
|
||||||
|
useAndroidPrebuilt = true;
|
||||||
|
};
|
||||||
|
|
||||||
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
||||||
platform = platforms.scaleway-c1;
|
platform = platforms.scaleway-c1;
|
||||||
inherit (platform.gcc) fpu;
|
inherit (platform.gcc) fpu;
|
||||||
@ -51,7 +58,7 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fuloongminipc = rec {
|
fuloongminipc = rec {
|
||||||
config = "mips64el-unknown-linux-gnu";
|
config = "mipsel-unknown-linux-gnu";
|
||||||
arch = "mips";
|
arch = "mips";
|
||||||
float = "hard";
|
float = "hard";
|
||||||
platform = platforms.fuloong2f_n32;
|
platform = platforms.fuloong2f_n32;
|
||||||
|
@ -34,7 +34,15 @@ rec {
|
|||||||
Cygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
Cygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
||||||
MinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
MinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
||||||
|
|
||||||
|
Android = [ { abi = abis.android; } { abi = abis.androideabi; } ];
|
||||||
Musl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
|
Musl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
|
||||||
|
|
||||||
|
Kexecable = map (family: { kernel = kernels.linux; cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" "mips" ];
|
||||||
|
Efi = map (family: { cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" ];
|
||||||
|
Seccomputable = map (family: { kernel = kernels.linux; cpu.family = family; })
|
||||||
|
[ "x86" "arm" "aarch64" "mips" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
matchAnyAttrs = patterns:
|
matchAnyAttrs = patterns:
|
||||||
|
@ -75,7 +75,10 @@ rec {
|
|||||||
aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
|
aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
|
||||||
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||||
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
||||||
mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||||
|
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||||
|
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||||
|
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||||
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
||||||
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
|
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
|
||||||
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
|
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
|
||||||
@ -173,6 +176,7 @@ rec {
|
|||||||
types.abi = enum (attrValues abis);
|
types.abi = enum (attrValues abis);
|
||||||
|
|
||||||
abis = setTypes types.openAbi {
|
abis = setTypes types.openAbi {
|
||||||
|
android = {};
|
||||||
cygnus = {};
|
cygnus = {};
|
||||||
gnu = {};
|
gnu = {};
|
||||||
msvc = {};
|
msvc = {};
|
||||||
|
@ -561,6 +561,6 @@ rec {
|
|||||||
"armv6l-linux" = raspberrypi;
|
"armv6l-linux" = raspberrypi;
|
||||||
"armv7l-linux" = armv7l-hf-multiplatform;
|
"armv7l-linux" = armv7l-hf-multiplatform;
|
||||||
"aarch64-linux" = aarch64-multiplatform;
|
"aarch64-linux" = aarch64-multiplatform;
|
||||||
"mips64el-linux" = fuloong2f_n32;
|
"mipsel-linux" = fuloong2f_n32;
|
||||||
}.${system} or pcBase;
|
}.${system} or pcBase;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ in with lib.systems.doubles; lib.runTests {
|
|||||||
|
|
||||||
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
||||||
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
|
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
|
||||||
mips = assertTrue (mseteq mips [ "mips64el-linux" ]);
|
mips = assertTrue (mseteq mips [ "mipsel-linux" ]);
|
||||||
x86_64 = assertTrue (mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" ]);
|
x86_64 = assertTrue (mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" ]);
|
||||||
|
|
||||||
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
|
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
|
||||||
@ -24,7 +24,7 @@ in with lib.systems.doubles; lib.runTests {
|
|||||||
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
|
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
|
||||||
gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
|
gnu = assertTrue (mseteq gnu (linux /* ++ hurd ++ kfreebsd ++ ... */));
|
||||||
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
|
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
|
||||||
linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mips64el-linux" ]);
|
linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ]);
|
||||||
netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
|
netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
|
||||||
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
|
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
|
||||||
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
||||||
|
47
lib/versions.nix
Normal file
47
lib/versions.nix
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* Version string functions. */
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
splitVersion = builtins.splitVersion or (lib.splitString ".");
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
/* Get the major version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
major "1.2.3"
|
||||||
|
=> "1"
|
||||||
|
*/
|
||||||
|
major = v: builtins.elemAt (splitVersion v) 0;
|
||||||
|
|
||||||
|
/* Get the minor version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
minor "1.2.3"
|
||||||
|
=> "2"
|
||||||
|
*/
|
||||||
|
minor = v: builtins.elemAt (splitVersion v) 1;
|
||||||
|
|
||||||
|
/* Get the patch version string from a string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
patch "1.2.3"
|
||||||
|
=> "3"
|
||||||
|
*/
|
||||||
|
patch = v: builtins.elemAt (splitVersion v) 2;
|
||||||
|
|
||||||
|
/* Get string of the first two parts (major and minor)
|
||||||
|
of a version string.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
majorMinor "1.2.3"
|
||||||
|
=> "1.2"
|
||||||
|
*/
|
||||||
|
majorMinor = v:
|
||||||
|
builtins.concatStringsSep "."
|
||||||
|
(lib.take 2 (splitVersion v));
|
||||||
|
|
||||||
|
}
|
66
maintainers/scripts/check-maintainer-github-handles.sh
Executable file
66
maintainers/scripts/check-maintainer-github-handles.sh
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p jq parallel
|
||||||
|
|
||||||
|
# Example how to work with the `lib.maintainers` attrset.
|
||||||
|
# Can be used to check whether all user handles are still valid.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# nixpkgs='<nixpkgs>'
|
||||||
|
# if [ -n "$1" ]; then
|
||||||
|
|
||||||
|
function checkCommits {
|
||||||
|
local user="$1"
|
||||||
|
local tmp=$(mktemp)
|
||||||
|
curl --silent -w "%{http_code}" \
|
||||||
|
"https://github.com/NixOS/nixpkgs/commits?author=$user" \
|
||||||
|
> "$tmp"
|
||||||
|
# the last line of tmp contains the http status
|
||||||
|
local status=$(tail -n1 "$tmp")
|
||||||
|
local ret=
|
||||||
|
case $status in
|
||||||
|
200) if <"$tmp" grep -i "no commits found" > /dev/null; then
|
||||||
|
ret=1
|
||||||
|
else
|
||||||
|
ret=0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
# because of github’s hard request limits, this can take some time
|
||||||
|
429) sleep 2
|
||||||
|
printf "."
|
||||||
|
checkCommits "$user"
|
||||||
|
ret=$?
|
||||||
|
;;
|
||||||
|
*) printf "BAD STATUS: $(tail -n1 $tmp) for %s\n" "$user"; ret=1
|
||||||
|
ret=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
rm "$tmp"
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
export -f checkCommits
|
||||||
|
|
||||||
|
function checkUser {
|
||||||
|
local user="$1"
|
||||||
|
local status=
|
||||||
|
status="$(curl --silent --head "https://github.com/${user}" | grep Status)"
|
||||||
|
# checks whether a user handle can be found on github
|
||||||
|
if [[ "$status" =~ 404 ]]; then
|
||||||
|
printf "%s\t\t\t\t%s\n" "$status" "$user"
|
||||||
|
# checks whether the user handle has any nixpkgs commits
|
||||||
|
elif checkCommits "$user"; then
|
||||||
|
printf "OK!\t\t\t\t%s\n" "$user"
|
||||||
|
else
|
||||||
|
printf "No Commits!\t\t\t%s\n" "$user"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
export -f checkUser
|
||||||
|
|
||||||
|
# output the maintainers set as json
|
||||||
|
# and filter out the github username of each maintainer (if it exists)
|
||||||
|
# then check some at the same time
|
||||||
|
nix-instantiate -A lib.maintainers --eval --strict --json \
|
||||||
|
| jq -r '.[]|.github|select(.)' \
|
||||||
|
| parallel -j5 checkUser
|
||||||
|
|
||||||
|
# parallel -j100 checkUser ::: "eelco" "profpatsch" "Profpatsch" "a"
|
@ -1,192 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
GNOME_FTP=ftp.gnome.org/pub/GNOME/sources
|
|
||||||
|
|
||||||
# projects that don't follow the GNOME major versioning, or that we don't want to
|
|
||||||
# programmatically update
|
|
||||||
NO_GNOME_MAJOR="ghex gtkhtml gdm gucharmap"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 <show project>|<update project>|<update-all> [major.minor]" >&2
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$#" -lt 1 ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
GNOME_TOP=pkgs/desktops/gnome-3
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
|
|
||||||
# curl -l ftp://... doesn't work from my office in HSE, and I don't want to have
|
|
||||||
# any conversations with sysadmin. Somehow lftp works.
|
|
||||||
if [ "$FTP_CLIENT" = "lftp" ]; then
|
|
||||||
ls_ftp() {
|
|
||||||
lftp -c "open $1; cls"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ls_ftp() {
|
|
||||||
curl -s -l "$1"/
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
find_project() {
|
|
||||||
exec find "$GNOME_TOP" -mindepth 2 -maxdepth 2 -type d "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
show_project() {
|
|
||||||
local project=$1
|
|
||||||
local majorVersion=$2
|
|
||||||
local version=
|
|
||||||
|
|
||||||
if [ -z "$majorVersion" ]; then
|
|
||||||
echo "Looking for available versions..." >&2
|
|
||||||
local available_baseversions=$(ls_ftp ftp://${GNOME_FTP}/${project} | grep '[0-9]\.[0-9]' | sort -t. -k1,1n -k 2,2n)
|
|
||||||
if [ "$?" -ne 0 ]; then
|
|
||||||
echo "Project $project not found" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "The following versions are available:\n ${available_baseversions[@]}" >&2
|
|
||||||
echo -en "Choose one of them: " >&2
|
|
||||||
read majorVersion
|
|
||||||
fi
|
|
||||||
|
|
||||||
if echo "$majorVersion" | grep -q "[0-9]\+\.[0-9]\+\.[0-9]\+"; then
|
|
||||||
# not a major version
|
|
||||||
version=$majorVersion
|
|
||||||
majorVersion=$(echo "$majorVersion" | cut -d '.' -f 1,2)
|
|
||||||
fi
|
|
||||||
|
|
||||||
local FTPDIR=${GNOME_FTP}/${project}/${majorVersion}
|
|
||||||
|
|
||||||
#version=`curl -l ${FTPDIR}/ 2>/dev/null | grep LATEST-IS | sed -e s/LATEST-IS-//`
|
|
||||||
# gnome's LATEST-IS is broken. Do not trust it.
|
|
||||||
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
local files=$(ls_ftp "${FTPDIR}")
|
|
||||||
declare -A versions
|
|
||||||
|
|
||||||
for f in $files; do
|
|
||||||
case $f in
|
|
||||||
(LATEST-IS-*|*.news|*.changes|*.sha256sum|*.diff*):
|
|
||||||
;;
|
|
||||||
($project-*.*.9*.tar.*):
|
|
||||||
tmp=${f#$project-}
|
|
||||||
tmp=${tmp%.tar*}
|
|
||||||
echo "Ignored unstable version ${tmp}" >&2
|
|
||||||
;;
|
|
||||||
($project-*.tar.*):
|
|
||||||
tmp=${f#$project-}
|
|
||||||
tmp=${tmp%.tar*}
|
|
||||||
versions[${tmp}]=1
|
|
||||||
;;
|
|
||||||
(*):
|
|
||||||
echo "UNKNOWN FILE $f" >&2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
echo "Found versions ${!versions[@]}" >&2
|
|
||||||
version=$(echo ${!versions[@]} | sed -e 's/ /\n/g' | sort -t. -k1,1n -k 2,2n -k 3,3n | tail -n1)
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
echo "No version available for major $majorVersion" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Latest version is: ${version}" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local name=${project}-${version}
|
|
||||||
echo "Fetching .sha256 file" >&2
|
|
||||||
local sha256out=$(curl -s -f http://"${FTPDIR}"/"${name}".sha256sum)
|
|
||||||
|
|
||||||
if [ "$?" -ne "0" ]; then
|
|
||||||
echo "Version not found" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
extensions=( "xz" "bz2" "gz" )
|
|
||||||
echo "Choosing archive extension (known are ${extensions[@]})..." >&2
|
|
||||||
for ext in ${extensions[@]}; do
|
|
||||||
if echo -e "$sha256out" | grep -q "\\.tar\\.${ext}$"; then
|
|
||||||
ext_pref=$ext
|
|
||||||
sha256=$(echo -e "$sha256out" | grep "\\.tar\\.${ext}$" | cut -f1 -d\ )
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo "Chosen ${ext_pref}, hash is ${sha256}" >&2
|
|
||||||
|
|
||||||
echo "# Autogenerated by maintainers/scripts/gnome.sh update
|
|
||||||
|
|
||||||
fetchurl: {
|
|
||||||
name = \"${project}-${version}\";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = mirror://gnome/sources/${project}/${majorVersion}/${project}-${version}.tar.${ext_pref};
|
|
||||||
sha256 = \"${sha256}\";
|
|
||||||
};
|
|
||||||
}"
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
update_project() {
|
|
||||||
local project=$1
|
|
||||||
local majorVersion=$2
|
|
||||||
|
|
||||||
# find project in nixpkgs tree
|
|
||||||
projectPath=$(find_project -name "$project" -print)
|
|
||||||
if [ -z "$projectPath" ]; then
|
|
||||||
echo "Project $project not found under $GNOME_TOP"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
src=$(show_project "$project" "$majorVersion")
|
|
||||||
|
|
||||||
if [ "$?" -eq "0" ]; then
|
|
||||||
echo "Updating $projectPath/src.nix" >&2
|
|
||||||
echo -e "$src" > "$projectPath"/src.nix
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$action" = "update-all" ]; then
|
|
||||||
majorVersion=$2
|
|
||||||
if [ -z "$majorVersion" ]; then
|
|
||||||
echo "No major version specified" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
# find projects
|
|
||||||
projects=$(find_project -exec basename '{}' \;)
|
|
||||||
for project in $projects; do
|
|
||||||
if echo "$NO_GNOME_MAJOR"|grep -q $project; then
|
|
||||||
echo "Skipping $project"
|
|
||||||
else
|
|
||||||
echo "= Updating $project to $majorVersion" >&2
|
|
||||||
update_project "$project" "$majorVersion"
|
|
||||||
echo >&2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
project=$2
|
|
||||||
majorVersion=$3
|
|
||||||
|
|
||||||
if [ -z "$project" ]; then
|
|
||||||
echo "No project specified, exiting" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$action" = show ]; then
|
|
||||||
show_project "$project" "$majorVersion"
|
|
||||||
elif [ "$action" = update ]; then
|
|
||||||
update_project "$project" "$majorVersion"
|
|
||||||
else
|
|
||||||
echo "Unknown action $action" >&2
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
fi
|
|
@ -1,5 +1,6 @@
|
|||||||
{ package ? null
|
{ package ? null
|
||||||
, maintainer ? null
|
, maintainer ? null
|
||||||
|
, path ? null
|
||||||
}:
|
}:
|
||||||
|
|
||||||
# TODO: add assert statements
|
# TODO: add assert statements
|
||||||
@ -9,7 +10,8 @@ let
|
|||||||
pkgs = import ./../../default.nix { };
|
pkgs = import ./../../default.nix { };
|
||||||
|
|
||||||
packagesWith = cond: return: set:
|
packagesWith = cond: return: set:
|
||||||
pkgs.lib.flatten
|
pkgs.lib.unique
|
||||||
|
(pkgs.lib.flatten
|
||||||
(pkgs.lib.mapAttrsToList
|
(pkgs.lib.mapAttrsToList
|
||||||
(name: pkg:
|
(name: pkg:
|
||||||
let
|
let
|
||||||
@ -25,6 +27,7 @@ let
|
|||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
set
|
set
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
packagesWithUpdateScriptAndMaintainer = maintainer':
|
packagesWithUpdateScriptAndMaintainer = maintainer':
|
||||||
@ -47,6 +50,14 @@ let
|
|||||||
(name: pkg: pkg)
|
(name: pkg: pkg)
|
||||||
pkgs;
|
pkgs;
|
||||||
|
|
||||||
|
packagesWithUpdateScript = path:
|
||||||
|
let
|
||||||
|
attrSet = pkgs.lib.attrByPath (pkgs.lib.splitString "." path) null pkgs;
|
||||||
|
in
|
||||||
|
packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg)
|
||||||
|
(name: pkg: pkg)
|
||||||
|
attrSet;
|
||||||
|
|
||||||
packageByName = name:
|
packageByName = name:
|
||||||
let
|
let
|
||||||
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
|
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
|
||||||
@ -63,6 +74,8 @@ let
|
|||||||
[ (packageByName package) ]
|
[ (packageByName package) ]
|
||||||
else if maintainer != null then
|
else if maintainer != null then
|
||||||
packagesWithUpdateScriptAndMaintainer maintainer
|
packagesWithUpdateScriptAndMaintainer maintainer
|
||||||
|
else if path != null then
|
||||||
|
packagesWithUpdateScript path
|
||||||
else
|
else
|
||||||
builtins.throw "No arguments provided.\n\n${helpText}";
|
builtins.throw "No arguments provided.\n\n${helpText}";
|
||||||
|
|
||||||
@ -76,7 +89,11 @@ let
|
|||||||
|
|
||||||
% nix-shell maintainers/scripts/update.nix --argstr package garbas
|
% nix-shell maintainers/scripts/update.nix --argstr package garbas
|
||||||
|
|
||||||
to run update script for specific package.
|
to run update script for specific package, or
|
||||||
|
|
||||||
|
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
|
||||||
|
|
||||||
|
to run update script for all package under an attribute path.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
runUpdateScript = package: ''
|
runUpdateScript = package: ''
|
||||||
|
@ -11,15 +11,17 @@ tedious, so here is a quick way to see if the installer works
|
|||||||
properly:
|
properly:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build -A config.system.build.nixos-install
|
|
||||||
# mount -t tmpfs none /mnt
|
# mount -t tmpfs none /mnt
|
||||||
|
# nixos-generate-config --root /mnt
|
||||||
|
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-install
|
||||||
# ./result/bin/nixos-install</screen>
|
# ./result/bin/nixos-install</screen>
|
||||||
|
|
||||||
To start a login shell in the new NixOS installation in
|
To start a login shell in the new NixOS installation in
|
||||||
<filename>/mnt</filename>:
|
<filename>/mnt</filename>:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
# ./result/bin/nixos-install --chroot
|
$ nix-build '<nixpkgs/nixos>' -A config.system.build.nixos-enter
|
||||||
|
# ./result/bin/nixos-enter
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
297
nixos/doc/manual/installation/installing-from-other-distro.xml
Normal file
297
nixos/doc/manual/installation/installing-from-other-distro.xml
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
<!-- vim: set expandtab ts=2 softtabstop=2 shiftwidth=2 smarttab textwidth=80 wrapmargin=2 -->
|
||||||
|
<section
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-installing-from-other-distro">
|
||||||
|
|
||||||
|
<title>Installing from another Linux distribution</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Because Nix (the package manager) & Nixpkgs (the Nix packages
|
||||||
|
collection) can both be installed on any (most?) Linux distributions,
|
||||||
|
they can be used to install NixOS in various creative ways. You can,
|
||||||
|
for instance:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Install NixOS on another partition, from your existing
|
||||||
|
Linux distribution (without the use of a USB or optical
|
||||||
|
device!)</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Install NixOS on the same partition (in place!), from
|
||||||
|
your existing non-NixOS Linux distribution using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Install NixOS on your hard drive from the Live CD of
|
||||||
|
any Linux distribution.</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>The first steps to all these are the same:</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Install the Nix package manager:</para>
|
||||||
|
|
||||||
|
<para>Short version:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ bash <(curl https://nixos.org/nix/install)
|
||||||
|
$ . $HOME/.nix-profile/etc/profile.d/nix.sh # …or open a fresh shell</screen>
|
||||||
|
|
||||||
|
<para>More details in the <link
|
||||||
|
xlink:href="https://nixos.org/nix/manual/#chap-quick-start">
|
||||||
|
Nix manual</link></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Switch to the NixOS channel:</para>
|
||||||
|
|
||||||
|
<para>If you've just installed Nix on a non-NixOS distribution, you
|
||||||
|
will be on the <literal>nixpkgs</literal> channel by
|
||||||
|
default.</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-channel --list
|
||||||
|
nixpkgs https://nixos.org/channels/nixpkgs-unstable</screen>
|
||||||
|
|
||||||
|
<para>As that channel gets released without running the NixOS
|
||||||
|
tests, it will be safer to use the <literal>nixos-*</literal>
|
||||||
|
channels instead:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-channel --add https://nixos.org/channels/nixos-<replaceable>version</replaceable> nixpkgs</screen>
|
||||||
|
|
||||||
|
<para>You may want to throw in a <literal>nix-channel
|
||||||
|
--update</literal> for good measure.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Install the NixOS installation tools:</para>
|
||||||
|
|
||||||
|
<para>You'll need <literal>nixos-generate-config</literal> and
|
||||||
|
<literal>nixos-install</literal> and we'll throw in some man
|
||||||
|
pages and <literal>nixos-enter</literal> just in case you want
|
||||||
|
to chroot into your NixOS partition. They are installed by
|
||||||
|
default on NixOS, but you don't have NixOS yet..</para>
|
||||||
|
|
||||||
|
<screen>$ nix-env -iE "_: with import <nixpkgs/nixos> { configuration = {}; }; with config.system.build; [ nixos-generate-config nixos-install nixos-enter manual.manpages ]"</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<note><para>The following 5 steps are only for installing NixOS to
|
||||||
|
another partition. For installing NixOS in place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>, skip ahead.</para></note>
|
||||||
|
|
||||||
|
<para>Prepare your target partition:</para>
|
||||||
|
|
||||||
|
<para>At this point it is time to prepare your target partition.
|
||||||
|
Please refer to the partitioning, file-system creation, and
|
||||||
|
mounting steps of <xref linkend="sec-installation" /></para>
|
||||||
|
|
||||||
|
<para>If you're about to install NixOS in place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal> there is nothing to do for
|
||||||
|
this step.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Generate your NixOS configuration:</para>
|
||||||
|
|
||||||
|
<screen>$ sudo `which nixos-generate-config` --root /mnt</screen>
|
||||||
|
|
||||||
|
<para>You'll probably want to edit the configuration files. Refer
|
||||||
|
to the <literal>nixos-generate-config</literal> step in <xref
|
||||||
|
linkend="sec-installation" /> for more information.</para>
|
||||||
|
|
||||||
|
<para>Consider setting up the NixOS bootloader to give you the
|
||||||
|
ability to boot on your existing Linux partition. For instance,
|
||||||
|
if you're using GRUB and your existing distribution is running
|
||||||
|
Ubuntu, you may want to add something like this to your
|
||||||
|
<literal>configuration.nix</literal>:</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
boot.loader.grub.extraEntries = ''
|
||||||
|
menuentry "Ubuntu" {
|
||||||
|
search --set=ubuntu --fs-uuid 3cc3e652-0c1f-4800-8451-033754f68e6e
|
||||||
|
configfile "($ubuntu)/boot/grub/grub.cfg"
|
||||||
|
}
|
||||||
|
'';</programlisting>
|
||||||
|
|
||||||
|
<para>(You can find the appropriate UUID for your partition in
|
||||||
|
<literal>/dev/disk/by-uuid</literal>)</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Create the <literal>nixbld</literal> group and user on your
|
||||||
|
original distribution:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo groupadd -g 30000 nixbld
|
||||||
|
$ sudo useradd -u 30000 -g nixbld -G nixbld nixbld</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Download/build/install NixOS:</para>
|
||||||
|
|
||||||
|
<warning><para>Once you complete this step, you might no longer be
|
||||||
|
able to boot on existing systems without the help of a
|
||||||
|
rescue USB drive or similar.</para></warning>
|
||||||
|
|
||||||
|
<screen>$ sudo PATH="$PATH" NIX_PATH="$NIX_PATH" `which nixos-install` --root /mnt</screen>
|
||||||
|
|
||||||
|
<para>Again, please refer to the <literal>nixos-install</literal>
|
||||||
|
step in <xref linkend="sec-installation" /> for more
|
||||||
|
information.</para>
|
||||||
|
|
||||||
|
<para>That should be it for installation to another partition!</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Optionally, you may want to clean up your non-NixOS distribution:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo userdel nixbld
|
||||||
|
$ sudo groupdel nixbld</screen>
|
||||||
|
|
||||||
|
<para>If you do not wish to keep the Nix package mananager
|
||||||
|
installed either, run something like <literal>sudo rm -rv
|
||||||
|
~/.nix-* /nix</literal> and remove the line that the Nix
|
||||||
|
installer added to your <literal>~/.profile</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<note><para>The following steps are only for installing NixOS in
|
||||||
|
place using
|
||||||
|
<literal>NIXOS_LUSTRATE</literal>:</para></note>
|
||||||
|
|
||||||
|
<para>Generate your NixOS configuration:</para>
|
||||||
|
|
||||||
|
<screen>$ sudo `which nixos-generate-config` --root /</screen>
|
||||||
|
|
||||||
|
<para>Note that this will place the generated configuration files
|
||||||
|
in <literal>/etc/nixos</literal>. You'll probably want to edit
|
||||||
|
the configuration files. Refer to the
|
||||||
|
<literal>nixos-generate-config</literal> step in <xref
|
||||||
|
linkend="sec-installation" /> for more information.</para>
|
||||||
|
|
||||||
|
<para>You'll likely want to set a root password for your first boot
|
||||||
|
using the configuration files because you won't have a chance
|
||||||
|
to enter a password until after you reboot. You can initalize
|
||||||
|
the root password to an empty one with this line: (and of course
|
||||||
|
don't forget to set one once you've rebooted or to lock the
|
||||||
|
account with <literal>sudo passwd -l root</literal> if you use
|
||||||
|
<literal>sudo</literal>)</para>
|
||||||
|
|
||||||
|
<programlisting>users.extraUsers.root.initialHashedPassword = "";</programlisting>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Build the NixOS closure and install it in the
|
||||||
|
<literal>system</literal> profile:</para>
|
||||||
|
|
||||||
|
<screen>$ nix-env -p /nix/var/nix/profiles/system -f '<nixpkgs/nixos>' -I nixos-config=/etc/nixos/configuration.nix -iA system</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Change ownership of the <literal>/nix</literal> tree to root
|
||||||
|
(since your Nix install was probably single user):</para>
|
||||||
|
|
||||||
|
<screen>$ sudo chown -R 0.0 /nix</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Set up the <literal>/etc/NIXOS</literal> and
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> files:</para>
|
||||||
|
|
||||||
|
<para><literal>/etc/NIXOS</literal> officializes that this is now a
|
||||||
|
NixOS partition (the bootup scripts require its presence).</para>
|
||||||
|
|
||||||
|
<para><literal>/etc/NIXOS_LUSTRATE</literal> tells the NixOS bootup
|
||||||
|
scripts to move <emphasis>everything</emphasis> that's in the
|
||||||
|
root partition to <literal>/old-root</literal>. This will move
|
||||||
|
your existing distribution out of the way in the very early
|
||||||
|
stages of the NixOS bootup. There are exceptions (we do need to
|
||||||
|
keep NixOS there after all), so the NixOS lustrate process will
|
||||||
|
not touch:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>The <literal>/nix</literal>
|
||||||
|
directory</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>The <literal>/boot</literal>
|
||||||
|
directory</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>Any file or directory listed in
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> (one per
|
||||||
|
line)</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>Let's create the files:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo touch /etc/NIXOS
|
||||||
|
$ sudo touch /etc/NIXOS_LUSTRATE</screen>
|
||||||
|
|
||||||
|
<para>Let's also make sure the NixOS configuration files are kept
|
||||||
|
once we reboot on NixOS:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ echo etc/nixos | sudo tee -a /etc/NIXOS_LUSTRATE</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Finally, move the <literal>/boot</literal> directory of your
|
||||||
|
current distribution out of the way (the lustrate process will
|
||||||
|
take care of the rest once you reboot, but this one must be
|
||||||
|
moved out now because NixOS needs to install its own boot
|
||||||
|
files:</para>
|
||||||
|
|
||||||
|
<warning><para>Once you complete this step, your current
|
||||||
|
distribution will no longer be bootable! If you didn't get
|
||||||
|
all the NixOS configuration right, especially those
|
||||||
|
settings pertaining to boot loading and root partition,
|
||||||
|
NixOS may not be bootable either. Have a USB rescue device
|
||||||
|
ready in case this happens. </para></warning>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ sudo mv -v /boot /boot.bak &&
|
||||||
|
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration boot</screen>
|
||||||
|
|
||||||
|
<para>Cross your fingers, reboot, hopefully you should get a NixOS
|
||||||
|
prompt!</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>If for some reason you want to revert to the old
|
||||||
|
distribution, you'll need to boot on a USB rescue disk and do
|
||||||
|
something along these lines:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# mkdir root
|
||||||
|
# mount /dev/sdaX root
|
||||||
|
# mkdir root/nixos-root
|
||||||
|
# mv -v root/* root/nixos-root/
|
||||||
|
# mv -v root/nixos-root/old-root/* root/
|
||||||
|
# mv -v root/boot.bak root/boot # We had renamed this by hand earlier
|
||||||
|
# umount root
|
||||||
|
# reboot</screen>
|
||||||
|
|
||||||
|
<para>This may work as is or you might also need to reinstall the
|
||||||
|
boot loader</para>
|
||||||
|
|
||||||
|
<para>And of course, if you're happy with NixOS and no longer need
|
||||||
|
the old distribution:</para>
|
||||||
|
|
||||||
|
<screen>sudo rm -rf /old-root</screen>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>It's also worth noting that this whole process can be
|
||||||
|
automated. This is especially useful for Cloud VMs, where
|
||||||
|
provider do not provide NixOS. For instance, <link
|
||||||
|
xlink:href="https://github.com/elitak/nixos-infect">nixos-infect</link>
|
||||||
|
uses the lustrate process to convert Digital Ocean droplets to
|
||||||
|
NixOS from other distributions automatically.</para>
|
||||||
|
</listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</section>
|
@ -401,5 +401,6 @@ drive (here <filename>/dev/sda</filename>). <xref linkend="ex-config"
|
|||||||
<xi:include href="installing-usb.xml" />
|
<xi:include href="installing-usb.xml" />
|
||||||
<xi:include href="installing-pxe.xml" />
|
<xi:include href="installing-pxe.xml" />
|
||||||
<xi:include href="installing-virtualbox-guest.xml" />
|
<xi:include href="installing-virtualbox-guest.xml" />
|
||||||
|
<xi:include href="installing-from-other-distro.xml" />
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
119
nixos/doc/manual/man-nixos-enter.xml
Normal file
119
nixos/doc/manual/man-nixos-enter.xml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle><command>nixos-enter</command></refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
<refmiscinfo class="source">NixOS</refmiscinfo>
|
||||||
|
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname><command>nixos-enter</command></refname>
|
||||||
|
<refpurpose>run a command in a NixOS chroot environment</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>nixos-enter</command>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--root</option></arg>
|
||||||
|
<replaceable>root</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--system</option></arg>
|
||||||
|
<replaceable>system</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>-c</option></arg>
|
||||||
|
<replaceable>shell-command</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--help</option></arg>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<arg choice='plain'><option>--</option></arg>
|
||||||
|
<replaceable>arguments</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
|
<para>This command runs a command in a NixOS chroot environment, that
|
||||||
|
is, in a filesystem hierarchy previously prepared using
|
||||||
|
<command>nixos-install</command>.</para>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Options</title>
|
||||||
|
|
||||||
|
<para>This command accepts the following options:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--root</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The path to the NixOS system you want to enter. It defaults to <filename>/mnt</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--system</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The NixOS system configuration to use. It defaults to
|
||||||
|
<filename>/nix/var/nix/profiles/system</filename>. You can enter
|
||||||
|
a previous NixOS configuration by specifying a path such as
|
||||||
|
<filename>/nix/var/nix/profiles/system-106-link</filename>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--command</option></term>
|
||||||
|
<term><option>-c</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The bash command to execute.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Interpret the remaining arguments as the program
|
||||||
|
name and arguments to be invoked. The program is not executed in a
|
||||||
|
shell.</para></listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
|
||||||
|
<refsection><title>Examples</title>
|
||||||
|
|
||||||
|
<para>Start an interactive shell in the NixOS installation in
|
||||||
|
<filename>/mnt</filename>:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter /mnt
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>Run a shell command:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter -c 'ls -l /; cat /proc/mounts'
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>Run a non-shell command:</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
# nixos-enter -- cat /proc/mounts
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
|
</refentry>
|
@ -26,8 +26,8 @@
|
|||||||
<replaceable>root</replaceable>
|
<replaceable>root</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'><option>--closure</option></arg>
|
<arg choice='plain'><option>--system</option></arg>
|
||||||
<replaceable>closure</replaceable>
|
<replaceable>path</replaceable>
|
||||||
</arg>
|
</arg>
|
||||||
<arg>
|
<arg>
|
||||||
<arg choice='plain'><option>--no-channel-copy</option></arg>
|
<arg choice='plain'><option>--no-channel-copy</option></arg>
|
||||||
@ -118,7 +118,7 @@ it.</para>
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--closure</option></term>
|
<term><option>--system</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
|
<para>If this option is provided, <command>nixos-install</command> will install the specified closure
|
||||||
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>
|
rather than attempt to build one from <filename>/mnt/etc/nixos/configuration.nix</filename>.</para>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</author>
|
</author>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2007-2015</year>
|
<year>2007-2018</year>
|
||||||
<holder>Eelco Dolstra</holder>
|
<holder>Eelco Dolstra</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
@ -25,6 +25,7 @@
|
|||||||
<xi:include href="man-nixos-build-vms.xml" />
|
<xi:include href="man-nixos-build-vms.xml" />
|
||||||
<xi:include href="man-nixos-generate-config.xml" />
|
<xi:include href="man-nixos-generate-config.xml" />
|
||||||
<xi:include href="man-nixos-install.xml" />
|
<xi:include href="man-nixos-install.xml" />
|
||||||
|
<xi:include href="man-nixos-enter.xml" />
|
||||||
<xi:include href="man-nixos-option.xml" />
|
<xi:include href="man-nixos-option.xml" />
|
||||||
<xi:include href="man-nixos-rebuild.xml" />
|
<xi:include href="man-nixos-rebuild.xml" />
|
||||||
<xi:include href="man-nixos-version.xml" />
|
<xi:include href="man-nixos-version.xml" />
|
||||||
|
@ -18,6 +18,25 @@
|
|||||||
has the following highlights: </para>
|
has the following highlights: </para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Nix now defaults to 2.0; see its
|
||||||
|
<link xlink:href="https://nixos.org/nix/manual/#ssec-relnotes-2.0">release notes</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Linux kernel defaults to the 4.14 branch (it was 4.9).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
GCC defaults to 7.x (it was 6.x).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
MariaDB 10.2, updated from 10.1, is now the default MySQL implementation. While upgrading a few changes
|
MariaDB 10.2, updated from 10.1, is now the default MySQL implementation. While upgrading a few changes
|
||||||
@ -181,7 +200,7 @@ following incompatible changes:</para>
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>lib.addPassthru drv passthru</literal> is removed. Use <literal>lib.extendDerivation true passthru drv</literal> instead. <emphasis role="strong">TODO: actually remove it before branching 18.03 off.</emphasis>
|
<literal>lib.addPassthru drv passthru</literal> is removed. Use <literal>lib.extendDerivation true passthru drv</literal> instead.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -244,6 +263,65 @@ following incompatible changes:</para>
|
|||||||
<link xlink:href="http://borgbackup.readthedocs.io/en/stable/usage/upgrade.html#attic-and-borg-0-xx-to-borg-1-x">here</link>.
|
<link xlink:href="http://borgbackup.readthedocs.io/en/stable/usage/upgrade.html#attic-and-borg-0-xx-to-borg-1-x">here</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The Piwik analytics software was renamed to Matomo:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>The package <literal>pkgs.piwik</literal> was renamed to <literal>pkgs.matomo</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>The service <literal>services.piwik</literal> was renamed to <literal>services.matomo</literal>.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The data directory <filename>/var/lib/piwik</filename> was renamed to <filename>/var/lib/matomo</filename>.
|
||||||
|
All files will be moved automatically on first startup, but you might need to adjust your backup scripts.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The default <option>serverName</option> for the nginx configuration changed from
|
||||||
|
<literal>piwik.${config.networking.hostName}</literal> to
|
||||||
|
<literal>matomo.${config.networking.hostName}.${config.networking.domain}</literal>
|
||||||
|
if <option>config.networking.domain</option> is set,
|
||||||
|
<literal>matomo.${config.networking.hostName}</literal> if it is not set.
|
||||||
|
If you change your <option>serverName</option>, remember you'll need to update the
|
||||||
|
<literal>trustedHosts[]</literal> array in <filename>/var/lib/matomo/config/config.ini.php</filename>
|
||||||
|
as well.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>piwik</literal> user was renamed to <literal>matomo</literal>.
|
||||||
|
The service will adjust ownership automatically for files in the data directory.
|
||||||
|
If you use unix socket authentication, remember to give the new <literal>matomo</literal> user
|
||||||
|
access to the database and to change the <literal>username</literal> to <literal>matomo</literal>
|
||||||
|
in the <literal>[database]</literal> section of <filename>/var/lib/matomo/config/config.ini.php</filename>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If you named your database `piwik`, you might want to rename it to `matomo` to keep things clean,
|
||||||
|
but this is neither enforced nor required.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>nodejs-4_x</literal> is end-of-life.
|
||||||
|
<literal>nodejs-4_x</literal>, <literal>nodejs-slim-4_x</literal> and <literal>nodePackages_4_x</literal> are removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>pump.io</literal> NixOS module was removed.
|
||||||
|
It is now maintained as an
|
||||||
|
<link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -378,6 +456,13 @@ following incompatible changes:</para>
|
|||||||
and <literal>stopJob</literal> provide an optional <literal>$user</literal> argument for that purpose.
|
and <literal>stopJob</literal> provide an optional <literal>$user</literal> argument for that purpose.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Enabling bash completion on NixOS, <literal>programs.bash.enableCompletion</literal>, will now also enable
|
||||||
|
completion for the Nix command line tools by installing the
|
||||||
|
<link xlink:href="https://github.com/hedning/nix-bash-completions">nix-bash-completions</link> package.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -51,7 +51,7 @@ with lib;
|
|||||||
|
|
||||||
let format' = format; in let
|
let format' = format; in let
|
||||||
|
|
||||||
format = if (format' == "qcow2-compressed") then "qcow2" else format';
|
format = if format' == "qcow2-compressed" then "qcow2" else format';
|
||||||
|
|
||||||
compress = optionalString (format' == "qcow2-compressed") "-c";
|
compress = optionalString (format' == "qcow2-compressed") "-c";
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ let format' = format; in let
|
|||||||
|
|
||||||
nixpkgs = cleanSource pkgs.path;
|
nixpkgs = cleanSource pkgs.path;
|
||||||
|
|
||||||
|
# FIXME: merge with channel.nix / make-channel.nix.
|
||||||
channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
|
channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp -prd ${nixpkgs} $out/nixos
|
cp -prd ${nixpkgs} $out/nixos
|
||||||
@ -95,13 +96,16 @@ let format' = format; in let
|
|||||||
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
|
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
|
||||||
'';
|
'';
|
||||||
|
|
||||||
metaClosure = pkgs.writeText "meta" ''
|
binPath = with pkgs; makeBinPath (
|
||||||
${config.system.build.toplevel}
|
[ rsync
|
||||||
${config.nix.package.out}
|
utillinux
|
||||||
${channelSources}
|
parted
|
||||||
'';
|
e2fsprogs
|
||||||
|
lkl
|
||||||
prepareImageInputs = with pkgs; [ rsync utillinux parted e2fsprogs lkl fakeroot config.system.build.nixos-prepare-root ] ++ stdenv.initialPath;
|
config.system.build.nixos-install
|
||||||
|
config.system.build.nixos-enter
|
||||||
|
nix
|
||||||
|
] ++ stdenv.initialPath);
|
||||||
|
|
||||||
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
||||||
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
||||||
@ -109,8 +113,10 @@ let format' = format; in let
|
|||||||
sources = map (x: x.source) contents;
|
sources = map (x: x.source) contents;
|
||||||
targets = map (x: x.target) contents;
|
targets = map (x: x.target) contents;
|
||||||
|
|
||||||
|
closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; };
|
||||||
|
|
||||||
prepareImage = ''
|
prepareImage = ''
|
||||||
export PATH=${makeBinPath prepareImageInputs}
|
export PATH=${binPath}
|
||||||
|
|
||||||
# Yes, mkfs.ext4 takes different units in different contexts. Fun.
|
# Yes, mkfs.ext4 takes different units in different contexts. Fun.
|
||||||
sectorsToKilobytes() {
|
sectorsToKilobytes() {
|
||||||
@ -168,11 +174,15 @@ let format' = format; in let
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# TODO: Nix really likes to chown things it creates to its current user...
|
export HOME=$TMPDIR
|
||||||
fakeroot nixos-prepare-root $root ${channelSources} ${config.system.build.toplevel} closure
|
|
||||||
|
|
||||||
# fakeroot seems to always give the owner write permissions, which we do not want
|
# Provide a Nix database so that nixos-install can copy closures.
|
||||||
find $root/nix/store -mindepth 1 -maxdepth 1 -type f -o -type d | xargs chmod -R a-w
|
export NIX_STATE_DIR=$TMPDIR/state
|
||||||
|
nix-store --load-db < ${closureInfo}/registration
|
||||||
|
|
||||||
|
echo "running nixos-install..."
|
||||||
|
nixos-install --root $root --no-bootloader --no-root-passwd \
|
||||||
|
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
||||||
|
|
||||||
echo "copying staging root to image..."
|
echo "copying staging root to image..."
|
||||||
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
|
cptofs -p ${optionalString (partitionTableType != "none") "-P ${rootPartition}"} -t ${fsType} -i $diskImage $root/* /
|
||||||
@ -181,7 +191,6 @@ in pkgs.vmTools.runInLinuxVM (
|
|||||||
pkgs.runCommand name
|
pkgs.runCommand name
|
||||||
{ preVM = prepareImage;
|
{ preVM = prepareImage;
|
||||||
buildInputs = with pkgs; [ utillinux e2fsprogs dosfstools ];
|
buildInputs = with pkgs; [ utillinux e2fsprogs dosfstools ];
|
||||||
exportReferencesGraph = [ "closure" metaClosure ];
|
|
||||||
postVM = ''
|
postVM = ''
|
||||||
${if format == "raw" then ''
|
${if format == "raw" then ''
|
||||||
mv $diskImage $out/${filename}
|
mv $diskImage $out/${filename}
|
||||||
@ -194,6 +203,8 @@ in pkgs.vmTools.runInLinuxVM (
|
|||||||
memSize = 1024;
|
memSize = 1024;
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
|
export PATH=${binPath}:$PATH
|
||||||
|
|
||||||
rootDisk=${if partitionTableType != "none" then "/dev/vda${rootPartition}" else "/dev/vda"}
|
rootDisk=${if partitionTableType != "none" then "/dev/vda${rootPartition}" else "/dev/vda"}
|
||||||
|
|
||||||
# Some tools assume these exist
|
# Some tools assume these exist
|
||||||
@ -218,15 +229,8 @@ in pkgs.vmTools.runInLinuxVM (
|
|||||||
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
||||||
''}
|
''}
|
||||||
|
|
||||||
mount --rbind /dev $mountPoint/dev
|
|
||||||
mount --rbind /proc $mountPoint/proc
|
|
||||||
mount --rbind /sys $mountPoint/sys
|
|
||||||
|
|
||||||
# Set up core system link, GRUB, etc.
|
# Set up core system link, GRUB, etc.
|
||||||
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root $mountPoint -- /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
||||||
|
|
||||||
# TODO: figure out if I should activate, but for now I won't
|
|
||||||
# chroot $mountPoint /nix/var/nix/profiles/system/activate
|
|
||||||
|
|
||||||
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
|
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
|
||||||
rm -f $mountPoint/etc/machine-id
|
rm -f $mountPoint/etc/machine-id
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, perl, pathsFromGraph, xorriso, syslinux
|
{ stdenv, perl, closureInfo, xorriso, syslinux
|
||||||
|
|
||||||
, # The file name of the resulting ISO image.
|
, # The file name of the resulting ISO image.
|
||||||
isoName ? "cd.iso"
|
isoName ? "cd.iso"
|
||||||
@ -48,9 +48,9 @@ assert usbBootable -> isohybridMbrImage != "";
|
|||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = isoName;
|
name = isoName;
|
||||||
builder = ./make-iso9660-image.sh;
|
builder = ./make-iso9660-image.sh;
|
||||||
buildInputs = [perl xorriso syslinux];
|
buildInputs = [ xorriso syslinux ];
|
||||||
|
|
||||||
inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
|
inherit isoName bootable bootImage compressImage volumeID efiBootImage efiBootable isohybridMbrImage usbBootable;
|
||||||
|
|
||||||
# !!! should use XML.
|
# !!! should use XML.
|
||||||
sources = map (x: x.source) contents;
|
sources = map (x: x.source) contents;
|
||||||
@ -61,6 +61,5 @@ stdenv.mkDerivation {
|
|||||||
symlinks = map (x: x.symlink) storeContents;
|
symlinks = map (x: x.symlink) storeContents;
|
||||||
|
|
||||||
# For obtaining the closure of `storeContents'.
|
# For obtaining the closure of `storeContents'.
|
||||||
exportReferencesGraph =
|
closureInfo = closureInfo { rootPaths = map (x: x.object) storeContents; };
|
||||||
map (x: [("closure-" + baseNameOf x.object) x.object]) storeContents;
|
|
||||||
}
|
}
|
||||||
|
@ -72,16 +72,15 @@ done
|
|||||||
|
|
||||||
|
|
||||||
# Add the closures of the top-level store objects.
|
# Add the closures of the top-level store objects.
|
||||||
storePaths=$(perl $pathsFromGraph closure-*)
|
for i in $(< $closureInfo/store-paths); do
|
||||||
for i in $storePaths; do
|
|
||||||
addPath "${i:1}" "$i"
|
addPath "${i:1}" "$i"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# Also include a manifest of the closures in a format suitable for
|
# Also include a manifest of the closures in a format suitable for
|
||||||
# nix-store --load-db.
|
# nix-store --load-db.
|
||||||
if [ -n "$object" ]; then
|
if [[ ${#objects[*]} != 0 ]]; then
|
||||||
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
|
cp $closureInfo/registration nix-path-registration
|
||||||
addPath "nix-path-registration" "nix-path-registration"
|
addPath "nix-path-registration" "nix-path-registration"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, squashfsTools, perl, pathsFromGraph
|
{ stdenv, squashfsTools, closureInfo
|
||||||
|
|
||||||
, # The root directory of the squashfs filesystem is filled with the
|
, # The root directory of the squashfs filesystem is filled with the
|
||||||
# closures of the Nix store paths listed here.
|
# closures of the Nix store paths listed here.
|
||||||
@ -8,50 +8,18 @@
|
|||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "squashfs.img";
|
name = "squashfs.img";
|
||||||
|
|
||||||
nativeBuildInputs = [perl squashfsTools];
|
nativeBuildInputs = [ squashfsTools ];
|
||||||
|
|
||||||
# For obtaining the closure of `storeContents'.
|
|
||||||
exportReferencesGraph =
|
|
||||||
map (x: [("closure-" + baseNameOf x) x]) storeContents;
|
|
||||||
|
|
||||||
buildCommand =
|
buildCommand =
|
||||||
''
|
''
|
||||||
# Add the closures of the top-level store objects.
|
closureInfo=${closureInfo { rootPaths = storeContents; }}
|
||||||
storePaths=$(perl ${pathsFromGraph} closure-*)
|
|
||||||
|
|
||||||
# If a Hydra slave happens to have store paths with bad permissions/mtime,
|
|
||||||
# abort now so that they don't end up in ISO images in the channel.
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/32242
|
|
||||||
hasBadPaths=""
|
|
||||||
for path in $storePaths; do
|
|
||||||
if [ -h "$path" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
mtime=$(stat -c %Y "$path")
|
|
||||||
mode=$(stat -c %a "$path")
|
|
||||||
|
|
||||||
if [ "$mtime" != 1 ]; then
|
|
||||||
echo "Store path '$path' has an invalid mtime."
|
|
||||||
hasBadPaths=1
|
|
||||||
fi
|
|
||||||
if [ "$mode" != 444 ] && [ "$mode" != 555 ]; then
|
|
||||||
echo "Store path '$path' has invalid permissions ($mode)."
|
|
||||||
hasBadPaths=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -n "$hasBadPaths" ]; then
|
|
||||||
echo "You have bad paths in your store, please fix them."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Also include a manifest of the closures in a format suitable
|
# Also include a manifest of the closures in a format suitable
|
||||||
# for nix-store --load-db.
|
# for nix-store --load-db.
|
||||||
printRegistration=1 perl ${pathsFromGraph} closure-* > nix-path-registration
|
cp $closureInfo/registration nix-path-registration
|
||||||
|
|
||||||
# Generate the squashfs image.
|
# Generate the squashfs image.
|
||||||
mksquashfs nix-path-registration $storePaths $out \
|
mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
|
||||||
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
|
-keep-as-directory -all-root -b 1048576 -comp xz -Xdict-size 100%
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,13 @@ with lib;
|
|||||||
|
|
||||||
nixpkgs.config.packageOverrides = pkgs: {
|
nixpkgs.config.packageOverrides = pkgs: {
|
||||||
dbus = pkgs.dbus.override { x11Support = false; };
|
dbus = pkgs.dbus.override { x11Support = false; };
|
||||||
networkmanager_fortisslvpn = pkgs.networkmanager_fortisslvpn.override { withGnome = false; };
|
networkmanager-fortisslvpn = pkgs.networkmanager-fortisslvpn.override { withGnome = false; };
|
||||||
networkmanager_l2tp = pkgs.networkmanager_l2tp.override { withGnome = false; };
|
networkmanager-l2tp = pkgs.networkmanager-l2tp.override { withGnome = false; };
|
||||||
networkmanager_openconnect = pkgs.networkmanager_openconnect.override { withGnome = false; };
|
networkmanager-openconnect = pkgs.networkmanager-openconnect.override { withGnome = false; };
|
||||||
networkmanager_openvpn = pkgs.networkmanager_openvpn.override { withGnome = false; };
|
networkmanager-openvpn = pkgs.networkmanager-openvpn.override { withGnome = false; };
|
||||||
networkmanager_pptp = pkgs.networkmanager_pptp.override { withGnome = false; };
|
networkmanager-pptp = pkgs.networkmanager-pptp.override { withGnome = false; };
|
||||||
networkmanager_vpnc = pkgs.networkmanager_vpnc.override { withGnome = false; };
|
networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; };
|
||||||
networkmanager_iodine = pkgs.networkmanager_iodine.override { withGnome = false; };
|
networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; };
|
||||||
pinentry = pkgs.pinentry_ncurses;
|
pinentry = pkgs.pinentry_ncurses;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -529,6 +529,9 @@ in {
|
|||||||
|
|
||||||
system.activationScripts.users = stringAfter [ "stdio" ]
|
system.activationScripts.users = stringAfter [ "stdio" ]
|
||||||
''
|
''
|
||||||
|
install -m 0700 -d /root
|
||||||
|
install -m 0755 -d /home
|
||||||
|
|
||||||
${pkgs.perl}/bin/perl -w \
|
${pkgs.perl}/bin/perl -w \
|
||||||
-I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl \
|
-I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl \
|
||||||
-I${pkgs.perlPackages.JSON}/lib/perl5/site_perl \
|
-I${pkgs.perlPackages.JSON}/lib/perl5/site_perl \
|
||||||
|
30
nixos/modules/hardware/digitalbitbox.nix
Normal file
30
nixos/modules/hardware/digitalbitbox.nix
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.hardware.digitalbitbox;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.hardware.digitalbitbox = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enables udev rules for Digital Bitbox devices.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.digitalbitbox;
|
||||||
|
defaultText = "pkgs.digitalbitbox";
|
||||||
|
description = "The Digital Bitbox package to use. This can be used to install a package with udev rules that differ from the defaults.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.udev.packages = [ cfg.package ];
|
||||||
|
};
|
||||||
|
}
|
@ -34,10 +34,17 @@ in
|
|||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
hardware.opengl.enable = mkOption {
|
hardware.opengl.enable = mkOption {
|
||||||
description = "Whether this configuration requires OpenGL.";
|
description = ''
|
||||||
|
Whether to enable OpenGL drivers. This is needed to enable
|
||||||
|
OpenGL support in X11 systems, as well as for Wayland compositors
|
||||||
|
like sway, way-cooler and Weston. It is enabled by default
|
||||||
|
by the corresponding modules, so you do not usually have to
|
||||||
|
set it yourself, only if there is no module for your wayland
|
||||||
|
compositor of choice. See services.xserver.enable,
|
||||||
|
programs.sway.enable, and programs.way-cooler.enable.
|
||||||
|
'';
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
internal = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hardware.opengl.driSupport = mkOption {
|
hardware.opengl.driSupport = mkOption {
|
||||||
|
@ -69,7 +69,7 @@ with lib;
|
|||||||
in ''
|
in ''
|
||||||
mkdir -p /root/Desktop
|
mkdir -p /root/Desktop
|
||||||
ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
|
ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
|
||||||
cp ${pkgs.gnome3.gnome_terminal}/share/applications/gnome-terminal.desktop /root/Desktop/gnome-terminal.desktop
|
cp ${pkgs.gnome3.gnome-terminal}/share/applications/gnome-terminal.desktop /root/Desktop/gnome-terminal.desktop
|
||||||
chmod a+rx /root/Desktop/gnome-terminal.desktop
|
chmod a+rx /root/Desktop/gnome-terminal.desktop
|
||||||
cp ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
|
cp ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
|
||||||
chmod a+rx /root/Desktop/gparted.desktop
|
chmod a+rx /root/Desktop/gparted.desktop
|
||||||
|
@ -331,8 +331,7 @@ in
|
|||||||
config.system.build.toplevel.drvPath;
|
config.system.build.toplevel.drvPath;
|
||||||
|
|
||||||
# Create the squashfs image that contains the Nix store.
|
# Create the squashfs image that contains the Nix store.
|
||||||
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
|
system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
|
||||||
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
|
|
||||||
storeContents = config.isoImage.storeContents;
|
storeContents = config.isoImage.storeContents;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -383,11 +382,8 @@ in
|
|||||||
boot.loader.timeout = 10;
|
boot.loader.timeout = 10;
|
||||||
|
|
||||||
# Create the ISO image.
|
# Create the ISO image.
|
||||||
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
|
system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({
|
||||||
inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
|
|
||||||
|
|
||||||
inherit (config.isoImage) isoName compressImage volumeID contents;
|
inherit (config.isoImage) isoName compressImage volumeID contents;
|
||||||
|
|
||||||
bootable = true;
|
bootable = true;
|
||||||
bootImage = "/isolinux/isolinux.bin";
|
bootImage = "/isolinux/isolinux.bin";
|
||||||
} // optionalAttrs config.isoImage.makeUsbBootable {
|
} // optionalAttrs config.isoImage.makeUsbBootable {
|
||||||
|
@ -67,7 +67,7 @@ with lib;
|
|||||||
|
|
||||||
# Create the squashfs image that contains the Nix store.
|
# Create the squashfs image that contains the Nix store.
|
||||||
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
|
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
|
||||||
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
|
inherit (pkgs) stdenv squashfsTools closureInfo;
|
||||||
storeContents = config.netboot.storeContents;
|
storeContents = config.netboot.storeContents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
x86_64-linux = "/nix/store/gy4yv67gv3j6in0lalw37j353zdmfcwm-nix-1.11.16";
|
x86_64-linux = "/nix/store/6p2gambjac7xdkd2a7w1dsxdk1q5cq4d-nix-2.0";
|
||||||
i686-linux = "/nix/store/ifmyq5ryfxhhrzh62hiq65xyz1fwffga-nix-1.11.16";
|
i686-linux = "/nix/store/zznnaijjk3nwx0cmpczxsvngmqzhl7r4-nix-2.0";
|
||||||
aarch64-linux = "/nix/store/y9mfv3sx75mbfibf1zna1kq9v98fk2nb-nix-1.11.16";
|
aarch64-linux = "/nix/store/ci96w9kxfkmlc7x2vwqiz4da0r6abxnq-nix-2.0";
|
||||||
x86_64-darwin = "/nix/store/hwpp7kia2f0in5ns2hiw41q38k30jpj2-nix-1.11.16";
|
x86_64-darwin = "/nix/store/xmi4fylvx4qc79ji9v5q3zfy9vfdy4sv-nix-2.0";
|
||||||
}
|
}
|
||||||
|
60
nixos/modules/installer/tools/nixos-enter.sh
Normal file
60
nixos/modules/installer/tools/nixos-enter.sh
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#! @shell@
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Re-exec ourselves in a private mount namespace so that our bind
|
||||||
|
# mounts get cleaned up automatically.
|
||||||
|
if [ -z "$NIXOS_ENTER_REEXEC" ]; then
|
||||||
|
export NIXOS_ENTER_REEXEC=1
|
||||||
|
if [ "$(id -u)" != 0 ]; then
|
||||||
|
extraFlags="-r"
|
||||||
|
fi
|
||||||
|
exec unshare --fork --mount --uts --mount-proc --pid $extraFlags -- "$0" "$@"
|
||||||
|
else
|
||||||
|
mount --make-rprivate /
|
||||||
|
fi
|
||||||
|
|
||||||
|
mountPoint=/mnt
|
||||||
|
system=/nix/var/nix/profiles/system
|
||||||
|
command=($system/sw/bin/bash "--login")
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
i="$1"; shift 1
|
||||||
|
case "$i" in
|
||||||
|
--root)
|
||||||
|
mountPoint="$1"; shift 1
|
||||||
|
;;
|
||||||
|
--system)
|
||||||
|
system="$1"; shift 1
|
||||||
|
;;
|
||||||
|
--help)
|
||||||
|
exec man nixos-enter
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
--command|-c)
|
||||||
|
command=($system/sw/bin/bash "-c" "$1")
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
command=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$0: unknown option \`$i'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -e $mountPoint/etc/NIXOS ]]; then
|
||||||
|
echo "$0: '$mountPoint' is not a NixOS installation" >&2
|
||||||
|
exit 126
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -m 0755 -p "$mountPoint/dev"
|
||||||
|
mount --rbind /dev "$mountPoint/dev"
|
||||||
|
|
||||||
|
# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
|
||||||
|
LOCALE_ARCHIVE=$system/sw/lib/locale/locale-archive chroot "$mountPoint" "$system/activate" >&2 || true
|
||||||
|
|
||||||
|
exec chroot "$mountPoint" "${command[@]}"
|
@ -1,35 +1,23 @@
|
|||||||
#! @shell@
|
#! @shell@
|
||||||
|
|
||||||
# - make Nix store etc.
|
set -e
|
||||||
# - copy closure of Nix to target device
|
shopt -s nullglob
|
||||||
# - register validity
|
|
||||||
# - with a chroot to the target device:
|
export PATH=@path@:$PATH
|
||||||
# * nix-env -p /nix/var/nix/profiles/system -i <nix-expr for the configuration>
|
|
||||||
# * install the boot loader
|
|
||||||
|
|
||||||
# Ensure a consistent umask.
|
# Ensure a consistent umask.
|
||||||
umask 0022
|
umask 0022
|
||||||
|
|
||||||
# Re-exec ourselves in a private mount namespace so that our bind
|
|
||||||
# mounts get cleaned up automatically.
|
|
||||||
if [ "$(id -u)" = 0 ]; then
|
|
||||||
if [ -z "$NIXOS_INSTALL_REEXEC" ]; then
|
|
||||||
export NIXOS_INSTALL_REEXEC=1
|
|
||||||
exec unshare --mount --uts -- "$0" "$@"
|
|
||||||
else
|
|
||||||
mount --make-rprivate /
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse the command line for the -I flag
|
# Parse the command line for the -I flag
|
||||||
extraBuildFlags=()
|
extraBuildFlags=()
|
||||||
chrootCommand=(/run/current-system/sw/bin/bash)
|
|
||||||
buildUsersGroup="nixbld"
|
mountPoint=/mnt
|
||||||
|
channelPath=
|
||||||
|
|
||||||
while [ "$#" -gt 0 ]; do
|
while [ "$#" -gt 0 ]; do
|
||||||
i="$1"; shift 1
|
i="$1"; shift 1
|
||||||
case "$i" in
|
case "$i" in
|
||||||
--max-jobs|-j|--cores|-I)
|
--max-jobs|-j|--cores|-I|--substituters)
|
||||||
j="$1"; shift 1
|
j="$1"; shift 1
|
||||||
extraBuildFlags+=("$i" "$j")
|
extraBuildFlags+=("$i" "$j")
|
||||||
;;
|
;;
|
||||||
@ -41,9 +29,11 @@ while [ "$#" -gt 0 ]; do
|
|||||||
--root)
|
--root)
|
||||||
mountPoint="$1"; shift 1
|
mountPoint="$1"; shift 1
|
||||||
;;
|
;;
|
||||||
--closure)
|
--system|--closure)
|
||||||
closure="$1"; shift 1
|
system="$1"; shift 1
|
||||||
buildUsersGroup=""
|
;;
|
||||||
|
--channel)
|
||||||
|
channelPath="$1"; shift 1
|
||||||
;;
|
;;
|
||||||
--no-channel-copy)
|
--no-channel-copy)
|
||||||
noChannelCopy=1
|
noChannelCopy=1
|
||||||
@ -57,17 +47,13 @@ while [ "$#" -gt 0 ]; do
|
|||||||
--show-trace)
|
--show-trace)
|
||||||
extraBuildFlags+=("$i")
|
extraBuildFlags+=("$i")
|
||||||
;;
|
;;
|
||||||
--chroot)
|
|
||||||
runChroot=1
|
|
||||||
if [[ "$@" != "" ]]; then
|
|
||||||
chrootCommand=("$@")
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
--help)
|
--help)
|
||||||
exec man nixos-install
|
exec man nixos-install
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
--debug)
|
||||||
|
set -x
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "$0: unknown option \`$i'"
|
echo "$0: unknown option \`$i'"
|
||||||
exit 1
|
exit 1
|
||||||
@ -75,132 +61,83 @@ while [ "$#" -gt 0 ]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
set -e
|
|
||||||
shopt -s nullglob
|
|
||||||
|
|
||||||
if test -z "$mountPoint"; then
|
|
||||||
mountPoint=/mnt
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! test -e "$mountPoint"; then
|
if ! test -e "$mountPoint"; then
|
||||||
echo "mount point $mountPoint doesn't exist"
|
echo "mount point $mountPoint doesn't exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the path of the NixOS configuration file.
|
# Get the path of the NixOS configuration file.
|
||||||
if test -z "$NIXOS_CONFIG"; then
|
if [[ -z $NIXOS_CONFIG ]]; then
|
||||||
NIXOS_CONFIG=/etc/nixos/configuration.nix
|
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e "$mountPoint/$NIXOS_CONFIG" ] && [ -z "$closure" ]; then
|
if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
|
||||||
echo "configuration file $mountPoint/$NIXOS_CONFIG doesn't exist"
|
echo "$0: \$NIXOS_CONFIG is not an absolute path"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ! -e $NIXOS_CONFIG && -z $system ]]; then
|
||||||
# Builds will use users that are members of this group
|
echo "configuration file $NIXOS_CONFIG doesn't exist"
|
||||||
extraBuildFlags+=(--option "build-users-group" "$buildUsersGroup")
|
|
||||||
|
|
||||||
# Inherit binary caches from the host
|
|
||||||
# TODO: will this still work with Nix 1.12 now that it has no perl? Probably not...
|
|
||||||
binary_caches="$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};')"
|
|
||||||
extraBuildFlags+=(--option "binary-caches" "$binary_caches")
|
|
||||||
|
|
||||||
# We only need nixpkgs in the path if we don't already have a system closure to install
|
|
||||||
if [[ -z "$closure" ]]; then
|
|
||||||
nixpkgs="$(readlink -f "$(nix-instantiate --find-file nixpkgs)")"
|
|
||||||
export NIX_PATH="nixpkgs=$nixpkgs:nixos-config=$mountPoint/$NIXOS_CONFIG"
|
|
||||||
fi
|
|
||||||
unset NIXOS_CONFIG
|
|
||||||
|
|
||||||
# These get created in nixos-prepare-root as well, but we want to make sure they're here in case we're
|
|
||||||
# running with --chroot. TODO: --chroot should just be split into a separate tool.
|
|
||||||
mkdir -m 0755 -p "$mountPoint/dev" "$mountPoint/proc" "$mountPoint/sys"
|
|
||||||
|
|
||||||
# Set up some bind mounts we'll want regardless of chroot or not
|
|
||||||
mount --rbind /dev "$mountPoint/dev"
|
|
||||||
mount --rbind /proc "$mountPoint/proc"
|
|
||||||
mount --rbind /sys "$mountPoint/sys"
|
|
||||||
|
|
||||||
# If we asked for a chroot, that means we're not actually installing anything (yeah I was confused too)
|
|
||||||
# and we just want to run a command in the context of a $mountPoint that we're assuming has already been
|
|
||||||
# set up by a previous nixos-install invocation. In that case we set up some remaining bind mounts and
|
|
||||||
# exec the requested command, skipping the rest of the installation procedure.
|
|
||||||
if [ -n "$runChroot" ]; then
|
|
||||||
mount -t tmpfs -o "mode=0755" none $mountPoint/run
|
|
||||||
rm -rf $mountPoint/var/run
|
|
||||||
ln -s /run $mountPoint/var/run
|
|
||||||
for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done
|
|
||||||
for f in /etc/passwd /etc/group; do touch $mountPoint/$f; [ -f "$f" ] && mount --rbind -o ro $f $mountPoint/$f; done
|
|
||||||
|
|
||||||
if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then
|
|
||||||
echo "$0: installation not finished; cannot chroot into installation directory"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
|
||||||
ln -s /nix/var/nix/profiles/system $mountPoint/run/current-system
|
|
||||||
exec chroot $mountPoint "${chrootCommand[@]}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# A place to drop temporary closures
|
# A place to drop temporary stuff.
|
||||||
trap "rm -rf $tmpdir" EXIT
|
trap "rm -rf $tmpdir" EXIT
|
||||||
tmpdir="$(mktemp -d)"
|
tmpdir="$(mktemp -d)"
|
||||||
|
|
||||||
# Build a closure (on the host; we then copy it into the guest)
|
sub="auto?trusted=1"
|
||||||
function closure() {
|
|
||||||
nix-build "${extraBuildFlags[@]}" --no-out-link -E "with import <nixpkgs> {}; runCommand \"closure\" { exportReferencesGraph = [ \"x\" (buildEnv { name = \"env\"; paths = [ ($1) stdenv ]; }) ]; } \"cp x \$out\""
|
|
||||||
}
|
|
||||||
|
|
||||||
system_closure="$tmpdir/system.closure"
|
# Build the system configuration in the target filesystem.
|
||||||
# Use a FIFO for piping nix-store --export into nix-store --import, saving disk
|
if [[ -z $system ]]; then
|
||||||
# I/O and space. nix-store --import is run by nixos-prepare-root.
|
echo "building the configuration in $NIXOS_CONFIG..."
|
||||||
mkfifo $system_closure
|
outLink="$tmpdir/system"
|
||||||
|
nix build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
|
||||||
if [ -z "$closure" ]; then
|
--extra-substituters "$sub" \
|
||||||
expr="(import <nixpkgs/nixos> {}).system"
|
-f '<nixpkgs/nixos>' system -I "nixos-config=$NIXOS_CONFIG"
|
||||||
system_root="$(nix-build -E "$expr")"
|
system=$(readlink -f $outLink)
|
||||||
system_closure="$(closure "$expr")"
|
|
||||||
else
|
|
||||||
system_root=$closure
|
|
||||||
# Create a temporary file ending in .closure (so nixos-prepare-root knows to --import it) to transport the store closure
|
|
||||||
# to the filesytem we're preparing. Also delete it on exit!
|
|
||||||
# Run in background to avoid blocking while trying to write to the FIFO
|
|
||||||
# $system_closure refers to
|
|
||||||
nix-store --export $(nix-store -qR $closure) > $system_closure &
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
channel_root="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
|
# Set the system profile to point to the configuration. TODO: combine
|
||||||
channel_closure="$tmpdir/channel.closure"
|
# this with the previous step once we have a nix-env replacement with
|
||||||
nix-store --export $channel_root > $channel_closure
|
# a progress bar.
|
||||||
|
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" \
|
||||||
|
--extra-substituters "$sub" \
|
||||||
|
-p $mountPoint/nix/var/nix/profiles/system --set "$system"
|
||||||
|
|
||||||
# Populate the target root directory with the basics
|
# Copy the NixOS/Nixpkgs sources to the target as the initial contents
|
||||||
@prepare_root@/bin/nixos-prepare-root "$mountPoint" "$channel_root" "$system_root" @nixClosure@ "$system_closure" "$channel_closure"
|
# of the NixOS channel.
|
||||||
|
if [[ -z $noChannelCopy ]]; then
|
||||||
|
if [[ -z $channelPath ]]; then
|
||||||
|
channelPath="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
|
||||||
|
fi
|
||||||
|
if [[ -n $channelPath ]]; then
|
||||||
|
echo "copying channel..."
|
||||||
|
mkdir -p $mountPoint/nix/var/nix/profiles/per-user/root
|
||||||
|
nix-env --store "$mountPoint" "${extraBuildFlags[@]}" --extra-substituters "$sub" \
|
||||||
|
-p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet
|
||||||
|
install -m 0700 -d $mountPoint/root/.nix-defexpr
|
||||||
|
ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# nixos-prepare-root doesn't currently do anything with file ownership, so we set it up here instead
|
# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
|
||||||
chown @root_uid@:@nixbld_gid@ $mountPoint/nix/store
|
mkdir -m 0755 -p "$mountPoint/etc"
|
||||||
|
touch "$mountPoint/etc/NIXOS"
|
||||||
|
|
||||||
|
|
||||||
# Grub needs an mtab.
|
|
||||||
ln -sfn /proc/mounts $mountPoint/etc/mtab
|
|
||||||
|
|
||||||
# Switch to the new system configuration. This will install Grub with
|
# Switch to the new system configuration. This will install Grub with
|
||||||
# a menu default pointing at the kernel/initrd/etc of the new
|
# a menu default pointing at the kernel/initrd/etc of the new
|
||||||
# configuration.
|
# configuration.
|
||||||
echo "finalising the installation..."
|
if [[ -z $noBootLoader ]]; then
|
||||||
if [ -z "$noBootLoader" ]; then
|
echo "installing the boot loader..."
|
||||||
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint \
|
# Grub needs an mtab.
|
||||||
/nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
ln -sfn /proc/mounts $mountPoint/etc/mtab
|
||||||
|
NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$mountPoint" -- /run/current-system/bin/switch-to-configuration boot
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run the activation script.
|
# Ask the user to set a root password, but only if the passwd command
|
||||||
chroot $mountPoint /nix/var/nix/profiles/system/activate
|
# exists (i.e. when mutable user accounts are enabled).
|
||||||
|
if [[ -z $noRootPasswd ]] && [ -t 0 ]; then
|
||||||
|
nixos-enter --root "$mountPoint" -c '[[ -e /nix/var/nix/profiles/system/sw/bin/passwd ]] && echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd'
|
||||||
# Ask the user to set a root password.
|
|
||||||
if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/bin/passwd ] && [ -t 0 ]; then
|
|
||||||
echo "setting root password..."
|
|
||||||
chroot $mountPoint /run/wrappers/bin/passwd
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "installation finished!"
|
echo "installation finished!"
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
#! @shell@
|
|
||||||
|
|
||||||
# This script's goal is to perform all "static" setup of a filesystem structure from pre-built store paths. Everything
|
|
||||||
# in here should run in a non-root context and inside a Nix builder. It's designed primarily to be called from image-
|
|
||||||
# building scripts and from nixos-install, but because it makes very few assumptions about the context in which it runs,
|
|
||||||
# it could be useful in other contexts as well.
|
|
||||||
#
|
|
||||||
# Current behavior:
|
|
||||||
# - set up basic filesystem structure
|
|
||||||
# - make Nix store etc.
|
|
||||||
# - copy Nix, system, channel, and misceallaneous closures to target Nix store
|
|
||||||
# - register validity of all paths in the target store
|
|
||||||
# - set up channel and system profiles
|
|
||||||
|
|
||||||
# Ensure a consistent umask.
|
|
||||||
umask 0022
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
mountPoint="$1"
|
|
||||||
channel="$2"
|
|
||||||
system="$3"
|
|
||||||
shift 3
|
|
||||||
closures="$@"
|
|
||||||
|
|
||||||
PATH="@coreutils@/bin:@nix@/bin:@perl@/bin:@utillinux@/bin:@rsync@/bin"
|
|
||||||
|
|
||||||
if ! test -e "$mountPoint"; then
|
|
||||||
echo "mount point $mountPoint doesn't exist"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a few of the standard directories in the target root directory.
|
|
||||||
install -m 0755 -d $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home
|
|
||||||
install -m 01777 -d $mountPoint/tmp
|
|
||||||
install -m 0755 -d $mountPoint/tmp/root
|
|
||||||
install -m 0755 -d $mountPoint/var
|
|
||||||
install -m 0700 -d $mountPoint/root
|
|
||||||
|
|
||||||
ln -sf /run $mountPoint/var/run
|
|
||||||
|
|
||||||
# Create the necessary Nix directories on the target device
|
|
||||||
install -m 0755 -d \
|
|
||||||
$mountPoint/nix/var/nix/gcroots \
|
|
||||||
$mountPoint/nix/var/nix/temproots \
|
|
||||||
$mountPoint/nix/var/nix/userpool \
|
|
||||||
$mountPoint/nix/var/nix/profiles \
|
|
||||||
$mountPoint/nix/var/nix/db \
|
|
||||||
$mountPoint/nix/var/log/nix/drvs
|
|
||||||
|
|
||||||
install -m 1775 -d $mountPoint/nix/store
|
|
||||||
|
|
||||||
# All Nix operations below should operate on our target store, not /nix/store.
|
|
||||||
# N.B: this relies on Nix 1.12 or higher
|
|
||||||
export NIX_REMOTE=local?root=$mountPoint
|
|
||||||
|
|
||||||
# Copy our closures to the Nix store on the target mount point, unless they're already there.
|
|
||||||
for i in $closures; do
|
|
||||||
# We support closures both in the format produced by `nix-store --export` and by `exportReferencesGraph`,
|
|
||||||
# mostly because there doesn't seem to be a single format that can be produced outside of a nix build and
|
|
||||||
# inside one. See https://github.com/NixOS/nix/issues/1242 for more discussion.
|
|
||||||
if [[ "$i" =~ \.closure$ ]]; then
|
|
||||||
echo "importing serialized closure $i to $mountPoint..."
|
|
||||||
nix-store --import < $i
|
|
||||||
else
|
|
||||||
# There has to be a better way to do this, right?
|
|
||||||
echo "copying closure $i to $mountPoint..."
|
|
||||||
for j in $(perl @pathsFromGraph@ $i); do
|
|
||||||
echo " $j... "
|
|
||||||
rsync -a $j $mountPoint/nix/store/
|
|
||||||
done
|
|
||||||
|
|
||||||
nix-store --option build-users-group root --register-validity < $i
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create the required /bin/sh symlink; otherwise lots of things
|
|
||||||
# (notably the system() function) won't work.
|
|
||||||
if [ ! -x $mountPoint/@shell@ ]; then
|
|
||||||
echo "Error: @shell@ wasn't included in the closure" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
install -m 0755 -d $mountPoint/bin
|
|
||||||
ln -sf @shell@ $mountPoint/bin/sh
|
|
||||||
|
|
||||||
echo "setting the system closure to '$system'..."
|
|
||||||
nix-env "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/system --set "$system"
|
|
||||||
|
|
||||||
ln -sfn /nix/var/nix/profiles/system $mountPoint/run/current-system
|
|
||||||
|
|
||||||
# Copy the NixOS/Nixpkgs sources to the target as the initial contents of the NixOS channel.
|
|
||||||
install -m 0755 -d $mountPoint/nix/var/nix/profiles
|
|
||||||
install -m 1777 -d $mountPoint/nix/var/nix/profiles/per-user
|
|
||||||
install -m 0755 -d $mountPoint/nix/var/nix/profiles/per-user/root
|
|
||||||
|
|
||||||
if [ -z "$noChannelCopy" ] && [ -n "$channel" ]; then
|
|
||||||
echo "copying channel..."
|
|
||||||
nix-env --option build-use-substitutes false "${extraBuildFlags[@]}" -p $mountPoint/nix/var/nix/profiles/per-user/root/channels --set "$channel" --quiet
|
|
||||||
fi
|
|
||||||
install -m 0700 -d $mountPoint/root/.nix-defexpr
|
|
||||||
ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels
|
|
||||||
|
|
||||||
# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
|
|
||||||
touch $mountPoint/etc/NIXOS
|
|
@ -1,7 +1,9 @@
|
|||||||
# This module generates nixos-install, nixos-rebuild,
|
# This module generates nixos-install, nixos-rebuild,
|
||||||
# nixos-generate-config, etc.
|
# nixos-generate-config, etc.
|
||||||
|
|
||||||
{ config, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.installer;
|
cfg = config.installer;
|
||||||
@ -16,28 +18,11 @@ let
|
|||||||
src = ./nixos-build-vms/nixos-build-vms.sh;
|
src = ./nixos-build-vms/nixos-build-vms.sh;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixos-prepare-root = makeProg {
|
|
||||||
name = "nixos-prepare-root";
|
|
||||||
src = ./nixos-prepare-root.sh;
|
|
||||||
|
|
||||||
nix = pkgs.nixUnstable;
|
|
||||||
inherit (pkgs) perl pathsFromGraph rsync utillinux coreutils;
|
|
||||||
};
|
|
||||||
|
|
||||||
nixos-install = makeProg {
|
nixos-install = makeProg {
|
||||||
name = "nixos-install";
|
name = "nixos-install";
|
||||||
src = ./nixos-install.sh;
|
src = ./nixos-install.sh;
|
||||||
|
|
||||||
inherit (pkgs) perl pathsFromGraph rsync;
|
|
||||||
nix = config.nix.package.out;
|
nix = config.nix.package.out;
|
||||||
cacert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
|
path = makeBinPath [ nixos-enter ];
|
||||||
root_uid = config.ids.uids.root;
|
|
||||||
nixbld_gid = config.ids.gids.nixbld;
|
|
||||||
prepare_root = nixos-prepare-root;
|
|
||||||
|
|
||||||
nixClosure = pkgs.runCommand "closure"
|
|
||||||
{ exportReferencesGraph = ["refs" config.nix.package.out]; }
|
|
||||||
"cp refs $out";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nixos-rebuild =
|
nixos-rebuild =
|
||||||
@ -69,6 +54,11 @@ let
|
|||||||
inherit (config.system.nixos) version codeName revision;
|
inherit (config.system.nixos) version codeName revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nixos-enter = makeProg {
|
||||||
|
name = "nixos-enter";
|
||||||
|
src = ./nixos-enter.sh;
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -77,16 +67,16 @@ in
|
|||||||
|
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[ nixos-build-vms
|
[ nixos-build-vms
|
||||||
nixos-prepare-root
|
|
||||||
nixos-install
|
nixos-install
|
||||||
nixos-rebuild
|
nixos-rebuild
|
||||||
nixos-generate-config
|
nixos-generate-config
|
||||||
nixos-option
|
nixos-option
|
||||||
nixos-version
|
nixos-version
|
||||||
|
nixos-enter
|
||||||
];
|
];
|
||||||
|
|
||||||
system.build = {
|
system.build = {
|
||||||
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild;
|
inherit nixos-install nixos-prepare-root nixos-generate-config nixos-option nixos-rebuild nixos-enter;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -233,7 +233,7 @@
|
|||||||
calibre-server = 213;
|
calibre-server = 213;
|
||||||
heapster = 214;
|
heapster = 214;
|
||||||
bepasty = 215;
|
bepasty = 215;
|
||||||
pumpio = 216;
|
# pumpio = 216; # unused, removed 2018-02-24
|
||||||
nm-openvpn = 217;
|
nm-openvpn = 217;
|
||||||
mathics = 218;
|
mathics = 218;
|
||||||
ejabberd = 219;
|
ejabberd = 219;
|
||||||
@ -304,6 +304,7 @@
|
|||||||
mighttpd2 = 285;
|
mighttpd2 = 285;
|
||||||
hass = 286;
|
hass = 286;
|
||||||
monero = 287;
|
monero = 287;
|
||||||
|
ceph = 288;
|
||||||
|
|
||||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||||
|
|
||||||
@ -513,7 +514,7 @@
|
|||||||
xtreemfs = 212;
|
xtreemfs = 212;
|
||||||
calibre-server = 213;
|
calibre-server = 213;
|
||||||
bepasty = 215;
|
bepasty = 215;
|
||||||
pumpio = 216;
|
# pumpio = 216; # unused, removed 2018-02-24
|
||||||
nm-openvpn = 217;
|
nm-openvpn = 217;
|
||||||
mathics = 218;
|
mathics = 218;
|
||||||
ejabberd = 219;
|
ejabberd = 219;
|
||||||
@ -576,6 +577,7 @@
|
|||||||
mighttpd2 = 285;
|
mighttpd2 = 285;
|
||||||
hass = 286;
|
hass = 286;
|
||||||
monero = 287;
|
monero = 287;
|
||||||
|
ceph = 288;
|
||||||
|
|
||||||
# When adding a gid, make sure it doesn't match an existing
|
# When adding a gid, make sure it doesn't match an existing
|
||||||
# uid. Users and groups with the same name should have equal
|
# uid. Users and groups with the same name should have equal
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
./hardware/ckb.nix
|
./hardware/ckb.nix
|
||||||
./hardware/cpu/amd-microcode.nix
|
./hardware/cpu/amd-microcode.nix
|
||||||
./hardware/cpu/intel-microcode.nix
|
./hardware/cpu/intel-microcode.nix
|
||||||
|
./hardware/digitalbitbox.nix
|
||||||
./hardware/sensor/iio.nix
|
./hardware/sensor/iio.nix
|
||||||
./hardware/ksm.nix
|
./hardware/ksm.nix
|
||||||
./hardware/mcelog.nix
|
./hardware/mcelog.nix
|
||||||
@ -78,6 +79,7 @@
|
|||||||
./programs/command-not-found/command-not-found.nix
|
./programs/command-not-found/command-not-found.nix
|
||||||
./programs/criu.nix
|
./programs/criu.nix
|
||||||
./programs/dconf.nix
|
./programs/dconf.nix
|
||||||
|
./programs/digitalbitbox/default.nix
|
||||||
./programs/environment.nix
|
./programs/environment.nix
|
||||||
./programs/fish.nix
|
./programs/fish.nix
|
||||||
./programs/freetds.nix
|
./programs/freetds.nix
|
||||||
@ -109,6 +111,7 @@
|
|||||||
./programs/sway.nix
|
./programs/sway.nix
|
||||||
./programs/thefuck.nix
|
./programs/thefuck.nix
|
||||||
./programs/tmux.nix
|
./programs/tmux.nix
|
||||||
|
./programs/udevil.nix
|
||||||
./programs/venus.nix
|
./programs/venus.nix
|
||||||
./programs/vim.nix
|
./programs/vim.nix
|
||||||
./programs/way-cooler.nix
|
./programs/way-cooler.nix
|
||||||
@ -436,6 +439,7 @@
|
|||||||
./services/network-filesystems/u9fs.nix
|
./services/network-filesystems/u9fs.nix
|
||||||
./services/network-filesystems/yandex-disk.nix
|
./services/network-filesystems/yandex-disk.nix
|
||||||
./services/network-filesystems/xtreemfs.nix
|
./services/network-filesystems/xtreemfs.nix
|
||||||
|
./services/network-filesystems/ceph.nix
|
||||||
./services/networking/amuled.nix
|
./services/networking/amuled.nix
|
||||||
./services/networking/aria2.nix
|
./services/networking/aria2.nix
|
||||||
./services/networking/asterisk.nix
|
./services/networking/asterisk.nix
|
||||||
@ -637,8 +641,7 @@
|
|||||||
./services/web-apps/nixbot.nix
|
./services/web-apps/nixbot.nix
|
||||||
./services/web-apps/nexus.nix
|
./services/web-apps/nexus.nix
|
||||||
./services/web-apps/pgpkeyserver-lite.nix
|
./services/web-apps/pgpkeyserver-lite.nix
|
||||||
./services/web-apps/piwik.nix
|
./services/web-apps/matomo.nix
|
||||||
./services/web-apps/pump.io.nix
|
|
||||||
./services/web-apps/restya-board.nix
|
./services/web-apps/restya-board.nix
|
||||||
./services/web-apps/tt-rss.nix
|
./services/web-apps/tt-rss.nix
|
||||||
./services/web-apps/selfoss.nix
|
./services/web-apps/selfoss.nix
|
||||||
|
@ -72,7 +72,13 @@ with lib;
|
|||||||
|
|
||||||
# To speed up installation a little bit, include the complete
|
# To speed up installation a little bit, include the complete
|
||||||
# stdenv in the Nix store on the CD.
|
# stdenv in the Nix store on the CD.
|
||||||
system.extraDependencies = with pkgs; [ stdenv stdenvNoCC busybox ];
|
system.extraDependencies = with pkgs;
|
||||||
|
[
|
||||||
|
stdenv
|
||||||
|
stdenvNoCC # for runCommand
|
||||||
|
busybox
|
||||||
|
jq # for closureInfo
|
||||||
|
];
|
||||||
|
|
||||||
# Show all debug messages from the kernel but don't log refused packets
|
# Show all debug messages from the kernel but don't log refused packets
|
||||||
# because we have the firewall enabled. This makes installs from the
|
# because we have the firewall enabled. This makes installs from the
|
||||||
|
@ -211,6 +211,9 @@ in
|
|||||||
"/share/bash-completion"
|
"/share/bash-completion"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = optional cfg.enableCompletion
|
||||||
|
pkgs.nix-bash-completions;
|
||||||
|
|
||||||
environment.shells =
|
environment.shells =
|
||||||
[ "/run/current-system/sw/bin/bash"
|
[ "/run/current-system/sw/bin/bash"
|
||||||
"/var/run/current-system/sw/bin/bash"
|
"/var/run/current-system/sw/bin/bash"
|
||||||
|
@ -36,7 +36,7 @@ in
|
|||||||
"${pkgs.gnome3.dconf.lib}/lib/gio/modules";
|
"${pkgs.gnome3.dconf.lib}/lib/gio/modules";
|
||||||
# https://github.com/NixOS/nixpkgs/pull/31891
|
# https://github.com/NixOS/nixpkgs/pull/31891
|
||||||
#environment.variables.XDG_DATA_DIRS = optional cfg.enable
|
#environment.variables.XDG_DATA_DIRS = optional cfg.enable
|
||||||
# "$(echo ${pkgs.gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas-*)";
|
# "$(echo ${pkgs.gnome3.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas-*)";
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
39
nixos/modules/programs/digitalbitbox/default.nix
Normal file
39
nixos/modules/programs/digitalbitbox/default.nix
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.digitalbitbox;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.programs.digitalbitbox = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Installs the Digital Bitbox application and enables the complementary hardware module.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.digitalbitbox;
|
||||||
|
defaultText = "pkgs.digitalbitbox";
|
||||||
|
description = "The Digital Bitbox package to use. This can be used to install a package with udev rules that differ from the defaults.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
hardware.digitalbitbox = {
|
||||||
|
enable = true;
|
||||||
|
package = cfg.package;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
doc = ./doc.xml;
|
||||||
|
maintainers = with stdenv.lib.maintainers; [ vidbina ];
|
||||||
|
};
|
||||||
|
}
|
85
nixos/modules/programs/digitalbitbox/doc.xml
Normal file
85
nixos/modules/programs/digitalbitbox/doc.xml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="module-programs-digitalbitbox">
|
||||||
|
|
||||||
|
<title>Digital Bitbox</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Digital Bitbox is a hardware wallet and second-factor authenticator.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <literal>digitalbitbox</literal> programs module may be
|
||||||
|
installed by setting <literal>programs.digitalbitbox</literal>
|
||||||
|
to <literal>true</literal> in a manner similar to
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
programs.digitalbitbox.enable = true;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
and bundles the <literal>digitalbitbox</literal> package (see <xref
|
||||||
|
linkend="sec-digitalbitbox-package" />), which contains the
|
||||||
|
<literal>dbb-app</literal> and <literal>dbb-cli</literal> binaries,
|
||||||
|
along with the hardware module (see <xref
|
||||||
|
linkend="sec-digitalbitbox-hardware-module" />) which sets up the
|
||||||
|
necessary udev rules to access the device.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Enabling the digitalbitbox module is pretty much the easiest way to
|
||||||
|
get a Digital Bitbox device working on your system.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For more information, see
|
||||||
|
<link xlink:href="https://digitalbitbox.com/start_linux" />.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="sec-digitalbitbox-package">
|
||||||
|
<title>Package</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The binaries, <literal>dbb-app</literal> (a GUI tool) and
|
||||||
|
<literal>dbb-cli</literal> (a CLI tool), are available through the
|
||||||
|
<literal>digitalbitbox</literal> package which could be installed
|
||||||
|
as follows:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.digitalbitbox
|
||||||
|
];
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section xml:id="sec-digitalbitbox-hardware-module">
|
||||||
|
<title>Hardware</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The digitalbitbox hardware package enables the udev rules for
|
||||||
|
Digital Bitbox devices and may be installed as follows:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
hardware.digitalbitbox.enable = true;
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In order to alter the udev rules, one may provide different values for
|
||||||
|
the <literal>udevRule51</literal> and <literal>udevRule52</literal>
|
||||||
|
attributes by means of overriding as follows:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
programs.digitalbitbox = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.digitalbitbox.override {
|
||||||
|
udevRule51 = "something else";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</chapter>
|
14
nixos/modules/programs/udevil.nix
Normal file
14
nixos/modules/programs/udevil.nix
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.udevil;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.programs.udevil.enable = mkEnableOption "udevil";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
security.wrappers.udevil.source = "${lib.getBin pkgs.udevil}/bin/udevil";
|
||||||
|
};
|
||||||
|
}
|
@ -148,6 +148,12 @@ with lib;
|
|||||||
# parsoid
|
# parsoid
|
||||||
(mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] [ "services" "parsoid" "wikis" ])
|
(mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] [ "services" "parsoid" "wikis" ])
|
||||||
|
|
||||||
|
# piwik was renamed to matomo
|
||||||
|
(mkRenamedOptionModule [ "services" "piwik" "enable" ] [ "services" "matomo" "enable" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "piwik" "webServerUser" ] [ "services" "matomo" "webServerUser" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "piwik" "phpfpmProcessManagerConfig" ] [ "services" "matomo" "phpfpmProcessManagerConfig" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "piwik" "nginx" ] [ "services" "matomo" "nginx" ])
|
||||||
|
|
||||||
# tarsnap
|
# tarsnap
|
||||||
(mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
|
(mkRemovedOptionModule [ "services" "tarsnap" "cachedir" ] "Use services.tarsnap.archives.<name>.cachedir")
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ let
|
|||||||
("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
("auth optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
||||||
${optionalString cfg.enableGnomeKeyring
|
${optionalString cfg.enableGnomeKeyring
|
||||||
("auth optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so")}
|
("auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so")}
|
||||||
${optionalString cfg.googleAuthenticator.enable
|
${optionalString cfg.googleAuthenticator.enable
|
||||||
"auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"}
|
"auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"}
|
||||||
'') + ''
|
'') + ''
|
||||||
@ -384,7 +384,7 @@ let
|
|||||||
("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
("session optional ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so" +
|
||||||
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
" kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
|
||||||
${optionalString (cfg.enableGnomeKeyring)
|
${optionalString (cfg.enableGnomeKeyring)
|
||||||
"session optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start"}
|
"session optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start"}
|
||||||
${optionalString (config.virtualisation.lxc.lxcfs.enable)
|
${optionalString (config.virtualisation.lxc.lxcfs.enable)
|
||||||
"session optional ${pkgs.lxcfs}/lib/security/pam_cgfs.so -c freezer,memory,name=systemd,unified,cpuset"}
|
"session optional ${pkgs.lxcfs}/lib/security/pam_cgfs.so -c freezer,memory,name=systemd,unified,cpuset"}
|
||||||
'');
|
'');
|
||||||
|
@ -208,7 +208,7 @@ in {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
postStart = ''
|
postStart = ''
|
||||||
until [[ $(${pkgs.curl.bin}/bin/curl -s --head -w '\n%{http_code}' http://${cfg.listenAddress}:${toString cfg.port}${cfg.prefix} | tail -n1) =~ ^(200|403)$ ]]; do
|
until [[ $(${pkgs.curl.bin}/bin/curl -L -s --head -w '\n%{http_code}' http://${cfg.listenAddress}:${toString cfg.port}${cfg.prefix} | tail -n1) =~ ^(200|403)$ ]]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
@ -133,7 +133,7 @@ in
|
|||||||
'';
|
'';
|
||||||
example = [
|
example = [
|
||||||
"nextcloud"
|
"nextcloud"
|
||||||
"piwik"
|
"matomo"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,10 +289,10 @@ in
|
|||||||
# Create initial databases
|
# Create initial databases
|
||||||
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
||||||
echo "Creating initial database: ${database.name}"
|
echo "Creating initial database: ${database.name}"
|
||||||
( echo "create database `${database.name}`;"
|
( echo 'create database `${database.name}`;'
|
||||||
|
|
||||||
${optionalString (database ? "schema") ''
|
${optionalString (database ? "schema") ''
|
||||||
echo "use `${database.name}`;"
|
echo 'use `${database.name}`;'
|
||||||
|
|
||||||
if [ -f "${database.schema}" ]
|
if [ -f "${database.schema}" ]
|
||||||
then
|
then
|
||||||
|
@ -7,8 +7,10 @@ let
|
|||||||
cfg = config.services.openldap;
|
cfg = config.services.openldap;
|
||||||
openldap = pkgs.openldap;
|
openldap = pkgs.openldap;
|
||||||
|
|
||||||
|
dataFile = pkgs.writeText "ldap-contents.ldif" cfg.declarativeContents;
|
||||||
configFile = pkgs.writeText "slapd.conf" cfg.extraConfig;
|
configFile = pkgs.writeText "slapd.conf" cfg.extraConfig;
|
||||||
|
configOpts = if cfg.configDir == null then "-f ${configFile}"
|
||||||
|
else "-F ${cfg.configDir}";
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -81,6 +83,34 @@ in
|
|||||||
'''
|
'''
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declarativeContents = mkOption {
|
||||||
|
type = with types; nullOr lines;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Declarative contents for the LDAP database, in LDIF format.
|
||||||
|
|
||||||
|
Note a few facts when using it. First, the database
|
||||||
|
<emphasis>must</emphasis> be stored in the directory defined by
|
||||||
|
<code>dataDir</code>. Second, all <code>dataDir</code> will be erased
|
||||||
|
when starting the LDAP server. Third, modifications to the database
|
||||||
|
are not prevented, they are just dropped on the next reboot of the
|
||||||
|
server. Finally, performance-wise the database and indexes are rebuilt
|
||||||
|
on each server startup, so this will slow down server startup,
|
||||||
|
especially with large databases.
|
||||||
|
'';
|
||||||
|
example = ''
|
||||||
|
dn: dc=example,dc=org
|
||||||
|
objectClass: domain
|
||||||
|
dc: example
|
||||||
|
|
||||||
|
dn: ou=users,dc=example,dc=org
|
||||||
|
objectClass = organizationalUnit
|
||||||
|
ou: users
|
||||||
|
|
||||||
|
# ...
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -88,7 +118,7 @@ in
|
|||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf config.services.openldap.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ openldap ];
|
environment.systemPackages = [ openldap ];
|
||||||
|
|
||||||
@ -98,11 +128,21 @@ in
|
|||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -p /var/run/slapd
|
mkdir -p /var/run/slapd
|
||||||
chown -R ${cfg.user}:${cfg.group} /var/run/slapd
|
chown -R "${cfg.user}:${cfg.group}" /var/run/slapd
|
||||||
mkdir -p ${cfg.dataDir}
|
${optionalString (cfg.declarativeContents != null) ''
|
||||||
chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
|
rm -Rf "${cfg.dataDir}"
|
||||||
|
''}
|
||||||
|
mkdir -p "${cfg.dataDir}"
|
||||||
|
${optionalString (cfg.declarativeContents != null) ''
|
||||||
|
${openldap.out}/bin/slapadd ${configOpts} -l ${dataFile}
|
||||||
|
''}
|
||||||
|
chown -R "${cfg.user}:${cfg.group}" "${cfg.dataDir}"
|
||||||
'';
|
'';
|
||||||
serviceConfig.ExecStart = "${openldap.out}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -h \"${concatStringsSep " " cfg.urlList}\" ${if cfg.configDir == null then "-f "+configFile else "-F "+cfg.configDir}";
|
serviceConfig.ExecStart =
|
||||||
|
"${openldap.out}/libexec/slapd -d 0 " +
|
||||||
|
"-u '${cfg.user}' -g '${cfg.group}' " +
|
||||||
|
"-h '${concatStringsSep " " cfg.urlList}' " +
|
||||||
|
"${configOpts}";
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraUsers.openldap =
|
users.extraUsers.openldap =
|
||||||
|
@ -30,9 +30,9 @@ with lib;
|
|||||||
|
|
||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
(mkIf config.services.gnome3.at-spi2-core.enable {
|
(mkIf config.services.gnome3.at-spi2-core.enable {
|
||||||
environment.systemPackages = [ pkgs.at_spi2_core ];
|
environment.systemPackages = [ pkgs.at-spi2-core ];
|
||||||
services.dbus.packages = [ pkgs.at_spi2_core ];
|
services.dbus.packages = [ pkgs.at-spi2-core ];
|
||||||
systemd.packages = [ pkgs.at_spi2_core ];
|
systemd.packages = [ pkgs.at-spi2-core ];
|
||||||
})
|
})
|
||||||
|
|
||||||
(mkIf (!config.services.gnome3.at-spi2-core.enable) {
|
(mkIf (!config.services.gnome3.at-spi2-core.enable) {
|
||||||
|
@ -30,11 +30,11 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.services.gnome3.evolution-data-server.enable {
|
config = mkIf config.services.gnome3.evolution-data-server.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.gnome3.evolution_data_server ];
|
environment.systemPackages = [ pkgs.gnome3.evolution-data-server ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.gnome3.evolution_data_server ];
|
services.dbus.packages = [ pkgs.gnome3.evolution-data-server ];
|
||||||
|
|
||||||
systemd.packages = [ pkgs.gnome3.evolution_data_server ];
|
systemd.packages = [ pkgs.gnome3.evolution-data-server ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.services.gnome3.gnome-keyring.enable {
|
config = mkIf config.services.gnome3.gnome-keyring.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.gnome3.gnome_keyring ];
|
environment.systemPackages = [ pkgs.gnome3.gnome-keyring ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.gnome3.gnome_keyring pkgs.gnome3.gcr ];
|
services.dbus.packages = [ pkgs.gnome3.gnome-keyring pkgs.gnome3.gcr ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.services.gnome3.gnome-online-accounts.enable {
|
config = mkIf config.services.gnome3.gnome-online-accounts.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.gnome3.gnome_online_accounts ];
|
environment.systemPackages = [ pkgs.gnome3.gnome-online-accounts ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.gnome3.gnome_online_accounts ];
|
services.dbus.packages = [ pkgs.gnome3.gnome-online-accounts ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.services.gnome3.gnome-terminal-server.enable {
|
config = mkIf config.services.gnome3.gnome-terminal-server.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.gnome3.gnome_terminal ];
|
environment.systemPackages = [ pkgs.gnome3.gnome-terminal ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.gnome3.gnome_terminal ];
|
services.dbus.packages = [ pkgs.gnome3.gnome-terminal ];
|
||||||
|
|
||||||
systemd.packages = [ pkgs.gnome3.gnome_terminal ];
|
systemd.packages = [ pkgs.gnome3.gnome-terminal ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf config.services.telepathy.enable {
|
config = mkIf config.services.telepathy.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.telepathy_mission_control ];
|
environment.systemPackages = [ pkgs.telepathy-mission-control ];
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.telepathy_mission_control ];
|
services.dbus.packages = [ pkgs.telepathy-mission-control ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,6 +32,12 @@ in
|
|||||||
description = "Whether to enable Disnix";
|
description = "Whether to enable Disnix";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enableMultiUser = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to support multi-user mode by enabling the Disnix D-Bus service";
|
||||||
|
};
|
||||||
|
|
||||||
useWebServiceInterface = mkOption {
|
useWebServiceInterface = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
|
description = "Whether to enable the DisnixWebService interface running on Apache Tomcat";
|
||||||
@ -71,7 +77,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
systemd.services = {
|
systemd.services = {
|
||||||
disnix = {
|
disnix = mkIf cfg.enableMultiUser {
|
||||||
description = "Disnix server";
|
description = "Disnix server";
|
||||||
wants = [ "dysnomia.target" ];
|
wants = [ "dysnomia.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
@ -33,9 +33,9 @@ let
|
|||||||
sh = pkgs.stdenv.shell;
|
sh = pkgs.stdenv.shell;
|
||||||
binshDeps = pkgs.writeReferencesToFile sh;
|
binshDeps = pkgs.writeReferencesToFile sh;
|
||||||
in
|
in
|
||||||
pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; inherit binshDeps; } ''
|
pkgs.runCommand "nix.conf" { extraOptions = cfg.extraOptions; } ''
|
||||||
${optionalString (!isNix20) ''
|
${optionalString (!isNix20) ''
|
||||||
extraPaths=$(for i in $(cat binshDeps); do if test -d $i; then echo $i; fi; done)
|
extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done)
|
||||||
''}
|
''}
|
||||||
cat > $out <<END
|
cat > $out <<END
|
||||||
# WARNING: this file is generated from the nix.* options in
|
# WARNING: this file is generated from the nix.* options in
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
let cfg = config.nix.sshServe;
|
||||||
{
|
command =
|
||||||
|
if cfg.protocol == "ssh"
|
||||||
|
then "nix-store --serve"
|
||||||
|
else "nix-daemon --stdio";
|
||||||
|
in {
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
nix.sshServe = {
|
nix.sshServe = {
|
||||||
@ -10,7 +14,7 @@ with lib;
|
|||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Whether to enable serving the Nix store as a binary cache via SSH.";
|
description = "Whether to enable serving the Nix store as a remote store via SSH.";
|
||||||
};
|
};
|
||||||
|
|
||||||
keys = mkOption {
|
keys = mkOption {
|
||||||
@ -20,14 +24,20 @@ with lib;
|
|||||||
description = "A list of SSH public keys allowed to access the binary cache via SSH.";
|
description = "A list of SSH public keys allowed to access the binary cache via SSH.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protocol = mkOption {
|
||||||
|
type = types.enum [ "ssh" "ssh-ng" ];
|
||||||
|
default = "ssh";
|
||||||
|
description = "The specific Nix-over-SSH protocol to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.nix.sshServe.enable {
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
users.extraUsers.nix-ssh = {
|
users.extraUsers.nix-ssh = {
|
||||||
description = "Nix SSH substituter user";
|
description = "Nix SSH store user";
|
||||||
uid = config.ids.uids.nix-ssh;
|
uid = config.ids.uids.nix-ssh;
|
||||||
useDefaultShell = true;
|
useDefaultShell = true;
|
||||||
};
|
};
|
||||||
@ -41,11 +51,11 @@ with lib;
|
|||||||
PermitTTY no
|
PermitTTY no
|
||||||
PermitTunnel no
|
PermitTunnel no
|
||||||
X11Forwarding no
|
X11Forwarding no
|
||||||
ForceCommand ${config.nix.package.out}/bin/nix-store --serve
|
ForceCommand ${config.nix.package.out}/bin/${command}
|
||||||
Match All
|
Match All
|
||||||
'';
|
'';
|
||||||
|
|
||||||
users.extraUsers.nix-ssh.openssh.authorizedKeys.keys = config.nix.sshServe.keys;
|
users.extraUsers.nix-ssh.openssh.authorizedKeys.keys = cfg.keys;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ in {
|
|||||||
};
|
};
|
||||||
preStart = ''
|
preStart = ''
|
||||||
ln -fs ${cfg.package}/share/grafana/conf ${cfg.dataDir}
|
ln -fs ${cfg.package}/share/grafana/conf ${cfg.dataDir}
|
||||||
ln -fs ${cfg.package}/share/grafana/vendor ${cfg.dataDir}
|
ln -fs ${cfg.package}/share/grafana/tools ${cfg.dataDir}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
371
nixos/modules/services/network-filesystems/ceph.nix
Normal file
371
nixos/modules/services/network-filesystems/ceph.nix
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
ceph = pkgs.ceph;
|
||||||
|
cfg = config.services.ceph;
|
||||||
|
# function that translates "camelCaseOptions" to "camel case options", credits to tilpner in #nixos@freenode
|
||||||
|
translateOption = replaceStrings upperChars (map (s: " ${s}") lowerChars);
|
||||||
|
generateDaemonList = (daemonType: daemons: extraServiceConfig:
|
||||||
|
mkMerge (
|
||||||
|
map (daemon:
|
||||||
|
{ "ceph-${daemonType}-${daemon}" = generateServiceFile daemonType daemon cfg.global.clusterName ceph extraServiceConfig; }
|
||||||
|
) daemons
|
||||||
|
)
|
||||||
|
);
|
||||||
|
generateServiceFile = (daemonType: daemonId: clusterName: ceph: extraServiceConfig: {
|
||||||
|
enable = true;
|
||||||
|
description = "Ceph ${builtins.replaceStrings lowerChars upperChars daemonType} daemon ${daemonId}";
|
||||||
|
after = [ "network-online.target" "local-fs.target" "time-sync.target" ] ++ optional (daemonType == "osd") "ceph-mon.target";
|
||||||
|
wants = [ "network-online.target" "local-fs.target" "time-sync.target" ];
|
||||||
|
partOf = [ "ceph-${daemonType}.target" ];
|
||||||
|
wantedBy = [ "ceph-${daemonType}.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
LimitNOFILE = 1048576;
|
||||||
|
LimitNPROC = 1048576;
|
||||||
|
Environment = "CLUSTER=${clusterName}";
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
PrivateDevices = "yes";
|
||||||
|
PrivateTmp = "true";
|
||||||
|
ProtectHome = "true";
|
||||||
|
ProtectSystem = "full";
|
||||||
|
Restart = "on-failure";
|
||||||
|
StartLimitBurst = "5";
|
||||||
|
StartLimitInterval = "30min";
|
||||||
|
ExecStart = "${ceph.out}/bin/${if daemonType == "rgw" then "radosgw" else "ceph-${daemonType}"} -f --cluster ${clusterName} --id ${if daemonType == "rgw" then "client.${daemonId}" else daemonId} --setuser ceph --setgroup ceph";
|
||||||
|
} // extraServiceConfig
|
||||||
|
// optionalAttrs (daemonType == "osd") { ExecStartPre = "${ceph.out}/libexec/ceph/ceph-osd-prestart.sh --id ${daemonId} --cluster ${clusterName}"; };
|
||||||
|
} // optionalAttrs (builtins.elem daemonType [ "mds" "mon" "rgw" "mgr" ]) { preStart = ''
|
||||||
|
daemonPath="/var/lib/ceph/${if daemonType == "rgw" then "radosgw" else daemonType}/${clusterName}-${daemonId}"
|
||||||
|
if [ ! -d ''$daemonPath ]; then
|
||||||
|
mkdir -m 755 -p ''$daemonPath
|
||||||
|
chown -R ceph:ceph ''$daemonPath
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
} // optionalAttrs (daemonType == "osd") { path = [ pkgs.getopt ]; }
|
||||||
|
);
|
||||||
|
generateTargetFile = (daemonType:
|
||||||
|
{
|
||||||
|
"ceph-${daemonType}" = {
|
||||||
|
description = "Ceph target allowing to start/stop all ceph-${daemonType} services at once";
|
||||||
|
partOf = [ "ceph.target" ];
|
||||||
|
before = [ "ceph.target" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.ceph = {
|
||||||
|
# Ceph has a monolithic configuration file but different sections for
|
||||||
|
# each daemon, a separate client section and a global section
|
||||||
|
enable = mkEnableOption "Ceph global configuration";
|
||||||
|
|
||||||
|
global = {
|
||||||
|
fsid = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = ''
|
||||||
|
433a2193-4f8a-47a0-95d2-209d7ca2cca5
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Filesystem ID, a generated uuid, its must be generated and set before
|
||||||
|
attempting to start a cluster
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
clusterName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "ceph";
|
||||||
|
description = ''
|
||||||
|
Name of cluster
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
monInitialMembers = mkOption {
|
||||||
|
type = with types; nullOr commas;
|
||||||
|
default = null;
|
||||||
|
example = ''
|
||||||
|
node0, node1, node2
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
List of hosts that will be used as monitors at startup.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
monHost = mkOption {
|
||||||
|
type = with types; nullOr commas;
|
||||||
|
default = null;
|
||||||
|
example = ''
|
||||||
|
10.10.0.1, 10.10.0.2, 10.10.0.3
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
List of hostname shortnames/IP addresses of the initial monitors.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maxOpenFiles = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 131072;
|
||||||
|
description = ''
|
||||||
|
Max open files for each OSD daemon.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
authClusterRequired = mkOption {
|
||||||
|
type = types.enum [ "cephx" "none" ];
|
||||||
|
default = "cephx";
|
||||||
|
description = ''
|
||||||
|
Enables requiring daemons to authenticate with eachother in the cluster.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
authServiceRequired = mkOption {
|
||||||
|
type = types.enum [ "cephx" "none" ];
|
||||||
|
default = "cephx";
|
||||||
|
description = ''
|
||||||
|
Enables requiring clients to authenticate with the cluster to access services in the cluster (e.g. radosgw, mds or osd).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
authClientRequired = mkOption {
|
||||||
|
type = types.enum [ "cephx" "none" ];
|
||||||
|
default = "cephx";
|
||||||
|
description = ''
|
||||||
|
Enables requiring the cluster to authenticate itself to the client.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
publicNetwork = mkOption {
|
||||||
|
type = with types; nullOr commas;
|
||||||
|
default = null;
|
||||||
|
example = ''
|
||||||
|
10.20.0.0/24, 192.168.1.0/24
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A comma-separated list of subnets that will be used as public networks in the cluster.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
clusterNetwork = mkOption {
|
||||||
|
type = with types; nullOr commas;
|
||||||
|
default = null;
|
||||||
|
example = ''
|
||||||
|
10.10.0.0/24, 192.168.0.0/24
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A comma-separated list of subnets that will be used as cluster networks in the cluster.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mgr = {
|
||||||
|
enable = mkEnableOption "Ceph MGR daemon";
|
||||||
|
daemons = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ''
|
||||||
|
[ "name1" "name2" ];
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A list of names for manager daemons that should have a service created. The names correspond
|
||||||
|
to the id part in ceph i.e. [ "name1" ] would result in mgr.name1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Extra configuration to add to the global section for manager daemons.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mon = {
|
||||||
|
enable = mkEnableOption "Ceph MON daemon";
|
||||||
|
daemons = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ''
|
||||||
|
[ "name1" "name2" ];
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A list of monitor daemons that should have a service created. The names correspond
|
||||||
|
to the id part in ceph i.e. [ "name1" ] would result in mon.name1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Extra configuration to add to the monitor section.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
osd = {
|
||||||
|
enable = mkEnableOption "Ceph OSD daemon";
|
||||||
|
daemons = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ''
|
||||||
|
[ "name1" "name2" ];
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A list of OSD daemons that should have a service created. The names correspond
|
||||||
|
to the id part in ceph i.e. [ "name1" ] would result in osd.name1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {
|
||||||
|
"osd journal size" = "10000";
|
||||||
|
"osd pool default size" = "3";
|
||||||
|
"osd pool default min size" = "2";
|
||||||
|
"osd pool default pg num" = "200";
|
||||||
|
"osd pool default pgp num" = "200";
|
||||||
|
"osd crush chooseleaf type" = "1";
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Extra configuration to add to the OSD section.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mds = {
|
||||||
|
enable = mkEnableOption "Ceph MDS daemon";
|
||||||
|
daemons = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ''
|
||||||
|
[ "name1" "name2" ];
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A list of metadata service daemons that should have a service created. The names correspond
|
||||||
|
to the id part in ceph i.e. [ "name1" ] would result in mds.name1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Extra configuration to add to the MDS section.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rgw = {
|
||||||
|
enable = mkEnableOption "Ceph RadosGW daemon";
|
||||||
|
daemons = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = ''
|
||||||
|
[ "name1" "name2" ];
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
A list of rados gateway daemons that should have a service created. The names correspond
|
||||||
|
to the id part in ceph i.e. [ "name1" ] would result in client.name1, radosgw daemons
|
||||||
|
aren't daemons to cluster in the sense that OSD, MGR or MON daemons are. They are simply
|
||||||
|
daemons, from ceph, that uses the cluster as a backend.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
client = {
|
||||||
|
enable = mkEnableOption "Ceph client configuration";
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
example = ''
|
||||||
|
{
|
||||||
|
# This would create a section for a radosgw daemon named node0 and related
|
||||||
|
# configuration for it
|
||||||
|
"client.radosgw.node0" = { "some config option" = "true"; };
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Extra configuration to add to the client section. Configuration for rados gateways
|
||||||
|
would be added here, with their own sections, see example.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.services.ceph.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = cfg.global.fsid != "";
|
||||||
|
message = "fsid has to be set to a valid uuid for the cluster to function";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.mgr.enable == true;
|
||||||
|
message = "ceph 12.x requires atleast 1 MGR daemon enabled for the cluster to function";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.mon.enable == true -> cfg.mon.daemons != [];
|
||||||
|
message = "have to set id of atleast one MON if you're going to enable Monitor";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.mds.enable == true -> cfg.mds.daemons != [];
|
||||||
|
message = "have to set id of atleast one MDS if you're going to enable Metadata Service";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.osd.enable == true -> cfg.osd.daemons != [];
|
||||||
|
message = "have to set id of atleast one OSD if you're going to enable OSD";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.mgr.enable == true -> cfg.mgr.daemons != [];
|
||||||
|
message = "have to set id of atleast one MGR if you're going to enable MGR";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
warnings = optional (cfg.global.monInitialMembers == null)
|
||||||
|
''Not setting up a list of members in monInitialMembers requires that you set the host variable for each mon daemon or else the cluster won't function'';
|
||||||
|
|
||||||
|
environment.etc."ceph/ceph.conf".text = let
|
||||||
|
# Translate camelCaseOptions to the expected camel case option for ceph.conf
|
||||||
|
translatedGlobalConfig = mapAttrs' (name: value: nameValuePair (translateOption name) value) cfg.global;
|
||||||
|
# Merge the extraConfig set for mgr daemons, as mgr don't have their own section
|
||||||
|
globalAndMgrConfig = translatedGlobalConfig // optionalAttrs cfg.mgr.enable cfg.mgr.extraConfig;
|
||||||
|
# Remove all name-value pairs with null values from the attribute set to avoid making empty sections in the ceph.conf
|
||||||
|
globalConfig = mapAttrs' (name: value: nameValuePair (translateOption name) value) (filterAttrs (name: value: value != null) globalAndMgrConfig);
|
||||||
|
totalConfig = {
|
||||||
|
"global" = globalConfig;
|
||||||
|
} // optionalAttrs (cfg.mon.enable && cfg.mon.extraConfig != {}) { "mon" = cfg.mon.extraConfig; }
|
||||||
|
// optionalAttrs (cfg.mds.enable && cfg.mds.extraConfig != {}) { "mds" = cfg.mds.extraConfig; }
|
||||||
|
// optionalAttrs (cfg.osd.enable && cfg.osd.extraConfig != {}) { "osd" = cfg.osd.extraConfig; }
|
||||||
|
// optionalAttrs (cfg.client.enable && cfg.client.extraConfig != {}) cfg.client.extraConfig;
|
||||||
|
in
|
||||||
|
generators.toINI {} totalConfig;
|
||||||
|
|
||||||
|
users.extraUsers = singleton {
|
||||||
|
name = "ceph";
|
||||||
|
uid = config.ids.uids.ceph;
|
||||||
|
description = "Ceph daemon user";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraGroups = singleton {
|
||||||
|
name = "ceph";
|
||||||
|
gid = config.ids.gids.ceph;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services = let
|
||||||
|
services = []
|
||||||
|
++ optional cfg.mon.enable (generateDaemonList "mon" cfg.mon.daemons { RestartSec = "10"; })
|
||||||
|
++ optional cfg.mds.enable (generateDaemonList "mds" cfg.mds.daemons { StartLimitBurst = "3"; })
|
||||||
|
++ optional cfg.osd.enable (generateDaemonList "osd" cfg.osd.daemons { StartLimitBurst = "30"; RestartSec = "20s"; })
|
||||||
|
++ optional cfg.rgw.enable (generateDaemonList "rgw" cfg.rgw.daemons { })
|
||||||
|
++ optional cfg.mgr.enable (generateDaemonList "mgr" cfg.mgr.daemons { StartLimitBurst = "3"; });
|
||||||
|
in
|
||||||
|
mkMerge services;
|
||||||
|
|
||||||
|
systemd.targets = let
|
||||||
|
targets = [
|
||||||
|
{ "ceph" = { description = "Ceph target allowing to start/stop all ceph service instances at once"; }; }
|
||||||
|
] ++ optional cfg.mon.enable (generateTargetFile "mon")
|
||||||
|
++ optional cfg.mds.enable (generateTargetFile "mds")
|
||||||
|
++ optional cfg.osd.enable (generateTargetFile "osd")
|
||||||
|
++ optional cfg.rgw.enable (generateTargetFile "rgw")
|
||||||
|
++ optional cfg.mgr.enable (generateTargetFile "mgr");
|
||||||
|
in
|
||||||
|
mkMerge targets;
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /run/ceph 0770 ceph ceph -"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@ -133,10 +133,10 @@ in {
|
|||||||
basePackages = mkOption {
|
basePackages = mkOption {
|
||||||
type = types.attrsOf types.package;
|
type = types.attrsOf types.package;
|
||||||
default = { inherit networkmanager modemmanager wpa_supplicant
|
default = { inherit networkmanager modemmanager wpa_supplicant
|
||||||
networkmanager_openvpn networkmanager_vpnc
|
networkmanager-openvpn networkmanager-vpnc
|
||||||
networkmanager_openconnect networkmanager_fortisslvpn
|
networkmanager-openconnect networkmanager-fortisslvpn
|
||||||
networkmanager_pptp networkmanager_l2tp
|
networkmanager-pptp networkmanager-l2tp
|
||||||
networkmanager_iodine; };
|
networkmanager-iodine; };
|
||||||
internal = true;
|
internal = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -273,28 +273,28 @@ in {
|
|||||||
{ source = configFile;
|
{ source = configFile;
|
||||||
target = "NetworkManager/NetworkManager.conf";
|
target = "NetworkManager/NetworkManager.conf";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_openvpn}/etc/NetworkManager/VPN/nm-openvpn-service.name";
|
{ source = "${networkmanager-openvpn}/etc/NetworkManager/VPN/nm-openvpn-service.name";
|
||||||
target = "NetworkManager/VPN/nm-openvpn-service.name";
|
target = "NetworkManager/VPN/nm-openvpn-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_vpnc}/etc/NetworkManager/VPN/nm-vpnc-service.name";
|
{ source = "${networkmanager-vpnc}/etc/NetworkManager/VPN/nm-vpnc-service.name";
|
||||||
target = "NetworkManager/VPN/nm-vpnc-service.name";
|
target = "NetworkManager/VPN/nm-vpnc-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
|
{ source = "${networkmanager-openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
|
||||||
target = "NetworkManager/VPN/nm-openconnect-service.name";
|
target = "NetworkManager/VPN/nm-openconnect-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name";
|
{ source = "${networkmanager-fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name";
|
||||||
target = "NetworkManager/VPN/nm-fortisslvpn-service.name";
|
target = "NetworkManager/VPN/nm-fortisslvpn-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
|
{ source = "${networkmanager-pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
|
||||||
target = "NetworkManager/VPN/nm-pptp-service.name";
|
target = "NetworkManager/VPN/nm-pptp-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
|
{ source = "${networkmanager-l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
|
||||||
target = "NetworkManager/VPN/nm-l2tp-service.name";
|
target = "NetworkManager/VPN/nm-l2tp-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_strongswan}/etc/NetworkManager/VPN/nm-strongswan-service.name";
|
{ source = "${networkmanager_strongswan}/etc/NetworkManager/VPN/nm-strongswan-service.name";
|
||||||
target = "NetworkManager/VPN/nm-strongswan-service.name";
|
target = "NetworkManager/VPN/nm-strongswan-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager_iodine}/etc/NetworkManager/VPN/nm-iodine-service.name";
|
{ source = "${networkmanager-iodine}/etc/NetworkManager/VPN/nm-iodine-service.name";
|
||||||
target = "NetworkManager/VPN/nm-iodine-service.name";
|
target = "NetworkManager/VPN/nm-iodine-service.name";
|
||||||
}
|
}
|
||||||
] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
|
] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
|
||||||
@ -335,6 +335,7 @@ in {
|
|||||||
|
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -m 700 -p /etc/NetworkManager/system-connections
|
mkdir -m 700 -p /etc/NetworkManager/system-connections
|
||||||
|
mkdir -m 700 -p /etc/ipsec.d
|
||||||
mkdir -m 755 -p ${stateDirs}
|
mkdir -m 755 -p ${stateDirs}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -32,13 +32,13 @@ let
|
|||||||
${caConf}
|
${caConf}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
strongswanConf = {setup, connections, ca, secrets, managePlugins, enabledPlugins}: toFile "strongswan.conf" ''
|
strongswanConf = {setup, connections, ca, secretsFile, managePlugins, enabledPlugins}: toFile "strongswan.conf" ''
|
||||||
charon {
|
charon {
|
||||||
${if managePlugins then "load_modular = no" else ""}
|
${if managePlugins then "load_modular = no" else ""}
|
||||||
${if managePlugins then ("load = " + (concatStringsSep " " enabledPlugins)) else ""}
|
${if managePlugins then ("load = " + (concatStringsSep " " enabledPlugins)) else ""}
|
||||||
plugins {
|
plugins {
|
||||||
stroke {
|
stroke {
|
||||||
secrets_file = ${ipsecSecrets secrets}
|
secrets_file = ${secretsFile}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +135,18 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = with cfg; mkIf enable {
|
|
||||||
|
config = with cfg;
|
||||||
|
let
|
||||||
|
secretsFile = ipsecSecrets cfg.secrets;
|
||||||
|
in
|
||||||
|
mkIf enable
|
||||||
|
{
|
||||||
|
|
||||||
|
# here we should use the default strongswan ipsec.secrets and
|
||||||
|
# append to it (default one is empty so not a pb for now)
|
||||||
|
environment.etc."ipsec.secrets".source = secretsFile;
|
||||||
|
|
||||||
systemd.services.strongswan = {
|
systemd.services.strongswan = {
|
||||||
description = "strongSwan IPSec Service";
|
description = "strongSwan IPSec Service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
@ -143,11 +154,15 @@ in
|
|||||||
wants = [ "keys.target" ];
|
wants = [ "keys.target" ];
|
||||||
after = [ "network-online.target" "keys.target" ];
|
after = [ "network-online.target" "keys.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secrets managePlugins enabledPlugins; };
|
STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secretsFile managePlugins enabledPlugins; };
|
||||||
};
|
};
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork";
|
ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork";
|
||||||
};
|
};
|
||||||
|
preStart = ''
|
||||||
|
# with 'nopeerdns' setting, ppp writes into this folder
|
||||||
|
mkdir -m 700 -p /etc/ppp
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,6 @@ in {
|
|||||||
available on http://127.0.0.1:8384/.
|
available on http://127.0.0.1:8384/.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
useInotify = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Provide syncthing-inotify as a service.";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemService = mkOption {
|
systemService = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -90,6 +84,12 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule ["services" "syncthing" "useInotify"] ''
|
||||||
|
This option was removed because syncthing now has the inotify functionality included under the name "fswatcher".
|
||||||
|
It can be enabled on a per-folder basis through the webinterface.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
@ -100,8 +100,7 @@ in {
|
|||||||
allowedUDPPorts = [ 21027 ];
|
allowedUDPPorts = [ 21027 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.packages = [ pkgs.syncthing ]
|
systemd.packages = [ pkgs.syncthing ];
|
||||||
++ lib.optional cfg.useInotify pkgs.syncthing-inotify;
|
|
||||||
|
|
||||||
users = mkIf (cfg.user == defaultUser) {
|
users = mkIf (cfg.user == defaultUser) {
|
||||||
extraUsers."${defaultUser}" =
|
extraUsers."${defaultUser}" =
|
||||||
@ -125,7 +124,6 @@ in {
|
|||||||
STNOUPGRADE = "yes";
|
STNOUPGRADE = "yes";
|
||||||
inherit (cfg) all_proxy;
|
inherit (cfg) all_proxy;
|
||||||
} // config.networking.proxy.envVars;
|
} // config.networking.proxy.envVars;
|
||||||
wants = mkIf cfg.useInotify [ "syncthing-inotify.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
@ -141,20 +139,6 @@ in {
|
|||||||
syncthing-resume = {
|
syncthing-resume = {
|
||||||
wantedBy = [ "suspend.target" ];
|
wantedBy = [ "suspend.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
syncthing-inotify = mkIf (cfg.systemService && cfg.useInotify) {
|
|
||||||
description = "Syncthing Inotify File Watcher service";
|
|
||||||
after = [ "network.target" "syncthing.service" ];
|
|
||||||
requires = [ "syncthing.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
SuccessExitStatus = "2";
|
|
||||||
RestartForceExitStatus = "3";
|
|
||||||
Restart = "on-failure";
|
|
||||||
User = cfg.user;
|
|
||||||
ExecStart = "${pkgs.syncthing-inotify.bin}/bin/syncthing-inotify -home=${cfg.dataDir} -logflags=0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ in {
|
|||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
ExecStart = ''${pkgs.usbguard}/bin/usbguard-daemon -d -k -c ${daemonConfFile}'';
|
ExecStart = ''${pkgs.usbguard}/bin/usbguard-daemon -P -d -k -c ${daemonConfFile}'';
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
version="5.0"
|
version="5.0"
|
||||||
xml:id="module-services-piwik">
|
xml:id="module-services-matomo">
|
||||||
|
|
||||||
<title>Piwik</title>
|
<title>Matomo</title>
|
||||||
<para>
|
<para>
|
||||||
Piwik is a real-time web analytics application.
|
Matomo is a real-time web analytics application.
|
||||||
This module configures php-fpm as backend for piwik, optionally configuring an nginx vhost as well.
|
This module configures php-fpm as backend for Matomo, optionally configuring an nginx vhost as well.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
An automatic setup is not suported by piwik, so you need to configure piwik itself in the browser-based piwik setup.
|
An automatic setup is not suported by Matomo, so you need to configure Matomo itself in the browser-based Matomo setup.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<title>Database Setup</title>
|
<title>Database Setup</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
You also need to configure a MariaDB or MySQL database and -user for piwik yourself,
|
You also need to configure a MariaDB or MySQL database and -user for Matomo yourself,
|
||||||
and enter those credentials in your browser.
|
and enter those credentials in your browser.
|
||||||
You can use passwordless database authentication via the UNIX_SOCKET authentication plugin
|
You can use passwordless database authentication via the UNIX_SOCKET authentication plugin
|
||||||
with the following SQL commands:
|
with the following SQL commands:
|
||||||
@ -27,20 +27,20 @@
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
# For MariaDB
|
# For MariaDB
|
||||||
INSTALL PLUGIN unix_socket SONAME 'auth_socket';
|
INSTALL PLUGIN unix_socket SONAME 'auth_socket';
|
||||||
CREATE DATABASE piwik;
|
CREATE DATABASE matomo;
|
||||||
CREATE USER 'piwik'@'localhost' IDENTIFIED WITH unix_socket;
|
CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket;
|
||||||
GRANT ALL PRIVILEGES ON piwik.* TO 'piwik'@'localhost';
|
GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
|
||||||
|
|
||||||
# For MySQL
|
# For MySQL
|
||||||
INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
|
INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
|
||||||
CREATE DATABASE piwik;
|
CREATE DATABASE matomo;
|
||||||
CREATE USER 'piwik'@'localhost' IDENTIFIED WITH auth_socket;
|
CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket;
|
||||||
GRANT ALL PRIVILEGES ON piwik.* TO 'piwik'@'localhost';
|
GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
Then fill in <literal>piwik</literal> as database user and database name, and leave the password field blank.
|
Then fill in <literal>matomo</literal> as database user and database name, and leave the password field blank.
|
||||||
This authentication works by allowing only the <literal>piwik</literal> unix user to authenticate as the
|
This authentication works by allowing only the <literal>matomo</literal> unix user to authenticate as the
|
||||||
<literal>piwik</literal> database user (without needing a password), but no other users.
|
<literal>matomo</literal> database user (without needing a password), but no other users.
|
||||||
For more information on passwordless login, see
|
For more information on passwordless login, see
|
||||||
<link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/" />.
|
<link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/" />.
|
||||||
</para>
|
</para>
|
||||||
@ -55,9 +55,9 @@
|
|||||||
<title>Backup</title>
|
<title>Backup</title>
|
||||||
<para>
|
<para>
|
||||||
You only need to take backups of your MySQL database and the
|
You only need to take backups of your MySQL database and the
|
||||||
<filename>/var/lib/piwik/config/config.ini.php</filename> file.
|
<filename>/var/lib/matomo/config/config.ini.php</filename> file.
|
||||||
Use a user in the <literal>piwik</literal> group or root to access the file.
|
Use a user in the <literal>matomo</literal> group or root to access the file.
|
||||||
For more information, see <link xlink:href="https://piwik.org/faq/how-to-install/faq_138/" />.
|
For more information, see <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/" />.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -67,14 +67,14 @@
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Piwik's file integrity check will warn you.
|
Matomo's file integrity check will warn you.
|
||||||
This is due to the patches necessary for NixOS, you can safely ignore this.
|
This is due to the patches necessary for NixOS, you can safely ignore this.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Piwik will warn you that the JavaScript tracker is not writable.
|
Matomo will warn you that the JavaScript tracker is not writable.
|
||||||
This is because it's located in the read-only nix store.
|
This is because it's located in the read-only nix store.
|
||||||
You can safely ignore this, unless you need a plugin that needs JavaScript tracker access.
|
You can safely ignore this, unless you need a plugin that needs JavaScript tracker access.
|
||||||
</para>
|
</para>
|
||||||
@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
You can use other web servers by forwarding calls for <filename>index.php</filename> and
|
You can use other web servers by forwarding calls for <filename>index.php</filename> and
|
||||||
<filename>piwik.php</filename> to the <literal>/run/phpfpm-piwik.sock</literal> fastcgi unix socket.
|
<filename>piwik.php</filename> to the <literal>/run/phpfpm-matomo.sock</literal> fastcgi unix socket.
|
||||||
You can use the nginx configuration in the module code as a reference to what else should be configured.
|
You can use the nginx configuration in the module code as a reference to what else should be configured.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
@ -1,10 +1,11 @@
|
|||||||
{ config, lib, pkgs, services, ... }:
|
{ config, lib, pkgs, services, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.services.piwik;
|
cfg = config.services.matomo;
|
||||||
|
|
||||||
user = "piwik";
|
user = "matomo";
|
||||||
dataDir = "/var/lib/${user}";
|
dataDir = "/var/lib/${user}";
|
||||||
|
deprecatedDataDir = "/var/lib/piwik";
|
||||||
|
|
||||||
pool = user;
|
pool = user;
|
||||||
# it's not possible to use /run/phpfpm/${pool}.sock because /run/phpfpm/ is root:root 0770,
|
# it's not possible to use /run/phpfpm/${pool}.sock because /run/phpfpm/ is root:root 0770,
|
||||||
@ -13,17 +14,22 @@ let
|
|||||||
phpExecutionUnit = "phpfpm-${pool}";
|
phpExecutionUnit = "phpfpm-${pool}";
|
||||||
databaseService = "mysql.service";
|
databaseService = "mysql.service";
|
||||||
|
|
||||||
|
fqdn =
|
||||||
|
let
|
||||||
|
join = hostName: domain: hostName + optionalString (domain != null) ".${domain}";
|
||||||
|
in join config.networking.hostName config.networking.domain;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
services.piwik = {
|
services.matomo = {
|
||||||
# NixOS PR for database setup: https://github.com/NixOS/nixpkgs/pull/6963
|
# NixOS PR for database setup: https://github.com/NixOS/nixpkgs/pull/6963
|
||||||
# piwik issue for automatic piwik setup: https://github.com/piwik/piwik/issues/10257
|
# matomo issue for automatic matomo setup: https://github.com/matomo-org/matomo/issues/10257
|
||||||
# TODO: find a nice way to do this when more NixOS MySQL and / or piwik automatic setup stuff is implemented.
|
# TODO: find a nice way to do this when more NixOS MySQL and / or matomo automatic setup stuff is implemented.
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Enable piwik web analytics with php-fpm backend.
|
Enable matomo web analytics with php-fpm backend.
|
||||||
Either the nginx option or the webServerUser option is mandatory.
|
Either the nginx option or the webServerUser option is mandatory.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -32,8 +38,9 @@ in {
|
|||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = null;
|
default = null;
|
||||||
example = "lighttpd";
|
example = "lighttpd";
|
||||||
|
# TODO: piwik.php might get renamed to matomo.php in future releases
|
||||||
description = ''
|
description = ''
|
||||||
Name of the web server user that forwards requests to the ${phpSocket} fastcgi socket for piwik if the nginx
|
Name of the web server user that forwards requests to the ${phpSocket} fastcgi socket for matomo if the nginx
|
||||||
option is not used. Either this option or the nginx option is mandatory.
|
option is not used. Either this option or the nginx option is mandatory.
|
||||||
If you want to use another webserver than nginx, you need to set this to that server's user
|
If you want to use another webserver than nginx, you need to set this to that server's user
|
||||||
and pass fastcgi requests to `index.php` and `piwik.php` to this socket.
|
and pass fastcgi requests to `index.php` and `piwik.php` to this socket.
|
||||||
@ -55,7 +62,7 @@ in {
|
|||||||
catch_workers_output = yes
|
catch_workers_output = yes
|
||||||
'';
|
'';
|
||||||
description = ''
|
description = ''
|
||||||
Settings for phpfpm's process manager. You might need to change this depending on the load for piwik.
|
Settings for phpfpm's process manager. You might need to change this depending on the load for matomo.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,7 +72,7 @@ in {
|
|||||||
(import ../web-servers/nginx/vhost-options.nix { inherit config lib; })
|
(import ../web-servers/nginx/vhost-options.nix { inherit config lib; })
|
||||||
{
|
{
|
||||||
# enable encryption by default,
|
# enable encryption by default,
|
||||||
# as sensitive login and piwik data should not be transmitted in clear text.
|
# as sensitive login and matomo data should not be transmitted in clear text.
|
||||||
options.forceSSL.default = true;
|
options.forceSSL.default = true;
|
||||||
options.enableACME.default = true;
|
options.enableACME.default = true;
|
||||||
}
|
}
|
||||||
@ -73,15 +80,19 @@ in {
|
|||||||
);
|
);
|
||||||
default = null;
|
default = null;
|
||||||
example = {
|
example = {
|
||||||
serverName = "stats.$\{config.networking.hostName\}";
|
serverAliases = [
|
||||||
|
"matomo.$\{config.networking.domain\}"
|
||||||
|
"stats.$\{config.networking.domain\}"
|
||||||
|
];
|
||||||
enableACME = false;
|
enableACME = false;
|
||||||
};
|
};
|
||||||
description = ''
|
description = ''
|
||||||
With this option, you can customize an nginx virtualHost which already has sensible defaults for piwik.
|
With this option, you can customize an nginx virtualHost which already has sensible defaults for matomo.
|
||||||
Either this option or the webServerUser option is mandatory.
|
Either this option or the webServerUser option is mandatory.
|
||||||
Set this to {} to just enable the virtualHost if you don't need any customization.
|
Set this to {} to just enable the virtualHost if you don't need any customization.
|
||||||
If enabled, then by default, the serverName is piwik.$\{config.networking.hostName\}, SSL is active,
|
If enabled, then by default, the <option>serverName</option> is
|
||||||
and certificates are acquired via ACME.
|
<literal>${user}.$\{config.networking.hostName\}.$\{config.networking.domain\}</literal>,
|
||||||
|
SSL is active, and certificates are acquired via ACME.
|
||||||
If this is set to null (the default), no nginx virtualHost will be configured.
|
If this is set to null (the default), no nginx virtualHost will be configured.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -90,12 +101,12 @@ in {
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
warnings = mkIf (cfg.nginx != null && cfg.webServerUser != null) [
|
warnings = mkIf (cfg.nginx != null && cfg.webServerUser != null) [
|
||||||
"If services.piwik.nginx is set, services.piwik.nginx.webServerUser is ignored and should be removed."
|
"If services.matomo.nginx is set, services.matomo.nginx.webServerUser is ignored and should be removed."
|
||||||
];
|
];
|
||||||
|
|
||||||
assertions = [ {
|
assertions = [ {
|
||||||
assertion = cfg.nginx != null || cfg.webServerUser != null;
|
assertion = cfg.nginx != null || cfg.webServerUser != null;
|
||||||
message = "Either services.piwik.nginx or services.piwik.nginx.webServerUser is mandatory";
|
message = "Either services.matomo.nginx or services.matomo.nginx.webServerUser is mandatory";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
users.extraUsers.${user} = {
|
users.extraUsers.${user} = {
|
||||||
@ -106,19 +117,20 @@ in {
|
|||||||
};
|
};
|
||||||
users.extraGroups.${user} = {};
|
users.extraGroups.${user} = {};
|
||||||
|
|
||||||
systemd.services.piwik_setup_update = {
|
systemd.services.matomo_setup_update = {
|
||||||
# everything needs to set up and up to date before piwik php files are executed
|
# everything needs to set up and up to date before matomo php files are executed
|
||||||
requiredBy = [ "${phpExecutionUnit}.service" ];
|
requiredBy = [ "${phpExecutionUnit}.service" ];
|
||||||
before = [ "${phpExecutionUnit}.service" ];
|
before = [ "${phpExecutionUnit}.service" ];
|
||||||
# the update part of the script can only work if the database is already up and running
|
# the update part of the script can only work if the database is already up and running
|
||||||
requires = [ databaseService ];
|
requires = [ databaseService ];
|
||||||
after = [ databaseService ];
|
after = [ databaseService ];
|
||||||
path = [ pkgs.piwik ];
|
path = [ pkgs.matomo ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
User = user;
|
User = user;
|
||||||
# hide especially config.ini.php from other
|
# hide especially config.ini.php from other
|
||||||
UMask = "0007";
|
UMask = "0007";
|
||||||
|
# TODO: might get renamed to MATOMO_USER_PATH in future versions
|
||||||
Environment = "PIWIK_USER_PATH=${dataDir}";
|
Environment = "PIWIK_USER_PATH=${dataDir}";
|
||||||
# chown + chmod in preStart needs root
|
# chown + chmod in preStart needs root
|
||||||
PermissionsStartOnly = true;
|
PermissionsStartOnly = true;
|
||||||
@ -127,27 +139,32 @@ in {
|
|||||||
# e.g. after restoring from backup or moving from another system.
|
# e.g. after restoring from backup or moving from another system.
|
||||||
# Note that ${dataDir}/config/config.ini.php might contain the MySQL password.
|
# Note that ${dataDir}/config/config.ini.php might contain the MySQL password.
|
||||||
preStart = ''
|
preStart = ''
|
||||||
|
# migrate data from piwik to matomo folder
|
||||||
|
if [ -d ${deprecatedDataDir} ]; then
|
||||||
|
echo "Migrating from ${deprecatedDataDir} to ${dataDir}"
|
||||||
|
mv -T ${deprecatedDataDir} ${dataDir}
|
||||||
|
fi
|
||||||
chown -R ${user}:${user} ${dataDir}
|
chown -R ${user}:${user} ${dataDir}
|
||||||
chmod -R ug+rwX,o-rwx ${dataDir}
|
chmod -R ug+rwX,o-rwx ${dataDir}
|
||||||
'';
|
'';
|
||||||
script = ''
|
script = ''
|
||||||
# Use User-Private Group scheme to protect piwik data, but allow administration / backup via piwik group
|
# Use User-Private Group scheme to protect matomo data, but allow administration / backup via matomo group
|
||||||
# Copy config folder
|
# Copy config folder
|
||||||
chmod g+s "${dataDir}"
|
chmod g+s "${dataDir}"
|
||||||
cp -r "${pkgs.piwik}/config" "${dataDir}/"
|
cp -r "${pkgs.matomo}/config" "${dataDir}/"
|
||||||
chmod -R u+rwX,g+rwX,o-rwx "${dataDir}"
|
chmod -R u+rwX,g+rwX,o-rwx "${dataDir}"
|
||||||
|
|
||||||
# check whether user setup has already been done
|
# check whether user setup has already been done
|
||||||
if test -f "${dataDir}/config/config.ini.php"; then
|
if test -f "${dataDir}/config/config.ini.php"; then
|
||||||
# then execute possibly pending database upgrade
|
# then execute possibly pending database upgrade
|
||||||
piwik-console core:update --yes
|
matomo-console core:update --yes
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.${phpExecutionUnit} = {
|
systemd.services.${phpExecutionUnit} = {
|
||||||
# stop phpfpm on package upgrade, do database upgrade via piwik_setup_update, and then restart
|
# stop phpfpm on package upgrade, do database upgrade via matomo_setup_update, and then restart
|
||||||
restartTriggers = [ pkgs.piwik ];
|
restartTriggers = [ pkgs.matomo ];
|
||||||
# stop config.ini.php from getting written with read permission for others
|
# stop config.ini.php from getting written with read permission for others
|
||||||
serviceConfig.UMask = "0007";
|
serviceConfig.UMask = "0007";
|
||||||
};
|
};
|
||||||
@ -175,14 +192,14 @@ in {
|
|||||||
# References:
|
# References:
|
||||||
# https://fralef.me/piwik-hardening-with-nginx-and-php-fpm.html
|
# https://fralef.me/piwik-hardening-with-nginx-and-php-fpm.html
|
||||||
# https://github.com/perusio/piwik-nginx
|
# https://github.com/perusio/piwik-nginx
|
||||||
"${user}.${config.networking.hostName}" = mkMerge [ cfg.nginx {
|
"${user}.${fqdn}" = mkMerge [ cfg.nginx {
|
||||||
# don't allow to override the root easily, as it will almost certainly break piwik.
|
# don't allow to override the root easily, as it will almost certainly break matomo.
|
||||||
# disadvantage: not shown as default in docs.
|
# disadvantage: not shown as default in docs.
|
||||||
root = mkForce "${pkgs.piwik}/share";
|
root = mkForce "${pkgs.matomo}/share";
|
||||||
|
|
||||||
# define locations here instead of as the submodule option's default
|
# define locations here instead of as the submodule option's default
|
||||||
# so that they can easily be extended with additional locations if required
|
# so that they can easily be extended with additional locations if required
|
||||||
# without needing to redefine the piwik ones.
|
# without needing to redefine the matomo ones.
|
||||||
# disadvantage: not shown as default in docs.
|
# disadvantage: not shown as default in docs.
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
index = "index.php";
|
index = "index.php";
|
||||||
@ -191,6 +208,7 @@ in {
|
|||||||
locations."= /index.php".extraConfig = ''
|
locations."= /index.php".extraConfig = ''
|
||||||
fastcgi_pass unix:${phpSocket};
|
fastcgi_pass unix:${phpSocket};
|
||||||
'';
|
'';
|
||||||
|
# TODO: might get renamed to matomo.php in future versions
|
||||||
# allow piwik.php for tracking
|
# allow piwik.php for tracking
|
||||||
locations."= /piwik.php".extraConfig = ''
|
locations."= /piwik.php".extraConfig = ''
|
||||||
fastcgi_pass unix:${phpSocket};
|
fastcgi_pass unix:${phpSocket};
|
||||||
@ -212,6 +230,7 @@ in {
|
|||||||
locations."= /robots.txt".extraConfig = ''
|
locations."= /robots.txt".extraConfig = ''
|
||||||
return 200 "User-agent: *\nDisallow: /\n";
|
return 200 "User-agent: *\nDisallow: /\n";
|
||||||
'';
|
'';
|
||||||
|
# TODO: might get renamed to matomo.js in future versions
|
||||||
# let browsers cache piwik.js
|
# let browsers cache piwik.js
|
||||||
locations."= /piwik.js".extraConfig = ''
|
locations."= /piwik.js".extraConfig = ''
|
||||||
expires 1M;
|
expires 1M;
|
||||||
@ -221,7 +240,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
doc = ./piwik-doc.xml;
|
doc = ./matomo-doc.xml;
|
||||||
maintainers = with stdenv.lib.maintainers; [ florianjacob ];
|
maintainers = with stdenv.lib.maintainers; [ florianjacob ];
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,23 +0,0 @@
|
|||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
var opts = JSON.parse(fs.readFileSync("/dev/stdin").toString());
|
|
||||||
var config = opts.config;
|
|
||||||
|
|
||||||
var readSecret = function(filename) {
|
|
||||||
return fs.readFileSync(filename).toString().trim();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (opts.secretFile) {
|
|
||||||
config.secret = readSecret(opts.secretFile);
|
|
||||||
}
|
|
||||||
if (opts.dbPasswordFile) {
|
|
||||||
config.params.dbpass = readSecret(opts.dbPasswordFile);
|
|
||||||
}
|
|
||||||
if (opts.smtpPasswordFile) {
|
|
||||||
config.smtppass = readSecret(opts.smtpPasswordFile);
|
|
||||||
}
|
|
||||||
if (opts.spamClientSecretFile) {
|
|
||||||
config.spamclientsecret = readSecret(opts.opts.spamClientSecretFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(opts.outputFile, JSON.stringify(config));
|
|
@ -1,438 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.pumpio;
|
|
||||||
dataDir = "/var/lib/pump.io";
|
|
||||||
runDir = "/run/pump.io";
|
|
||||||
user = "pumpio";
|
|
||||||
|
|
||||||
optionalSet = condition: value: if condition then value else {};
|
|
||||||
|
|
||||||
configScript = ./pump.io-configure.js;
|
|
||||||
configOptions = {
|
|
||||||
outputFile = "${runDir}/config.json";
|
|
||||||
config =
|
|
||||||
(optionalSet (cfg.driver != "disk") {
|
|
||||||
driver = cfg.driver;
|
|
||||||
}) //
|
|
||||||
{
|
|
||||||
params = (optionalSet (cfg.driver == "disk") { dir = dataDir; }) //
|
|
||||||
(optionalSet (cfg.driver == "mongodb" || cfg.driver == "redis") {
|
|
||||||
host = cfg.dbHost;
|
|
||||||
port = cfg.dbPort;
|
|
||||||
dbname = cfg.dbName;
|
|
||||||
dbuser = cfg.dbUser;
|
|
||||||
dbpass = cfg.dbPassword;
|
|
||||||
}) //
|
|
||||||
(optionalSet (cfg.driver == "memcached") {
|
|
||||||
host = cfg.dbHost;
|
|
||||||
port = cfg.dbPort;
|
|
||||||
}) // cfg.driverParams;
|
|
||||||
secret = cfg.secret;
|
|
||||||
|
|
||||||
address = cfg.address;
|
|
||||||
port = cfg.port;
|
|
||||||
|
|
||||||
noweb = false;
|
|
||||||
urlPort = cfg.urlPort;
|
|
||||||
hostname = cfg.hostname;
|
|
||||||
favicon = cfg.favicon;
|
|
||||||
|
|
||||||
site = cfg.site;
|
|
||||||
owner = cfg.owner;
|
|
||||||
ownerURL = cfg.ownerURL;
|
|
||||||
|
|
||||||
key = cfg.sslKey;
|
|
||||||
cert = cfg.sslCert;
|
|
||||||
bounce = false;
|
|
||||||
|
|
||||||
spamhost = cfg.spamHost;
|
|
||||||
spamclientid = cfg.spamClientId;
|
|
||||||
spamclientsecret = cfg.spamClientSecret;
|
|
||||||
|
|
||||||
requireEmail = cfg.requireEmail;
|
|
||||||
smtpserver = cfg.smtpHost;
|
|
||||||
smtpport = cfg.smtpPort;
|
|
||||||
smtpuser = cfg.smtpUser;
|
|
||||||
smtppass = cfg.smtpPassword;
|
|
||||||
smtpusessl = cfg.smtpUseSSL;
|
|
||||||
smtpfrom = cfg.smtpFrom;
|
|
||||||
|
|
||||||
nologger = false;
|
|
||||||
enableUploads = cfg.enableUploads;
|
|
||||||
datadir = dataDir;
|
|
||||||
debugClient = false;
|
|
||||||
firehose = cfg.firehose;
|
|
||||||
disableRegistration = cfg.disableRegistration;
|
|
||||||
|
|
||||||
inherit (cfg) secretFile dbPasswordFile smtpPasswordFile spamClientSecretFile;
|
|
||||||
} //
|
|
||||||
(optionalSet (cfg.port < 1024) {
|
|
||||||
serverUser = user; # have pump.io listen then drop privileges
|
|
||||||
}) // cfg.extraConfig;
|
|
||||||
}; in {
|
|
||||||
options = {
|
|
||||||
|
|
||||||
services.pumpio = {
|
|
||||||
|
|
||||||
enable = mkEnableOption "Pump.io social streams server";
|
|
||||||
|
|
||||||
secret = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "my dog has fleas";
|
|
||||||
description = ''
|
|
||||||
A session-generating secret, server-wide password. Warning:
|
|
||||||
this is stored in cleartext in the Nix store!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
secretFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/run/keys/pump.io-secret";
|
|
||||||
description = ''
|
|
||||||
A file containing the session-generating secret,
|
|
||||||
server-wide password.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
site = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "Awesome Sauce";
|
|
||||||
description = "Name of the server";
|
|
||||||
};
|
|
||||||
|
|
||||||
owner = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
example = "Awesome Inc.";
|
|
||||||
description = "Name of owning entity, if you want to link to it.";
|
|
||||||
};
|
|
||||||
|
|
||||||
ownerURL = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
example = "https://pump.io";
|
|
||||||
description = "URL of owning entity, if you want to link to it.";
|
|
||||||
};
|
|
||||||
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = ''
|
|
||||||
Web server listen address.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 31337;
|
|
||||||
description = ''
|
|
||||||
Port to listen on. Defaults to 31337, which is suitable for
|
|
||||||
running behind a reverse proxy. For a standalone server,
|
|
||||||
use 443.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
hostname = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = ''
|
|
||||||
The hostname of the server, used for generating
|
|
||||||
URLs. Defaults to "localhost" which doesn't do much for you.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
urlPort = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 443;
|
|
||||||
description = ''
|
|
||||||
Port to use for generating URLs. This basically has to be
|
|
||||||
either 80 or 443 because the host-meta and Webfinger
|
|
||||||
protocols don't make any provision for HTTP/HTTPS servers
|
|
||||||
running on other ports.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
favicon = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Local filesystem path to the favicon.ico file to use. This
|
|
||||||
will be served as "/favicon.ico" by the server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enableUploads = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
If you want to disable file uploads, set this to false. Uploaded files will be stored
|
|
||||||
in ${dataDir}/uploads.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sslKey = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
example = "${dataDir}/myserver.key";
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
The path to the server certificate private key. The
|
|
||||||
certificate is required, but it can be self-signed.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sslCert = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
example = "${dataDir}/myserver.crt";
|
|
||||||
default = "";
|
|
||||||
description = ''
|
|
||||||
The path to the server certificate. The certificate is
|
|
||||||
required, but it can be self-signed.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
firehose = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "ofirehose.com";
|
|
||||||
description = ''
|
|
||||||
Firehose host running the ofirehose software. Defaults to
|
|
||||||
"ofirehose.com". Public notices will be ping this firehose
|
|
||||||
server and from there go out to search engines and the
|
|
||||||
world. If you want to disconnect from the public web, set
|
|
||||||
this to something falsy.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
disableRegistration = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Disables registering new users on the site through the Web
|
|
||||||
or the API.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
requireEmail = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Require an e-mail address to register.";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Extra configuration options which are serialized to json and added
|
|
||||||
to the pump.io.json config file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
driver = mkOption {
|
|
||||||
type = types.enum [ "mongodb" "disk" "lrucache" "memcached" "redis" ];
|
|
||||||
default = "mongodb";
|
|
||||||
description = "Type of database. Corresponds to a nodejs databank driver.";
|
|
||||||
};
|
|
||||||
|
|
||||||
driverParams = mkOption {
|
|
||||||
default = { };
|
|
||||||
description = "Extra parameters for the driver.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbHost = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = "The database host to connect to.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbPort = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 27017;
|
|
||||||
description = "The port that the database is listening on.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "pumpio";
|
|
||||||
description = "The name of the database to use.";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbUser = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The username. Defaults to null, meaning no authentication.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dbPassword = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The password corresponding to dbUser. Warning: this is
|
|
||||||
stored in cleartext in the Nix store!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dbPasswordFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/run/keys/pump.io-dbpassword";
|
|
||||||
description = ''
|
|
||||||
A file containing the password corresponding to dbUser.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpHost = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "localhost";
|
|
||||||
description = ''
|
|
||||||
Server to use for sending transactional email. If it's not
|
|
||||||
set up, no email is sent and features like password recovery
|
|
||||||
and email notification won't work.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpPort = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 25;
|
|
||||||
description = ''
|
|
||||||
Port to connect to on SMTP server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpUser = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Username to use to connect to SMTP server. Might not be
|
|
||||||
necessary for some servers.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpPassword = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Password to use to connect to SMTP server. Might not be
|
|
||||||
necessary for some servers. Warning: this is stored in
|
|
||||||
cleartext in the Nix store!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpPasswordFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/run/keys/pump.io-smtppassword";
|
|
||||||
description = ''
|
|
||||||
A file containing the password used to connect to SMTP
|
|
||||||
server. Might not be necessary for some servers.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
smtpUseSSL = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Only use SSL with the SMTP server. By default, a SSL
|
|
||||||
connection is negotiated using TLS. You may need to change
|
|
||||||
the smtpPort value if you set this.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpFrom = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Email address to use in the "From:" header of outgoing
|
|
||||||
notifications. Defaults to 'no-reply@' plus the site
|
|
||||||
hostname.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
spamHost = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Host running activityspam software to use to test updates
|
|
||||||
for spam.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
spamClientId = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "OAuth pair for spam server.";
|
|
||||||
};
|
|
||||||
spamClientSecret = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
OAuth pair for spam server. Warning: this is
|
|
||||||
stored in cleartext in the Nix store!
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
spamClientSecretFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
example = "/run/keys/pump.io-spamclientsecret";
|
|
||||||
description = ''
|
|
||||||
A file containing the OAuth key for the spam server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
warnings = let warn = k: optional (cfg.${k} != null)
|
|
||||||
"config.services.pumpio.${k} is insecure. Use ${k}File instead.";
|
|
||||||
in concatMap warn [ "secret" "dbPassword" "smtpPassword" "spamClientSecret" ];
|
|
||||||
|
|
||||||
assertions = [
|
|
||||||
{ assertion = !(isNull cfg.secret && isNull cfg.secretFile);
|
|
||||||
message = "pump.io needs a secretFile configured";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services."pump.io" =
|
|
||||||
{ description = "Pump.io - stream server that does most of what people really want from a social network";
|
|
||||||
after = [ "network.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
preStart = ''
|
|
||||||
mkdir -p ${dataDir}/uploads
|
|
||||||
mkdir -p ${runDir}
|
|
||||||
chown pumpio:pumpio ${dataDir}/uploads ${runDir}
|
|
||||||
chmod 770 ${dataDir}/uploads ${runDir}
|
|
||||||
|
|
||||||
${pkgs.nodejs}/bin/node ${configScript} <<EOF
|
|
||||||
${builtins.toJSON configOptions}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chgrp pumpio ${configOptions.outputFile}
|
|
||||||
chmod 640 ${configOptions.outputFile}
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.pumpio}/bin/pump -c ${configOptions.outputFile}";
|
|
||||||
PermissionsStartOnly = true;
|
|
||||||
User = if cfg.port < 1024 then "root" else user;
|
|
||||||
Group = user;
|
|
||||||
};
|
|
||||||
environment = { NODE_ENV = "production"; };
|
|
||||||
};
|
|
||||||
|
|
||||||
users.extraGroups.pumpio.gid = config.ids.gids.pumpio;
|
|
||||||
users.extraUsers.pumpio = {
|
|
||||||
group = "pumpio";
|
|
||||||
uid = config.ids.uids.pumpio;
|
|
||||||
description = "Pump.io user";
|
|
||||||
home = dataDir;
|
|
||||||
createHome = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -33,7 +33,7 @@ in
|
|||||||
pkgs.xorg.xauth # used by kdesu
|
pkgs.xorg.xauth # used by kdesu
|
||||||
pkgs.gtk2 # To get GTK+'s themes.
|
pkgs.gtk2 # To get GTK+'s themes.
|
||||||
pkgs.tango-icon-theme
|
pkgs.tango-icon-theme
|
||||||
pkgs.shared_mime_info
|
pkgs.shared-mime-info
|
||||||
pkgs.gnome2.gnomeicontheme
|
pkgs.gnome2.gnomeicontheme
|
||||||
pkgs.xorg.xcursorthemes
|
pkgs.xorg.xcursorthemes
|
||||||
];
|
];
|
||||||
|
@ -27,7 +27,7 @@ let
|
|||||||
nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" {}
|
nixos-gsettings-desktop-schemas = pkgs.runCommand "nixos-gsettings-desktop-schemas" {}
|
||||||
''
|
''
|
||||||
mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
|
mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
|
||||||
cp -rf ${pkgs.gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
|
cp -rf ${pkgs.gnome3.gsettings-desktop-schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
|
||||||
|
|
||||||
${concatMapStrings (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n") cfg.extraGSettingsOverridePackages}
|
${concatMapStrings (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n") cfg.extraGSettingsOverridePackages}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ in {
|
|||||||
example = literalExample "[ pkgs.gnome3.gpaste ]";
|
example = literalExample "[ pkgs.gnome3.gpaste ]";
|
||||||
description = "Additional list of packages to be added to the session search path.
|
description = "Additional list of packages to be added to the session search path.
|
||||||
Useful for gnome shell extensions or gsettings-conditionated autostart.";
|
Useful for gnome shell extensions or gsettings-conditionated autostart.";
|
||||||
apply = list: list ++ [ pkgs.gnome3.gnome_shell pkgs.gnome3.gnome-shell-extensions ];
|
apply = list: list ++ [ pkgs.gnome3.gnome-shell pkgs.gnome3.gnome-shell-extensions ];
|
||||||
};
|
};
|
||||||
|
|
||||||
extraGSettingsOverrides = mkOption {
|
extraGSettingsOverrides = mkOption {
|
||||||
@ -118,13 +118,13 @@ in {
|
|||||||
services.packagekit.enable = mkDefault true;
|
services.packagekit.enable = mkDefault true;
|
||||||
hardware.bluetooth.enable = mkDefault true;
|
hardware.bluetooth.enable = mkDefault true;
|
||||||
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
|
services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
|
||||||
services.udev.packages = [ pkgs.gnome3.gnome_settings_daemon ];
|
services.udev.packages = [ pkgs.gnome3.gnome-settings-daemon ];
|
||||||
systemd.packages = [ pkgs.gnome3.vino ];
|
systemd.packages = [ pkgs.gnome3.vino ];
|
||||||
|
|
||||||
# If gnome3 is installed, build vim for gtk3 too.
|
# If gnome3 is installed, build vim for gtk3 too.
|
||||||
nixpkgs.config.vim.gui = "gtk3";
|
nixpkgs.config.vim.gui = "gtk3";
|
||||||
|
|
||||||
fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
|
fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell-fonts ];
|
||||||
|
|
||||||
services.xserver.desktopManager.session = singleton
|
services.xserver.desktopManager.session = singleton
|
||||||
{ name = "gnome3";
|
{ name = "gnome3";
|
||||||
@ -164,7 +164,7 @@ in {
|
|||||||
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
|
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
|
||||||
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
|
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
|
||||||
|
|
||||||
${pkgs.gnome3.gnome_session}/bin/gnome-session ${optionalString cfg.debug "--debug"} &
|
${pkgs.gnome3.gnome-session}/bin/gnome-session ${optionalString cfg.debug "--debug"} &
|
||||||
waitPID=$!
|
waitPID=$!
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -172,7 +172,7 @@ in {
|
|||||||
services.xserver.updateDbusEnvironment = true;
|
services.xserver.updateDbusEnvironment = true;
|
||||||
|
|
||||||
environment.variables.GIO_EXTRA_MODULES = [ "${lib.getLib pkgs.gnome3.dconf}/lib/gio/modules"
|
environment.variables.GIO_EXTRA_MODULES = [ "${lib.getLib pkgs.gnome3.dconf}/lib/gio/modules"
|
||||||
"${pkgs.gnome3.glib_networking.out}/lib/gio/modules"
|
"${pkgs.gnome3.glib-networking.out}/lib/gio/modules"
|
||||||
"${pkgs.gnome3.gvfs}/lib/gio/modules" ];
|
"${pkgs.gnome3.gvfs}/lib/gio/modules" ];
|
||||||
environment.systemPackages = pkgs.gnome3.corePackages ++ cfg.sessionPath
|
environment.systemPackages = pkgs.gnome3.corePackages ++ cfg.sessionPath
|
||||||
++ (removePackagesByName pkgs.gnome3.optionalPackages config.environment.gnome3.excludePackages);
|
++ (removePackagesByName pkgs.gnome3.optionalPackages config.environment.gnome3.excludePackages);
|
||||||
@ -180,10 +180,10 @@ in {
|
|||||||
# Use the correct gnome3 packageSet
|
# Use the correct gnome3 packageSet
|
||||||
networking.networkmanager.basePackages =
|
networking.networkmanager.basePackages =
|
||||||
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant;
|
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant;
|
||||||
inherit (pkgs.gnome3) networkmanager_openvpn networkmanager_vpnc
|
inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
|
||||||
networkmanager_openconnect networkmanager_fortisslvpn
|
networkmanager-openconnect networkmanager-fortisslvpn
|
||||||
networkmanager_pptp networkmanager_iodine
|
networkmanager-pptp networkmanager-iodine
|
||||||
networkmanager_l2tp; };
|
networkmanager-l2tp; };
|
||||||
|
|
||||||
# Needed for themes and backgrounds
|
# Needed for themes and backgrounds
|
||||||
environment.pathsToLink = [ "/share" ];
|
environment.pathsToLink = [ "/share" ];
|
||||||
|
@ -102,7 +102,7 @@ in
|
|||||||
|
|
||||||
services.dbus.packages = [
|
services.dbus.packages = [
|
||||||
pkgs.gnome3.dconf
|
pkgs.gnome3.dconf
|
||||||
pkgs.at_spi2_core
|
pkgs.at-spi2-core
|
||||||
];
|
];
|
||||||
|
|
||||||
services.gnome3.gnome-keyring.enable = true;
|
services.gnome3.gnome-keyring.enable = true;
|
||||||
|
@ -154,7 +154,7 @@ in
|
|||||||
print-manager
|
print-manager
|
||||||
|
|
||||||
breeze-icons
|
breeze-icons
|
||||||
pkgs.hicolor_icon_theme
|
pkgs.hicolor-icon-theme
|
||||||
|
|
||||||
kde-gtk-config breeze-gtk
|
kde-gtk-config breeze-gtk
|
||||||
|
|
||||||
|
@ -61,12 +61,12 @@ in
|
|||||||
# utilities-terminal, accessories-text-editor
|
# utilities-terminal, accessories-text-editor
|
||||||
gnome3.defaultIconTheme
|
gnome3.defaultIconTheme
|
||||||
|
|
||||||
hicolor_icon_theme
|
hicolor-icon-theme
|
||||||
tango-icon-theme
|
tango-icon-theme
|
||||||
xfce4-icon-theme
|
xfce4-icon-theme
|
||||||
|
|
||||||
desktop_file_utils
|
desktop-file-utils
|
||||||
shared_mime_info
|
shared-mime-info
|
||||||
|
|
||||||
# Needed by Xfce's xinitrc script
|
# Needed by Xfce's xinitrc script
|
||||||
# TODO: replace with command -v
|
# TODO: replace with command -v
|
||||||
|
@ -133,7 +133,7 @@ in
|
|||||||
StandardError = "inherit";
|
StandardError = "inherit";
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.display-manager.path = [ pkgs.gnome3.gnome_session ];
|
systemd.services.display-manager.path = [ pkgs.gnome3.gnome-session ];
|
||||||
|
|
||||||
services.dbus.packages = [ gdm ];
|
services.dbus.packages = [ gdm ];
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ in
|
|||||||
auth required pam_env.so envfile=${config.system.build.pamEnvironment}
|
auth required pam_env.so envfile=${config.system.build.pamEnvironment}
|
||||||
|
|
||||||
auth required pam_succeed_if.so uid >= 1000 quiet
|
auth required pam_succeed_if.so uid >= 1000 quiet
|
||||||
auth optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so
|
auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so
|
||||||
auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
|
auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
|
||||||
${optionalString config.security.pam.enableEcryptfs
|
${optionalString config.security.pam.enableEcryptfs
|
||||||
"auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
"auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
||||||
@ -213,7 +213,7 @@ in
|
|||||||
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
||||||
session required pam_loginuid.so
|
session required pam_loginuid.so
|
||||||
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
|
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
|
||||||
session optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start
|
session optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
|
||||||
'';
|
'';
|
||||||
|
|
||||||
gdm-password.text = ''
|
gdm-password.text = ''
|
||||||
@ -221,7 +221,7 @@ in
|
|||||||
auth required pam_env.so envfile=${config.system.build.pamEnvironment}
|
auth required pam_env.so envfile=${config.system.build.pamEnvironment}
|
||||||
|
|
||||||
auth required pam_succeed_if.so uid >= 1000 quiet
|
auth required pam_succeed_if.so uid >= 1000 quiet
|
||||||
auth optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so
|
auth optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so
|
||||||
auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
|
auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
|
||||||
${optionalString config.security.pam.enableEcryptfs
|
${optionalString config.security.pam.enableEcryptfs
|
||||||
"auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
"auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
|
||||||
@ -240,7 +240,7 @@ in
|
|||||||
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
"session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
|
||||||
session required pam_loginuid.so
|
session required pam_loginuid.so
|
||||||
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
|
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
|
||||||
session optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start
|
session optional ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
|
||||||
'';
|
'';
|
||||||
|
|
||||||
gdm-autologin.text = ''
|
gdm-autologin.text = ''
|
||||||
|
@ -68,8 +68,8 @@ in
|
|||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.gnome3.gnome_themes_standard;
|
default = pkgs.gnome3.gnome-themes-standard;
|
||||||
defaultText = "pkgs.gnome3.gnome_themes_standard";
|
defaultText = "pkgs.gnome3.gnome-themes-standard";
|
||||||
description = ''
|
description = ''
|
||||||
The package path that contains the theme given in the name option.
|
The package path that contains the theme given in the name option.
|
||||||
'';
|
'';
|
||||||
|
@ -9,6 +9,10 @@ let
|
|||||||
xEnv = config.systemd.services."display-manager".environment;
|
xEnv = config.systemd.services."display-manager".environment;
|
||||||
cfg = dmcfg.lightdm;
|
cfg = dmcfg.lightdm;
|
||||||
|
|
||||||
|
dmDefault = xcfg.desktopManager.default;
|
||||||
|
wmDefault = xcfg.windowManager.default;
|
||||||
|
hasDefaultUserSession = dmDefault != "none" || wmDefault != "none";
|
||||||
|
|
||||||
inherit (pkgs) stdenv lightdm writeScript writeText;
|
inherit (pkgs) stdenv lightdm writeScript writeText;
|
||||||
|
|
||||||
# lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup
|
# lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup
|
||||||
@ -54,14 +58,13 @@ let
|
|||||||
autologin-user-timeout = ${toString cfg.autoLogin.timeout}
|
autologin-user-timeout = ${toString cfg.autoLogin.timeout}
|
||||||
autologin-session = ${defaultSessionName}
|
autologin-session = ${defaultSessionName}
|
||||||
''}
|
''}
|
||||||
|
${optionalString hasDefaultUserSession ''
|
||||||
|
user-session=${defaultSessionName}
|
||||||
|
''}
|
||||||
${cfg.extraSeatDefaults}
|
${cfg.extraSeatDefaults}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
defaultSessionName =
|
defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault);
|
||||||
let
|
|
||||||
dm = xcfg.desktopManager.default;
|
|
||||||
wm = xcfg.windowManager.default;
|
|
||||||
in dm + optionalString (wm != "none") ("+" + wm);
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Note: the order in which lightdm greeter modules are imported
|
# Note: the order in which lightdm greeter modules are imported
|
||||||
@ -179,6 +182,14 @@ in
|
|||||||
default session: ${defaultSessionName} is not valid.
|
default session: ${defaultSessionName} is not valid.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
{ assertion = hasDefaultUserSession -> elem defaultSessionName dmcfg.session.names;
|
||||||
|
message = ''
|
||||||
|
services.xserver.desktopManager.default and
|
||||||
|
services.xserver.windowMananger.default are not set to valid
|
||||||
|
values. The current default session: ${defaultSessionName}
|
||||||
|
is not valid.
|
||||||
|
'';
|
||||||
|
}
|
||||||
{ assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0);
|
{ assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0);
|
||||||
message = ''
|
message = ''
|
||||||
LightDM can only run without greeter if automatic login is enabled and the timeout for it
|
LightDM can only run without greeter if automatic login is enabled and the timeout for it
|
||||||
|
@ -117,14 +117,7 @@ in
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
system.activationScripts.stdio =
|
system.activationScripts.stdio = ""; # obsolete
|
||||||
''
|
|
||||||
# Needed by some programs.
|
|
||||||
ln -sfn /proc/self/fd /dev/fd
|
|
||||||
ln -sfn /proc/self/fd/0 /dev/stdin
|
|
||||||
ln -sfn /proc/self/fd/1 /dev/stdout
|
|
||||||
ln -sfn /proc/self/fd/2 /dev/stderr
|
|
||||||
'';
|
|
||||||
|
|
||||||
system.activationScripts.var =
|
system.activationScripts.var =
|
||||||
''
|
''
|
||||||
|
@ -118,7 +118,7 @@ in
|
|||||||
echo ${escapeShellArg key} >> /root/.ssh/authorized_keys
|
echo ${escapeShellArg key} >> /root/.ssh/authorized_keys
|
||||||
'') cfg.authorizedKeys)}
|
'') cfg.authorizedKeys)}
|
||||||
|
|
||||||
dropbear -s -j -k -E -m -p ${toString cfg.port} ${optionalString (cfg.hostRSAKey == null && cfg.hostDSSKey == null && cfg.hostECDSAKey == null) "-R"}
|
dropbear -s -j -k -E -p ${toString cfg.port} ${optionalString (cfg.hostRSAKey == null && cfg.hostDSSKey == null && cfg.hostECDSAKey == null) "-R"}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
boot.initrd.secrets =
|
boot.initrd.secrets =
|
||||||
|
@ -5,7 +5,7 @@ with lib;
|
|||||||
let
|
let
|
||||||
luks = config.boot.initrd.luks;
|
luks = config.boot.initrd.luks;
|
||||||
|
|
||||||
openCommand = name': { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, ... }: assert name' == name; ''
|
openCommand = name': { name, device, header, keyFile, keyFileSize, allowDiscards, yubikey, fallbackToPassword, ... }: assert name' == name; ''
|
||||||
|
|
||||||
# Wait for a target (e.g. device, keyFile, header, ...) to appear.
|
# Wait for a target (e.g. device, keyFile, header, ...) to appear.
|
||||||
wait_target() {
|
wait_target() {
|
||||||
@ -43,8 +43,17 @@ let
|
|||||||
open_normally() {
|
open_normally() {
|
||||||
echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
|
echo luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} \
|
||||||
${optionalString (header != null) "--header=${header}"} \
|
${optionalString (header != null) "--header=${header}"} \
|
||||||
${optionalString (keyFile != null) "--key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}"} \
|
|
||||||
> /.luksopen_args
|
> /.luksopen_args
|
||||||
|
${optionalString (keyFile != null) ''
|
||||||
|
${optionalString fallbackToPassword "if [ -e ${keyFile} ]; then"}
|
||||||
|
echo " --key-file=${keyFile} ${optionalString (keyFileSize != null) "--keyfile-size=${toString keyFileSize}"}" \
|
||||||
|
>> /.luksopen_args
|
||||||
|
${optionalString fallbackToPassword ''
|
||||||
|
else
|
||||||
|
echo "keyfile ${keyFile} not found -- fallback to interactive unlocking"
|
||||||
|
fi
|
||||||
|
''}
|
||||||
|
''}
|
||||||
cryptsetup-askpass
|
cryptsetup-askpass
|
||||||
rm /.luksopen_args
|
rm /.luksopen_args
|
||||||
}
|
}
|
||||||
@ -228,10 +237,6 @@ in
|
|||||||
[ "aes" "aes_generic" "blowfish" "twofish"
|
[ "aes" "aes_generic" "blowfish" "twofish"
|
||||||
"serpent" "cbc" "xts" "lrw" "sha1" "sha256" "sha512"
|
"serpent" "cbc" "xts" "lrw" "sha1" "sha256" "sha512"
|
||||||
|
|
||||||
# workaround until https://marc.info/?l=linux-crypto-vger&m=148783562211457&w=4 is merged
|
|
||||||
# remove once 'modprobe --show-depends xts' shows ecb as a dependency
|
|
||||||
"ecb"
|
|
||||||
|
|
||||||
(if pkgs.stdenv.system == "x86_64-linux" then "aes_x86_64" else "aes_i586")
|
(if pkgs.stdenv.system == "x86_64-linux" then "aes_x86_64" else "aes_i586")
|
||||||
];
|
];
|
||||||
description = ''
|
description = ''
|
||||||
@ -328,6 +333,16 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fallbackToPassword = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether to fallback to interactive passphrase prompt if the keyfile
|
||||||
|
cannot be found. This will prevent unattended boot should the keyfile
|
||||||
|
go missing.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
yubikey = mkOption {
|
yubikey = mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
@ -441,7 +456,10 @@ in
|
|||||||
# Some modules that may be needed for mounting anything ciphered
|
# Some modules that may be needed for mounting anything ciphered
|
||||||
# Also load input_leds to get caps lock light working (#12456)
|
# Also load input_leds to get caps lock light working (#12456)
|
||||||
boot.initrd.availableKernelModules = [ "dm_mod" "dm_crypt" "cryptd" "input_leds" ]
|
boot.initrd.availableKernelModules = [ "dm_mod" "dm_crypt" "cryptd" "input_leds" ]
|
||||||
++ luks.cryptoModules;
|
++ luks.cryptoModules
|
||||||
|
# workaround until https://marc.info/?l=linux-crypto-vger&m=148783562211457&w=4 is merged
|
||||||
|
# remove once 'modprobe --show-depends xts' shows ecb as a dependency
|
||||||
|
++ (if builtins.elem "xts" luks.cryptoModules then ["ecb"] else []);
|
||||||
|
|
||||||
# copy the cryptsetup binary and it's dependencies
|
# copy the cryptsetup binary and it's dependencies
|
||||||
boot.initrd.extraUtilsCommands = ''
|
boot.initrd.extraUtilsCommands = ''
|
||||||
|
@ -54,7 +54,7 @@ with lib;
|
|||||||
|
|
||||||
environment.systemPackages = [ pkgs.kmod ];
|
environment.systemPackages = [ pkgs.kmod ];
|
||||||
|
|
||||||
system.activationScripts.modprobe =
|
system.activationScripts.modprobe = stringAfter ["specialfs"]
|
||||||
''
|
''
|
||||||
# Allow the kernel to find our wrapped modprobe (which searches
|
# Allow the kernel to find our wrapped modprobe (which searches
|
||||||
# in the right location in the Nix store for kernel modules).
|
# in the right location in the Nix store for kernel modules).
|
||||||
|
@ -82,7 +82,6 @@ ln -s /proc/mounts /etc/mtab
|
|||||||
mkdir -m 01777 -p /tmp
|
mkdir -m 01777 -p /tmp
|
||||||
mkdir -m 0755 -p /var/{log,lib,db} /nix/var /etc/nixos/ \
|
mkdir -m 0755 -p /var/{log,lib,db} /nix/var /etc/nixos/ \
|
||||||
/run/lock /home /bin # for the /bin/sh symlink
|
/run/lock /home /bin # for the /bin/sh symlink
|
||||||
install -m 0700 -d /root
|
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous boot time cleanup.
|
# Miscellaneous boot time cleanup.
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
prl-tools = config.hardware.parallels.package;
|
||||||
prl-tools = config.boot.kernelPackages.prl-tools;
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -22,6 +20,26 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
autoMountShares = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Control prlfsmountd service. When this service is running, shares can not be manually
|
||||||
|
mounted through `mount -t prl_fs ...` as this service will remount and trample any set options.
|
||||||
|
Recommended to enable for simple file sharing, but extended share use such as for code should
|
||||||
|
disable this to manually mount shares.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = config.boot.kernelPackages.prl-tools;
|
||||||
|
defaultText = "config.boot.kernelPackages.prl-tools";
|
||||||
|
example = literalExample "config.boot.kernelPackages.prl-tools";
|
||||||
|
description = ''
|
||||||
|
Defines which package to use for prl-tools. Override to change the version.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -67,7 +85,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.prlfsmountd = {
|
systemd.services.prlfsmountd = mkIf config.hardware.parallels.autoMountShares {
|
||||||
description = "Parallels Shared Folders Daemon";
|
description = "Parallels Shared Folders Daemon";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
|
@ -50,6 +50,10 @@ in rec {
|
|||||||
separateBoot
|
separateBoot
|
||||||
simple;
|
simple;
|
||||||
};
|
};
|
||||||
|
boot = {
|
||||||
|
inherit (nixos'.tests.boot)
|
||||||
|
biosCdrom;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,7 +228,9 @@ in rec {
|
|||||||
tests.boot = callSubTests tests/boot.nix {};
|
tests.boot = callSubTests tests/boot.nix {};
|
||||||
tests.boot-stage1 = callTest tests/boot-stage1.nix {};
|
tests.boot-stage1 = callTest tests/boot-stage1.nix {};
|
||||||
tests.borgbackup = callTest tests/borgbackup.nix {};
|
tests.borgbackup = callTest tests/borgbackup.nix {};
|
||||||
|
tests.buildbot = callTest tests/buildbot.nix {};
|
||||||
tests.cadvisor = callTestOnTheseSystems ["x86_64-linux"] tests/cadvisor.nix {};
|
tests.cadvisor = callTestOnTheseSystems ["x86_64-linux"] tests/cadvisor.nix {};
|
||||||
|
tests.ceph = callTestOnTheseSystems ["x86_64-linux"] tests/ceph.nix {};
|
||||||
tests.chromium = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/chromium.nix {}).stable;
|
tests.chromium = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/chromium.nix {}).stable;
|
||||||
tests.cjdns = callTest tests/cjdns.nix {};
|
tests.cjdns = callTest tests/cjdns.nix {};
|
||||||
tests.cloud-init = callTest tests/cloud-init.nix {};
|
tests.cloud-init = callTest tests/cloud-init.nix {};
|
||||||
@ -272,6 +274,7 @@ in rec {
|
|||||||
tests.hibernate = callTest tests/hibernate.nix {};
|
tests.hibernate = callTest tests/hibernate.nix {};
|
||||||
tests.home-assistant = callTest tests/home-assistant.nix { };
|
tests.home-assistant = callTest tests/home-assistant.nix { };
|
||||||
tests.hound = callTest tests/hound.nix {};
|
tests.hound = callTest tests/hound.nix {};
|
||||||
|
tests.hocker-fetchdocker = callTest tests/hocker-fetchdocker {};
|
||||||
tests.i3wm = callTest tests/i3wm.nix {};
|
tests.i3wm = callTest tests/i3wm.nix {};
|
||||||
tests.initrd-network-ssh = callTest tests/initrd-network-ssh {};
|
tests.initrd-network-ssh = callTest tests/initrd-network-ssh {};
|
||||||
tests.installer = callSubTests tests/installer.nix {};
|
tests.installer = callSubTests tests/installer.nix {};
|
||||||
@ -318,10 +321,12 @@ in rec {
|
|||||||
tests.nfs4 = callTest tests/nfs.nix { version = 4; };
|
tests.nfs4 = callTest tests/nfs.nix { version = 4; };
|
||||||
tests.nginx = callTest tests/nginx.nix { };
|
tests.nginx = callTest tests/nginx.nix { };
|
||||||
tests.nghttpx = callTest tests/nghttpx.nix { };
|
tests.nghttpx = callTest tests/nghttpx.nix { };
|
||||||
|
tests.nix-ssh-serve = callTest tests/nix-ssh-serve.nix { };
|
||||||
tests.novacomd = callTestOnTheseSystems ["x86_64-linux"] tests/novacomd.nix { };
|
tests.novacomd = callTestOnTheseSystems ["x86_64-linux"] tests/novacomd.nix { };
|
||||||
tests.leaps = callTest tests/leaps.nix { };
|
tests.leaps = callTest tests/leaps.nix { };
|
||||||
tests.nsd = callTest tests/nsd.nix {};
|
tests.nsd = callTest tests/nsd.nix {};
|
||||||
tests.openssh = callTest tests/openssh.nix {};
|
tests.openssh = callTest tests/openssh.nix {};
|
||||||
|
tests.openldap = callTest tests/openldap.nix {};
|
||||||
tests.owncloud = callTest tests/owncloud.nix {};
|
tests.owncloud = callTest tests/owncloud.nix {};
|
||||||
tests.pam-oath-login = callTest tests/pam-oath-login.nix {};
|
tests.pam-oath-login = callTest tests/pam-oath-login.nix {};
|
||||||
#tests.panamax = callTestOnTheseSystems ["x86_64-linux"] tests/panamax.nix {};
|
#tests.panamax = callTestOnTheseSystems ["x86_64-linux"] tests/panamax.nix {};
|
||||||
@ -336,7 +341,6 @@ in rec {
|
|||||||
tests.printing = callTest tests/printing.nix {};
|
tests.printing = callTest tests/printing.nix {};
|
||||||
tests.prometheus = callTest tests/prometheus.nix {};
|
tests.prometheus = callTest tests/prometheus.nix {};
|
||||||
tests.proxy = callTest tests/proxy.nix {};
|
tests.proxy = callTest tests/proxy.nix {};
|
||||||
tests.pumpio = callTest tests/pump.io.nix {};
|
|
||||||
# tests.quagga = callTest tests/quagga.nix {};
|
# tests.quagga = callTest tests/quagga.nix {};
|
||||||
tests.quake3 = callTest tests/quake3.nix {};
|
tests.quake3 = callTest tests/quake3.nix {};
|
||||||
tests.rabbitmq = callTest tests/rabbitmq.nix {};
|
tests.rabbitmq = callTest tests/rabbitmq.nix {};
|
||||||
@ -352,6 +356,7 @@ in rec {
|
|||||||
tests.snapper = callTest tests/snapper.nix {};
|
tests.snapper = callTest tests/snapper.nix {};
|
||||||
tests.statsd = callTest tests/statsd.nix {};
|
tests.statsd = callTest tests/statsd.nix {};
|
||||||
tests.sudo = callTest tests/sudo.nix {};
|
tests.sudo = callTest tests/sudo.nix {};
|
||||||
|
tests.systemd = callTest tests/systemd.nix {};
|
||||||
tests.switchTest = callTest tests/switch-test.nix {};
|
tests.switchTest = callTest tests/switch-test.nix {};
|
||||||
tests.taskserver = callTest tests/taskserver.nix {};
|
tests.taskserver = callTest tests/taskserver.nix {};
|
||||||
tests.tomcat = callTest tests/tomcat.nix {};
|
tests.tomcat = callTest tests/tomcat.nix {};
|
||||||
@ -361,6 +366,7 @@ in rec {
|
|||||||
tests.wordpress = callTest tests/wordpress.nix {};
|
tests.wordpress = callTest tests/wordpress.nix {};
|
||||||
tests.xfce = callTest tests/xfce.nix {};
|
tests.xfce = callTest tests/xfce.nix {};
|
||||||
tests.xmonad = callTest tests/xmonad.nix {};
|
tests.xmonad = callTest tests/xmonad.nix {};
|
||||||
|
tests.xrdp = callTest tests/xrdp.nix {};
|
||||||
tests.yabar = callTest tests/yabar.nix {};
|
tests.yabar = callTest tests/yabar.nix {};
|
||||||
tests.zookeeper = callTest tests/zookeeper.nix {};
|
tests.zookeeper = callTest tests/zookeeper.nix {};
|
||||||
|
|
||||||
|
@ -24,6 +24,12 @@ let
|
|||||||
my $machine = createMachine({ ${machineConfig}, qemuFlags => '-m 768' });
|
my $machine = createMachine({ ${machineConfig}, qemuFlags => '-m 768' });
|
||||||
$machine->start;
|
$machine->start;
|
||||||
$machine->waitForUnit("multi-user.target");
|
$machine->waitForUnit("multi-user.target");
|
||||||
|
$machine->succeed("nix verify -r --no-trust /run/current-system");
|
||||||
|
|
||||||
|
# Test whether the channel got installed correctly.
|
||||||
|
$machine->succeed("nix-instantiate --dry-run '<nixpkgs>' -A hello");
|
||||||
|
$machine->succeed("nix-env --dry-run -iA nixos.procps");
|
||||||
|
|
||||||
$machine->shutdown;
|
$machine->shutdown;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
140
nixos/tests/ceph.nix
Normal file
140
nixos/tests/ceph.nix
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import ./make-test.nix ({pkgs, ...}: rec {
|
||||||
|
name = "All-in-one-basic-ceph-cluster";
|
||||||
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
|
maintainers = [ lejonet ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
aio = { config, pkgs, ... }: {
|
||||||
|
virtualisation = {
|
||||||
|
emptyDiskImages = [ 20480 20480 ];
|
||||||
|
vlans = [ 1 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
firewall.allowPing = true;
|
||||||
|
useDHCP = false;
|
||||||
|
interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
|
||||||
|
{ address = "192.168.1.1"; prefixLength = 24; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
bash
|
||||||
|
sudo
|
||||||
|
ceph
|
||||||
|
xfsprogs
|
||||||
|
];
|
||||||
|
nixpkgs.config.packageOverrides = super: {
|
||||||
|
ceph = super.ceph.override({ nss = super.nss; libxfs = super.libxfs; libaio = super.libaio; jemalloc = super.jemalloc; });
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.kernelModules = [ "xfs" ];
|
||||||
|
|
||||||
|
services.ceph.enable = true;
|
||||||
|
services.ceph.global = {
|
||||||
|
fsid = "066ae264-2a5d-4729-8001-6ad265f50b03";
|
||||||
|
monInitialMembers = "aio";
|
||||||
|
monHost = "192.168.1.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.ceph.mon = {
|
||||||
|
enable = true;
|
||||||
|
daemons = [ "aio" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.ceph.mgr = {
|
||||||
|
enable = true;
|
||||||
|
daemons = [ "aio" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.ceph.osd = {
|
||||||
|
enable = true;
|
||||||
|
daemons = [ "0" "1" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = { nodes, ... }: ''
|
||||||
|
startAll;
|
||||||
|
|
||||||
|
$aio->waitForUnit("network.target");
|
||||||
|
|
||||||
|
# Create the ceph-related directories
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"mkdir -p /var/lib/ceph/mgr/ceph-aio/",
|
||||||
|
"mkdir -p /var/lib/ceph/mon/ceph-aio/",
|
||||||
|
"mkdir -p /var/lib/ceph/osd/ceph-{0..1}/",
|
||||||
|
"chown ceph:ceph -R /var/lib/ceph/"
|
||||||
|
);
|
||||||
|
|
||||||
|
# Bootstrap ceph-mon daemon
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"mkdir -p /var/lib/ceph/bootstrap-osd && chown ceph:ceph /var/lib/ceph/bootstrap-osd",
|
||||||
|
"sudo -u ceph ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'",
|
||||||
|
"ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --set-uid=0 --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'",
|
||||||
|
"ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring",
|
||||||
|
"monmaptool --create --add aio 192.168.1.1 --fsid 066ae264-2a5d-4729-8001-6ad265f50b03 /tmp/monmap",
|
||||||
|
"sudo -u ceph ceph-mon --mkfs -i aio --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring",
|
||||||
|
"touch /var/lib/ceph/mon/ceph-aio/done",
|
||||||
|
"systemctl start ceph-mon-aio"
|
||||||
|
);
|
||||||
|
$aio->waitForUnit("ceph-mon-aio");
|
||||||
|
|
||||||
|
# Can't check ceph status until a mon is up
|
||||||
|
$aio->succeed("ceph -s | grep 'mon: 1 daemons'");
|
||||||
|
|
||||||
|
# Start the ceph-mgr daemon, it has no deps and hardly any setup
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"ceph auth get-or-create mgr.aio mon 'allow profile mgr' osd 'allow *' mds 'allow *' > /var/lib/ceph/mgr/ceph-aio/keyring",
|
||||||
|
"systemctl start ceph-mgr-aio"
|
||||||
|
);
|
||||||
|
$aio->waitForUnit("ceph-mgr-aio");
|
||||||
|
$aio->waitUntilSucceeds("ceph -s | grep 'quorum aio'");
|
||||||
|
|
||||||
|
# Bootstrap both OSDs
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"mkfs.xfs /dev/vdb",
|
||||||
|
"mkfs.xfs /dev/vdc",
|
||||||
|
"mount /dev/vdb /var/lib/ceph/osd/ceph-0",
|
||||||
|
"mount /dev/vdc /var/lib/ceph/osd/ceph-1",
|
||||||
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-0/keyring --name osd.0 --add-key AQBCEJNa3s8nHRAANvdsr93KqzBznuIWm2gOGg==",
|
||||||
|
"ceph-authtool --create-keyring /var/lib/ceph/osd/ceph-1/keyring --name osd.1 --add-key AQBEEJNac00kExAAXEgy943BGyOpVH1LLlHafQ==",
|
||||||
|
"echo '{\"cephx_secret\": \"AQBCEJNa3s8nHRAANvdsr93KqzBznuIWm2gOGg==\"}' | ceph osd new 55ba2294-3e24-478f-bee0-9dca4c231dd9 -i -",
|
||||||
|
"echo '{\"cephx_secret\": \"AQBEEJNac00kExAAXEgy943BGyOpVH1LLlHafQ==\"}' | ceph osd new 5e97a838-85b6-43b0-8950-cb56d554d1e5 -i -"
|
||||||
|
);
|
||||||
|
|
||||||
|
# Initialize the OSDs with regular filestore
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"ceph-osd -i 0 --mkfs --osd-uuid 55ba2294-3e24-478f-bee0-9dca4c231dd9",
|
||||||
|
"ceph-osd -i 1 --mkfs --osd-uuid 5e97a838-85b6-43b0-8950-cb56d554d1e5",
|
||||||
|
"chown -R ceph:ceph /var/lib/ceph/osd",
|
||||||
|
"systemctl start ceph-osd-0",
|
||||||
|
"systemctl start ceph-osd-1"
|
||||||
|
);
|
||||||
|
|
||||||
|
$aio->waitUntilSucceeds("ceph osd stat | grep '2 osds: 2 up, 2 in'");
|
||||||
|
$aio->waitUntilSucceeds("ceph -s | grep 'mgr: aio(active)'");
|
||||||
|
$aio->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
||||||
|
|
||||||
|
$aio->mustSucceed(
|
||||||
|
"ceph osd pool create aio-test 100 100",
|
||||||
|
"ceph osd pool ls | grep 'aio-test'",
|
||||||
|
"ceph osd pool rename aio-test aio-other-test",
|
||||||
|
"ceph osd pool ls | grep 'aio-other-test'",
|
||||||
|
"ceph -s | grep '1 pools, 100 pgs'",
|
||||||
|
"ceph osd getcrushmap -o crush",
|
||||||
|
"crushtool -d crush -o decrushed",
|
||||||
|
"sed 's/step chooseleaf firstn 0 type host/step chooseleaf firstn 0 type osd/' decrushed > modcrush",
|
||||||
|
"crushtool -c modcrush -o recrushed",
|
||||||
|
"ceph osd setcrushmap -i recrushed",
|
||||||
|
"ceph osd pool set aio-other-test size 2"
|
||||||
|
);
|
||||||
|
$aio->waitUntilSucceeds("ceph -s | grep 'HEALTH_OK'");
|
||||||
|
$aio->waitUntilSucceeds("ceph -s | grep '100 active+clean'");
|
||||||
|
$aio->mustFail(
|
||||||
|
"ceph osd pool ls | grep 'aio-test'",
|
||||||
|
"ceph osd pool delete aio-other-test aio-other-test --yes-i-really-really-mean-it"
|
||||||
|
);
|
||||||
|
'';
|
||||||
|
})
|
15
nixos/tests/hocker-fetchdocker/default.nix
Normal file
15
nixos/tests/hocker-fetchdocker/default.nix
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import ../make-test.nix ({ pkgs, ...} : {
|
||||||
|
name = "test-hocker-fetchdocker";
|
||||||
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
|
maintainers = [ ixmatus ];
|
||||||
|
};
|
||||||
|
|
||||||
|
machine = import ./machine.nix;
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
startAll;
|
||||||
|
|
||||||
|
$machine->waitForUnit("sockets.target");
|
||||||
|
$machine->waitUntilSucceeds("docker run registry-1.docker.io/v2/library/hello-world:latest");
|
||||||
|
'';
|
||||||
|
})
|
19
nixos/tests/hocker-fetchdocker/hello-world-container.nix
Normal file
19
nixos/tests/hocker-fetchdocker/hello-world-container.nix
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{ fetchDockerConfig, fetchDockerLayer, fetchdocker }:
|
||||||
|
fetchdocker rec {
|
||||||
|
name = "hello-world";
|
||||||
|
registry = "https://registry-1.docker.io/v2/";
|
||||||
|
repository = "library";
|
||||||
|
imageName = "hello-world";
|
||||||
|
tag = "latest";
|
||||||
|
imageConfig = fetchDockerConfig {
|
||||||
|
inherit tag registry repository imageName;
|
||||||
|
sha256 = "1ivbd23hyindkahzfw4kahgzi6ibzz2ablmgsz6340vc6qr1gagj";
|
||||||
|
};
|
||||||
|
imageLayers = let
|
||||||
|
layer0 = fetchDockerLayer {
|
||||||
|
inherit registry repository imageName;
|
||||||
|
layerDigest = "ca4f61b1923c10e9eb81228bd46bee1dfba02b9c7dac1844527a734752688ede";
|
||||||
|
sha256 = "1plfd194fwvsa921ib3xkhms1yqxxrmx92r2h7myj41wjaqn2kya";
|
||||||
|
};
|
||||||
|
in [ layer0 ];
|
||||||
|
}
|
26
nixos/tests/hocker-fetchdocker/machine.nix
Normal file
26
nixos/tests/hocker-fetchdocker/machine.nix
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
{ nixpkgs.config.packageOverrides = pkgs': {
|
||||||
|
hello-world-container = pkgs'.callPackage ./hello-world-container.nix { };
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.docker;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.docker-load-fetchdocker-image = {
|
||||||
|
description = "Docker load hello-world-container";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "docker.service" "local-fs.target" ];
|
||||||
|
after = [ "docker.service" "local-fs.target" ];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
${pkgs.hello-world-container}/compositeImage.sh | ${pkgs.docker}/bin/docker load
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -145,7 +145,7 @@ let
|
|||||||
# Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon)
|
# Check that the daemon works, and that non-root users can run builds (this will build a new profile generation through the daemon)
|
||||||
$machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2");
|
$machine->succeed("su alice -l -c 'nix-env -iA nixos.procps' >&2");
|
||||||
|
|
||||||
# We need to a writable nix-store on next boot.
|
# We need a writable Nix store on next boot.
|
||||||
$machine->copyFileFromHost(
|
$machine->copyFileFromHost(
|
||||||
"${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 1; } }",
|
"${ makeConfig { inherit bootLoader grubVersion grubDevice grubIdentifier grubUseEfi extraConfig; forceGrubReinstallCount = 1; } }",
|
||||||
"/etc/nixos/configuration.nix");
|
"/etc/nixos/configuration.nix");
|
||||||
@ -195,8 +195,7 @@ let
|
|||||||
};
|
};
|
||||||
nodes = {
|
nodes = {
|
||||||
|
|
||||||
# The configuration of the machine used to run "nixos-install". It
|
# The configuration of the machine used to run "nixos-install".
|
||||||
# also has a web server that simulates cache.nixos.org.
|
|
||||||
machine =
|
machine =
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
@ -208,7 +207,6 @@ let
|
|||||||
|
|
||||||
virtualisation.diskSize = 8 * 1024;
|
virtualisation.diskSize = 8 * 1024;
|
||||||
virtualisation.memorySize = 1024;
|
virtualisation.memorySize = 1024;
|
||||||
virtualisation.writableStore = true;
|
|
||||||
|
|
||||||
# Use a small /dev/vdb as the root disk for the
|
# Use a small /dev/vdb as the root disk for the
|
||||||
# installer. This ensures the target disk (/dev/vda) is
|
# installer. This ensures the target disk (/dev/vda) is
|
||||||
@ -245,6 +243,11 @@ let
|
|||||||
++ optionals (bootLoader == "grub" && grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ];
|
++ optionals (bootLoader == "grub" && grubVersion == 2) [ pkgs.grub2 pkgs.grub2_efi ];
|
||||||
|
|
||||||
nix.binaryCaches = mkForce [ ];
|
nix.binaryCaches = mkForce [ ];
|
||||||
|
nix.extraOptions =
|
||||||
|
''
|
||||||
|
hashed-mirrors =
|
||||||
|
connect-timeout = 1
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
# Miscellaneous small tests that don't warrant their own VM run.
|
# Miscellaneous small tests that don't warrant their own VM run.
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test.nix ({ pkgs, ...} : rec {
|
||||||
name = "misc";
|
name = "misc";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ eelco chaoflow ];
|
maintainers = [ eelco chaoflow ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foo = pkgs.writeText "foo" "Hello World";
|
||||||
|
|
||||||
machine =
|
machine =
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
@ -27,10 +29,17 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
security.sudo = { enable = true; wheelNeedsPassword = false; };
|
security.sudo = { enable = true; wheelNeedsPassword = false; };
|
||||||
boot.kernel.sysctl."vm.swappiness" = 1;
|
boot.kernel.sysctl."vm.swappiness" = 1;
|
||||||
boot.kernelParams = [ "vsyscall=emulate" ];
|
boot.kernelParams = [ "vsyscall=emulate" ];
|
||||||
|
system.extraDependencies = [ foo ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
''
|
''
|
||||||
|
subtest "nix-db", sub {
|
||||||
|
my $json = $machine->succeed("nix path-info --json ${foo}");
|
||||||
|
$json =~ /"narHash":"sha256:0afw0d9j1hvwiz066z93jiddc33nxg6i6qyp26vnqyglpyfivlq5"/ or die "narHash not set";
|
||||||
|
$json =~ /"narSize":128/ or die "narSize not set";
|
||||||
|
};
|
||||||
|
|
||||||
subtest "nixos-version", sub {
|
subtest "nixos-version", sub {
|
||||||
$machine->succeed("[ `nixos-version | wc -w` = 2 ]");
|
$machine->succeed("[ `nixos-version | wc -w` = 2 ]");
|
||||||
};
|
};
|
||||||
|
39
nixos/tests/nix-ssh-serve.nix
Normal file
39
nixos/tests/nix-ssh-serve.nix
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import ./make-test.nix ({ pkgs, lib, ... }:
|
||||||
|
let inherit (import ./ssh-keys.nix pkgs)
|
||||||
|
snakeOilPrivateKey snakeOilPublicKey;
|
||||||
|
ssh-config = builtins.toFile "ssh.conf" ''
|
||||||
|
UserKnownHostsFile=/dev/null
|
||||||
|
StrictHostKeyChecking=no
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{ name = "nix-ssh-serve";
|
||||||
|
meta.maintainers = [ lib.maintainers.shlevy ];
|
||||||
|
nodes =
|
||||||
|
{ server.nix.sshServe =
|
||||||
|
{ enable = true;
|
||||||
|
keys = [ snakeOilPublicKey ];
|
||||||
|
protocol = "ssh-ng";
|
||||||
|
};
|
||||||
|
server.nix.package = pkgs.nixUnstable;
|
||||||
|
client.nix.package = pkgs.nixUnstable;
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
startAll;
|
||||||
|
|
||||||
|
$client->succeed("mkdir -m 700 /root/.ssh");
|
||||||
|
$client->copyFileFromHost("${ssh-config}", "/root/.ssh/config");
|
||||||
|
$client->succeed("cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa");
|
||||||
|
$client->succeed("chmod 600 /root/.ssh/id_ecdsa");
|
||||||
|
|
||||||
|
$client->succeed("nix-store --add /etc/machine-id > mach-id-path");
|
||||||
|
|
||||||
|
$server->waitForUnit("sshd");
|
||||||
|
|
||||||
|
$client->fail("diff /root/other-store\$(cat mach-id-path) /etc/machine-id");
|
||||||
|
# Currently due to shared store this is a noop :(
|
||||||
|
$client->succeed("nix copy --to ssh-ng://nix-ssh\@server \$(cat mach-id-path)");
|
||||||
|
$client->succeed("nix-store --realise \$(cat mach-id-path) --store /root/other-store --substituters ssh-ng://nix-ssh\@server");
|
||||||
|
$client->succeed("diff /root/other-store\$(cat mach-id-path) /etc/machine-id");
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
)
|
35
nixos/tests/openldap.nix
Normal file
35
nixos/tests/openldap.nix
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import ./make-test.nix {
|
||||||
|
name = "dovecot";
|
||||||
|
|
||||||
|
machine = { pkgs, ... }: {
|
||||||
|
services.openldap = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
include ${pkgs.openldap}/etc/schema/core.schema
|
||||||
|
include ${pkgs.openldap}/etc/schema/cosine.schema
|
||||||
|
include ${pkgs.openldap}/etc/schema/inetorgperson.schema
|
||||||
|
include ${pkgs.openldap}/etc/schema/nis.schema
|
||||||
|
database bdb
|
||||||
|
suffix dc=example
|
||||||
|
directory /var/db/openldap
|
||||||
|
rootdn cn=root,dc=example
|
||||||
|
rootpw notapassword
|
||||||
|
'';
|
||||||
|
declarativeContents = ''
|
||||||
|
dn: dc=example
|
||||||
|
objectClass: domain
|
||||||
|
dc: example
|
||||||
|
|
||||||
|
dn: ou=users,dc=example
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
ou: users
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
$machine->succeed('systemctl status openldap.service');
|
||||||
|
$machine->waitForUnit('openldap.service');
|
||||||
|
$machine->succeed('ldapsearch -LLL -D "cn=root,dc=example" -w notapassword -b "dc=example"');
|
||||||
|
'';
|
||||||
|
}
|
@ -1,20 +1,7 @@
|
|||||||
import ./make-test.nix ({ pkgs, ... }:
|
import ./make-test.nix ({ pkgs, ... }:
|
||||||
|
|
||||||
let
|
let inherit (import ./ssh-keys.nix pkgs)
|
||||||
snakeOilPrivateKey = pkgs.writeText "privkey.snakeoil" ''
|
snakeOilPrivateKey snakeOilPublicKey;
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MHcCAQEEIHQf/khLvYrQ8IOika5yqtWvI0oquHlpRLTZiJy5dRJmoAoGCCqGSM49
|
|
||||||
AwEHoUQDQgAEKF0DYGbBwbj06tA3fd/+yP44cvmwmHBWXZCKbS+RQlAKvLXMWkpN
|
|
||||||
r1lwMyJZoSGgBHoUahoYjTh9/sJL7XLJtA==
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
||||||
'';
|
|
||||||
|
|
||||||
snakeOilPublicKey = pkgs.lib.concatStrings [
|
|
||||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
|
|
||||||
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
|
|
||||||
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil"
|
|
||||||
];
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
name = "openssh";
|
name = "openssh";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
# This test runs pump.io with mongodb, listing on port 443.
|
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : let
|
|
||||||
snakeOilKey = ''
|
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqVemio78R41Tz
|
|
||||||
MnR2zFD/wFT0iScOpFkuytNmuPf28FLaa9wSBWmuAGbEi7wBIfw8/bUqFBTQp2G1
|
|
||||||
m1cmcCKxhmvvOkGs89eM131s1lW/bXU3zYso4e7724kHwU65jRlQs6cFWIlmW7V5
|
|
||||||
3HQobP05dy+zPpujPPSlOQ0qYViR1s+RgZI8r0wS2ZDsliNtQwBLJSIvX6XVnXLo
|
|
||||||
F/HmF4/ySJ9pL2AxQXCwZE8SfCzHpArs9COIqTaAuwB79kxWSFQJewmab74BXiM6
|
|
||||||
9FMCtHON24Pl7OR9sRJHH8rMEzUumppmUeCNEzABjzQQ7svR18cmbzRWetp0tT9Y
|
|
||||||
7rj6URHHAgMBAAECggEAGmbCldDnlrAzxJY3cwpsK5f2EwkHIr/aiuQpLCzTUlUh
|
|
||||||
onVBYRGxtaSeSSyXcV2BKTrxz5nZOBYZkPqI4Y5T8kwxgpz2/QW2jUABUtNN6yPe
|
|
||||||
HU4gma+bSTJX5PnTZ/M0z0tpQezdLx5b3I2M+48ZGMUegZvcp8qU6N8U6VK5VbFD
|
|
||||||
DMTGL4b+Kc9HScRkCJjU3FfQcqf9Ml5w9jzHSeHImYEDrG0nX8N8EImRCBXbgxCl
|
|
||||||
5XT1h6LFUGdr+N6n2w56+6l8OZZVmwj1NdF6NJybUQl4Y7b0niA+5czzjRt/YUjZ
|
|
||||||
HW0fXmx3XlbYGWYdMdS+VaIW6pkUpm8kZkqjngqLwQKBgQDfhbFQmg9lsJQ8/dQZ
|
|
||||||
WzRNsozHKWkQiZbW5sXBWygJbAB3Hc8gvQkuZe9TVyF99cznRj6ro6pGZjP0rTdY
|
|
||||||
3ACTL+ygRArcIR6VsJCIr6nPvBLpOoNb8TQeKPmHC2gnSP9zaT/K2lldYISKNaYQ
|
|
||||||
0seB2gvZhIgMgWtZtmb3jdgl9wKBgQDDFdknXgvFgB+y96//9wTu2WWuE5yQ5yB7
|
|
||||||
utAcHNO9rx5X1tJqxymYh+iE8HUN25By+96SpNMQFI+0wNGVB00YWNBKtyepimWN
|
|
||||||
EUCojTy+MIXIjrLcvviEePsI4TPWYf8XtZeiYtcczYrt/wPQUYaDb8LBRfpIfmhr
|
|
||||||
rCGW93s+sQKBgEDOKTeeQyKPjJsWWL01RTfVsZ04s155FcOeyu0heb0plAT1Ho12
|
|
||||||
YUgTg8zc8Tfs4QiYxCjNXdvlW+Dvq6FWv8/s0CUzNRbXf1+U/oKys4AoHi+CqH0q
|
|
||||||
tJqd9KKjuwHQ10dl13n/znMVPbg4j7pG8lMCnfblxvAhQbeT+8yAUo/HAoGBAL3t
|
|
||||||
/n4KXNGK3NHDvXEp0H6t3wWsiEi3DPQJO+Wy1x8caCFCv5c/kaqz3tfWt0+njSm1
|
|
||||||
N8tzdx13tzVWaHV8Jz3l8dxcFtxEJnxB6L5wy0urOAS7kT3DG3b1xgmuH2a//7fY
|
|
||||||
jumE60NahcER/2eIh7pdS7IZbAO6NfVmH0m4Zh/xAoGAbquh60sAfLC/1O2/4Xom
|
|
||||||
PHS7z2+TNpwu4ou3nspxfigNQcTWzzzTVFLnaTPg+HKbLRXSWysjssmmj5u3lCyc
|
|
||||||
S2M9xuhApa9CrN/udz4gEojRVsTla/gyLifIZ3CtTn2QEQiIJEMxM+59KAlkgUBo
|
|
||||||
9BeZ03xTaEZfhVZ9bEN30Ak=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
'';
|
|
||||||
|
|
||||||
snakeOilCert = ''
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICvjCCAaagAwIBAgIJANhA6+PPhomZMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
|
|
||||||
BAMMDGIwOTM0YWMwYWZkNTAeFw0xNTExMzAxNzQ3MzVaFw0yNTExMjcxNzQ3MzVa
|
|
||||||
MBcxFTATBgNVBAMMDGIwOTM0YWMwYWZkNTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
|
||||||
ADCCAQoCggEBAKpV6aKjvxHjVPMydHbMUP/AVPSJJw6kWS7K02a49/bwUtpr3BIF
|
|
||||||
aa4AZsSLvAEh/Dz9tSoUFNCnYbWbVyZwIrGGa+86Qazz14zXfWzWVb9tdTfNiyjh
|
|
||||||
7vvbiQfBTrmNGVCzpwVYiWZbtXncdChs/Tl3L7M+m6M89KU5DSphWJHWz5GBkjyv
|
|
||||||
TBLZkOyWI21DAEslIi9fpdWdcugX8eYXj/JIn2kvYDFBcLBkTxJ8LMekCuz0I4ip
|
|
||||||
NoC7AHv2TFZIVAl7CZpvvgFeIzr0UwK0c43bg+Xs5H2xEkcfyswTNS6ammZR4I0T
|
|
||||||
MAGPNBDuy9HXxyZvNFZ62nS1P1juuPpREccCAwEAAaMNMAswCQYDVR0TBAIwADAN
|
|
||||||
BgkqhkiG9w0BAQsFAAOCAQEAd2w9rxi6qF9WV8L3rHnTE7uu0ldtdgJlCASx6ouj
|
|
||||||
TleOnjfEg+kH8r8UbmRV5vsTDn1Qp5JGDYxfytRUQwLb1zTLde0xotx37E3LY8Wr
|
|
||||||
sD6Al4t8sHywB/hc5dy29TgG0iyG8LKZrkwytLvDZ814W3OwpN2rpEz6pdizdHNn
|
|
||||||
jsoDEngZiDHvLjIyE0cDkFXkeYMGXOnBUeOcu4nfu4C5eKs3nXGGAcNDbDRIuLoE
|
|
||||||
BZExUBY+YSs6JBvh5tvRqLVW0Dz0akEcjb/jhwS2LmDip8Pdoxx4Q1jPKEu38zrr
|
|
||||||
Vd5WD2HJhLb9u0UxVp9vfWIUDgydopV5ZmWCQ5YvNepb1w==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
name = "pumpio";
|
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
|
||||||
maintainers = [ rvl ];
|
|
||||||
};
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
one =
|
|
||||||
{ config, pkgs, ... }:
|
|
||||||
{
|
|
||||||
services = {
|
|
||||||
pumpio = {
|
|
||||||
port = 443;
|
|
||||||
enable = true;
|
|
||||||
sslCert = pkgs.writeText "snakeoil.cert" snakeOilCert;
|
|
||||||
sslKey = pkgs.writeText "snakeoil.pem" snakeOilKey;
|
|
||||||
secretFile = pkgs.writeText "secretFile" "test123";
|
|
||||||
site = "test";
|
|
||||||
};
|
|
||||||
mongodb.enable = true;
|
|
||||||
mongodb.extraConfig = ''
|
|
||||||
storage.journal.enabled: false
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
systemd.services.mongodb.unitConfig.Before = "pump.io.service";
|
|
||||||
systemd.services."pump.io".unitConfig.Requires = "mongodb.service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
startAll;
|
|
||||||
|
|
||||||
$one->waitForUnit("pump.io.service");
|
|
||||||
$one->waitUntilSucceeds("curl -k https://localhost");
|
|
||||||
'';
|
|
||||||
})
|
|
15
nixos/tests/ssh-keys.nix
Normal file
15
nixos/tests/ssh-keys.nix
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
pkgs:
|
||||||
|
{ snakeOilPrivateKey = pkgs.writeText "privkey.snakeoil" ''
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MHcCAQEEIHQf/khLvYrQ8IOika5yqtWvI0oquHlpRLTZiJy5dRJmoAoGCCqGSM49
|
||||||
|
AwEHoUQDQgAEKF0DYGbBwbj06tA3fd/+yP44cvmwmHBWXZCKbS+RQlAKvLXMWkpN
|
||||||
|
r1lwMyJZoSGgBHoUahoYjTh9/sJL7XLJtA==
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
'';
|
||||||
|
|
||||||
|
snakeOilPublicKey = pkgs.lib.concatStrings [
|
||||||
|
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
|
||||||
|
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
|
||||||
|
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= sakeoil"
|
||||||
|
];
|
||||||
|
}
|
66
nixos/tests/systemd.nix
Normal file
66
nixos/tests/systemd.nix
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import ./make-test.nix {
|
||||||
|
name = "systemd";
|
||||||
|
|
||||||
|
machine = { lib, ... }: {
|
||||||
|
imports = [ common/user-account.nix common/x11.nix ];
|
||||||
|
|
||||||
|
virtualisation.emptyDiskImages = [ 512 ];
|
||||||
|
|
||||||
|
fileSystems = lib.mkVMOverride {
|
||||||
|
"/test-x-initrd-mount" = {
|
||||||
|
device = "/dev/vdb";
|
||||||
|
fsType = "ext2";
|
||||||
|
autoFormat = true;
|
||||||
|
noCheck = true;
|
||||||
|
options = [ "x-initrd.mount" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.extraConfig = "DefaultEnvironment=\"XXX_SYSTEM=foo\"";
|
||||||
|
systemd.user.extraConfig = "DefaultEnvironment=\"XXX_USER=bar\"";
|
||||||
|
services.journald.extraConfig = "Storage=volatile";
|
||||||
|
services.xserver.displayManager.auto.user = "alice";
|
||||||
|
|
||||||
|
systemd.services.testservice1 = {
|
||||||
|
description = "Test Service 1";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
if [ "$XXX_SYSTEM" = foo ]; then
|
||||||
|
touch /system_conf_read
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.testservice2 = {
|
||||||
|
description = "Test Service 2";
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
if [ "$XXX_USER" = bar ]; then
|
||||||
|
touch "$HOME/user_conf_read"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
$machine->waitForX;
|
||||||
|
|
||||||
|
# Regression test for https://github.com/NixOS/nixpkgs/issues/35415
|
||||||
|
subtest "configuration files are recognized by systemd", sub {
|
||||||
|
$machine->succeed('test -e /system_conf_read');
|
||||||
|
$machine->succeed('test -e /home/alice/user_conf_read');
|
||||||
|
$machine->succeed('test -z $(ls -1 /var/log/journal)');
|
||||||
|
};
|
||||||
|
|
||||||
|
# Regression test for https://github.com/NixOS/nixpkgs/issues/35268
|
||||||
|
subtest "file system with x-initrd.mount is not unmounted", sub {
|
||||||
|
$machine->shutdown;
|
||||||
|
$machine->waitForUnit('multi-user.target');
|
||||||
|
# If the file system was unmounted during the shutdown the file system
|
||||||
|
# has a last mount time, because the file system wasn't checked.
|
||||||
|
$machine->fail('dumpe2fs /dev/vdb | grep -q "^Last mount time: *n/a"');
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user