summaryrefslogtreecommitdiff
path: root/mkosi.md
blob: 2b56a58151bc1a012c817e453e2be20bf8da76eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
% mkosi(1)
% The mkosi Authors
% 2016-

# NAME

mkosi — Build Legacy-Free OS Images

# SYNOPSIS

`mkosi [options…] build`

`mkosi [options…] clean`

`mkosi [options…] summary`

`mkosi [options…] shell [command line…]`

`mkosi [options…] boot [command line…]`

`mkosi [options…] qemu`

# DESCRIPTION

`mkosi` is a tool for easily     building legacy-free OS images. It's a
fancy wrapper around `dnf --installroot`, `debootstrap`, `pacstrap`
and `zypper` that may generate disk images with a number of bells and
whistles.

## Supported output formats

The following output formats are supported:

* Raw *GPT* disk image, with ext4 as root (*gpt_ext4*)

* Raw *GPT* disk image, with xfs as root (*gpt_xfs*)

* Raw *GPT* disk image, with btrfs as root (*gpt_btrfs*)

* Raw *GPT* disk image, with squashfs as read-only root (*gpt_squashfs*)

* Plain squashfs image, without partition table, as read-only root
  (*plain_squashfs*)

* Plain directory, containing the *OS* tree (*directory*)

* btrfs subvolume, with separate subvolumes for `/var`, `/home`,
  `/srv`, `/var/tmp` (*subvolume*)

* Tarball (*tar*)

When a *GPT* disk image is created, the following additional
options are available:

* A swap partition may be added in

* The image may be made bootable on *EFI* and *BIOS* systems

* Separate partitions for `/srv` and `/home` may be added in

* The root, /srv and /home partitions may optionally be encrypted with
  LUKS.

* A dm-verity partition may be added in that adds runtime integrity
  data for the root partition

## Other features

* Optionally, create an *SHA256SUMS* checksum file for the result,
  possibly even signed via `gpg`.

* Optionally, place a specific `.nspawn` settings file along
  with the result.

* Optionally, build a local project's *source* tree in the image
  and add the result to the generated image (see below).

* Optionally, share *RPM*/*DEB* package cache between multiple runs,
  in order to optimize build speeds.

* Optionally, the resulting image may be compressed with *XZ*.

* Optionally, the resulting image may be converted into a *QCOW2* file
  suitable for `qemu` storage.

* Optionally, btrfs' read-only flag for the root subvolume may be
  set.

* Optionally, btrfs' compression may be enabled for all
  created subvolumes.

* By default images are created without all files marked as
  documentation in the packages, on distributions where the
  package manager supports this. Use the `--with-docs` flag to
  build an image with docs added.

## Command Line Verbs

The following command line verbs are known:

`build`

: This builds the image, based on the settings passed in on the
  command line or read from a `mkosi.default` file, see below. This
  verb is the default if no verb is explicitly specified. This command
  must be executed as `root`.

`clean`

: Remove build artifacts generated on a previous build. If combined
  with `-f`, also removes incremental build cache images. If `-f` is
  specified twice, also removes any package cache.

`summary`

: Outputs a human-readable summary of all options used for building an
  image. This will parse the command line and `mkosi.default` file as it
  would do on `build`, but only output what it is configured for and not
  actually build anything.`

`shell`

: This builds the image if it is not build yet, and then invokes
  `systemd-nspawn` to acquire an interactive shell prompt in it. If
  this verb is used an optional command line may be specified which is
  then invoked in place of the shell in the container. Combine this
  with `-f` in order to rebuild the image unconditionally before
  acquiring the shell, see below. This command must be executed as
  `root`.

`boot`

: Similar to `shell` but boots the image up using `systemd-nspawn`. If
  this verb is used an optional command line may be specified which is
  passed as "kernel command line" to the init system in the image.

`qemu`

: Similar to `boot` but uses `qemu` to boot up the image, i.e. instead
  of container virtualization VM virtualization is used. This verb is
  only supported on images that contain a boot loader, i.e. those
  built with `--bootable` (see below). This command must be executed
  as `root` unless the image already exists and `-f` is not specified.

`help`

: This verb is equivalent to the `--help` switch documented below: it
  shows a brief usage explanation.

## Command Line Parameters

The following command line parameters are understood. Note that many
of these parameters can also be set in the `mkosi.default` file, for
details see the table below.

`--distribution=`, `-d`
: The distribution to install in the image. Takes one of the following
  arguments: `fedora`, `debian`, `ubuntu`, `arch`, `opensuse`,
  `mageia`, `centos`, `clear`. If not specified, defaults to the
  distribution of the host.

`--release=`, `-r`

: The release of the distribution to install in the image. The precise
  syntax of the argument this takes depends on the distribution used,
  and is either a numeric string (in case of Fedora, CentOS, …,
  e.g. `29`), or a distribution version name (in case of Debian,
  Ubuntu, …, e.g. `artful`). If neither this option, not
  `--distribution=` is specified, defaults to the distribution version
  of the host. If the distribution is specified, defaults to a recent
  version of it.

`--mirror=`, `-m`

: The mirror to use for downloading the distribution packages. Expects
  a mirror URL as argument.

`--repositories=`

: Additional package repositories to use during installation. Expects
  one or more URLs as argument, separated by commas. This option may
  be used multiple times, in which case the list of repositories to
  use is combined.

`--architecture=`

: The architecture to build the image for. Note that this currently
  only works for architectures compatible with the host's
  architecture.

`--format=`, `-t`

: The image format type to generate. One of `directory` (for
  generating OS images inside a local directory), `subvolume`
  (similar, but as a btrfs subvolume), `tar` (similar, but a tarball
  of the image is generated), `gpt_ext4` (a block device image with an
  ext4 file system inside a GPT partition table), `gpt_xfs`
  (similar, but with an xfs file system), `gpt_btrfs` (similar, but
  with an btrfs file system), `gpt_squashfs` (similar, but with a
  squashfs file system), `plain_squashfs` (a plain squashfs file
  system without a partition table).

`--output=`, `-o`

: Path for the output image file to generate. Takes a relative or
  absolute path where the generated image will be placed. If neither
  this option nor `--output-dir=` is used (see below), the image is
  generated under the name `image`, but its name suffixed with an
  appropriate file suffix (e.g. `image.raw.xz` in case `gpt_ext4` is
  used in combination with `--xz`).

`--output-dir=`, `-O`

: Path to a directory where to place all generated artifacts (i.e. the
  `SHA256SUMS` file and similar). If this is not specified and a
  directory `mkosi.output/` exists in the local directory it is
  automatically used for this purpose. If this is not specified and
  such a directory does not exist, all output artifacts are placed
  adjacent to the output image file.

`--force`, `-f`

: Replace the output file if it already exists, when building an
  image. By default when building an image and an output artifact
  already exists `mkosi` will refuse operation. Specify `-f` to delete
  all build artifacts from a previous run before re-building the
  image. If incremental builds are enabled (see below), specifying
  this option twice will ensure the intermediary cache files are
  removed, too, before the re-build is initiated. If a package cache
  is used (see below), specifying this option thrice will ensure the
  package cache is removed too, before the re-build is initiated. For
  the `clean` operation `-f` has a slightly different effect: by
  default the verb will only remove build artifacts from a previous
  run, when specified once the incremental cache files are deleted
  too, and when specified twice the package cache is also removed.

`--bootable`, `-b`

: Generate a bootable image. By default this will generate an image
  bootable on UEFI systems. Use `--boot-protocols=` to select support
  for a different boot protocol.

`--boot-protocols=`

: Pick one or more boot protocols to support when generating a
  bootable image, as enabled with `--bootable` above. Takes a
  comma-separated list of `uefi` or `bios`. May be specified more than
  once in which case the specified lists are merged. If `uefi` is
  specified the `sd-boot` UEFI boot loader is used, if `bios` is
  specified the GNU Grub boot loader is used.

`--kernel-command-line=`

: Use the specified kernel command line for when building bootable
  images.

`--secure-boot`

: Sign the resulting kernel/initrd image for UEFI SecureBoot

`--secure-boot-key=`

: Path to the PEM file containing the secret key for signing the
  UEFI kernel image, if `--secure-boot` is used.

`--secure-boot-certificate=`

: Path to the X.509 file containing the certificate for the signed
  UEFI kernel image, if `--secure-boot` is used.

`--read-only`

: Make root file system read-only. Only applies to `gpt_ext4`,
  `gpt_xfs`, `gpt-btrfs`, `subvolume` output formats, and implied on
  `gpt_squashfs` and `plain_squashfs`.

`--encrypt`

: Encrypt all partitions in the file system or just the root file
  system. Takes either `all` or `data` as argument. If `all` the root,
  `/home` and `/srv` file systems will be encrypted using
  dm-crypt/LUKS (with its default settings). If `data` the root file
  system will be left unencrypted, but `/home` and `/srv` will be
  encrypted. The passphrase to use is read from the `mkosi.passphrase`
  file in the current working directory (see below). Note that the
  UEFI System Partition (ESP) containing the boot loader and kernel to
  boot is never encrypted since it needs to be accessible by the
  firmware.

`--verity`

: Add an "Verity" integrity partition to the image. If enabled, the
  root partition is protected with `dm-verity` against off-line
  modification, the verification data is placed in an additional GPT
  partition. Implies `--read-only`.

`--compress=`

: Compress the generated file systems. Only applies to `gpt_btrfs`,
  `subvolume`, `gpt_squashfs`, `plain_squashfs`. Takes one of `zlib`,
  `lzo`, `zstd`, `lz4`, `xz` or a boolean value as argument. If the
  latter is used compression is enabled/disabled and the default
  algorithm is used. In case of the `squashfs` output formats
  compression is implied, however this option may be used to select
  the algorithm.

`--mksquashfs=`

: Set the path to the `mksquashfs` executable to use. This is useful
  in case the parameters for the tool shall be augmented, as the tool
  may be replaced by a script invoking it with the right parameters,
  this way.

`--xz`

: Compress the resulting image with `xz`. This only applies to
  `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`, `gpt_squashfs` and is implied
  for `tar`. Note that when applied to the block device image types
  this means the image cannot be started directly but needs to be
  decompressed first. This also means that the `shell`, `boot`, `qemu`
  verbs are not available when this option is used.

`--qcow2`

: Encode the resulting image as QEMU QCOW2 image. This only applies to
  `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`, `gpt_squashfs`. QCOW2 images can
  be read natively by `qemu`, but not by the Linux kernel. This means
  the `shell` and `boot` verbs are not available when this option is
  used, however `qemu` will work.

`--hostname=`

: Set the image's hostname to the specified name.

`--no-chown`

: By default, if `mkosi` is run inside a `sudo` environment all
  generated artifacts have their UNIX user/group ownership changed to
  the user which invoked `sudo`. With this option this may be turned
  off and all generated files are owned by `root`.

`--incremental`, `-i`

: Enable incremental build mode. This only applies if the two-phase
  `mkosi.build` build script logic is used. In this mode, a copy of
  the OS image is created immediately after all OS packages are
  unpacked but before the `mkosi.build` script is invoked in the
  development container. Similar a copy of the final image is created
  immediately before the build artifacts from the `mkosi.build` script
  are copied in. On subsequent invocations of `mkosi` with the `-i`
  switch these cached images may be used to skip the OS package
  unpacking, thus drastically speeding up repetitive build times. Note
  that when this is used and a pair of cached incremental images
  exists they are not automatically regenerated, even if options such
  as `--packages=` are modified. In order to force rebuilding of these
  cached images, combined `-i` with `-ff`, which ensures the cached
  images are removed first, and then re-created.

`--package=`, `-p`

: Install the specified distribution packages (i.e. RPM, DEB, …) in
  the image. Takes a comma separated list of packages. This option may
  be used multiple times in which case the specified package list is
  combined. Packaged specified this way will be installed both in the
  development and the final image (see below). Use `--build-package=`
  (see below) to specify packages that shall only be used for the
  image generated in the build image, but that shall not appear in the
  final image.

`--with-docs`

: Include documentation in the image built. By default if the
  underlying distribution package manager supports it documentation is
  not included in the image built. The `$WITH_DOCS` environment
  variable passed to the `mkosi.build` script indicates whether this
  option was used or not, see below.

`--without-tests`, `-T`

: If set the `$WITH_TESTS` environment variable is set to `0` when the
  `mkosi.build` script is invoked. This is supposed to be used by the
  build script to bypass any unit or integration tests that are
  normally run during the source build process. Note that this option
  has no effect unless the `mkosi.build` build script honors it.

`--cache=`

: Takes a path to a directory to use as package cache for the
  distribution package manager used. If this option is not used, but a
  `mkosi.cache/` directory is found in the local directory it is
  automatically used for this purpose (also see below). The directory
  configured this way is mounted into both the development and the
  final image while the package manager is running.

`--extra-tree=`

: Takes a path to a directory to copy on top of the OS tree the
  package manager generated. Use this to override any default
  configuration files shipped with the distribution. If this option is
  not used, but the `mkosi.extra/` directory is found in the local
  directory it is automatically used for this purpose (also see
  below). Instead of a directory a `tar` file may be specified too. In
  this case it is unpacked into the OS tree before the package manager
  is invoked. This mode of operation allows setting permissions and
  file ownership explicitly, in particular for projects stored in a
  version control system such as `git` which does retain full file
  ownership and access mode metadata for committed files. If a tar file
  `mkosi.extra.tar` is found in the local directory it automatically
  used for this purpose.

`--skeleton-tree=`

: Takes a path to a directory to copy into the OS tree before invoking
  the package manager. Use this to insert files and directories into
  the OS tree before the package manager installs any packages. If
  this option is not used, but the `mkosi.skeleton/` directory is
  found in the local directory it is automatically used for this
  purpose (also see below). As with the extra tree logic above,
  instead of a directory a `tar` file may be used too, and
  `mkosi.skeleton.tar` is automatically used.

`--build-script=`

: Takes a path to an executable that is used as build script for this
  image. If this option is used the build process will be two-phased
  instead of single-phased (see below). The specified script is copied
  onto the development image and executed inside an `systemd-nspawn`
  container environment. If this option is not used, but the
  `mkosi.build` file found in the local directory it is automatically
  used for this purpose (also see below).

`--build-sources=`

: Takes a path of a source tree to copy into the development image, if
  a build script is used. This only applies if a build script is used,
  and defaults to the local directory. Use `--source-file-transfer=`
  to configure how the files are transferred from the host to the
  container image.

`--build-dir=`

: Takes a path of a directory to use as build directory for build
  systems that support out-of-tree builds (such as Meson). The
  directory used this way is shared between repeated builds, and
  allows the build system to reuse artifacts (such as object files,
  executable, …) generated on previous invocations. This directory is
  mounted into the development image when the build script is
  invoked. The build script can find the path to this directory in the
  `$BUILDDIR` environment variable. If this option is not specified,
  but a directory `mkosi.builddir/` exists in the local directory it
  is automatically used for this purpose (also see below).

`--build-package=`

: Similar to `--package=`, but configures packages to install only in
  the first phase of the build, into the development image. This
  option should be used to list packages containing header files,
  compilers, build systems, linkers and other build tools the
  `mkosi.build` script requires to operate. Note that packages listed
  here are only included in the image created during the first phase
  of the build, and are absent in the final image. use `--package=` to
  list packages that shall be included in both.

`--postinst-script=`

: Takes a path to an executable that is invoked inside the final image
  right after copying in the build artifacts generated in the first
  phase of the build. This script is invoked inside a `systemd-nspawn`
  container environment, and thus does not have access to host
  resources. If this option is not used, but an executable
  `mkosi.postinst` is found in the local directory, it is
  automatically used for this purpose (also see below).

`--finalize-script=`

: Takes a path to an executable that is invoked outside the final
  image right after copying in the build artifacts generated in the
  first phase of the build, and after having executed the
  `mkosi.postinst` script (see above). This script is invoked directly
  in the host environment, and hence has full access to the host's
  resources. If this option is not used, but an executable
  `mkosi.finalize` is found in the local directory, it is
  automatically used for this purpose (also see below).

`--source-file-transfer=`

: Configures how the source file tree (as configured with
  `--build-sources=`) is transferred into the container image
  during the first phase of the build. Takes one of `copy-all` (to
  copy all files from the source tree), `copy-git-cached` (to copy
  only those files `git-ls-files --cached` lists), `copy-git-others`
  (to copy only those files `git-ls-files --others` lists), `mount` to
  bind mount the source tree directly. Defaults to `copy-git-cached`
  if a `git` source tree is detected, otherwise `copy-all`.

`--with-network`

: Enables network connectivity while the build script `mkosi.build` is
  invoked. By default, the build script runs with networking turned
  off. The `$WITH_NETWORK` environment variable is passed to the
  `mkosi.build` build script indicating whether the build is done with
  or without this option.

`--settings=`

: Specifies a `.nspawn` settings file for `systemd-nspawn` to use in
  the `boot` and `shell` verbs, and to place next to the generated
  image file. This is useful to configure the `systemd-nspawn`
  environment when the image is run. If this setting is not used but
  an `mkosi.nspawn` file found in the local directory it is
  automatically used for this purpose (also see below).

`--root-size=`

: Takes a size in bytes for the root file system. The specified
  numeric value may be suffixed with `K`, `M`, `G` to indicate kilo-,
  mega- and gigabytes (all to the base of 1024). This applies to
  output formats `gpt_ext4`, `gpt_xfs`, `gpt_btrfs`. Defaults to 1G,
  except for `gpt_xfs` where it defaults to 1.3G.

`--esp-size=`

: Similar, and configures the size of the UEFI System Partition
  (ESP). This is only relevant if the `--bootable` option is used to
  generate a bootable image. Defaults to 256M.

`--swap-size=`

: Similar, and configures the size of a swap partition on the
  image. If omitted no swap partition is created.

`--home-size=`

: Similar, and configures the size of the `/home` partition. If
  omitted no separate `/home` partition is created.

`--srv-size=`

: Similar, and configures the size of the `/srv` partition. If
  omitted no separate `/srv` partition is created.

`--checksum`

: Generate a `SHA256SUMS` file of all generated artifacts after the
  build is complete.

`--sign`

: Sign the generated `SHA256SUMS` using `gpg` after completion.

`--key=`

: Select the `gpg` key to use for signing `SHA256SUMS`. This key
  is required to exist in the `gpg` keyring already.

`--bmap`

: Generate a `bmap` file for usage with `bmaptool` from the generated
  image file.

`--password=`

: Set the password of the `root` user. By default the `root` account
  is locked. If this option is not used but a file `mkosi.rootpw` exists
  in the local directory the root password is automatically read from it.

`--extra-search-paths=`

: List of colon-separated paths to look for tools in, before using the
  regular `$PATH` search path.

`--directory=`, `-C`

: Takes a path to a directory. `mkosi` switches to this directory
  before doing anything. Note that the various `mkosi.*` files are
  searched for only after changing to this directory, hence using this
  option is an effective way to build a project located in a specific
  directory.

`--default=`

: Loads additional settings from the specified settings file. Most
  command line options may also be configured in a settings file. See
  the table below to see which command line options match which
  settings file option. If this option is not used, but a file
  `mkosi.default` is found in the local directory it is automatically
  used for this purpose. If a setting is configured both on the
  command line and in the settings file, the command line generally
  wins, except for options taking lists in which case both lists are
  combined.

`--all`, `-a`

: Iterate through all files `mkosi.*` in the `mkosi.files/`
  subdirectory, and build each as if `--default=mkosi.files/mkosi.…`
  was invoked. This is a quick way to build a large number of images
  in one go. Any additional specified command line arguments override
  the relevant options in all files processed this way.

`--all-directory=`

: If specified, overrides the directory the `--all` logic described
  above looks for settings files in. If unspecified, defaults to
  `mkosi.files/` in the current working directory (see above).

`--version`
: Show package version.

`--help`, `-h`
: Show brief usage information.

## Command Line Parameters and their Settings File Counterparts

Most command line parameters may also be placed in an `mkosi.default`
settings file (or any other file `--default=` is used on). The
following table shows which command lines parameters correspond with
which settings file options.

| Command Line Parameter       | `mkosi.default` section | `mkosi.default` setting   |
|------------------------------|-------------------------|---------------------------|
| `--distribution=`, `-d`      | `[Distribution]`        | `Distribution=`           |
| `--release=`, `-r`           | `[Distribution]`        | `Release=`                |
| `--repositories=`            | `[Distribution]`        | `Repositories=`           |
| `--mirror=`, `-m`            | `[Distribution]`        | `Mirror=`                 |
| `--architecture=`            | `[Distribution]`        | `Architecture=`           |
| `--format=`, `-t`            | `[Output]`              | `Format=`                 |
| `--output=`, `-o`            | `[Output]`              | `Output=`                 |
| `--output-dir=`, `-O`        | `[Output]`              | `OutputDirectory=`        |
| `--force`, `-f`              | `[Output]`              | `Force=`                  |
| `--bootable`, `-b`           | `[Output]`              | `Bootable=`               |
| `--boot-protocols=`          | `[Output]`              | `BootProtocols=`          |
| `--kernel-command-line=`     | `[Output]`              | `KernelCommandLine=`      |
| `--secure-boot`              | `[Output]`              | `SecureBoot=`             |
| `--secure-boot-key=`         | `[Output]`              | `SecureBootKey=`          |
| `--secure-boot-certificate=` | `[Output]`              | `SecureBootCertificate=`  |
| `--read-only`                | `[Output]`              | `ReadOnly=`               |
| `--encrypt=`                 | `[Output]`              | `Encrypt=`                |
| `--verity=`                  | `[Output]`              | `Verity=`                 |
| `--compress=`                | `[Output]`              | `Compress=`               |
| `--mksquashfs=`              | `[Output]`              | `Mksquashfs=`             |
| `--xz`                       | `[Output]`              | `XZ=`                     |
| `--qcow2`                    | `[Output]`              | `QCow2=`                  |
| `--hostname=`                | `[Output]`              | `Hostname=`               |
| `--package=`                 | `[Packages]`            | `Packages=`               |
| `--with-docs`                | `[Packages]`            | `WithDocs=`               |
| `--without-tests`, `-T`      | `[Packages]`            | `WithTests=`              |
| `--cache=`                   | `[Packages]`            | `Cache=`                  |
| `--extra-tree=`              | `[Packages]`            | `ExtraTrees=`             |
| `--skeleton-tree=`           | `[Packages]`            | `SkeletonTrees=`          |
| `--build-script=`            | `[Packages]`            | `BuildScript=`            |
| `--build-sources=`           | `[Packages]`            | `BuildSources=`           |
| `--source-file-transfer=`    | `[Packages]`            | `SourceFileTransfer=`     |
| `--build-directory=`         | `[Packages]`            | `BuildDirectory=`         |
| `--build-packages=`          | `[Packages]`            | `BuildPackages=`          |
| `--postinst-script=`         | `[Packages]`            | `PostInstallationScript=` |
| `--finalize-script=`         | `[Packages]`            | `FinalizeScript=`         |
| `--with-network`             | `[Packages]`            | `WithNetwork=`            |
| `--settings=`                | `[Packages]`            | `NSpawnSettings=`         |
| `--root-size=`               | `[Partitions]`          | `RootSize=`               |
| `--esp-size=`                | `[Partitions]`          | `ESPSize=`                |
| `--swap-size=`               | `[Partitions]`          | `SwapSize=`               |
| `--home-size=`               | `[Partitions]`          | `HomeSize=`               |
| `--srv-size=`                | `[Partitions]`          | `SrvSize=`                |
| `--checksum`                 | `[Validation]`          | `CheckSum=`               |
| `--sign`                     | `[Validation]`          | `Sign=`                   |
| `--key=`                     | `[Validation]`          | `Key=`                    |
| `--bmap`                     | `[Validation]`          | `BMap=`                   |
| `--password=`                | `[Validation]`          | `Password=`               |
| `--extra-search-paths=`      | `[Host]`                | `ExtraSearchPaths=`       |

Command line options that take no argument are not suffixed with a `=`
in their long version in the table above. In the `mkosi.default` file
they are modeled as boolean option that take either `1`, `yes`,
`true` for enabling, and `0`, `no`, `false` for disabling.

## Supported distributions

Images may be created containing installations of the
following *OS*es.

* *Fedora*

* *Debian*

* *Ubuntu*

* *Arch Linux*

* *openSUSE*

* *Mageia*

* *CentOS*

* *Clear Linux*

In theory, any distribution may be used on the host for building
images containing any other distribution, as long as the necessary
tools are available. Specifically, any distribution that packages
`debootstrap` may be used to build *Debian* or *Ubuntu* images. Any
distribution that packages `dnf` may be used to build *Fedora* or
*Mageia* images. Any distro that packages `pacstrap` may be used to
build *Arch Linux* images. Any distribution that packages `zypper` may
be used to build *openSUSE* images. Any distribution that packages
`yum` (or the newer replacement `dnf`) may be used to build *CentOS*
images.

Currently, *Fedora* packages all relevant tools as of Fedora 28.

## Compatibility

Generated images are *legacy-free*. This means only *GPT* disk labels
(and no *MBR* disk labels) are supported, and only systemd based
images may be generated.

All generated *GPT* disk images may be booted in a local
container directly with:

```bash
systemd-nspawn -bi image.raw
```

Additionally, bootable *GPT* disk images (as created with the
`--bootable` flag) work when booted directly by *EFI* and *BIOS*
systems, for example in *KVM* via:

```bash
qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=image.raw
```

*EFI* bootable *GPT* images are larger than plain *GPT* images, as
they additionally carry an *EFI* system partition containing a
boot loader, as well as a kernel, kernel modules, udev and
more.

All directory or btrfs subvolume images may be booted directly
with:

```bash
systemd-nspawn -bD image
```

# FILES

To make it easy to build images for development versions of your
projects, mkosi can read configuration data from the local directory,
under the assumption that it is invoked from a *source*
tree. Specifically, the following files are used if they exist in the
local directory:

* `mkosi.default` may be used to configure mkosi's image building
  process. For example, you may configure the distribution to use
  (`fedora`, `ubuntu`, `debian`, `arch`, `opensuse`, `mageia`) for the
  image, or additional distribution packages to install. Note that all
  options encoded in this configuration file may also be set on the
  command line, and this file is hence little more than a way to make
  sure simply typing `mkosi` without further parameters in your
  *source* tree is enough to get the right image of your choice set
  up.  Additionally if a `mkosi.default.d` directory exists, each file
  in it is loaded in the same manner adding/overriding the values
  specified in `mkosi.default`. The file format is inspired by Windows
  `.ini` files and supports multi-line assignments: any line with
  initial whitespace is considered a continuation line of the line
  before. Command-line arguments, as shown in the help description,
  have to be included in a configuration block (e.g.  "[Packages]")
  corresponding to the argument group (e.g. "Packages"), and the
  argument gets converted as follows: "--with-network" becomes
  "WithNetwork=yes". For further details see the table above.

* `mkosi.extra/` or `mkosi.extra.tar` may be respectively a directory
  or archive. If any exist all files contained in it are copied over
  the directory tree of the image after the *OS* was installed. This
  may be used to add in additional files to an image, on top of what
  the distribution includes in its packages. When using a directory
  file ownership is not preserved: all files copied will be owned by
  root. To preserve ownership use a tar archive.

* `mkosi.skeleton/` or `mkosi.skeleton.tar` may be respectively a
  directory or archive, and they work in the same way as
  `mkosi.extra`/`mkosi.skeleton.tar`. However the files are copied
  before anything else so to have a skeleton tree for the OS. This
  allows to change the package manager and create files that need to
  be there before anything is installed. When using a directory file
  ownership is not preserved: all files copied will be owned by
  root. To preserve ownership use a tar archive.

* `mkosi.build` may be an executable script. If it exists the image
  will be built twice: the first iteration will be the *development*
  image, the second iteration will be the *final* image. The
  *development* image is used to build the project in the current
  working directory (the *source* tree). For that the whole directory
  is copied into the image, along with the mkosi.build build
  script. The script is then invoked inside the image (via
  `systemd-nspawn`), with `$SRCDIR` pointing to the *source*
  tree. `$DESTDIR` points to a directory where the script should place
  any files generated it would like to end up in the *final*
  image. Note that `make`/`automake`/`meson` based build systems
  generally honor `$DESTDIR`, thus making it very natural to build
  *source* trees from the build script. After the *development* image
  was built and the build script ran inside of it, it is removed
  again. After that the *final* image is built, without any *source*
  tree or build script copied in. However, this time the contents of
  `$DESTDIR` are added into the image.

  When the source tree is copied into the *build* image, all files are
  copied, except for `mkosi.builddir/`, `mkosi.cache/` and
  `mkosi.output/`. That said, `.gitignore` is respected if the source
  tree is a `git` checkout. If multiple different images shall be
  built from the same source tree it's essential to exclude their
  output files from this copy operation, as otherwise a version of an
  image built earlier might be included in a later build, which is
  usually not intended. An alternative to excluding these built images
  via `.gitignore` entries is making use of the `mkosi.output/`
  directory (see below), which is an easy way to exclude all build
  artifacts.

* `mkosi.postinst` may be an executable script. If it exists it is
  invoked as the penultimate step of preparing an image, from within
  the image context. It is once called for the *development* image (if
  this is enabled, see above) with the "build" command line parameter,
  right before invoking the build script. It is called a second time
  for the *final* image with the "final" command line parameter, right
  before the image is considered complete. This script may be used to
  alter the images without any restrictions, after all software
  packages and built sources have been installed. Note that this
  script is executed directly in the image context with the final root
  directory in place, without any `$SRCDIR`/`$DESTDIR` setup.

* `mkosi.finalize` may be an executable script. If it exists it is
  invoked as last step of preparing an image, from the host system.
  It is once called for the *development* image (if this is enabled,
  see above) with the "build" command line parameter, as the last step
  before invoking the build script, after the `mkosi.postinst` script
  is invoked.  It is called the second time with the "final" command
  line parameter as the last step before the image is considered
  complete. The environment variable `$BUILDROOT` points to the root
  directory of the installation image. Additional verbs may be added
  in the future, the script should be prepared for that. This script
  may be used to alter the images without any restrictions, after all
  software packages and built sources have been installed. This script
  is more flexible than `mkosi.postinst` in two regards: it has access
  to the host file system so it's easier to copy in additional files
  or to modify the image based on external configuration, and the
  script is run in the host, so it can be used even without emulation
  even if the image has a foreign architecture.

* `mkosi.mksquashfs-tool` may be an executable script. If it exists is
  is called instead of `mksquashfs`.

* `mkosi.nspawn` may be an nspawn settings file. If this exists it
  will be copied into the same place as the output image file. This is
  useful since nspawn looks for settings files next to image files it
  boots, for additional container runtime settings.

* `mkosi.cache/` may be a directory. If so, it is automatically used as
  package download cache, in order to speed repeated runs of the tool.

* `mkosi.builddir/` may be a directory. If so, it is automatically
  used as out-of-tree build directory, if the build commands in the
  `mkosi.build` script support it. Specifically, this directory will
  be mounted into the build container, and the `$BUILDDIR` environment
  variable will be set to it when the build script is invoked. The
  build script may then use this directory as build directory, for
  automake-style or ninja-style out-of-tree builds. This speeds up
  builds considerably, in particular when `mkosi` is used in
  incremental mode (`-i`): not only the disk images but also the build
  tree is reused between subsequent invocations. Note that if this
  directory does not exist the `$BUILDDIR` environment variable is not
  set, and it is up to build script to decide whether to do in in-tree
  or an out-of-tree build, and which build directory to use.

* `mkosi.rootpw` may be a file containing the password for the root
  user of the image to set. The password may optionally be followed by
  a newline character which is implicitly removed. The file must have
  an access mode of 0600 or less. If this file does not exist the
  distribution's default root password is set (which usually means
  access to the root user is blocked).

* `mkosi.passphrase` may be a passphrase file to use when LUKS
  encryption is selected. It should contain the passphrase literally,
  and not end in a newline character (i.e. in the same format as
  cryptsetup and /etc/crypttab expect the passphrase files). The file
  must have an access mode of 0600 or less. If this file does not
  exist and encryption is requested the user is queried instead.

* `mkosi.secure-boot.crt` and `mkosi.secure-boot.key` may contain an
  X.509 certificate and PEM private key to use when UEFI SecureBoot
  support is enabled. All EFI binaries included in the image's ESP are
  signed with this key, as a late step in the build process.

* `mkosi.output/` may be a directory. If it exists, and the image
  output path is not configured (i.e. no `--output=` setting
  specified), or configured to a filename (i.e. a path containing no
  `/` character) all build artifacts (that is: the image itself, the
  root hash file in case Verity is used, the checksum and its
  signature if that's enabled, and the nspawn settings file if there
  is any) are placed in this directory. Note that this directory is
  not used if the image output path contains at least one slash, and
  has no effect in that case. This setting is particularly useful if
  multiple different images shall be built from the same working
  directory, as otherwise the build result of a preceding run might be
  copied into a build image as part of the source tree (see above).

All these files are optional.

Note that the location of all these files may also be configured
during invocation via command line switches, and as settings in
`mkosi.default`, in case the default settings are not acceptable for a
project.

# BUILD PHASES

If no build script `mkosi.build` (see above) is used the build
consists of a single phase only: the final image is generated as the
combination of `mkosi.skeleton/` (see above), the unpacked
distribution packages and `mkosi.extra/`.

If a build script `mkosi.build` is used the build consists of two
phases: in the the first `development` phase an image that includes
necessary build tools (i.e. the combination of `Packages=` and
`BuildPackages=` is installed) is generated (i.e. the combination of
`mkosi.skeleton/` and unpacked distribution packages). Into this image
the source tree is copied and `mkosi.build` executed. The artifacts
the `mkosi.build` generates are saved. Then, the second `final` phase
starts: an image that excludes the build tools (i.e. only `Packages=`
is installed, `BuildPackages=` is not) is generated. This time the
build artifacts saved from the first phase are copied in, and
`mkosi.extra` copied on top, thus generating the final image.

The two-phased approach ensures that source tree is executed in a
clean and comprehensive environment, while at the same the final image
remains minimal and contains only those packages necessary at runtime,
but avoiding those necessary at build-time.

Note that only the package cache `mkosi.cache/` (see below) is shared
between the two phases. The distribution package manager is executed
exactly once in each phase, always starting from a directory tree that
is populated with `mkosi.skeleton` but nothing else.

# CACHING

`mkosi` supports three different caches for speeding up repetitive
re-building of images. Specifically:

1. The package cache of the distribution package manager may be cached
   between builds. This is configured with the `--cache=` option or
   the `mkosi.cache/` directory. This form of caching relies on the
   distribution's package manager, and caches distribution packages
   (RPM, DEB, …) after they are downloaded, but before they are
   unpacked.

2. If an `mkosi.build` script is used, by enabling incremental build
   mode with `--incremental` (see above) a cached copy of the
   development and final images can be made immediately before the
   build sources are copied in (for the development image) or the
   artifacts generated by `mkosi.build` are copied in (in case of the
   final image). This form of caching allows bypassing the
   time-consuming package unpacking step of the distribution package
   managers, but is only effective if the list of packages to use
   remains stable, but the build sources and its scripts change
   regularly. Note that this cache requires manual flushing: whenever
   the package list is modified the cached images need to be
   explicitly removed before the next re-build, using the `-f` switch.

3. Finally, between multiple builds the build artifact directory may
   be shared, using the `mkosi.builddir/` directory. This directory
   allows build systems such as Meson to reuse already compiled
   sources from a previous built, thus speeding up the build process
   of the `mkosi.build` build script.

The package cache (i.e. the first item above) is unconditionally
useful. The latter two caches only apply to uses of `mkosi` with a
source tree and build script. When all three are enabled together
turn-around times for complete image builds are minimal, as only
changed source files need to be recompiled: an OS image rebuilt will
be almost as quick to build the source tree only.

# ENVIRONMENT VARIABLES

The build script `mkosi.build` receives the following environment
variables:

* `$SRCDIR` contains the path to the sources to build.

* `$DESTDIR` is a directory into which any artifacts generated by the
  build script shall be placed.

* `$BUILDDIR` is only defined if `mkosi.builddir` and points to the
  build directory to use. This is useful for all build systems that
  support out-of-tree builds to reuse already built artifacts from
  previous runs.

* `$WITH_DOCS` is either `0` or `1` depending on whether a build
  without or with installed documentation was requested (see
  `--with-docs` above). The build script should suppress installation
  of any package documentation to `$DESTDIR` in case `$WITH_DOCS` is
  set to `0`.

* `$WITH_TESTS` is either `0`or `1` depending on whether a build
  without or with running the test suite was requested (see
  `--without-tests` above). The build script should avoid running any
  unit or integration tests in case `$WITH_TESTS` is `0`.

* `$WITH_NETWORK` is either `0`or `1` depending on whether a build
  without or with networking is being executed (see `--with-network`
  above). The build script should avoid any network communication in
  case `$WITH_NETWORK` is `0`.

# EXAMPLES

Create and run a raw *GPT* image with *ext4*, as `image.raw`:

```bash
# mkosi
# systemd-nspawn -b -i image.raw
```

Create and run a bootable btrfs *GPT* image, as `foobar.raw`:

```bash
# mkosi -t gpt_btrfs --bootable -o foobar.raw
# systemd-nspawn -b -i foobar.raw
# qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=foobar.raw
```

Create and run a *Fedora* image into a plain directory:

```bash
# mkosi -d fedora -t directory -o quux
# systemd-nspawn -b -D quux
```

Create a compressed image `image.raw.xz` and add a checksum file, and
install *SSH* into it:

```bash
# mkosi -d fedora -t gpt_squashfs --checksum --xz --package=openssh-clients
```

Inside the source directory of an `automake`-based project,
configure *mkosi* so that simply invoking `mkosi` without any
parameters builds an *OS* image containing a built version of
the project in its current state:

```bash
# cat > mkosi.default <<EOF
[Distribution]
Distribution=fedora
Release=24

[Output]
Format=gpt_btrfs
Bootable=yes

[Packages]
Packages=openssh-clients httpd
BuildPackages=make gcc libcurl-devel
EOF
# cat > mkosi.build <<EOF
#!/bin/sh
cd $SRCDIR
./autogen.sh
./configure --prefix=/usr
make -j `nproc`
make install
EOF
# chmod +x mkosi.build
# mkosi
# systemd-nspawn -bi image.raw
```

To create a *Fedora* image with hostname:
```bash
# mkosi -d fedora --hostname image
```

Also you could set hostname in configuration file:
```bash
# cat mkosi.default
...
[Output]
Hostname=image
...
```

# REQUIREMENTS

mkosi is packaged for various distributions: Debian, Ubuntu, Arch (in AUR), Fedora.
It is usually easiest to use the distribution package.

The current version requires systemd 233 (or actually, systemd-nspawn of it).

When not using distribution packages make sure to install the
necessary dependencies. For example, on *Fedora* you need:

```bash
dnf install arch-install-scripts btrfs-progs debootstrap dosfstools edk2-ovmf e2fsprogs squashfs-tools gnupg python3 tar veritysetup xfsprogs xz zypper sbsigntools
```

On Debian/Ubuntu it might be necessary to install the `ubuntu-keyring`,
`ubuntu-archive-keyring` and/or `debian-archive-keyring` packages explicitly,
in addition to `debootstrap`, depending on what kind of distribution images
you want to build. `debootstrap` on Debian only pulls in the Debian keyring
on its own, and the version on Ubuntu only the one from Ubuntu.

Note that the minimum required Python version is 3.6.

# REFERENCES
* [Primary mkosi git repository on GitHub](https://github.com/systemd/mkosi/)
* [mkosi — A Tool for Generating OS Images](http://0pointer.net/blog/mkosi-a-tool-for-generating-os-images.html) introductory blog post by Lennart Poettering
* [The mkosi OS generation tool](https://lwn.net/Articles/726655/) story on LWN

# SEE ALSO
`systemd-nspawn(1)`, `dnf(8)`, `debootstrap(8)`