summaryrefslogtreecommitdiffstats
path: root/slides.md
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2019-10-06 19:49:50 +0200
committerMinijackson <minijackson@riseup.net>2019-10-06 19:52:49 +0200
commit1b4c03ac98ded631108e417f01940b7680ddc4ca (patch)
treeab347d6bf7fe9b2f4997c44c0cfb00c1939f0334 /slides.md
parent34aeabeeb9a02d31baff861aff69bb4308f81bd9 (diff)
downloadnixos-embedded-slides-1b4c03ac98ded631108e417f01940b7680ddc4ca.tar.gz
nixos-embedded-slides-1b4c03ac98ded631108e417f01940b7680ddc4ca.zip
somewhat final version
Diffstat (limited to 'slides.md')
-rw-r--r--slides.md383
1 files changed, 314 insertions, 69 deletions
diff --git a/slides.md b/slides.md
index e013366..117059e 100644
--- a/slides.md
+++ b/slides.md
@@ -170,10 +170,10 @@ of the "package function".
170 170
171- Use the Nix language to write derivations 171- Use the Nix language to write derivations
172 172
173 Derivation 173 Derivation:
174 : Data structure that describes how to create an output path (file / directory) 174 : Data structure that describes how to create an output path (file / directory)
175 175
176- The derivation is compiled into a `.drv` file. 176- The derivation is compiled into a `.drv` file (evaluation).
177- Realising a derivation creates the output path 177- Realising a derivation creates the output path
178- The closure of an output path is the path and all its dependencies 178- The closure of an output path is the path and all its dependencies
179 179
@@ -213,7 +213,7 @@ of the "package function".
213/nix/store/486r3d12gc042yric302jg14in7j3jwm-i3.conf 213/nix/store/486r3d12gc042yric302jg14in7j3jwm-i3.conf
214``` 214```
215 215
216## Nix---Language (Types){.fragile} 216## Nix---Language (Types){.fragile .shrink}
217 217
218```{=latex} 218```{=latex}
219\begin{minted}{nix} 219\begin{minted}{nix}
@@ -226,6 +226,7 @@ of the "package function".
226 initial indentation is removed! 226 initial indentation is removed!
227 ''; 227 '';
228 "attribute set" = { a = 1; b = 2; }; 228 "attribute set" = { a = 1; b = 2; };
229 a.b.c = 1; # same as a = { b = { c = 1; }; };
229 list = [ 1 2 "hello" ]; 230 list = [ 1 2 "hello" ];
230 function = a: toString a; 231 function = a: toString a;
231 "function w/ named parameters" = { a, b, c ? "default"}: a; 232 "function w/ named parameters" = { a, b, c ? "default"}: a;
@@ -454,10 +455,10 @@ derive2 {
454 name = "ggplot2"; 455 name = "ggplot2";
455 version = "3.2.0"; 456 version = "3.2.0";
456 sha256 = "1cvk9pw..."; 457 sha256 = "1cvk9pw...";
457 depends = [ digest gtable lazyeval 458 depends = [ digest gtable
458 MASS mgcv reshape2 rlang 459 lazyeval MASS mgcv reshape2
459 scales tibble viridisLite 460 rlang scales tibble
460 withr ]; 461 viridisLite withr ];
461}; 462};
462\end{minted} 463\end{minted}
463``` 464```
@@ -496,9 +497,7 @@ stdenv.mkDerivation rec {
496 nativeBuildInputs = [ cmake ninja ]; 497 nativeBuildInputs = [ cmake ninja ];
497 498
498 cmakeFlags = stdenv.lib.optional (!static) "-DBUILD_SHARED_LIBS=ON"; 499 cmakeFlags = stdenv.lib.optional (!static) "-DBUILD_SHARED_LIBS=ON";
499 # src = ...; 500 # src = ...; patches = ...; meta = ...;
500 # patches = [ ... ];
501 # meta = ...;
502} 501}
503\end{minted} 502\end{minted}
504``` 503```
@@ -548,11 +547,11 @@ in
548\end{minted} 547\end{minted}
549``` 548```
550 549
551We run: 550- We run:
552 551
553```{=latex} 552```{=latex}
554\begin{minted}{console} 553\begin{minted}{console}
555$ nix build --file default.nix 554roger@os $ nix build --file default.nix
556\end{minted} 555\end{minted}
557``` 556```
558 557
@@ -590,7 +589,7 @@ We get as output path:
590 589
591```{=latex} 590```{=latex}
592\begin{minted}{console} 591\begin{minted}{console}
593$ ./result/bin/myScript 592slartibartfast@magrathea $ ./result/bin/myScript
594Hello, World! 593Hello, World!
595\end{minted} 594\end{minted}
596``` 595```
@@ -606,7 +605,7 @@ Hello, World!
606 605
607```{=latex} 606```{=latex}
608\begin{minted}{console} 607\begin{minted}{console}
609$ ls -l result 608slartibartfast@magrathea $ ls -l result
610result -> /nix/store/a7db5d4v5b2pxppl8drb30ljx9z0kwg0-myScript 609result -> /nix/store/a7db5d4v5b2pxppl8drb30ljx9z0kwg0-myScript
611\end{minted} 610\end{minted}
612``` 611```
@@ -644,8 +643,7 @@ let
644 overlays = [ 643 overlays = [
645 (self: super: { 644 (self: super: {
646 myAlias = super.pandoc; 645 myAlias = super.pandoc;
647 inherit (super.llvmPackages_7) 646 inherit (super.llvmPackages_7) clang libclang llvm;
648 clang libclang llvm;
649 myPackage = self.callPackage ./myProject/default.nix { }; 647 myPackage = self.callPackage ./myProject/default.nix { };
650 } ) 648 } )
651 ]; 649 ];
@@ -730,6 +728,7 @@ exec -a "$0" "/nix/store/...-kodi-18.1/bin/.kodi-wrapped" \
730 728
731::: notes 729::: notes
732 730
731- *Strategic pause*
733- This is actually called by another wrapper who tells Kodi where to find its 732- This is actually called by another wrapper who tells Kodi where to find its
734 data. 733 data.
735- Everything you see here is automated, writing derivations is much much less 734- Everything you see here is automated, writing derivations is much much less
@@ -742,7 +741,7 @@ exec -a "$0" "/nix/store/...-kodi-18.1/bin/.kodi-wrapped" \
742 741
743```{=latex} 742```{=latex}
744\begin{minted}{console} 743\begin{minted}{console}
745$ readelf -d coreutils 744PinkiePie@Equestria $ readelf -d coreutils
746... 745...
747Bibliothèque partagée: [librt.so.1] 746Bibliothèque partagée: [librt.so.1]
748Bibliothèque partagée: [libpthread.so.0] 747Bibliothèque partagée: [libpthread.so.0]
@@ -784,19 +783,47 @@ functools.reduce(
784 783
785::: 784:::
786 785
786## Shelling out{.fragile}
787
788```{=latex}
789\begin{minted}{console}
790roger@os $ nix-shell '<nixpkgs>' -A openssh
791roger@os (nix-shell) $ echo $src
792/nix/store/...-openssh-7.9p1.tar.gz
793roger@os (nix-shell) $ pkg-config --cflags openssl
794-I/nix/store/...-openssl-1.0.2t-dev/include
795roger@os (nix-shell) $ unpackPhase
796...
797roger@os (nix-shell) $ configurePhase
798...
799\end{minted}
800```
801
802::: notes
803
804- pkg-config is here because it's in the native build inputs
805- There is also the concept of nix-shell scripts, which declare their
806 dependencies, and Nix will download and provide the dependencies before
807 running the script.
808
809
810:::
811
787# NixOS 812# NixOS
788 813
789## How do you make a Linux distribution out of that? 814## How do you make a Linux distribution out of that?
790 815
791- A distribution is a bunch of files 816- A distribution is a bunch of files
817
792- In the end, the Nix package manager creates files 818- In the end, the Nix package manager creates files
819
793- Let's use Nix to create *every* (non user data) file 820- Let's use Nix to create *every* (non user data) file
794 821
795## Adding yourself to the environment---Symbolic links{.fragile} 822## Adding yourself to the environment---Symbolic links{.fragile}
796 823
797```{=latex} 824```{=latex}
798\begin{minted}{console} 825\begin{minted}{console}
799$ ls -l /etc/static/ssh/ssh_config 826roger@os $ ls -l /etc/static/ssh/ssh_config
800/etc/static/ssh/ssh_config -> /nix/store/...-etc-ssh_config 827/etc/static/ssh/ssh_config -> /nix/store/...-etc-ssh_config
801\end{minted} 828\end{minted}
802``` 829```
@@ -838,7 +865,7 @@ Type=simple
838 865
839```{=latex} 866```{=latex}
840\begin{minted}{console} 867\begin{minted}{console}
841$ echo $PATH 868roger@os $ echo $PATH
842/home/minijackson/bin: 869/home/minijackson/bin:
843/run/wrappers/bin: 870/run/wrappers/bin:
844/home/minijackson/.nix-profile/bin: 871/home/minijackson/.nix-profile/bin:
@@ -1010,8 +1037,7 @@ Introducing: the module system!
1010 1037
1011```{=latex} 1038```{=latex}
1012\begin{minted}{nix} 1039\begin{minted}{nix}
1013{ ... }: 1040{ ... }: {
1014{
1015 containers = { 1041 containers = {
1016 myContainer = { 1042 myContainer = {
1017 config = { ... }: { services.postgresql.enable = true; }; 1043 config = { ... }: { services.postgresql.enable = true; };
@@ -1203,7 +1229,7 @@ with lib;
1203 1229
1204::: notes 1230::: notes
1205 1231
1206Sorry if the formatting is horrible, it had to fit in one slide. 1232- Sorry if the formatting is horrible, it had to fit in one slide.
1207 1233
1208 1234
1209::: 1235:::
@@ -1241,20 +1267,141 @@ Sorry if the formatting is horrible, it had to fit in one slide.
1241## Assertions{.fragile} 1267## Assertions{.fragile}
1242 1268
1243```{=latex} 1269```{=latex}
1244\begin{minted}{text} 1270\begin{minted}{md}
1245Failed assertions: 1271Failed assertions:
1246- services.xserver.xkbOptions = "eurosign:e" is useless on fr/ch 1272- The ‘fileSystems’ option does not specify your root file system.
1247 layouts and plays badly with bépo 1273- You must set the option ‘boot.loader.grub.devices’ or
1274 'boot.loader.grub.mirroredBoots' to make the system bootable.
1275\end{minted}
1276```
1277
1278## More Assertions
1279
1280- *Synaptics and libinput are incompatible, you cannot enable both* (in
1281 `services.xserver`).
1282
1283- *CONFIG_ZRAM is not built as a module!* (in `zramSwap`)
1284
1285- *Yubikey and GPG Card may not be used at the same time.* (in
1286 `boot.initrd.luks`)
1287
1288- *Trusted GRUB does not have EFI support* (in `boot.loader.grub`)
1289
1290## Assertion implementations{.fragile}
1291
1292```{=latex}
1293\begin{minted}{nix}
1294# in module configuration
1295{
1296 assertions = [
1297 { assertion = any (fs: fs.mountPoint == "/") fileSystems;
1298 message = "The ‘fileSystems’ option does not specify your root file system.";
1299 }
1300 ];
1301}
1302\end{minted}
1303```
1304
1305
1306::: notes
1307
1308Yes, these assertions are also a NixOS module!
1309
1310
1311:::
1312
1313## Module tests{.fragile}
1314
1315```{=latex}
1316\begin{minted}{nix}
1317import ./make-test.nix ({ ... }: {
1318 name = "myService";
1319 machine = { ... }: {
1320 services.myService.enable = true;
1321 };
1322
1323 testScript = ''
1324 $machine->waitForUnit('myService.service');
1325 $machine->waitForOpenPort('1337');
1326 $machine->succeed("curl --fail http://localhost:1337/");
1327 '';
1328})
1248\end{minted} 1329\end{minted}
1249``` 1330```
1250 1331
1251## More Assertions{.fragile} 1332::: notes
1333
1334- Will create a VM with the given config, and run the Perl script on that
1335
1336
1337:::
1252 1338
1253```{=late} 1339## Module tests, The Empire Strikes Back{.fragile}
1340
1341```{=latex}
1254\begin{minted}{nix} 1342\begin{minted}{nix}
1343import ./make-test.nix ({ pkgs, ... } : {
1344 name = "kernel-latest";
1345 machine = { pkgs, ... }: {
1346 boot.kernelPackages = pkgs.linuxPackages_latest;
1347 };
1348
1349 testScript = ''
1350 $machine->succeed("uname -s | grep 'Linux'");
1351 $machine->succeed("uname -a | grep '${pkgs.linuxPackages_latest.kernel.version}'");
1352 '';
1353})
1354\end{minted}
1355```
1356
1357## Module tests, Return of the Jedi{.fragile}
1358
1359```{=latex}
1360\begin{minted}[lastline=13]{nix}
1361import ./make-test.nix ({ pkgs, ... } : with pkgs.lib; {
1362 name = "Bridge";
1363 nodes.client1 = { pkgs, ... }: {
1364 virtualisation.vlans = [ 1 ];
1365 networking = {
1366 useDHCP = false;
1367 interfaces.eth1.ipv4.addresses = [ {
1368 address = "192.168.1.2/24"; prefixLength = 24
1369 } ];
1370 };
1371 };
1372 nodes.client2 = { /* same but in vlan 2 @ 192.168.1.3 */ };
1373 nodes.router = { /* bridges the vlans 1 and 2 */ };
1374})
1255\end{minted} 1375\end{minted}
1256``` 1376```
1257 1377
1378## Module tests, The Phantom Menace{.fragile}
1379
1380Test script:
1381
1382```{=latex}
1383\begin{minted}{perl}
1384startAll;
1385# Wait for networking to come up
1386$client1->waitForUnit("network.target");
1387$client2->waitForUnit("network.target");
1388$router->waitForUnit("network.target");
1389# Test bridging
1390$client1->waitUntilSucceeds("ping -c 1 192.168.1.1");
1391$client1->waitUntilSucceeds("ping -c 1 192.168.1.2");
1392$client1->waitUntilSucceeds("ping -c 1 192.168.1.3");
1393# Same with client2 and router
1394\end{minted}
1395```
1396
1397::: notes
1398
1399- There are even the possibilities of:
1400 - Taking a screenshot
1401 - Running OCR on screenshot
1402
1403:::
1404
1258# The embedded world 1405# The embedded world
1259 1406
1260## Proper project structure{.fragile} 1407## Proper project structure{.fragile}
@@ -1275,61 +1422,159 @@ Failed assertions:
1275 1422
1276```{=latex} 1423```{=latex}
1277\begin{minted}{console} 1424\begin{minted}{console}
1278$ nix build -f default.nix \ 1425roger@os $ nix build -f default.nix \
1279 -I machine=./machines/MY_BOARD \ 1426 -I machine=./machines/MY_BOARD \
1280 -I image=./images/MY_CONFIGURATION 1427 -I image=./images/MY_CONFIGURATION
1281\end{minted} 1428\end{minted}
1282``` 1429```
1283 1430
1284## TODO 1431## Building an iso image{.fragile}
1285 1432
1286- [x] Use good Markdown / Beamer template 1433```{=latex}
1287- [ ] Pinning repo version 1434\begin{minted}{nix}
1288- [ ] `a.b.c` = `a = { b = { c = ...; }; };` 1435{ ... }:
1289- [x] How to use different versions 1436{
1290- [ ] Modules can call other modules (and that's what they do **all** the time) 1437 imports = [
1291- [ ] How to build an image 1438 <nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix>
1292- [ ] Add some images to temporise the talk 1439 ];
1293- [ ] Talk about service tests!!! 1440
1294 - [ ] Single-node 1441 # ---8<---
1295 - [ ] Multi-node 1442}
1296- [ ] Add derivation example with compilation options 1443\end{minted}
1297- [ ] Add intro? about problems that I had in Buildroot (non-determinism, no 1444```
1298 auto-recompile) 1445
1299- [ ] Talk about nix-shell 1446```{=latex}
1300- [ ] Talk about nix-shell scripts 1447\begin{minted}{console}
1301- [ ] Talk about nixops 1448roger@os $ nix build -f default.nix config.system.build.sdImage
1302- [ ] Talk about choosing generation at boot 1449\end{minted}
1303- [ ] Have a functional programming intro 1450```
1304- [ ] You **don't** need to run NixOS to develop with Nix 1451
1305- [ ] https://r13y.com/ 1452::: notes
1306- [ ] Drawbacks 1453
1307 - [ ] Harder to compile anything, especially packages with bad build systems 1454- Yes, it's a module again!
1308 - [ ] If one package doesn't compile, harder to compile the system, since 1455- In the end an image is just a file that depends on your system
1309 it's a dependency of the system closure 1456- The sd-image module just uses the result of the `toplevel` derivation
1310 - [ ] You need deeper understanding of the ecosystem to package random 1457
1311 programs 1458
1312 - [ ] Sometimes need to patch software to bypass hardcoded paths (e.g. 1459:::
1313 locale archive) 1460
1314 - [ ] For now, only world readable store, makes it kinda harder for 1461## Other useful features
1315 passwords and other secrets 1462
1316 - Documentation / developer experience is sub-optimal 1463- Repository pinning (a.k.a. just clone `nixpkgs`)
1317- [ ] A burnable image is just a file that depends on every package of your 1464
1318 system 1465- Cross System (**no need to be on NixOS**)
1319 - [ ] instead of depending manually on each package, we depend on the 1466 - i686-linux / x86_64-linux
1320 top-level system closure (output and all dependencies) 1467 - x86_64-darwin (MacOS)
1321 1468 - *Beta*: aarch64-linux / FreeBSD
1322## The End {.standout} 1469
1470- Rollbacks
1471
1472- Declarative deployments (NixOps)
1473
1474::: notes
1475
1476- To rollback, you can just switch to the previous configuration, either by
1477 manually changing the config files, or choosing a previous configuration at
1478 boot
1479
1480:::
1481
1482# Recap
1483
1484## 4ever Drawbacks
1485
1486### Packaging
1487
1488- The language is alien
1489- harder (depends on the software / stack)
1490 - *1304 out of 1321 (98.71%) paths in the minimal installation image are
1491 reproducible*[^1]
1492- You need deeper understanding of the ecosystem
1493- Sometimes need to patch software to bypass hardcoded paths (e.g. locale archive)
1494- No "smart" recompilation of dependents
1495
1496[^1]: <https://r13y.com/>
1497
1498::: notes
1499
1500- Not reprodocible paths includes:
1501 - Python bytecode with timestamps
1502 - Some autotools
1503 - EFI stuff
1504
1505:::
1506
1507### NixOS
1508
1509- You can't compile part of a system without changing your configuration (all
1510 or nothing)
1511- If something doesn't work, you will need to dive into the abstractions
1512- Non POSIX compliant
1513
1514
1515::: notes
1516
1517- The final systems depends on the success of all derivations
1518- Non POSIX compliant means more work to make some tools work
1519- Another way to see it, NixOS does things so differently, and developers don't
1520 tend to take that into account.
1521
1522
1523:::
1524
1525## Current drawbacks
1526
1527- Documentation / developer experience is sub-optimal
1528
1529- Maturity (especially for Embedded)
1530
1531- For now, only world readable store, makes it kinda harder for passwords and
1532 other secrets
1533
1534- Cross compilation is not well tested / integrated
1535
1536
1537::: notes
1538
1539- Reading the code because the documentation isn't there yet happens way too
1540 much.
1541
1542
1543:::
1544
1545## Un-talked Advantages
1546
1547- Made out of simple building blocks
1548 - Makes it possible to develop tools
1549- Hydra
1550 - Safe binary cache
1551 - Distributed builds
1552- Distributed Nix store
1553- Very strong Haskell community for some reason :-)
1554- Usage as a server or workstation
1555- "Works for me" \rightarrow "Works for everybody"
1556
1557
1558## The End{.standout}
1323 1559
1324That's all folks! 1560That's all folks!
1325 1561
1326--- 1562## {.standout}
1327 1563
1328Questions? 1564Questions?
1329 1565
1330Slide sources 1566```{=latex}
1567\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
1568```
1569
1570Slide sources:
1331 ~ <https://github.com/minijackson/nixos-embedded-slides/> 1571 ~ <https://github.com/minijackson/nixos-embedded-slides/>
1332 1572
1573
1574```{=latex}
1575\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
1576```
1577
1333:::::: {.columns} 1578:::::: {.columns}
1334::: {.column width="40%"} 1579::: {.column width="40%"}
1335 1580