1PUNGI(1)                             Pungi                            PUNGI(1)
2
3
4

NAME

6       pungi - Pungi Documentation
7
8       Contents:
9

ABOUT PUNGI

11         [image: Pungi Logo] [image]
12
13       Pungi is a distribution compose tool.
14
15       Composes  are  release snapshots that contain release deliverables such
16       as:
17
18       • installation trees
19
20         • RPMs
21
22         • repodata
23
24         • comps
25
26       • (bootable) ISOs
27
28       • kickstart trees
29
30         • anaconda images
31
32         • images for PXE boot
33
34   Tool overview
35       Pungi consists of multiple separate executables backed by a common  li‐
36       brary.
37
38       The  main  entry-point  is  the pungi-koji script. It loads the compose
39       configuration and kicks off the process. Composing itself  is  done  in
40       phases.   Each  phase  is  responsible for generating some artifacts on
41       disk and updating the compose object that is threaded through  all  the
42       phases.
43
44       Pungi itself does not actually do that much. Most of the actual work is
45       delegated to separate executables. Pungi just makes sure that  all  the
46       commands  are  invoked  in the appropriate order and with correct argu‐
47       ments. It also moves the artifacts to correct locations.
48
49       The executable name pungi-koji comes from the fact that most  of  those
50       separate  executables submit tasks to Koji that does the actual work in
51       an auditable way.
52
53       However unlike doing everything manually in Koji, Pungi will make  sure
54       you are building all images from the same package set, and will produce
55       even deliverables that Koji can not create like YUM repos and installer
56       ISOs.
57
58   Links
59       • Upstream GIT: https://pagure.io/pungi/
60
61       • Issue tracker: https://pagure.io/pungi/issues
62
63       • Questions can be asked on #fedora-releng IRC channel on FreeNode
64
65   Origin of name
66       The name Pungi comes from the instrument used to charm snakes. Anaconda
67       being the software Pungi was manipulating, and anaconda being a  snake,
68       led to the referential naming.
69
70       The first name, which was suggested by Seth Vidal, was FIST, Fedora In‐
71       stallation <Something> Tool. That name was quickly  discarded  and  re‐
72       placed with Pungi.
73
74       There  was  also a bit of an inside joke that when said aloud, it could
75       sound like punji, which is a sharpened stick at the bottom of  a  trap.
76       Kind of like software…
77

PHASES

79       Each  invocation  of  pungi-koji  consists of a set of phases.  [image:
80       phase diagram] [image]
81
82       Most of the phases run sequentially (left-to-right in the diagram), but
83       there are use cases where multiple phases run in parallel. This happens
84       for phases whose main point is to wait for a Koji task to finish.
85
86   Init
87       The first phase to ever run. Can not be skipped. It prepares the  comps
88       files  for  variants  (by filtering out groups and packages that should
89       not be there).  See comps for details about how this is done.
90
91   Pkgset
92       This phase loads a set of packages that should be composed. It has  two
93       separate  results:  it  prepares repos with packages in work/ directory
94       (one per arch) for further processing, and it returns a data  structure
95       with mapping of packages to architectures.
96
97   Buildinstall
98       Spawns  a bunch of threads, each of which runs either lorax or buildin‐
99       stall command (the latter coming from anaconda package).  The  commands
100       create  boot.iso  and  other boot configuration files. The image is fi‐
101       nally linked into the compose/ directory as netinstall media.
102
103       The created images are also needed for creating live media or other im‐
104       ages in later phases.
105
106       With  lorax  this phase runs one task per variant.arch combination. For
107       buildinstall command there is only one task per architecture and  prod‐
108       uct.img should be used to customize the results.
109
110   Gather
111       This  phase  uses  data  collected by pkgset phase and figures out what
112       packages should be in each variant. The basic  mapping  can  come  from
113       comps  file,  a JSON mapping or additional_packages config option. This
114       inputs can then be enriched by adding all dependencies.  See  gathering
115       for details.
116
117       Once  the  mapping is finalized, the packages are linked to appropriate
118       places and the rpms.json manifest is created.
119
120   ExtraFiles
121       This phase collects extra files from the configuration and copies  them
122       to the compose directory. The files are described by a JSON file in the
123       compose subtree where the files are copied. This metadata is  meant  to
124       be distributed with the data (on ISO images).
125
126   Createrepo
127       This  phase  creates RPM repositories for each variant.arch tree. It is
128       actually reading the rpms.json manifest to figure  out  which  packages
129       should be included.
130
131   OSTree
132       Updates  an  ostree repository with a new commit with packages from the
133       compose.  The repository lives outside of the compose  and  is  updated
134       immediately. If the compose fails in a later stage, the commit will not
135       be reverted.
136
137       Implementation wise, this phase runs rpm-ostree command in Koji runroot
138       (to allow running on different arches).
139
140   Createiso
141       Generates  ISO files and accumulates enough metadata to be able to cre‐
142       ate image.json manifest. The file is however not created in this phase,
143       instead it is dumped in the pungi-koji script itself.
144
145       The  files  include  a repository with all RPMs from the variant. There
146       will be multiple images if the packages do not fit on a single image.
147
148       The image will be bootable if buildinstall phase  is  enabled  and  the
149       packages fit on a single image.
150
151       There  can  also  be  images  with source repositories. These are never
152       bootable.
153
154   ExtraIsos
155       This phase is very similar to createiso,  except  it  combines  content
156       from  multiple variants onto a single image. Packages, repodata and ex‐
157       tra files from each configured variant are put into a subdirectory. Ad‐
158       ditional  extra files can be put into top level of the image. The image
159       will be bootable if the main variant is bootable.
160
161   LiveImages, LiveMedia
162       Creates media in Koji with koji  spin-livecd,  koji  spin-appliance  or
163       koji  spin-livemedia  command.  When the media are finished, the images
164       are copied into the compose/ directory and metadata for images  is  up‐
165       dated.
166
167   ImageBuild
168       This  phase wraps up koji image-build. It also updates the metadata ul‐
169       timately responsible for images.json manifest.
170
171   OSBuild
172       Similarly to image build, this phases creates a koji osbuild  task.  In
173       the background it uses OSBuild Composer to create images.
174
175   OSBS
176       This phase builds container base images in OSBS.
177
178       The finished images are available in registry provided by OSBS, but not
179       downloaded directly into the compose. The is metadata about the created
180       image in compose/metadata/osbs.json.
181
182   ImageContainer
183       This phase builds a container image in OSBS, and stores the metadata in
184       the same file as OSBS phase. The container produced here wraps  a  dif‐
185       ferent  image, created it ImageBuild or OSBuild phase. It can be useful
186       to deliver a VM image to containerized environments.
187
188   OSTreeInstaller
189       Creates bootable media that carry an ostree repository  as  a  payload.
190       These images are created by running lorax with special templates. Again
191       it runs in Koji runroot.
192
193   Repoclosure
194       Run repoclosure on each repository. By default errors are only reported
195       in  the log, the compose will still be considered a success. The actual
196       error has to be looked up in the compose logs directory.  Configuration
197       allows customizing this.
198
199   ImageChecksum
200       Responsible  for generating checksums for the images. The checksums are
201       stored in image manifest as well as files on disk. The list  of  images
202       to  be  processed is obtained from the image manifest. This way all im‐
203       ages will get the same checksums irrespective of the phase that created
204       them.
205
206   Test
207       This  phase  is supposed to run some sanity checks on the finished com‐
208       pose.
209
210       The only test is to check all images listed  the  metadata  and  verify
211       that  they  look  sane. For ISO files headers are checked to verify the
212       format is correct, and for bootable media a check is run to verify they
213       have properties that allow booting.
214

CONFIG FILE FORMAT

216       The configuration file parser is provided by kobo
217
218       The  file  follows  a  Python-like format. It consists of a sequence of
219       variables that have a value assigned to them.
220
221          variable = value
222
223       The variable names must follow the  same  convention  as  Python  code:
224       start  with  a  letter  and  consist of letters, digits and underscores
225       only.
226
227       The values can be either an integer, float, boolean (True or False),  a
228       string  or  None.  Strings  must be enclosed in either single or double
229       quotes.
230
231       Complex types are supported as well.
232
233       A list is enclosed in square brackets and items are separated with com‐
234       mas.  There can be a comma after the last item as well.
235
236          a_list = [1,
237                    2,
238                    3,
239                   ]
240
241       A tuple works like a list, but is enclosed in parenthesis.
242
243          a_tuple = (1, "one")
244
245       A  dictionary  is wrapped in brackets, and consists of key: value pairs
246       separated by commas. The keys can only be formed from basic types (int,
247       float, string).
248
249          a_dict = {
250              'foo': 'bar',
251              1: None
252          }
253
254       The  value  assigned to a variable can also be taken from another vari‐
255       able.
256
257          one = 1
258          another = one
259
260       Anything on a line after a # symbol is ignored and functions as a  com‐
261       ment.
262
263   Importing other files
264       It  is  possible  to  include another configuration file. The files are
265       looked up relative to the currently processed file.
266
267       The general structure of import is:
268
269          from FILENAME import WHAT
270
271       The FILENAME should be just the base name of the file without extension
272       (which  must  be  .conf).  WHAT can either be a comma separated list of
273       variables or *.
274
275          # Opens constants.conf and brings PI and E into current scope.
276          from constants import PI, E
277
278          # Opens common.conf and brings everything defined in that file into current
279          # file as well.
280          from common import *
281
282       NOTE:
283          Pungi will copy the configuration file given on  command  line  into
284          the  logs/  directory. Only this single file will be copied, not any
285          included ones. (Copying included files requires a fix  in  kobo  li‐
286          brary.)
287
288          The JSON-formatted dump of configuration is correct though.
289
290   Formatting strings
291       String  interpolation is available as well. It uses a %-encoded format.
292       See Python documentation for more details.
293
294          joined = "%s %s" % (var_a, var_b)
295
296          a_dict = {
297              "fst": 1,
298              "snd": 2,
299          }
300          another = "%(fst)s %(snd)s" % a_dict
301

CONFIGURATION

303       Please read productmd documentation for terminology and  other  release
304       and compose related details.
305
306   Minimal Config Example
307          # RELEASE
308          release_name = "Fedora"
309          release_short = "Fedora"
310          release_version = "23"
311
312          # GENERAL SETTINGS
313          comps_file = "comps-f23.xml"
314          variants_file = "variants-f23.xml"
315
316          # KOJI
317          koji_profile = "koji"
318          runroot = False
319
320          # PKGSET
321          sigkeys = [None]
322          pkgset_source = "koji"
323          pkgset_koji_tag = "f23"
324
325          # GATHER
326          gather_method = "deps"
327          greedy_method = "build"
328          check_deps = False
329
330          # BUILDINSTALL
331          buildinstall_method = "lorax"
332
333   Release
334       Following mandatory options describe a release.
335
336   Options
337       release_name [mandatory]
338              (str) – release name
339
340       release_short [mandatory]
341              (str)  –  release short name, without spaces and special charac‐
342              ters
343
344       release_version [mandatory]
345              (str) – release version
346
347       release_type = “ga” (str) – release type, for example ga,
348              updates or updates-testing. See list of all valid values in pro‐
349              ductmd documentation.
350
351       release_internal = False
352              (bool) – whether the compose is meant for public consumption
353
354       treeinfo_version
355              (str)  Version to display in .treeinfo files. If not configured,
356              the value from release_version will be used.
357
358   Example
359          release_name = "Fedora"
360          release_short = "Fedora"
361          release_version = "23"
362          # release_type = "ga"
363
364   Base Product
365       Base product options are optional and we need to  them  only  if  we’re
366       composing a layered product built on another (base) product.
367
368   Options
369       base_product_name
370              (str) – base product name
371
372       base_product_short
373              (str)  –  base  product  short  name, without spaces and special
374              characters
375
376       base_product_version
377              (str) – base product major version
378
379       base_product_type = “ga”
380              (str) – base product type, “ga”, “updates” etc., for  full  list
381              see documentation of productmd.
382
383   Example
384          release_name = "RPM Fusion"
385          release_short = "rf"
386          release_version = "23.0"
387
388          base_product_name = "Fedora"
389          base_product_short = "Fedora"
390          base_product_version = "23"
391
392   General Settings
393   Options
394       comps_file [mandatory]
395              (scm_dict,  str  or None) – reference to comps XML file with in‐
396              stallation groups
397
398       variants_file [mandatory]
399              (scm_dict or str) – reference to variants XML file that  defines
400              release variants and architectures
401
402       module_defaults_dir [optional]
403              (scm_dict or str) – reference the module defaults directory con‐
404              taining modulemd-defaults YAML  documents.  Files  relevant  for
405              modules  included  in the compose will be embedded in the gener‐
406              ated repodata and available for DNF.
407
408                 module_defaults_dir = {
409                     "scm": "git",
410                     "repo": "https://pagure.io/releng/fedora-module-defaults.git",
411                     "dir": ".",
412                 }
413
414       failable_deliverables [optional]
415              (list) – list which deliverables on which variant and  architec‐
416              ture can fail and not abort the whole compose. This only applies
417              to buildinstall and iso parts. All other artifacts can  be  con‐
418              figured in their respective part of configuration.
419
420              Please  note  that * as a wildcard matches all architectures but
421              src.
422
423       comps_filter_environments [optional]
424              (bool) – When set to False, the comps files  for  variants  will
425              not have their environments filtered to match the variant.
426
427       tree_arches
428              ([str]) – list of architectures which should be included; if un‐
429              defined, all architectures from variants.xml will be included
430
431       tree_variants
432              ([str]) – list of variants which should be  included;  if  unde‐
433              fined, all variants from variants.xml will be included
434
435       repoclosure_strictness
436              (list)  – variant/arch mapping describing how repoclosure should
437              run.  Possible values are
438
439off – do not run repoclosure
440
441lenient – (default) run repoclosure and  write  results  to
442                   logs, but detected errors are only reported in logs
443
444fatal – abort compose when any issue is detected
445
446              When  multiple blocks in the mapping match a variant/arch combi‐
447              nation, the last value will win.
448
449       repoclosure_backend
450              (str) – Select which tool should be used to run repoclosure over
451              created repositories. By default yum is used, but you can switch
452              to dnf.  Please note that when dnf is used, the build  dependen‐
453              cies  check  is skipped. On Python 3, only dnf backend is avail‐
454              able.
455
456              See also: the gather_backend setting for Pungi’s gather phase.
457
458       cts_url
459              (str) – URL to Compose Tracking Service. If defined, Pungi  will
460              add  the  compose to Compose Tracking Service and ge the compose
461              ID from it.  For example https://cts.localhost.tld/
462
463       cts_keytab
464              (str) – Path to Kerberos keytab which will be used  for  Compose
465              Tracking  Service  Kerberos  authentication. If not defined, the
466              default Kerberos principal is used.
467
468       compose_type
469              (str) – Allows to set default compose type. Type set via a  com‐
470              mand-line option overwrites this.
471
472       mbs_api_url
473              (str)  –  URL  to  Module  Build Service (MBS) API.  For example
474              https://mbs.example.com/module-build-service/2.   This  is   re‐
475              quired by pkgset_scratch_modules.
476
477   Example
478          comps_file = {
479              "scm": "git",
480              "repo": "https://git.fedorahosted.org/git/comps.git",
481              "branch": None,
482              "file": "comps-f23.xml.in",
483          }
484
485          variants_file = {
486              "scm": "git",
487              "repo": "https://pagure.io/pungi-fedora.git ",
488              "branch": None,
489              "file": "variants-fedora.xml",
490          }
491
492          failable_deliverables = [
493              ('^.*$', {
494                  # Buildinstall can fail on any variant and any arch
495                  '*': ['buildinstall'],
496                  'src': ['buildinstall'],
497                  # Nothing on i386 blocks the compose
498                  'i386': ['buildinstall', 'iso', 'live'],
499              })
500          ]
501
502          tree_arches = ["x86_64"]
503          tree_variants = ["Server"]
504
505          repoclosure_strictness = [
506              # Make repoclosure failures fatal for compose on all variants …
507              ('^.*$', {'*': 'fatal'}),
508              # … except for Everything where it should not run at all.
509              ('^Everything$', {'*': 'off'})
510          ]
511
512   Image Naming
513       Both image name and volume id are generated based on the configuration.
514       Since the volume id is limited to 32 characters, there  are  more  set‐
515       tings available.  The process for generating volume id is to get a list
516       of possible formats and try them sequentially until  one  fits  in  the
517       length limit. If substitutions are configured, each attempted volume id
518       will be modified by it.
519
520       For layered products, the candidate formats are first  image_volid_lay‐
521       ered_product_formats  followed by image_volid_formats.  Otherwise, only
522       image_volid_formats are tried.
523
524       If no format matches the length limit, an error will  be  reported  and
525       compose aborted.
526
527   Options
528       There a couple common format specifiers available for both the options:
529
530compose_id
531
532release_short
533
534version
535
536date
537
538respin
539
540type
541
542type_suffix
543
544label
545
546label_major_version
547
548variant
549
550arch
551
552disc_type
553
554       image_name_format [optional]
555              (str|dict) – Python’s format string to serve as template for im‐
556              age names. The value can also be  a  dict  mapping  variant  UID
557              regexes  to  the  format string. The pattern should not overlap,
558              otherwise it is undefined which one will be used.
559
560              This format will be used for all phases generating images.  Cur‐
561              rently that means createiso, live_images and buildinstall.
562
563              Available extra keys are:
564
565disc_num
566
567suffix
568
569       image_volid_formats [optional]
570              (list) – A list of format strings for generating volume id.
571
572              The extra available keys are:
573
574base_product_short
575
576base_product_version
577
578       image_volid_layered_product_formats [optional]
579              (list)  –  A list of format strings for generating volume id for
580              layered products. The keys available are the  same  as  for  im‐
581              age_volid_formats.
582
583       restricted_volid = False
584              (bool)  –  New  versions of lorax replace all non-alphanumerical
585              characters with dashes (underscores are preserved). This  option
586              will mimic similar behaviour in Pungi.
587
588       volume_id_substitutions [optional]
589              (dict)  – A mapping of string replacements to shorten the volume
590              id.
591
592       disc_types [optional]
593              (dict) – A mapping  for  customizing  disc_type  used  in  image
594              names.
595
596              Available keys are:
597
598boot  –  for  boot.iso  images created in  buildinstall
599                       phase
600
601live – for images created by live_images phase
602
603dvd – for images created by createiso phase
604
605ostree – for ostree installer images
606
607              Default values are the same as the keys.
608
609   Example
610          # Image name respecting Fedora's image naming policy
611          image_name_format = "%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s%(suffix)s"
612          # Use the same format for volume id
613          image_volid_formats = [
614              "%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s"
615          ]
616          # No special handling for layered products, use same format as for regular images
617          image_volid_layered_product_formats = []
618          # Replace "Cloud" with "C" in volume id etc.
619          volume_id_substitutions = {
620              'Cloud': 'C',
621              'Alpha': 'A',
622              'Beta': 'B',
623              'TC': 'T',
624          }
625
626          disc_types = {
627              'boot': 'netinst',
628              'live': 'Live',
629              'dvd': 'DVD',
630          }
631
632   Signing
633       If you want to sign deliverables generated during pungi  run  like  RPM
634       wrapped images. You must provide few configuration options:
635
636       signing_command [optional]
637              (str)  –  Command that will be run with a koji build as a single
638              argument. This command must not require  any  user  interaction.
639              If you need to pass a password for a signing key to the command,
640              do this via command line option of the command  and  use  string
641              formatting    syntax   %(signing_key_password)s.    (See   sign‐
642              ing_key_password_file).
643
644       signing_key_id [optional]
645              (str) – ID of the key that will be used for the  signing.   This
646              ID will be used when crafting koji paths to signed files (kojip‐
647              kgs.fedoraproject.org/pack‐
648              ages/NAME/VER/REL/data/signed/KEYID/..).
649
650       signing_key_password_file [optional]
651              (str) – Path to a file with password that will be formatted into
652              signing_command string via %(signing_key_password)s string  for‐
653              mat syntax (if used).  Because pungi config is usually stored in
654              git and is part of compose logs we don’t want password to be in‐
655              cluded  directly  in  the config.  Note: If - string is used in‐
656              stead of a filename, then you will be asked for the password in‐
657              teractivelly right after pungi starts.
658
659   Example
660          signing_command = '~/git/releng/scripts/sigulsign_unsigned.py -vv --password=%(signing_key_password)s fedora-24'
661          signing_key_id = '81b46521'
662          signing_key_password_file = '~/password_for_fedora-24_key'
663
664   Git URLs
665       In multiple places the config requires URL of a Git repository to down‐
666       load some file from. This URL is passed on to Koji. It is  possible  to
667       specify which commit to use using this syntax:
668
669          git://git.example.com/git/repo-name.git?#<rev_spec>
670
671       The  <rev_spec>  pattern  can be replaced with actual commit SHA, a tag
672       name, HEAD to indicate that tip of default branch  should  be  used  or
673       origin/<branch_name> to use tip of arbitrary branch.
674
675       If  the  URL specifies a branch or HEAD, Pungi will replace it with the
676       actual commit SHA. This will later show up in Koji tasks and help  with
677       tracing what particular inputs were used.
678
679       NOTE:
680          The  origin must be specified because of the way Koji works with the
681          repository. It will clone the repository then  switch  to  requested
682          state  with  git  reset --hard REF. Since no local branches are cre‐
683          ated, we need to use full specification including the  name  of  the
684          remote.
685
686   Createrepo Settings
687   Options
688       createrepo_checksum
689              (str)  –  specify checksum type for createrepo; expected values:
690              sha512, sha256, sha1. Defaults to sha256.
691
692       createrepo_c = True
693              (bool) – use createrepo_c (True) or legacy createrepo (False)
694
695       createrepo_deltas = False
696              (list) – generate delta RPMs  against  an  older  compose.  This
697              needs to be used together with --old-composes command line argu‐
698              ment. The value should be a mapping of  variants  and  architec‐
699              tures  that should enable creating delta RPMs. Source and debug‐
700              info repos never have deltas.
701
702       createrepo_use_xz = False
703              (bool) – whether to pass --xz to the  createrepo  command.  This
704              will cause the SQLite databases to be compressed with xz.
705
706       createrepo_num_threads
707              (int)  –  how many concurrent createrepo process to run. The de‐
708              fault is to use one thread per CPU available on the machine.
709
710       createrepo_num_workers
711              (int) – how many concurrent createrepo workers to run. Value de‐
712              faults to 3.
713
714       createrepo_database
715              (bool)  – whether to create SQLite database as part of the repo‐
716              data. This is only useful as an optimization for  clients  using
717              Yum  to  consume  to  the  repo. Default value depends on gather
718              backend. For DNF it’s turned off, for Yum the default is True.
719
720       createrepo_extra_args
721              ([str]) – a list of extra arguments passed on to  createrepo  or
722              createrepo_c  executable.  This  could  be  useful  for enabling
723              zchunk generation and pointing it to correct dictionaries.
724
725       createrepo_extra_modulemd
726              (dict) – a mapping of variant UID to an scm dict.  If specified,
727              it  should  point to a directory with extra module metadata YAML
728              files that will be added to the repository for this variant. The
729              cloned files should be split into subdirectories for each archi‐
730              tecture of the variant.
731
732       createrepo_enable_cache = True
733              (bool) – whether to use --cachedir option of createrepo. It will
734              cache  and  reuse  checksum vaules to speed up createrepo phase.
735              The cache dir is located  at  /var/cache/pungi/createrepo_c/$re‐
736              lease_short-$uid e.g. /var/cache/pungi/createrepo_c/Fedora-1000
737
738       product_id = None
739              (scm_dict)  –  If specified, it should point to a directory with
740              certificates *<variant_uid>-<arch>-*.pem. Pungi will  copy  each
741              certificate file into the relevant Yum repositories as a produc‐
742              tid file in the repodata directories. The purpose of these  pro‐
743              ductid    files    is    to   expose   the   product   data   to
744              subscription-manager.  subscription-manager  includes  a  “prod‐
745              uct-id”  Yum  plugin  that  can read these productid certificate
746              files from each Yum repository.
747
748       product_id_allow_missing = False
749              (bool) – When product_id is used  and  a  certificate  for  some
750              variant and architecture is missing, Pungi will exit with an er‐
751              ror by default.  When you set this option to  True,  Pungi  will
752              ignore the missing certificate and simply log a warning message.
753
754       product_id_allow_name_prefix = True
755              (bool)  –  Allow  arbitrary prefix for the certificate file name
756              (see leading * in the pattern above).  Setting  this  option  to
757              False  will  make  the pattern more strict by requiring the file
758              name to start directly with variant name.
759
760   Example
761          createrepo_checksum = "sha"
762          createrepo_deltas = [
763              # All arches for Everything should have deltas.
764              ('^Everything$', {'*': True}),
765              # Also Server.x86_64 should have them (but not on other arches).
766              ('^Server$', {'x86_64': True}),
767          ]
768          createrepo_extra_modulemd = {
769              "Server": {
770                  "scm": "git",
771                  "repo": "https://example.com/extra-server-modulemd.git",
772                  "dir": ".",
773                  # The directory should have this layout. Each architecture for the
774                  # variant should be included (even if the directory is empty.
775                  # .
776                  # ├── aarch64
777                  # │   ├── some-file.yaml
778                  # │   └ ...
779                  # └── x86_64
780              }
781          }
782
783   Package Set Settings
784   Options
785       sigkeys
786              ([str or None]) – priority list of signing key  IDs.  These  key
787              IDs  match the key IDs for the builds in Koji. Pungi will choose
788              signed packages according to the order of the key IDs  that  you
789              specify here. Use one single key in this list to ensure that all
790              RPMs are signed by one key. If the list includes an empty string
791              or  None,  Pungi  will allow unsigned packages. If the list only
792              includes None, Pungi will use all unsigned packages.
793
794       pkgset_source [mandatory]
795              (str) – “koji” (any koji instance)  or  “repos”  (arbitrary  yum
796              repositories)
797
798       pkgset_koji_tag
799              (str|[str])  –  tag(s) to read package set from. This option can
800              be omitted for modular composes.
801
802       pkgset_koji_builds
803              (str|[str]) – extra build(s) to include in a package set defined
804              as NVRs.
805
806       pkgset_koji_scratch_tasks
807              (str|[str])  – RPM scratch build task(s) to include in a package
808              set, defined as task IDs. This option can be used only when com‐
809              pose_type is set to test. The RPM still needs to have higher NVR
810              than any other RPM with the same name coming from other  sources
811              in order to appear in the resulting compose.
812
813       pkgset_koji_module_tag
814              (str|[str])  – tags to read module from. This option works simi‐
815              larly to listing tags in variants XML. If tags are specified and
816              variants  XML specifies some modules via NSVC (or part of), only
817              modules matching that list will be  used  (and  taken  from  the
818              tag). Inheritance is used automatically.
819
820       pkgset_koji_module_builds
821              (dict) – A mapping of variants to extra module builds to include
822              in a package set: {variant: [N:S:V:C]}.
823
824       pkgset_koji_inherit = True
825              (bool) – inherit builds from parent tags; we  can  turn  it  off
826              only if we have all builds tagged in a single tag
827
828       pkgset_koji_inherit_modules = False
829              (bool)  –  the  same  as above, but this only applies to modular
830              tags. This option applies to the content tags that  contain  the
831              RPMs.
832
833       pkgset_repos
834              (dict)  –  A mapping of architectures to repositories with RPMs:
835              {arch: [repo]}. Only use when pkgset_source = "repos".
836
837       pkgset_scratch_modules
838              (dict) – A mapping of variants to scratch module builds:  {vari‐
839              ant: [N:S:V:C]}. Requires mbs_api_url.
840
841       pkgset_exclusive_arch_considers_noarch = True
842              (bool)  – If a package includes noarch in its ExclusiveArch tag,
843              it will be included in all architectures since noarch is compat‐
844              ible  with everything. Set this option to False to ignore noarch
845              in ExclusiveArch and always consider only binary architectures.
846
847       pkgset_allow_reuse = True
848              (bool) – When set to True, Pungi will try to reuse  pkgset  data
849              from the old composes specified by --old-composes. When enabled,
850              this option can speed up new composes because it does  not  need
851              to calculate the pkgset data from Koji. However, if you block or
852              unblock a package in Koji (for example) between  composes,  then
853              Pungi may not respect those changes in your new compose.
854
855       signed_packages_retries = 0
856              (int) – In automated workflows, you might start a compose before
857              Koji has completely written all signed packages to disk. In this
858              case  you  may  want  Pungi to wait for the package to appear in
859              Koji’s storage. This option controls how many times  Pungi  will
860              retry looking for the signed copy.
861
862       signed_packages_wait = 30
863              (int)  –  Interval  in  seconds for how long to wait between at‐
864              tempts to find signed packages. This  option  only  makes  sense
865              when signed_packages_retries is set higher than 0.
866
867   Example
868          sigkeys = [None]
869          pkgset_source = "koji"
870          pkgset_koji_tag = "f23"
871
872   Buildinstall Settings
873       Script  or process that creates bootable images with Anaconda installer
874       is historically called buildinstall.
875
876   Options
877       buildinstall_method
878              (str) – “lorax” (f16+,  rhel7+)  or  “buildinstall”  (older  re‐
879              leases)
880
881       lorax_options
882              (list) – special options passed on to lorax.
883
884              Format: [(variant_uid_regex, {arch|*: {option: name}})].
885
886              Recognized options are:
887
888bugurl str (default None)
889
890nomacboot bool (default True)
891
892noupgrade bool (default True)
893
894add_template [str] (default empty)
895
896add_arch_template [str] (default empty)
897
898add_template_var [str] (default empty)
899
900add_arch_template_var [str] (default empty)
901
902rootfs_size – [int] (default empty)
903
904version  –  [str] (default from treeinfo_version or re‐
905                       lease_version) – used as --version and --release  argu‐
906                       ment on the lorax command line
907
908dracut_args  –  [[str]]  (default empty) override argu‐
909                       ments for dracut. Please note that if  this  option  is
910                       used,  lorax  will  not use any other arguments, so you
911                       have to provide a full list and can not just add  some‐
912                       thing.
913
914skip_branding bool (default False)
915
916squashfs_only   bool   (default   False)  pass  the
917                       –squashfs_only to Lorax.
918
919configuration_file – (scm_dict)  (default  empty)  pass
920                       the  specified configuration file to Lorax using the -c
921                       option.
922
923       lorax_extra_sources
924              (list) – a variant/arch  mapping  with  urls  for  extra  source
925              repositories  added  to Lorax command line. Either one repo or a
926              list can be specified.
927
928       lorax_use_koji_plugin = False
929              (bool) – When set to True, the Koji pungi_buildinstall task will
930              be  used  to  execute  Lorax instead of runroot. Use only if the
931              Koji instance has the pungi_buildinstall plugin installed.
932
933       buildinstall_kickstart
934              (scm_dict) – If specified, this kickstart file  will  be  copied
935              into each file and pointed to in boot configuration.
936
937       buildinstall_topdir
938              (str)  –  Full  path to top directory where the runroot buildin‐
939              stall Koji tasks output should be stored. This is useful in sit‐
940              uation when the Pungi compose is not generated on the same stor‐
941              age as the Koji task is running on. In this case, Pungi can pro‐
942              vide  input  repository  for runroot task using HTTP and set the
943              output directory for this task to buildinstall_topdir. Once  the
944              runroot  task  finishes,  Pungi will copy the results of runroot
945              tasks to the compose working directory.
946
947       buildinstall_skip
948              (list) – mapping that defines which variants and arches to  skip
949              during   buildinstall;   format:  [(variant_uid_regex,  {arch|*:
950              True})]. This is only supported for lorax.
951
952       buildinstall_allow_reuse = False
953              (bool) – When set to True, Pungi will try to reuse  buildinstall
954              results from old compose specified by --old-composes.
955
956   Example
957          buildinstall_method = "lorax"
958
959          # Enables macboot on x86_64 for all variants and builds upgrade images
960          # everywhere.
961          lorax_options = [
962              ("^.*$", {
963                  "x86_64": {
964                      "nomacboot": False
965                  }
966                  "*": {
967                      "noupgrade": False
968                  }
969              })
970          ]
971
972          # Don't run buildinstall phase for Modular variant
973          buildinstall_skip = [
974              ('^Modular', {
975                  '*': True
976              })
977          ]
978
979          # Add another repository for lorax to install packages from
980          lorax_extra_sources = [
981              ('^Simple$', {
982                  '*': 'https://example.com/repo/$basearch/',
983              })
984          ]
985
986       NOTE:
987          It is advised to run buildinstall (lorax) in koji, i.e. with runroot
988          enabled for clean build environments, better logging, etc.
989
990       WARNING:
991          Lorax installs RPMs into  a  chroot.  This  involves  running  %post
992          scriptlets  and  they  frequently run executables in the chroot.  If
993          we’re composing for multiple architectures, we must use runroot  for
994          this reason.
995
996   Gather Settings
997   Options
998       gather_method [mandatory]
999              (str*|*dict)  –  Options are deps, nodeps and hybrid.  Specifies
1000              whether and how package dependencies should be pulled in.   Pos‐
1001              sible  configuration  can  be  one value for all variants, or if
1002              configured per-variant it can be a simple string hybrid or  a  a
1003              dictionary  mapping  source  type  to a value of deps or nodeps.
1004              Make sure only one regex matches each variant, as  there  is  no
1005              guarantee  which value will be used if there are multiple match‐
1006              ing ones. All used sources must have a configured method  unless
1007              hybrid solving is used.
1008
1009       gather_fulltree = False
1010              (bool)  –  When set to True all RPMs built from an SRPM will al‐
1011              ways be included. Only use when gather_method = "deps".
1012
1013       gather_selfhosting = False
1014              (bool) – When set to True, Pungi will build a self-hosting  tree
1015              by  following  build dependencies. Only use when gather_method =
1016              "deps".
1017
1018       gather_allow_reuse = False
1019              (bool) – When set to True, Pungi will try to  reuse  gather  re‐
1020              sults from old compose specified by --old-composes.
1021
1022       greedy_method
1023              (str) – This option controls how package requirements are satis‐
1024              fied in case a particular Requires has multiple candidates.
1025
1026none – the best packages is selected to satisfy the dependency
1027                and only that one is pulled into the compose
1028
1029all – packages that provide the symbol are pulled in
1030
1031build  –  the  best package is selected, and then all packages
1032                from the same build that provide the symbol are pulled in
1033
1034              NOTE:
1035                 As an example let’s work with this situation:  a  package  in
1036                 the  compose has Requires: foo. There are three packages with
1037                 Provides: foo: pkg-a, pkg-b-provider-1 and  pkg-b-provider-2.
1038                 The  pkg-b-* packages are build from the same source package.
1039                 Best match determines pkg-b-provider-1 as best matching pack‐
1040                 age.
1041
1042                 • With  greedy_method  = "none" only pkg-b-provider-1 will be
1043                   pulled in.
1044
1045                 • With greedy_method =  "all"  all  three  packages  will  be
1046                   pulled in.
1047
1048                 • With   greedy_method   =   "build"  ``pkg-b-provider-1  and
1049                   pkg-b-provider-2 will be pulled in.
1050
1051       gather_backend
1052              (str) –This changes the entire codebase doing  dependency  solv‐
1053              ing, so it can change the result in unpredictable ways.
1054
1055              On  Python  2,  the choice is between yum or dnf and defaults to
1056              yum. On Python 3 dnf is the only option and default.
1057
1058              Particularly the multilib work is performed differently by using
1059              python-multilib  library. Please refer to multilib option to see
1060              the differences.
1061
1062              See also: the repoclosure_backend setting for  Pungi’s  repoclo‐
1063              sure phase.
1064
1065       multilib
1066              (list) – mapping of variant regexes and arches to list of multi‐
1067              lib methods
1068
1069              Available methods are:
1070
1071none – no package matches this method
1072
1073all – all packages match this method
1074
1075runtime – packages that install some shared object file
1076                       (*.so.*) will match.
1077
1078devel  –  packages  whose  name  ends  with  -devel  or
1079                       --static suffix will be matched. When dnf is used, this
1080                       method  automatically  enables  runtime method as well.
1081                       With yum backend this  method  also  uses  a  hardcoded
1082                       blacklist and whitelist.
1083
1084kernel  –  packages  providing  kernel  or kernel-devel
1085                       match this method (only in yum backend)
1086
1087yaboot – only yaboot package on ppc arch  matches  this
1088                       (only in yum backend)
1089
1090       additional_packages
1091              (list) – additional packages to be included in a variant and ar‐
1092              chitecture;   format:   [(variant_uid_regex,   {arch|*:   [pack‐
1093              age_globs]})]
1094
1095              In  contrast  to the comps_file setting, the additional_packages
1096              setting merely adds the list of packages to the compose. When  a
1097              package  is  in  a  comps  group, it is visible to users via dnf
1098              groupinstall  and  Anaconda’s  Groups   selection,   but   addi‐
1099              tional_packages does not affect DNF groups.
1100
1101              The  packages  specified here are matched against RPM names, not
1102              any other provides in the package nor the name of  source  pack‐
1103              age.  Shell  globbing  is  used,  so wildcards are possible. The
1104              package can be specified as name only or name.arch.
1105
1106              With dnf gathering backend, you can specify a debuginfo  package
1107              to be included. This is meant to include a package if autodetec‐
1108              tion does not get it. If you add a debuginfo package  that  does
1109              not  have anything else from the same build included in the com‐
1110              pose, the sources will not be pulled in.
1111
1112              If you list a package in additional_packages  but  Pungi  cannot
1113              find it (for example, it’s not available in the Koji tag), Pungi
1114              will log a warning in the “work” or “logs” directories and  con‐
1115              tinue without aborting.
1116
1117              Example:  This configuration will add all packages in a Koji tag
1118              to an “Everything” variant:
1119
1120                 additional_packages = [
1121                     ('^Everything$', {
1122                         '*': [
1123                             '*',
1124                         ],
1125                     })
1126                 ]
1127
1128       filter_packages
1129              (list) – packages to be excluded from a  variant  and  architec‐
1130              ture; format: [(variant_uid_regex, {arch|*: [package_globs]})]
1131
1132              See additional_packages for details about package specification.
1133
1134       filter_modules
1135              (list) – modules to be excluded from a variant and architecture;
1136              format: [(variant_uid_regex, {arch|*: [name:stream]})]
1137
1138              Both name and stream can use shell-style  globs.  If  stream  is
1139              omitted, all streams are removed.
1140
1141              This  option  only  applies to modules taken from Koji tags, not
1142              modules explicitly listed in variants XML without any tags.
1143
1144       filter_system_release_packages
1145              (bool) – for each variant, figure out the  best  system  release
1146              package and filter out all others. This will not work if a vari‐
1147              ant needs more than one system release package.  In  such  case,
1148              set this option to False.
1149
1150       gather_prepopulate = None
1151              (scm_dict)  –  If  specified, you can use this to add additional
1152              packages. The format of the file pointed to by this option is  a
1153              JSON mapping {variant_uid: {arch: {build: [package]}}}. Packages
1154              added through this option can not be removed by filter_packages.
1155
1156       multilib_blacklist
1157              (dict) – multilib blacklist; format: {arch|*: [package_globs]}.
1158
1159              See additional_packages for details about package specification.
1160
1161       multilib_whitelist
1162              (dict) – multilib blacklist; format: {arch|*:  [package_names]}.
1163              The  whitelist  must  contain  exact package names; there are no
1164              wildcards or pattern matching.
1165
1166       gather_lookaside_repos = []
1167              (list) – lookaside repositories used for package gathering; for‐
1168              mat: [(variant_uid_regex, {arch|*: [repo_urls]})]
1169
1170              The  repo_urls  are passed to the depsolver, which can use pack‐
1171              ages in the repos for satisfying dependencies, but the  packages
1172              themselves  are  not  pulled into the compose. The repo_urls can
1173              contain $basearch  variable,  which  will  be  substituted  with
1174              proper value by the depsolver.
1175
1176              The  repo_urls  are  used by repoclosure too, but it can’t parse
1177              $basearch  currently  and  that  will  cause  Repoclosure  phase
1178              crashed.  repoclosure_strictness  option  could  be used to stop
1179              running repoclosure.
1180
1181              Please note that * as a wildcard matches all  architectures  but
1182              src.
1183
1184       hashed_directories = False
1185              (bool)  –  put  packages  into “hashed” directories, for example
1186              Packages/k/kernel-4.0.4-301.fc22.x86_64.rpm
1187
1188       check_deps = True
1189              (bool) – Set to False if you don’t want  the  compose  to  abort
1190              when some package has broken dependencies.
1191
1192       require_all_comps_packages = False
1193              (bool)  – Set to True to abort compose when package mentioned in
1194              comps file can not be found in the package  set.  When  disabled
1195              (the  default), such cases are still reported as warnings in the
1196              log.
1197
1198       gather_source_mapping
1199              (str) – JSON mapping with initial packages for the compose.  The
1200              value  should  be  a  path  to JSON file with following mapping:
1201              {variant: {arch: {rpm_name: [rpm_arch|None]}}}.  Relative  paths
1202              are interpreted relative to the location of main config file.
1203
1204       gather_profiler = False
1205              (bool)  –  When  set  to True the gather tool will produce addi‐
1206              tional performance profiling information at the end of its logs.
1207              Only takes effect when gather_backend = "dnf".
1208
1209       variant_as_lookaside
1210              (list)  – a variant/variant mapping that tells one or more vari‐
1211              ants in compose has other variant(s) in compose as a  lookaside.
1212              Only  top level variants are supported (not addons/layered prod‐
1213              ucts). Format: [(variant_uid, variant_uid)]
1214
1215   Example
1216          gather_method = "deps"
1217          greedy_method = "build"
1218          check_deps = False
1219          hashed_directories = True
1220
1221          gather_method = {
1222              "^Everything$": {
1223                  "comps": "deps"     # traditional content defined by comps groups
1224              },
1225              "^Modular$": {
1226                  "module": "nodeps"  # Modules do not need dependencies
1227              },
1228              "^Mixed$": {            # Mixed content in one variant
1229                  "comps": "deps",
1230                  "module": "nodeps"
1231              }
1232              "^OtherMixed$": "hybrid",   # Using hybrid depsolver
1233          }
1234
1235          additional_packages = [
1236              # bz#123456
1237              ('^(Workstation|Server)$', {
1238                  '*': [
1239                      'grub2',
1240                      'kernel',
1241                  ],
1242              }),
1243          ]
1244
1245          filter_packages = [
1246              # bz#111222
1247              ('^.*$', {
1248                  '*': [
1249                      'kernel-doc',
1250                  ],
1251              }),
1252          ]
1253
1254          multilib = [
1255              ('^Server$', {
1256                  'x86_64': ['devel', 'runtime']
1257              })
1258          ]
1259
1260          multilib_blacklist = {
1261              "*": [
1262                  "gcc",
1263              ],
1264          }
1265
1266          multilib_whitelist = {
1267              "*": [
1268                  "alsa-plugins-*",
1269              ],
1270          }
1271
1272          # gather_lookaside_repos = [
1273          #     ('^.*$', {
1274          #         '*': [
1275          #             "https://dl.fedoraproject.org/pub/fedora/linux/releases/22/Everything/$basearch/os/",
1276          #         ],
1277          #         'x86_64': [
1278          #             "https://dl.fedoraproject.org/pub/fedora/linux/releases/22/Everything/source/SRPMS/",
1279          #         ]
1280          #     }),
1281          # ]
1282
1283       NOTE:
1284          It is  a  good  practice  to  attach  bug/ticket  numbers  to  addi‐
1285          tional_packages,   filter_packages,  multilib_blacklist  and  multi‐
1286          lib_whitelist to track decisions.
1287
1288   Koji Settings
1289   Options
1290       koji_profile
1291              (str) – koji profile name. This tells Pungi how  to  communicate
1292              with  your  chosen Koji instance. See Koji’s documentation about
1293              profiles for more information about how  to  set  up  your  Koji
1294              client  profile.  In  the  examples, the profile name is “koji”,
1295              which points to Fedora’s koji.fedoraproject.org.
1296
1297       global_runroot_method
1298              (str) – global runroot method to use. If runroot_method  is  set
1299              per  Pungi phase using a dictionary, this option defines the de‐
1300              fault runroot method  for  phases  not  mentioned  in  the  run‐
1301              root_method dictionary.
1302
1303       runroot_method
1304              (str*|*dict) – Runroot method to use. It can further specify the
1305              runroot method in case the runroot is set to True.
1306
1307              Available methods are:
1308
1309local – runroot tasks are run locally
1310
1311koji – runroot tasks are run in Koji
1312
1313openssh – runroot tasks are run on remote machine  con‐
1314                       nected  using  OpenSSH.   The runroot_ssh_hostnames for
1315                       each architecture must be set and the user under  which
1316                       Pungi   runs  must  be  configured  to  login  as  run‐
1317                       root_ssh_username using the SSH key.
1318
1319              The runroot method can also be set per  Pungi  phase  using  the
1320              dictionary  with  phase name as key and runroot method as value.
1321              The default runroot method  is  in  this  case  defined  by  the
1322              global_runroot_method option.
1323
1324   Example
1325          global_runroot_method = "koji"
1326          runroot_method = {
1327              "createiso": "local"
1328          }
1329
1330       runroot_channel
1331              (str) – name of koji channel
1332
1333       runroot_tag
1334              (str) – name of koji build tag used for runroot
1335
1336       runroot_weights
1337              (dict)  –  customize task weights for various runroot tasks. The
1338              values in the mapping should be integers, the keys  can  be  se‐
1339              lected from the following list. By default no weight is assigned
1340              and Koji picks the default one according to policy.
1341
1342buildinstall
1343
1344createiso
1345
1346ostree
1347
1348ostree_installer
1349
1350   Example
1351          koji_profile = "koji"
1352          runroot_channel = "runroot"
1353          runroot_tag = "f23-build"
1354
1355   Runroot “openssh” method settings
1356   Options
1357       runroot_ssh_username
1358              (str) – For openssh runroot method, configures the username used
1359              to login the remote machine to run the runroot task. Defaults to
1360              “root”.
1361
1362       runroot_ssh_hostnames
1363              (dict) – For openssh runroot method, defines  the  hostname  for
1364              each  architecture  on which the runroot task should be running.
1365              Format: {"x86_64": "runroot-x86-64.localhost.tld", ...}
1366
1367       runroot_ssh_init_template
1368              (str) [optional] – For openssh runroot method, defines the  com‐
1369              mand to initializes the runroot task on the remote machine. This
1370              command is executed as first command for each runroot task  exe‐
1371              cuted.
1372
1373              The  command can print a string which is then available as {run‐
1374              root_key} for other SSH commands. This string might be  used  to
1375              keep the context across different SSH commands executed for sin‐
1376              gle runroot task.
1377
1378              The goal of this command is setting up the environment for  real
1379              runroot commands. For example preparing the unique mock environ‐
1380              ment, mounting the desired file-systems, …
1381
1382              The command string can contain following variables which are re‐
1383              placed by the real values before executing the init command:
1384
1385{runroot_tag}  -  Tag  to  initialize  the runroot environment
1386                from.
1387
1388              When not set, no init command is executed.
1389
1390       runroot_ssh_install_packages_template
1391              (str) [optional] – For openssh runroot method, defines the  tem‐
1392              plate  for  command to install the packages requested to run the
1393              runroot task.
1394
1395              The template string can contain following  variables  which  are
1396              replaced  by  the  real values before executing the install com‐
1397              mand:
1398
1399{runroot_key} - Replaced with  the  string  returned  by  run‐
1400                root_ssh_init_template  if  used. This can be used to keep the
1401                track of context of SSH commands belonging to  single  runroot
1402                task.
1403
1404{packages} - White-list separated list of packages to install.
1405
1406              Example  (The {runroot_key} is expected to be set to mock config
1407              file using the  runroot_ssh_init_template  command.):  "mock  -r
1408              {runroot_key} --install {packages}"
1409
1410              When  not  set, no command to install packages on remote machine
1411              is executed.
1412
1413       runroot_ssh_run_template
1414              (str) [optional] – For openssh runroot method, defines the  tem‐
1415              plate for the main runroot command.
1416
1417              The  template  string  can contain following variables which are
1418              replaced by the real values before executing  the  install  com‐
1419              mand:
1420
1421{runroot_key}  -  Replaced  with  the  string returned by run‐
1422                root_ssh_init_template if used. This can be used to  keep  the
1423                track  of  context of SSH commands belonging to single runroot
1424                task.
1425
1426{command} - Command to run.
1427
1428              Example (The {runroot_key} is expected to be set to mock  config
1429              file  using  the  runroot_ssh_init_template  command.): "mock -r
1430              {runroot_key} chroot -- {command}"
1431
1432              When not set, the runroot command is run directly.
1433
1434   Extra Files Settings
1435   Options
1436       extra_files
1437              (list) – references to external files to be placed in os/ direc‐
1438              tory    and   media;   format:   [(variant_uid_regex,   {arch|*:
1439              [scm_dict]})]. See scm_support for details. If the  dict  speci‐
1440              fies a target key, an additional subdirectory will be used.
1441
1442   Example
1443          extra_files = [
1444              ('^.*$', {
1445                  '*': [
1446                      # GPG keys
1447                      {
1448                          "scm": "rpm",
1449                          "repo": "fedora-repos",
1450                          "branch": None,
1451                          "file": [
1452                              "/etc/pki/rpm-gpg/RPM-GPG-KEY-22-fedora",
1453                          ],
1454                          "target": "",
1455                      },
1456                      # GPL
1457                      {
1458                          "scm": "git",
1459                          "repo": "https://pagure.io/pungi-fedora",
1460                          "branch": None,
1461                          "file": [
1462                              "GPL",
1463                          ],
1464                          "target": "",
1465                      },
1466                  ],
1467              }),
1468          ]
1469
1470   Extra Files Metadata
1471       If  extra  files  are  specified  a metadata file, extra_files.json, is
1472       placed in the os/ directory and media. The checksums generated are  de‐
1473       termined  by  media_checksums option. This metadata file is in the for‐
1474       mat:
1475
1476          {
1477            "header": {"version": "1.0},
1478            "data": [
1479              {
1480                "file": "GPL",
1481                "checksums": {
1482                  "sha256": "8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643"
1483                },
1484                "size": 18092
1485              },
1486              {
1487                "file": "release-notes/notes.html",
1488                "checksums": {
1489                  "sha256": "82b1ba8db522aadf101dca6404235fba179e559b95ea24ff39ee1e5d9a53bdcb"
1490                },
1491                "size": 1120
1492              }
1493            ]
1494          }
1495
1496   CreateISO Settings
1497   Options
1498       createiso_skip = False
1499              (list) – mapping that defines which variants and arches to  skip
1500              during createiso; format: [(variant_uid_regex, {arch|*: True})]
1501
1502       createiso_max_size
1503              (list)  –  mapping  that  defines maximum expected size for each
1504              variant and arch. If the ISO is larger than the limit, a warning
1505              will be issued.
1506
1507              Format: [(variant_uid_regex, {arch|*: number})]
1508
1509       createiso_max_size_is_strict
1510              (list)  –  Set  the  value to True to turn the warning from cre‐
1511              ateiso_max_size into a hard error that will abort  the  compose.
1512              If  there are multiple matches in the mapping, the check will be
1513              strict if at least one match says so.
1514
1515              Format: [(variant_uid_regex, {arch|*: bool})]
1516
1517       create_jigdo = False
1518              (bool) – controls the creation of jigdo from ISO
1519
1520       create_optional_isos = False
1521              (bool) – when set to True, ISOs will be  created  even  for  op‐
1522              tional  variants.  By default only variants with type variant or
1523              layered-product will get ISOs.
1524
1525       createiso_break_hardlinks = False
1526              (bool) – when set to True, all files that should go on  the  ISO
1527              and  have  a hardlink will be first copied into a staging direc‐
1528              tory. This should work around a bug in genisoimage including in‐
1529              correct link count in the image, but it is at the cost of having
1530              to copy a potentially significant amount of data.
1531
1532              The staging directory is deleted when ISO is  successfully  cre‐
1533              ated.  In  that case the same task to create the ISO will not be
1534              re-runnable.
1535
1536       createiso_use_xorrisofs = False
1537              (bool) – when set to True, use xorrisofs for creating  ISOs  in‐
1538              stead of genisoimage.
1539
1540       iso_size = 4700000000
1541              (int|str) – size of ISO image. The value should either be an in‐
1542              teger meaning size in bytes, or it can be a string with k, M,  G
1543              suffix (using multiples of 1024).
1544
1545       iso_level
1546              (int) [optional] – Set the ISO9660 conformance level. Valid num‐
1547              bers are 1 to 4.
1548
1549       split_iso_reserve = 10MiB
1550              (int|str) – how much free space should be left on each disk. The
1551              format is the same as for iso_size option.
1552
1553       iso_hfs_ppc64le_compatible = True
1554              (bool)  –  when  set  to  False,  the Apple/HFS compatibility is
1555              turned off for ppc64le ISOs. This option only  makes  sense  for
1556              bootable  products, and affects images produced in createiso and
1557              extra_isos phases.
1558
1559       NOTE:
1560          Source architecture needs to be listed  explicitly.   Excluding  ‘*’
1561          applies only on binary arches.  Jigdo causes significant increase of
1562          time to ISO creation.
1563
1564   Example
1565          createiso_skip = [
1566              ('^Workstation$', {
1567                  '*': True,
1568                  'src': True
1569              }),
1570          ]
1571
1572   Automatic generation of version and release
1573       Version and release values for certain artifacts can be generated auto‐
1574       matically  based  on  release  version,  compose  label, date, type and
1575       respin. This can be used to shorten the config and keep it the same for
1576       multiple uses.
1577
1578┌───────────────────────┬───────────────┬──────────┬──────────┬────────┬──────────────┐
1579│Compose ID             │ Label         │ Version  │ Date     │ Respin │ Release      │
1580├───────────────────────┼───────────────┼──────────┼──────────┼────────┼──────────────┤
1581F-Rawhide-20170406.n.0 -             Rawhide  20170406 0      20170406.n.0 
1582├───────────────────────┼───────────────┼──────────┼──────────┼────────┼──────────────┤
1583F-26-20170329.1        Alpha-1.6     26_Alpha 20170329 1      1.6          
1584├───────────────────────┼───────────────┼──────────┼──────────┼────────┼──────────────┤
1585F-Atomic-25-20170407.0 RC-20170407.0 25       20170407 0      20170407.0   
1586├───────────────────────┼───────────────┼──────────┼──────────┼────────┼──────────────┤
1587F-Atomic-25-20170407.0 -             25       20170407 0      20170407.0   
1588└───────────────────────┴───────────────┴──────────┴──────────┴────────┴──────────────┘
1589
1590       All non-RC milestones from label get appended to the version.  For  re‐
1591       lease either label is used or date, type and respin.
1592
1593   Common options for Live Images, Live Media and Image Build
1594       All images can have ksurl, version, release and target specified. Since
1595       this can create a lot of duplication, there are global options that can
1596       be used instead.
1597
1598       For each of the phases, if the option is not specified for a particular
1599       deliverable, an option named <PHASE_NAME>_<OPTION> is checked. If  that
1600       is  not specified either, the last fallback is global_<OPTION>. If even
1601       that is unset, the value is considered to not be specified.
1602
1603       The kickstart URL is configured by these options.
1604
1605global_ksurl – global fallback setting
1606
1607live_media_ksurl
1608
1609image_build_ksurl
1610
1611live_images_ksurl
1612
1613       Target is specified by these settings.
1614
1615global_target – global fallback setting
1616
1617live_media_target
1618
1619image_build_target
1620
1621live_images_target
1622
1623osbuild_target
1624
1625       Version is specified by these options. If no version is set, a  default
1626       value will be provided according to automatic versioning.
1627
1628global_version – global fallback setting
1629
1630live_media_version
1631
1632image_build_version
1633
1634live_images_version
1635
1636osbuild_version
1637
1638       Release  is specified by these options. If set to a magic value to !RE‐
1639       LEASE_FROM_LABEL_DATE_TYPE_RESPIN, a value will be generated  according
1640       to automatic versioning.
1641
1642global_release – global fallback setting
1643
1644live_media_release
1645
1646image_build_release
1647
1648live_images_release
1649
1650osbuild_release
1651
1652       Each  configuration  block  can also optionally specify a failable key.
1653       For live images it should have a boolean value. For live media and  im‐
1654       age  build it should be a list of strings containing architectures that
1655       are optional. If any deliverable fails on an optional architecture,  it
1656       will  not  abort  the whole compose. If the list contains only "*", all
1657       arches will be substituted.
1658
1659   Live Images Settings
1660       live_images
1661              (list) – Configuration for the particular image. The elements of
1662              the list should be tuples (variant_uid_regex, {arch|*: config}).
1663              The config should be a dict with these keys:
1664
1665kickstart (str)
1666
1667ksurl (str) [optional] – where to get the kickstart from
1668
1669name (str)
1670
1671version (str)
1672
1673target (str)
1674
1675repo (str|[str]) – repos specified by URL or variant UID
1676
1677specfile (str) – for images wrapped in RPM
1678
1679scratch (bool) – only RPM-wrapped images  can  use  scratch
1680                   builds, but by default this is turned off
1681
1682type  (str)  – what kind of task to start in Koji. Defaults
1683                   to live meaning koji spin-livecd will be used.  Alternative
1684                   option is appliance corresponding to koji spin-appliance.
1685
1686sign (bool) – only RPM-wrapped images can be signed
1687
1688       live_images_no_rename
1689              (bool)  –  When set to True, filenames generated by Koji will be
1690              used.  When False, filenames will  be  generated  based  on  im‐
1691              age_name_format configuration option.
1692
1693   Live Media Settings
1694       live_media
1695              (dict)  –  configuration for koji spin-livemedia; format: {vari‐
1696              ant_uid_regex: [{opt:value}]}
1697
1698              Required options:
1699
1700name (str)
1701
1702version (str)
1703
1704arches ([str]) – what architectures to build the media for;
1705                   by default uses all arches for the variant.
1706
1707kickstart (str) – name of the kickstart file
1708
1709              Available options:
1710
1711ksurl (str)
1712
1713ksversion (str)
1714
1715scratch (bool)
1716
1717target (str)
1718
1719release  (str)  –  a  string  with  the  release,  or  !RE‐
1720                   LEASE_FROM_LABEL_DATE_TYPE_RESPIN to automatically generate
1721                   a suitable value. See automatic versioning for details.
1722
1723skip_tag (bool)
1724
1725repo (str|[str]) – repos specified by URL or variant UID
1726
1727title (str)
1728
1729install_tree_from (str) – variant to take install tree from
1730
1731   Image Build Settings
1732       image_build
1733              (dict)   –   config   for   koji   image-build;  format:  {vari‐
1734              ant_uid_regex: [{opt: value}]}
1735
1736              By default, images will be built for each binary arch valid  for
1737              the  variant.  The config can specify a list of arches to narrow
1738              this down.
1739
1740       NOTE:
1741          Config can contain anything what is  accepted  by  koji  image-build
1742          --config configfile.ini
1743
1744          Repo  can  be  specified either as a string or a list of strings. It
1745          will be automatically transformed into format suitable for  koji.  A
1746          repo for the currently built variant will be added as well.
1747
1748          If    you    explicitly    set    release    to    !RELEASE_FROM_LA‐
1749          BEL_DATE_TYPE_RESPIN, it will be replaced with a value generated  as
1750          described in automatic versioning.
1751
1752          If  you explicitly set release to !RELEASE_FROM_DATE_RESPIN, it will
1753          be replaced with a value generated as described  in  automatic  ver‐
1754          sioning.
1755
1756          If  you  explicitly set version to !VERSION_FROM_VERSION, it will be
1757          replaced with a value generated as described in  automatic  version‐
1758          ing.
1759
1760          Please  don’t set install_tree. This gets automatically set by pungi
1761          based on current variant. You can use install_tree_from key  to  use
1762          install tree from another variant.
1763
1764          Both the install tree and repos can use one of following formats:
1765
1766              • URL to the location
1767
1768              • name of variant in the current compose
1769
1770              • absolute  path  on  local filesystem (which will be translated
1771                using configured mappings or used unchanged, in which case you
1772                have to ensure the koji builders can access it)
1773
1774          You can set either a single format, or a list of formats. For avail‐
1775          able values see help output for koji image-build command.
1776
1777          If ksurl ends with #HEAD, Pungi will figure out  the  SHA1  hash  of
1778          current HEAD and use that instead.
1779
1780          Setting scratch to True will run the koji tasks as scratch builds.
1781
1782   Example
1783          image_build = {
1784              '^Server$': [
1785                  {
1786                      'image-build': {
1787                          'format': ['docker', 'qcow2']
1788                          'name': 'fedora-qcow-and-docker-base',
1789                          'target': 'koji-target-name',
1790                          'ksversion': 'F23',     # value from pykickstart
1791                          'version': '23',
1792                          # correct SHA1 hash will be put into the URL below automatically
1793                          'ksurl': 'https://git.fedorahosted.org/git/spin-kickstarts.git?somedirectoryifany#HEAD',
1794                          'kickstart': "fedora-docker-base.ks",
1795                          'repo': ["http://someextrarepos.org/repo", "ftp://rekcod.oi/repo"],
1796                          'distro': 'Fedora-20',
1797                          'disk_size': 3,
1798
1799                          # this is set automatically by pungi to os_dir for given variant
1800                          # 'install_tree': 'http://somepath',
1801                      },
1802                      'factory-parameters': {
1803                          'docker_cmd':  "[ '/bin/bash' ]",
1804                          'docker_env': "[ 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' ]",
1805                          'docker_labels': "{'Name': 'fedora-docker-base', 'License': u'GPLv2', 'RUN': 'docker run -it --rm ${OPT1} --privileged -v \`pwd\`:/atomicapp -v /run:/run -v /:/host --net=host --name ${NAME} -e NAME=${NAME} -e IMAGE=${IMAGE} ${IMAGE} -v ${OPT2} run ${OPT3} /atomicapp', 'Vendor': 'Fedora Project', 'Version': '23', 'Architecture': 'x86_64' }",
1806                      }
1807                  },
1808                  {
1809                      'image-build': {
1810                          'format': ['docker', 'qcow2']
1811                          'name': 'fedora-qcow-and-docker-base',
1812                          'target': 'koji-target-name',
1813                          'ksversion': 'F23',     # value from pykickstart
1814                          'version': '23',
1815                          # correct SHA1 hash will be put into the URL below automatically
1816                          'ksurl': 'https://git.fedorahosted.org/git/spin-kickstarts.git?somedirectoryifany#HEAD',
1817                          'kickstart': "fedora-docker-base.ks",
1818                          'repo': ["http://someextrarepos.org/repo", "ftp://rekcod.oi/repo"],
1819                          'distro': 'Fedora-20',
1820                          'disk_size': 3,
1821
1822                          # this is set automatically by pungi to os_dir for given variant
1823                          # 'install_tree': 'http://somepath',
1824                      }
1825                  },
1826                  {
1827                      'image-build': {
1828                          'format': 'qcow2',
1829                          'name': 'fedora-qcow-base',
1830                          'target': 'koji-target-name',
1831                          'ksversion': 'F23',     # value from pykickstart
1832                          'version': '23',
1833                          'ksurl': 'https://git.fedorahosted.org/git/spin-kickstarts.git?somedirectoryifany#HEAD',
1834                          'kickstart': "fedora-docker-base.ks",
1835                          'distro': 'Fedora-23',
1836
1837                          # only build this type of image on x86_64
1838                          'arches': ['x86_64']
1839
1840                          # Use install tree and repo from Everything variant.
1841                          'install_tree_from': 'Everything',
1842                          'repo': ['Everything'],
1843
1844                          # Set release automatically.
1845                          'release': '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN',
1846                      }
1847                  }
1848              ]
1849          }
1850
1851   OSBuild Composer for building images
1852       osbuild
1853              (dict)  –  configuration for building images in OSBuild Composer
1854              service fronted by a Koji plugin. Pungi will trigger a Koji task
1855              delegating  to the OSBuild Composer, which will build the image,
1856              import it to Koji via content generators.
1857
1858              Format: {variant_uid_regex: [{...}]}.
1859
1860              Required keys in the configuration dict:
1861
1862name – name of the Koji package
1863
1864distro – image for which distribution should be build TODO ex‐
1865                amples
1866
1867image_type – a list of image types to build (e.g. qcow2)
1868
1869              Optional keys:
1870
1871target  –  which build target to use for the task. Either this
1872                option or the global osbuild_target is required.
1873
1874version – version for the final build (as a string). This  op‐
1875                tion  is  required if the global osbuild_version is not speci‐
1876                fied.
1877
1878release – release part of the final NVR. If neither  this  op‐
1879                tion nor the global osbuild_release is set, Koji will automat‐
1880                ically generate a value.
1881
1882repo – a list of repository URLs from which to  consume  pack‐
1883                ages  for  building  the  image.  By  default only the variant
1884                repository is used.
1885
1886arches – list of architectures for which to build  the  image.
1887                By  default, the variant arches are used. This option can only
1888                restrict it, not add a new one.
1889
1890       NOTE:
1891          There is initial support for having this task  as  failable  without
1892          aborting  the  whole  compose. This can be enabled by setting "fail‐
1893          able": ["*"] in the config for the image. It  is  an  on/off  switch
1894          without granularity per arch.
1895
1896   Image container
1897       This  phase  supports  building  containers in OSBS that embed an image
1898       created in the same compose. This can be useful for delivering the  im‐
1899       age to users running in containerized environments.
1900
1901       Pungi  will  start a buildContainer task in Koji with configured source
1902       repository. The Dockerfile can expect that a repo file will be injected
1903       into  the container that defines a repo named image-to-include, and its
1904       baseurl will point to the image to include. It is possible  to  extract
1905       the  URL with a command like dnf config-manager --dump image-to-include
1906       | awk '/baseurl =/{print $3}'`
1907
1908       image_container
1909              (dict) – configuration for building containers embedding an  im‐
1910              age.
1911
1912              Format: {variant_uid_regex: [{...}]}.
1913
1914              The  inner object will define a single container. These keys are
1915              required:
1916
1917url, target, git_branch. See OSBS section  for  definition  of
1918                these.
1919
1920image_spec  – (object) A string mapping of filters used to se‐
1921                lect the image to embed. All images listed in metadata for the
1922                variant will be processed. The keys of this filter are used to
1923                select metadata fields for the image, and values  are  regular
1924                expression that need to match the metadata value.
1925
1926                The filter should match exactly one image.
1927
1928   Example config
1929          image_container = {
1930              "^Server$": [{
1931                  "url": "git://example.com/dockerfiles.git?#HEAD",
1932                  "target": "f24-container-candidate",
1933                  "git_branch": "f24",
1934                  "image_spec": {
1935                      "format": "qcow2",
1936                      "arch": "x86_64",
1937                      "path": ".*/guest-image-.*$",
1938                  }
1939              }]
1940          }
1941
1942   OSTree Settings
1943       The  ostree  phase  of Pungi can create and update ostree repositories.
1944       This is done by running rpm-ostree compose in a Koji  runroot  environ‐
1945       ment.  The  ostree  repository  itself  is  not part of the compose and
1946       should be located in another directory. Any new packages in the compose
1947       will be added to the repository with a new commit.
1948
1949       ostree (dict)  – a mapping of configuration for each. The format should
1950              be {variant_uid_regex: config_dict}. It is  possible  to  use  a
1951              list of configuration dicts as well.
1952
1953              The  configuration  dict  for  each  variant arch pair must have
1954              these keys:
1955
1956treefile – (str) Filename of configuration for rpm-ostree.
1957
1958config_url – (str) URL for Git repository with the treefile.
1959
1960repo – (str|dict|[str|dict]) repos specified by URL or variant
1961                UID  or  a  dict  of  repo options, baseurl is required in the
1962                dict.
1963
1964ostree_repo – (str) Where to put the ostree repository
1965
1966              These keys are optional:
1967
1968keep_original_sources – (bool) Keep the existing source  repos
1969                in  the  tree  config  file.  If not enabled, all the original
1970                source repos will be removed from the tree config file.
1971
1972config_branch – (str) Git branch of the repo to use.  Defaults
1973                to master.
1974
1975arches – ([str]) List of architectures for which to update os‐
1976                tree.  There will be one task per architecture. By default all
1977                architectures in the variant are used.
1978
1979failable – ([str]) List of architectures for which this deliv‐
1980                erable is not release blocking.
1981
1982update_summary – (bool) Update  summary  metadata  after  tree
1983                composing.  Defaults to False.
1984
1985force_new_commit  –  (bool)  Do  not use rpm-ostree’s built-in
1986                change detection.  Defaults to False.
1987
1988version – (str) Version string to be added as versioning meta‐
1989                data.   If  this  option  is  set  to !OSTREE_VERSION_FROM_LA‐
1990                BEL_DATE_TYPE_RESPIN, a value will be generated  automatically
1991                as   $VERSION.$RELEASE.   If  this  option  is  set  to  !VER‐
1992                SION_FROM_VERSION_DATE_RESPIN, a value will be generated auto‐
1993                matically as $VERSION.$DATE.$RESPIN.  See how those values are
1994                created.
1995
1996tag_ref – (bool, default True) If set to False, a  git  refer‐
1997                ence will not be created.
1998
1999ostree_ref – (str) To override value ref from treefile.
2000
2001   Example config
2002          ostree = {
2003              "^Atomic$": {
2004                  "treefile": "fedora-atomic-docker-host.json",
2005                  "config_url": "https://git.fedorahosted.org/git/fedora-atomic.git",
2006                  "repo": [
2007                      "Server",
2008                      "http://example.com/repo/x86_64/os",
2009                      {"baseurl": "Everything"},
2010                      {"baseurl": "http://example.com/linux/repo", "exclude": "systemd-container"},
2011                  ],
2012                  "keep_original_sources": True,
2013                  "ostree_repo": "/mnt/koji/compose/atomic/Rawhide/",
2014                  "update_summary": True,
2015                  # Automatically generate a reasonable version
2016                  "version": "!OSTREE_VERSION_FROM_LABEL_DATE_TYPE_RESPIN",
2017                  # Only run this for x86_64 even if Atomic has more arches
2018                  "arches": ["x86_64"],
2019              }
2020          }
2021
2022       ostree_use_koji_plugin = False
2023              (bool)  –  When  set to True, the Koji pungi_ostree task will be
2024              used to execute rpm-ostree instead of runroot. Use only  if  the
2025              Koji instance has the pungi_ostree plugin installed.
2026
2027   Ostree Installer Settings
2028       The  ostree_installer  phase  of  Pungi  can  produce  installer  image
2029       bundling an OSTree repository. This always runs in Koji  as  a  runroot
2030       task.
2031
2032       ostree_installer
2033              (dict)  –  a  variant/arch  mapping of configuration. The format
2034              should be [(variant_uid_regex, {arch|*: config_dict})].
2035
2036              The configuration dict for each variant arch pair must have this
2037              key:
2038
2039              These keys are optional:
2040
2041repo – (str|[str]) repos specified by URL or variant UID
2042
2043release  – (str) Release value to set for the installer image.
2044                Set to !RELEASE_FROM_LABEL_DATE_TYPE_RESPIN  to  generate  the
2045                value automatically.
2046
2047failable – ([str]) List of architectures for which this deliv‐
2048                erable is not release blocking.
2049
2050              These optional keys are passed to lorax to customize the build.
2051
2052installpkgs – ([str])
2053
2054add_template – ([str])
2055
2056add_arch_template – ([str])
2057
2058add_template_var – ([str])
2059
2060add_arch_template_var – ([str])
2061
2062rootfs_size – ([str])
2063
2064template_repo – (str) Git repository with extra templates.
2065
2066template_branch – (str) Branch to use from template_repo.
2067
2068              The templates can either be absolute paths, in which  case  they
2069              will  be  used  as configured; or they can be relative paths, in
2070              which case template_repo needs to point to a Git repository from
2071              which to take the templates.
2072
2073              If  the templates need to run with additional dependencies, that
2074              can be configured with the optional key:
2075
2076extra_runroot_pkgs – ([str])
2077
2078       ostree_installer_overwrite = False
2079              (bool) – by default if a variant including OSTree installer also
2080              creates  regular  installer  images in buildinstall phase, there
2081              will be conflicts (as the files are put in the same  place)  and
2082              Pungi will report an error and fail the compose.
2083
2084              With  this  option it is possible to opt-in for the overwriting.
2085              The traditional boot.iso will be in the iso/ subdirectory.
2086
2087       ostree_installer_use_koji_plugin = False
2088              (bool) – When set to True, the Koji pungi_buildinstall task will
2089              be  used  to  execute  Lorax instead of runroot. Use only if the
2090              Koji instance has the pungi_buildinstall plugin installed.
2091
2092   Example config
2093          ostree_installer = [
2094              ("^Atomic$", {
2095                  "x86_64": {
2096                      "repo": [
2097                          "Everything",
2098                          "https://example.com/extra-repo1.repo",
2099                          "https://example.com/extra-repo2.repo",
2100                      ],
2101                      "release": "!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN",
2102                      "installpkgs": ["fedora-productimg-atomic"],
2103                      "add_template": ["atomic-installer/lorax-configure-repo.tmpl"],
2104                      "add_template_var": [
2105                          "ostree_osname=fedora-atomic",
2106                          "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
2107                      ],
2108                      "add_arch_template": ["atomic-installer/lorax-embed-repo.tmpl"],
2109                      "add_arch_template_var": [
2110                          "ostree_repo=https://kojipkgs.fedoraproject.org/compose/atomic/Rawhide/",
2111                          "ostree_osname=fedora-atomic",
2112                          "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
2113                      ]
2114                      'template_repo': 'https://git.fedorahosted.org/git/spin-kickstarts.git',
2115                      'template_branch': 'f24',
2116                  }
2117              })
2118          ]
2119
2120   OSBS Settings
2121       Pungi can build container  images  in  OSBS.  The  build  is  initiated
2122       through  Koji container-build plugin. The base image will be using RPMs
2123       from the current compose and a Dockerfile from  specified  Git  reposi‐
2124       tory.
2125
2126       Please  note  that the image is uploaded to a registry and not exported
2127       into compose directory. There will be a metadata file in  compose/meta‐
2128       data/osbs.json  with  details about the built images (assuming they are
2129       not scratch builds).
2130
2131       osbs   (dict) – a mapping from variant regexes to configuration blocks.
2132              The format should be {variant_uid_regex: [config_dict]}.
2133
2134              The configuration for each image must have at least these keys:
2135
2136url  – (str) URL pointing to a Git repository with Dockerfile.
2137                Please see Git URLs section for more details.
2138
2139target – (str) A Koji target to build the image for.
2140
2141git_branch – (str) A branch in SCM for the Dockerfile. This is
2142                required by OSBS to avoid race conditions when multiple builds
2143                from the same repo are submitted at the same time. Please note
2144                that  url  should  contain  the branch or tag name as well, so
2145                that it can be resolved to a particular commit hash.
2146
2147              Optionally you can specify failable. If it has a  truthy  value,
2148              failure to create the image will not abort the whole compose.
2149
2150              The  configuration  will  pass  other attributes directly to the
2151              Koji  task.   This  includes  scratch  and  priority.  See  koji
2152              list-api buildContainer for more details about these options.
2153
2154              A value for yum_repourls will be created automatically and point
2155              at a repository in the current compose. You can add extra repos‐
2156              itories  with  repo  key having a list of urls pointing to .repo
2157              files or just variant uid, Pungi will create the .repo file  for
2158              that  variant.  If  specific  URL is used in the repo, the $COM‐
2159              POSE_ID variable in the repo string will be  replaced  with  the
2160              real  compose ID.  gpgkey can be specified to enable gpgcheck in
2161              repo files for variants.
2162
2163       osbs_registries
2164              (dict) – It is possible to  configure  extra  information  about
2165              where to push the image (unless it is a scratch build). For each
2166              finished build, Pungi will try to match NVR  against  a  key  in
2167              this  mapping  (using  shell-style globbing) and take the corre‐
2168              sponding value and collect them across  all  built  images.  The
2169              data  will  be  saved into logs/global/osbs-registries.json as a
2170              mapping from Koji NVR to the registry data.  The  same  data  is
2171              also sent to the message bus on osbs-request-push topic once the
2172              compose finishes successfully. Handling the message and perform‐
2173              ing the actual push is outside of scope for Pungi.
2174
2175   Example config
2176          osbs = {
2177              "^Server$": {
2178                  # required
2179                  "url": "git://example.com/dockerfiles.git?#HEAD",
2180                  "target": "f24-docker-candidate",
2181                  "git_branch": "f24-docker",
2182
2183                  # optional
2184                  "repo": ["Everything", "https://example.com/extra-repo.repo"],
2185                  # This will result in three repo urls being passed to the task.
2186                  # They will be in this order: Server, Everything, example.com/
2187                  "gpgkey": 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release',
2188              }
2189          }
2190
2191   Extra ISOs
2192       Create an ISO image that contains packages from multiple variants. Such
2193       ISO always belongs to one variant, and will be stored in ISO  directory
2194       of that variant.
2195
2196       The  ISO  will  be  bootable  if buildinstall phase runs for the parent
2197       variant. It will reuse boot configuration from that variant.
2198
2199       extra_isos
2200              (dict) – a mapping from variant UID regex to a list of  configu‐
2201              ration blocks.
2202
2203include_variants – (list) list of variant UIDs from which con‐
2204                tent should be added to the ISO; the variant of this image  is
2205                added automatically.
2206
2207              Rest of configuration keys is optional.
2208
2209filename – (str) template for naming the image. In addition to
2210                the regular placeholders filename is available with  the  name
2211                generated using image_name_format option.
2212
2213volid  –  (str) template for generating volume ID. Again volid
2214                placeholder can be used similarly as for file name.  This  can
2215                also  be  a  list of templates that will be tried sequentially
2216                until one generates a volume ID that fits  into  32  character
2217                limit.
2218
2219extra_files  –  (list) a list of scm_dict objects. These files
2220                will be put in the top level directory of the image.
2221
2222arches – (list) a list of architectures  for  which  to  build
2223                this  image.  By  default  all arches from the variant will be
2224                used. This option can be used to limit them.
2225
2226failable_arches – (list) a list of architectures for which the
2227                image  can  fail  to be generated and not fail the entire com‐
2228                pose.
2229
2230skip_src – (bool) allows to disable  creating  an  image  with
2231                source packages.
2232
2233inherit_extra_files  –  (bool) by default extra files in vari‐
2234                ants are ignored. If you want to include them in the ISO,  set
2235                this option to True.
2236
2237max_size  – (int) expected maximum size in bytes. If the final
2238                image is larger, a warning will be issued.
2239
2240   Example config
2241          extra_isos = {
2242              'Server': [{
2243                  # Will generate foo-DP-1.0-20180510.t.43-Server-x86_64-dvd1.iso
2244                  'filename': 'foo-{filename}',
2245                  'volid': 'foo-{arch}',
2246
2247                  'extra_files': [{
2248                      'scm': 'git',
2249                      'repo': 'https://pagure.io/pungi.git',
2250                      'file': 'setup.py'
2251                  }],
2252
2253                  'include_variants': ['Client']
2254              }]
2255          }
2256          # This should create image with the following layout:
2257          #  .
2258          #  ├── Client
2259          #  │   ├── Packages
2260          #  │   │   ├── a
2261          #  │   │   └── b
2262          #  │   └── repodata
2263          #  ├── Server
2264          #  │   ├── Packages
2265          #  │   │   ├── a
2266          #  │   │   └── b
2267          #  │   └── repodata
2268          #  └── setup.py
2269
2270   Media Checksums Settings
2271       media_checksums
2272              (list) – list of checksum types to compute, allowed  values  are
2273              anything supported by Python’s hashlib module (see documentation
2274              for details).
2275
2276       media_checksum_one_file
2277              (bool) – when True, only one CHECKSUM file will be  created  per
2278              directory;  this option requires media_checksums to only specify
2279              one type
2280
2281       media_checksum_base_filename
2282              (str) – when not set, all checksums will be save to a file named
2283              either  CHECKSUM or based on the digest type; this option allows
2284              adding any prefix to that name
2285
2286              It is possible to use format strings that will be replace by ac‐
2287              tual values.  The allowed keys are:
2288
2289arch
2290
2291compose_id
2292
2293date
2294
2295label
2296
2297label_major_version
2298
2299release_short
2300
2301respin
2302
2303type
2304
2305type_suffix
2306
2307version
2308
2309dirname (only if media_checksum_one_file is enabled)
2310
2311              For   example,   for   Fedora   the   prefix   should  be  %(re‐
2312              lease_short)s-%(variant)s-%(version)s-%(date)s%(type_suf‐
2313              fix)s.%(respin)s.
2314
2315   Translate Paths Settings
2316       translate_paths
2317              (list)  –  list  of  paths  to translate; format: [(path, trans‐
2318              lated_path)]
2319
2320       NOTE:
2321          This feature becomes useful when you need to transform compose loca‐
2322          tion  into  e.g.  a  HTTP  repo  which  is can be passed to koji im‐
2323          age-build.  The path part is normalized via os.path.normpath().
2324
2325   Example config
2326          translate_paths = [
2327              ("/mnt/a", "http://b/dir"),
2328          ]
2329
2330   Example usage
2331          >>> from pungi.util import translate_paths
2332          >>> print translate_paths(compose_object_with_mapping, "/mnt/a/c/somefile")
2333          http://b/dir/c/somefile
2334
2335   Miscellaneous Settings
2336       paths_module
2337              (str) – Name of Python module implementing the same interface as
2338              pungi.paths.  This  module  can be used to override where things
2339              are placed.
2340
2341       link_type = hardlink-or-copy
2342              (str) – Method of putting packages into compose directory.
2343
2344              Available options:
2345
2346hardlink-or-copy
2347
2348hardlink
2349
2350copy
2351
2352symlink
2353
2354abspath-symlink
2355
2356       skip_phases
2357              (list) – List of phase names that should be  skipped.  The  same
2358              functionality is available via a command line option.
2359
2360       release_discinfo_description
2361              (str)  – Override description in .discinfo files. The value is a
2362              format string accepting %(variant_name)s and %(arch)s placehold‐
2363              ers.
2364
2365       symlink_isos_to
2366              (str)  –  If set, the ISO files from buildinstall, createiso and
2367              live_images phases will be put into this destination, and a sym‐
2368              link pointing to this location will be created in actual compose
2369              directory.
2370
2371       dogpile_cache_backend
2372              (str) – If set, Pungi will  use  the  configured  Dogpile  cache
2373              backend to cache various data between multiple Pungi calls. This
2374              can make Pungi faster in case more similar composes are  running
2375              regularly in short time.
2376
2377              For    list    of    available    backends,   please   see   the
2378              https://dogpilecache.readthedocs.io documentation.
2379
2380              Most typical configuration uses the dogpile.cache.dbm backend.
2381
2382       dogpile_cache_arguments
2383              (dict) – Arguments to be used when creating  the  Dogpile  cache
2384              backend.   See  the  particular  backend’s configuration for the
2385              list of possible key/value pairs.
2386
2387              For the dogpile.cache.dbm backend, the value can be for  example
2388              following:
2389
2390                 {
2391                     "filename": "/tmp/pungi_cache_file.dbm"
2392                 }
2393
2394       dogpile_cache_expiration_time
2395              (int)  –  Defines the default expiration time in seconds of data
2396              stored in the Dogpile cache. Defaults to 3600 seconds.
2397

BIG PICTURE EXAMPLES

2399       Actual Pungi configuration files can get very large. This pages  brings
2400       two examples of (almost) full configuration for two different composes.
2401
2402   Fedora Rawhide compose
2403       This  is  a  shortened  configuration  for Fedora Radhide compose as of
2404       2019-10-14.
2405
2406          release_name = 'Fedora'
2407          release_short = 'Fedora'
2408          release_version = 'Rawhide'
2409          release_is_layered = False
2410
2411          bootable = True
2412          comps_file = {
2413              'scm': 'git',
2414              'repo': 'https://pagure.io/fedora-comps.git',
2415              'branch': 'master',
2416              'file': 'comps-rawhide.xml',
2417              # Merge translations by running make. This command will generate the file.
2418              'command': 'make comps-rawhide.xml'
2419          }
2420          module_defaults_dir = {
2421              'scm': 'git',
2422              'repo': 'https://pagure.io/releng/fedora-module-defaults.git',
2423              'branch': 'master',
2424              'dir': '.'
2425          }
2426
2427          variants_file='variants-fedora.xml'
2428          sigkeys = ['12C944D0']
2429
2430          # Put packages into subdirectories hashed by their initial letter.
2431          hashed_directories = True
2432
2433          # There is a special profile for use with compose. It makes Pungi
2434          # authenticate automatically as rel-eng user.
2435          koji_profile = 'compose_koji'
2436
2437          # RUNROOT settings
2438          runroot = True
2439          runroot_channel = 'compose'
2440          runroot_tag = 'f32-build'
2441
2442          # PKGSET
2443          pkgset_source = 'koji'
2444          pkgset_koji_tag = 'f32'
2445          pkgset_koji_inherit = False
2446
2447          filter_system_release_packages = False
2448
2449          # GATHER
2450          gather_method = {
2451              '^.*': {                # For all variants
2452                  'comps': 'deps',    # resolve dependencies for packages from comps file
2453                  'module': 'nodeps', # but not for packages from modules
2454              }
2455          }
2456          gather_backend = 'dnf'
2457          gather_profiler = True
2458          check_deps = False
2459          greedy_method = 'build'
2460
2461          repoclosure_backend = 'dnf'
2462
2463          # CREATEREPO
2464          createrepo_deltas = False
2465          createrepo_database = True
2466          createrepo_use_xz = True
2467          createrepo_extra_args = ['--zck', '--zck-dict-dir=/usr/share/fedora-repo-zdicts/rawhide']
2468
2469          # CHECKSUMS
2470          media_checksums = ['sha256']
2471          media_checksum_one_file = True
2472          media_checksum_base_filename = '%(release_short)s-%(variant)s-%(version)s-%(arch)s-%(date)s%(type_suffix)s.%(respin)s'
2473
2474          # CREATEISO
2475          iso_hfs_ppc64le_compatible = False
2476
2477          # BUILDINSTALL
2478          buildinstall_method = 'lorax'
2479          buildinstall_skip = [
2480              # No installer for Modular variant
2481              ('^Modular$', {'*': True}),
2482              # No 32 bit installer for Everything.
2483              ('^Everything$', {'i386': True}),
2484          ]
2485
2486          # Enables macboot on x86_64 for all variants and disables upgrade image building
2487          # everywhere.
2488          lorax_options = [
2489            ('^.*$', {
2490               'x86_64': {
2491                   'nomacboot': False
2492               },
2493               'ppc64le': {
2494                   # Use 3GB image size for ppc64le.
2495                   'rootfs_size': 3
2496               },
2497               '*': {
2498                   'noupgrade': True
2499               }
2500            })
2501          ]
2502
2503          additional_packages = [
2504              ('^(Server|Everything)$', {
2505                  '*': [
2506                      # Add all architectures of dracut package.
2507                      'dracut.*',
2508                      # All all packages matching this pattern
2509                      'autocorr-*',
2510                  ],
2511              }),
2512
2513              ('^Everything$', {
2514                  # Everything should include all packages from the tag. This only
2515                  # applies to the native arch. Multilib will still be pulled in
2516                  # according to multilib rules.
2517                  '*': ['*'],
2518              }),
2519          ]
2520
2521          filter_packages = [
2522              ("^.*$", {"*": ["glibc32", "libgcc32"]}),
2523              ('(Server)$', {
2524                  '*': [
2525                      'kernel*debug*',
2526                      'kernel-kdump*',
2527                  ]
2528              }),
2529          ]
2530
2531          multilib = [
2532              ('^Everything$', {
2533                  'x86_64': ['devel', 'runtime'],
2534              })
2535          ]
2536
2537          # These packages should never be multilib on any arch.
2538          multilib_blacklist = {
2539              '*': [
2540                  'kernel', 'kernel-PAE*', 'kernel*debug*', 'java-*', 'php*', 'mod_*', 'ghc-*'
2541              ],
2542          }
2543
2544          # These should be multilib even if they don't match the rules defined above.
2545          multilib_whitelist = {
2546              '*': ['wine', '*-static'],
2547          }
2548
2549          createiso_skip = [
2550              # Keep binary ISOs for Server, but not source ones.
2551              ('^Server$', {'src': True}),
2552
2553              # Remove all other ISOs.
2554              ('^Everything$', {'*': True, 'src': True}),
2555              ('^Modular$', {'*': True, 'src': True}),
2556          ]
2557
2558          # Image name respecting Fedora's image naming policy
2559          image_name_format = '%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s.iso'
2560          # Use the same format for volume id
2561          image_volid_formats = [
2562              '%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s'
2563          ]
2564          # Used by Pungi to replace 'Cloud' with 'C' (etc.) in ISO volume IDs.
2565          # There is a hard 32-character limit on ISO volume IDs, so we use
2566          # these to try and produce short enough but legible IDs. Note this is
2567          # duplicated in Koji for live images, as livemedia-creator does not
2568          # allow Pungi to tell it what volume ID to use. Note:
2569          # https://fedoraproject.org/wiki/User:Adamwill/Draft_fedora_image_naming_policy
2570          volume_id_substitutions = {
2571                           'Beta': 'B',
2572                        'Rawhide': 'rawh',
2573                     'Silverblue': 'SB',
2574                       'Cinnamon': 'Cinn',
2575                          'Cloud': 'C',
2576                   'Design_suite': 'Dsgn',
2577                 'Electronic_Lab': 'Elec',
2578                     'Everything': 'E',
2579                 'Scientific_KDE': 'SciK',
2580                       'Security': 'Sec',
2581                         'Server': 'S',
2582                    'Workstation': 'WS',
2583          }
2584
2585          disc_types = {
2586              'boot': 'netinst',
2587              'live': 'Live',
2588          }
2589
2590          translate_paths = [
2591             ('/mnt/koji/compose/', 'https://kojipkgs.fedoraproject.org/compose/'),
2592          ]
2593
2594          # These will be inherited by live_media, live_images and image_build
2595          global_ksurl = 'git+https://pagure.io/fedora-kickstarts.git?#HEAD'
2596          global_release = '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN'
2597          global_version = 'Rawhide'
2598          # live_images ignores this in favor of live_target
2599          global_target = 'f32'
2600
2601          image_build = {
2602              '^Container$': [
2603                  {
2604                      'image-build': {
2605                              'format': [('docker', 'tar.xz')],
2606                              'name': 'Fedora-Container-Base',
2607                              'kickstart': 'fedora-container-base.ks',
2608                              'distro': 'Fedora-22',
2609                              'disk_size': 5,
2610                              'arches': ['armhfp', 'aarch64', 'ppc64le', 's390x', 'x86_64'],
2611                              'repo': 'Everything',
2612                              'install_tree_from': 'Everything',
2613                              'subvariant': 'Container_Base',
2614                              'failable': ['*'],
2615                              },
2616                      'factory-parameters': {
2617                          'dockerversion': "1.10.1",
2618                          'docker_cmd':  '[ "/bin/bash" ]',
2619                          'docker_env': '[ "DISTTAG=f32container", "FGC=f32", "container=oci" ]',
2620                          'docker_label': '{ "name": "fedora", "license": "MIT", "vendor": "Fedora Project", "version": "32"}',
2621                      },
2622                  },
2623              ],
2624          }
2625
2626          live_media = {
2627              '^Workstation$': [
2628                      {
2629                          'name': 'Fedora-Workstation-Live',
2630                          'kickstart': 'fedora-live-workstation.ks',
2631                          # Variants.xml also contains aarch64 and armhfp, but there
2632                          # should be no live media for those arches.
2633                          'arches': ['x86_64', 'ppc64le'],
2634                          'failable': ['ppc64le'],
2635                          # Take packages and install tree from Everything repo.
2636                          'repo': 'Everything',
2637                          'install_tree_from': 'Everything',
2638                      }
2639                  ],
2640              '^Spins': [
2641                  # There are multiple media for Spins variant. They use subvariant
2642                  # field so that they can be identified in the metadata.
2643                  {
2644                      'name': 'Fedora-KDE-Live',
2645                      'kickstart': 'fedora-live-kde.ks',
2646                      'arches': ['x86_64'],
2647                      'repo': 'Everything',
2648                      'install_tree_from': 'Everything',
2649                      'subvariant': 'KDE'
2650
2651                  },
2652                  {
2653                      'name': 'Fedora-Xfce-Live',
2654                      'kickstart': 'fedora-live-xfce.ks',
2655                      'arches': ['x86_64'],
2656                      'failable': ['*'],
2657                      'repo': 'Everything',
2658                      'install_tree_from': 'Everything',
2659                      'subvariant': 'Xfce'
2660                  },
2661              ],
2662          }
2663
2664          failable_deliverables = [
2665              # Installer and ISOs for server failing do not abort the compose.
2666              ('^Server$', {
2667                  '*': ['buildinstall', 'iso'],
2668              }),
2669              ('^.*$', {
2670                  # Buildinstall is not blocking
2671                  'src': ['buildinstall'],
2672                  # Nothing on i386, ppc64le blocks the compose
2673                  'i386': ['buildinstall', 'iso'],
2674                  'ppc64le': ['buildinstall', 'iso'],
2675                  's390x': ['buildinstall', 'iso'],
2676              })
2677          ]
2678
2679          live_target = 'f32'
2680          live_images_no_rename = True
2681          live_images = [
2682              ('^Workstation$', {
2683                  'armhfp': {
2684                      'kickstart': 'fedora-arm-workstation.ks',
2685                      'name': 'Fedora-Workstation-armhfp',
2686                      # Again workstation takes packages from Everything.
2687                      'repo': 'Everything',
2688                      'type': 'appliance',
2689                      'failable': True,
2690                  }
2691              }),
2692              ('^Server$', {
2693                  # But Server has its own repo.
2694                  'armhfp': {
2695                      'kickstart': 'fedora-arm-server.ks',
2696                      'name': 'Fedora-Server-armhfp',
2697                      'type': 'appliance',
2698                      'failable': True,
2699                  }
2700              }),
2701          ]
2702
2703          ostree = {
2704              "^Silverblue$": {
2705                  "version": "!OSTREE_VERSION_FROM_LABEL_DATE_TYPE_RESPIN",
2706                  # To get config, clone master branch from this repo and take
2707                  # treefile from there.
2708                  "treefile": "fedora-silverblue.yaml",
2709                  "config_url": "https://pagure.io/workstation-ostree-config.git",
2710                  "config_branch": "master",
2711                  # Consume packages from Everything
2712                  "repo": "Everything",
2713                  # Don't create a reference in the ostree repo (signing automation does that).
2714                  "tag_ref": False,
2715                  # Don't use change detection in ostree.
2716                  "force_new_commit": True,
2717                  # This is the location for the repo where new commit will be
2718                  # created. Note that this is outside of the compose dir.
2719                  "ostree_repo": "/mnt/koji/compose/ostree/repo/",
2720                  "ostree_ref": "fedora/rawhide/${basearch}/silverblue",
2721                  "arches": ["x86_64", "ppc64le", "aarch64"],
2722                  "failable": ['*'],
2723              }
2724          }
2725
2726          ostree_installer = [
2727              ("^Silverblue$", {
2728                  "x86_64": {
2729                      "repo": "Everything",
2730                      "release": None,
2731                      "rootfs_size": "8",
2732                      # Take templates from this repository.
2733                      'template_repo': 'https://pagure.io/fedora-lorax-templates.git',
2734                      'template_branch': 'master',
2735                      # Use following templates.
2736                      "add_template": ["ostree-based-installer/lorax-configure-repo.tmpl",
2737                                       "ostree-based-installer/lorax-embed-repo.tmpl",
2738                                       "ostree-based-installer/lorax-embed-flatpaks.tmpl"],
2739                      # And add these variables for the templates.
2740                      "add_template_var": [
2741                          "ostree_install_repo=https://kojipkgs.fedoraproject.org/compose/ostree/repo/",
2742                          "ostree_update_repo=https://ostree.fedoraproject.org",
2743                          "ostree_osname=fedora",
2744                          "ostree_oskey=fedora-32-primary",
2745                          "ostree_contenturl=mirrorlist=https://ostree.fedoraproject.org/mirrorlist",
2746                          "ostree_install_ref=fedora/rawhide/x86_64/silverblue",
2747                          "ostree_update_ref=fedora/rawhide/x86_64/silverblue",
2748                          "flatpak_remote_name=fedora",
2749                          "flatpak_remote_url=oci+https://registry.fedoraproject.org",
2750                          "flatpak_remote_refs=runtime/org.fedoraproject.Platform/x86_64/f30 app/org.gnome.Baobab/x86_64/stable",
2751                      ],
2752                      'failable': ['*'],
2753                  },
2754              })
2755          ]
2756
2757   RCM Tools compose
2758       This is a small compose used to deliver packages to  Red  Hat  internal
2759       users. The configuration is split into two files.
2760
2761          # rcmtools-common.conf
2762
2763          release_name = "RCM Tools"
2764          release_short = "RCMTOOLS"
2765          release_version = "2.0"
2766          release_type = "updates"
2767          release_is_layered = True
2768          createrepo_c = True
2769          createrepo_checksum = "sha256"
2770
2771          # PKGSET
2772          pkgset_source = "koji"
2773          koji_profile = "brew"
2774          pkgset_koji_inherit = True
2775
2776
2777          # GENERAL SETTINGS
2778          bootable = False
2779          comps_file = "rcmtools-comps.xml"
2780          variants_file = "rcmtools-variants.xml"
2781          sigkeys = ["3A3A33A3"]
2782
2783
2784          # RUNROOT settings
2785          runroot = False
2786
2787
2788          # GATHER
2789          gather_method = "deps"
2790          check_deps = True
2791
2792          additional_packages = [
2793              ('.*', {
2794                  '*': ['puddle', 'rcm-nexus'],
2795                  }
2796              ),
2797          ]
2798
2799          # Set repoclosure_strictness to fatal to avoid installation dependency
2800          # issues in production composes
2801          repoclosure_strictness = [
2802              ("^.*$", {
2803                  "*": "fatal"
2804              })
2805          ]
2806
2807       Configuration  specific for different base products is split into sepa‐
2808       rate files.
2809
2810          # rcmtools-common.conf
2811          from rcmtools-common import *
2812
2813          # BASE PRODUCT
2814          base_product_name = "Red Hat Enterprise Linux"
2815          base_product_short = "RHEL"
2816          base_product_version = "7"
2817
2818          # PKGSET
2819          pkgset_koji_tag = "rcmtools-rhel-7-compose"
2820
2821          # remove i386 arch on rhel7
2822          tree_arches = ["aarch64", "ppc64le", "s390x", "x86_64"]
2823
2824          check_deps = False
2825
2826          # Packages in these repos are available to satisfy dependencies inside the
2827          # compose, but will not be pulled in.
2828          gather_lookaside_repos = [
2829              ("^Client|Client-optional$", {
2830                  "x86_64": [
2831                      "http://example.redhat.com/rhel/7/Client/x86_64/os/",
2832                      "http://example.redhat.com/rhel/7/Client/x86_64/optional/os/",
2833                  ],
2834              }),
2835               ("^Workstation|Workstation-optional$", {
2836                  "x86_64": [
2837                      "http://example.redhat.com/rhel/7/Workstation/x86_64/os/",
2838                      "http://example.redhat.com/rhel/7/Workstation/x86_64/optional/os/",
2839                  ],
2840              }),
2841              ("^Server|Server-optional$", {
2842                  "aarch64": [
2843                      "http://example.redhat.com/rhel/7/Server/aarch64/os/",
2844                      "http://example.redhat.com/rhel/7/Server/aarch64/optional/os/",
2845                  ],
2846                  "ppc64": [
2847                      "http://example.redhat.com/rhel/7/Server/ppc64/os/",
2848                      "http://example.redhat.com/rhel/7/Server/ppc64/optional/os/",
2849                  ],
2850                  "ppc64le": [
2851                      "http://example.redhat.com/rhel/7/Server/ppc64le/os/",
2852                      "http://example.redhat.com/rhel/7/Server/ppc64le/optional/os/",
2853                  ],
2854                  "s390x": [
2855                      "http://example.redhat.com/rhel/7/Server/s390x/os/",
2856                      "http://example.redhat.com/rhel/7/Server/s390x/optional/os/",
2857                  ],
2858                  "x86_64": [
2859                      "http://example.redhat.com/rhel/7/Server/x86_64/os/",
2860                      "http://example.redhat.com/rhel/7/Server/x86_64/optional/os/",
2861                  ],
2862              })
2863          ]
2864

EXPORTING FILES FROM SCM

2866       Multiple places in Pungi can use files from external storage. The  con‐
2867       figuration  is  similar  independently of the backend that is used, al‐
2868       though some features may be different.
2869
2870       The so-called scm_dict is always put into configuration  as  a  dictio‐
2871       nary, which can contain following keys.
2872
2873scm  –  indicates  which SCM system is used. This is always required.
2874         Allowed values are:
2875
2876file – copies files from local filesystem
2877
2878git – copies files from a Git repository
2879
2880cvs – copies files from a CVS repository
2881
2882rpm – copies files from a package in the compose
2883
2884koji – downloads archives from a given build in Koji build system
2885
2886repo
2887
2888         • for Git and CVS backends this should be URL to the repository
2889
2890         • for RPM backend this should be a shell style glob matching  package
2891           names (or a list of such globs)
2892
2893         • for file backend this should be empty
2894
2895         • for Koji backend this should be an NVR or package name
2896
2897branch
2898
2899         • branch  name  for Git and CVS backends, with master and HEAD as de‐
2900           faults
2901
2902         • Koji tag for koji backend if only package name is given
2903
2904         • otherwise should not be specified
2905
2906file – a list of files that should be exported.
2907
2908dir – a directory that should be exported. All its contents  will  be
2909         exported. This option is mutually exclusive with file.
2910
2911command  – defines a shell command to run after Git clone to generate
2912         the needed file (for example to run  make).  Only  supported  in  Git
2913         backend.
2914
2915   Koji examples
2916       There are two different ways how to configure the Koji backend.
2917
2918          {
2919              # Download all *.tar files from build my-image-1.0-1.
2920              "scm": "koji",
2921              "repo": "my-image-1.0-1",
2922              "file": "*.tar",
2923          }
2924
2925          {
2926              # Find latest build of my-image in tag my-tag and take files from
2927              # there.
2928              "scm": "koji",
2929              "repo": "my-image",
2930              "branch": "my-tag",
2931              "file": "*.tar",
2932          }
2933
2934       Using  both  tag name and exact NVR will result in error: the NVR would
2935       be interpreted as a package name, and would not match anything.
2936
2937   file vs. dir
2938       Exactly one of these two options has to be specified. Documentation for
2939       each configuration option should specify whether it expects a file or a
2940       directory.
2941
2942       For extra_files phase either key is valid and should be chosen  depend‐
2943       ing on what the actual use case.
2944
2945   Caveats
2946       The rpm backend can only be used in phases that would extract the files
2947       after pkgset phase finished. You can’t get comps file from a package.
2948
2949       Depending on Git repository URL configuration Pungi can only export the
2950       requested  content using git archive. When a command should run this is
2951       not possible and a clone is always needed.
2952
2953       When using koji backend, it is required to  provide  configuration  for
2954       Koji  profile  to be used (koji_profile). It is not possible to contact
2955       multiple different Koji instances.
2956

PROGRESS NOTIFICATION

2958       Pungi has the ability to emit notification messages about progress  and
2959       general  status of the compose. These can be used to e.g. send messages
2960       to fedmsg. This is implemented by actually calling a separate script.
2961
2962       The script will be called with one argument describing action that just
2963       happened.  A  JSON-encoded  object  will be passed to standard input to
2964       provide more information about the event. At the very least, the object
2965       will contain a compose_id key.
2966
2967       The  script is invoked in compose directory and can read other informa‐
2968       tion there.
2969
2970       Currently these messages are sent:
2971
2972status-change – when composing starts, finishes or fails; a status
2973            key is provided to indicate details
2974
2975phase-start – on start of a phase
2976
2977phase-stop – when phase is finished
2978
2979createiso-targets – with a list of images to be created
2980
2981createiso-imagedone – when any single image is finished
2982
2983createiso-imagefail – when any single image fails to create
2984
2985fail-to-start  – when there are incorrect CLI options or errors in
2986            configuration file; this message does not contain  compose_id  nor
2987            is it started in the compose directory (which does not exist yet)
2988
2989ostree  – when a new commit is created, this message will announce
2990            its hash and the name of ref it is meant for.
2991
2992       For phase related messages phase_name key is provided as well.
2993
2994       A pungi-fedmsg-notification script is provided and understands this in‐
2995       terface.
2996
2997   Setting it up
2998       The  script  should  be provided as a command line argument --notifica‐
2999       tion-script.
3000
3001          --notification-script=pungi-fedmsg-notification
3002

GATHERING PACKAGES

3004       A compose created by Pungi consists of one or more variants. A  variant
3005       contains a subset of the content targeted at a particular use case.
3006
3007       There  are  different  types of variants. The type affects how packages
3008       are gathered into the variant.
3009
3010       The inputs for gathering are defined by various gather  sources.  Pack‐
3011       ages  from  all  sources  are collected to create a big list of package
3012       names, comps groups names and a list of packages that  should  be  fil‐
3013       tered out.
3014
3015       NOTE:
3016          The  inputs for both explicit package list and comps file are inter‐
3017          preted as RPM names, not any arbitrary provides nor  source  package
3018          name.
3019
3020       Next,  gather_method defines how the list is processed. For nodeps, the
3021       results from source are used pretty much as is [1]. For deps method,  a
3022       process will be launched to figure out what dependencies are needed and
3023       those will be pulled in.
3024
3025       [1]  The lists are filtered based on what packages are available in the
3026            package set, but nothing else will be pulled in.
3027
3028   Variant types
3029       Variant
3030              is a base type that has no special behaviour.
3031
3032       Addon  is  built  on top of a regular variant. Any packages that should
3033              go to both the addon and its parent will be removed from  addon.
3034              Packages  that  are  only  in  addon  but  pulled  in because of
3035              gather_fulltree option will be moved to parent.
3036
3037       Integrated Layered Product
3038              works similarly to addon. Additionally, all packages from addons
3039              on  the same parent variant are removed integrated layered prod‐
3040              ucts.
3041
3042              The main difference between  an  addon  and  integrated  layered
3043              product  is that integrated layered product has its own identity
3044              in the metadata (defined with product name and version).
3045
3046              NOTE:
3047                 There’s also Layered Product as a term, but this is  not  re‐
3048                 lated  to  variants.  It’s used to describe a product that is
3049                 not a standalone operating system and is instead meant to  be
3050                 used on some other base system.
3051
3052       Optional
3053              contains  packages that complete the base variants’ package set.
3054              It always has fulltree and selfhosting enabled, so  it  contains
3055              build  dependencies and packages which were not specifically re‐
3056              quested for base variant.
3057
3058       Some configuration options are overridden for particular variant types.
3059
3060   Depsolving configuration
3061                      ┌──────────┬──────────────┬──────────────┐
3062                      │Variant   │ Fulltree     │ Selfhosting  │
3063                      └──────────┴──────────────┴──────────────┘
3064
3065
3066                      │base      │ configurable │ configurable │
3067                      ├──────────┼──────────────┼──────────────┤
3068                      │addon/ILP │ enabled      │ disabled     │
3069                      ├──────────┼──────────────┼──────────────┤
3070                      │optional  │ enabled      │ enabled      │
3071                      └──────────┴──────────────┴──────────────┘
3072
3073   Profiling
3074       Profiling data on the pungi-gather tool can be enabled by  setting  the
3075       gather_profiler configuration option to True.
3076
3077   Modular compose
3078       A compose with gather_source set to module is called modular. The pack‐
3079       age list is determined by a list of modules.
3080
3081       The list of modules that will be put into a variant is defined  in  the
3082       variants.xml   file.   The  file  can  contain  either  Name:Stream  or
3083       Name:Stream:Version references. See Module Naming Policy  for  details.
3084       When  Version is missing from the specification, Pungi will ask PDC for
3085       the latest one.
3086
3087       The module metadata in PDC contains a list of RPMs  in  the  module  as
3088       well as Koji tag from which the packages can be retrieved.
3089
3090   Restrictions
3091          • A modular compose must always use Koji as a package set source.
3092

PROCESSING COMPS FILES

3094       The  comps  file  that Pungi takes as input is not really pure comps as
3095       used by tools like DNF. There are extensions used to customize how  the
3096       file is processed.
3097
3098       The first step of Pungi processing is to retrieve the actual file. This
3099       can use anything that scm_support supports.
3100
3101       Pungi extensions are arch attribute on packageref, group  and  environ‐
3102       ment tags. The value of this attribute is a comma separated list of ar‐
3103       chitectures.
3104
3105       Second step Pungi performs is creating a file  for  each  architecture.
3106       This is done by removing all elements with incompatible arch attribute.
3107       No additional clean up is performed on this file. The resulting file is
3108       only used internally for the rest of the compose process.
3109
3110       Third and final step is to create comps file for each Variant.Arch com‐
3111       bination.  This is the actual file that will be included  in  the  com‐
3112       pose.  The  start  file is the original input file, from which all ele‐
3113       ments with incompatible architecture are removed. Then clean up is per‐
3114       formed  by removing all empty groups, removing non-existing groups from
3115       environments and categories and finally removing empty environments and
3116       categories.  As  a last step groups not listed in the variants file are
3117       removed.
3118

CONTRIBUTING TO PUNGI

3120   Set up development environment
3121       In order to work on Pungi, you should install recent version of Fedora.
3122
3123   Python2
3124       Fedora 29 is recommended because some packages  are  not  available  in
3125       newer Fedora release, e.g. python2-libcomps.
3126
3127       Install required packages
3128
3129          $ sudo dnf install -y krb5-devel gcc make libcurl-devel python2-devel python2-createrepo_c kobo-rpmlib yum python2-libcomps python2-libselinx
3130
3131   Python3
3132       Install required packages
3133
3134          $ sudo dnf install -y krb5-devel gcc make libcurl-devel python3-devel python3-createrepo_c python3-libcomps
3135
3136   Developing
3137       Currently the development workflow for Pungi is on master branch:
3138
3139       • Make your own fork at https://pagure.io/pungi
3140
3141       • Clone your fork locally (replacing $USERNAME with your own):
3142
3143            git clone git@pagure.io:forks/$USERNAME/pungi.git
3144
3145       • cd into your local clone and add the remote upstream for rebasing:
3146
3147            cd pungi
3148            git remote add upstream git@pagure.io:pungi.git
3149
3150         NOTE:
3151            This  workflow  assumes  that you never git commit directly to the
3152            master branch of your fork. This will  make  more  sense  when  we
3153            cover rebasing below.
3154
3155       • create a topic branch based on master:
3156
3157            git branch my_topic_branch master
3158            git checkout my_topic_branch
3159
3160       • Make  edits,  changes,  add  new features, etc. and then make sure to
3161         pull from upstream master and rebase before  submitting  a  pull  re‐
3162         quest:
3163
3164            # lets just say you edited setup.py for sake of argument
3165            git checkout my_topic_branch
3166
3167            # make changes to setup.py
3168            black setup.py
3169            tox
3170            git add setup.py
3171            git commit -s -m "added awesome feature to setup.py"
3172
3173            # now we rebase
3174            git checkout master
3175            git pull --rebase upstream master
3176            git push origin master
3177            git push origin --tags
3178            git checkout my_topic_branch
3179            git rebase master
3180
3181            # resolve merge conflicts if any as a result of your development in
3182            # your topic branch
3183            git push origin my_topic_branch
3184
3185         NOTE:
3186            In order to for your commit to be merged:
3187
3188            • you must sign-off on it. Use -s option when running git commit.
3189
3190            • The code must be well formatted via black and pass flake8 check‐
3191              ing. Run tox -e black,flake8 to do the check.
3192
3193       • Create pull request in the pagure.io web UI
3194
3195       • For convenience, here is a bash shell function that can be placed  in
3196         your  ~/.bashrc  and  called  such as pullupstream pungi-4-devel that
3197         will automate a large portion of the rebase steps from above:
3198
3199            pullupstream () {
3200              if [[ -z "$1" ]]; then
3201                printf "Error: must specify a branch name (e.g. - master, devel)\n"
3202              else
3203                pullup_startbranch=$(git describe --contains --all HEAD)
3204                git checkout $1
3205                git pull --rebase upstream master
3206                git push origin $1
3207                git push origin --tags
3208                git checkout ${pullup_startbranch}
3209              fi
3210            }
3211
3212   Testing
3213       You must write  unit  tests  for  any  new  code  (except  for  trivial
3214       changes). Any code without sufficient test coverage may not be merged.
3215
3216       To run all existing tests, suggested method is to use tox.
3217
3218          $ sudo dnf install python3-tox -y
3219
3220          $ tox -e py3
3221          $ tox -e py27
3222
3223       Alternatively  you could create a vitualenv, install deps and run tests
3224       manually if you don’t want to use tox.
3225
3226          $ sudo dnf install python3-virtualenvwrapper -y
3227          $ mkvirtualenv --system-site-packages py3
3228          $ workon py3
3229          $ pip install -r requirements.txt -r test-requirements.txt
3230          $ make test
3231
3232          # or with coverage
3233          $ make test-coverage
3234
3235       If you need to run specified tests, pytest is recommended.
3236
3237          # Activate virtualenv first
3238
3239          # Run tests
3240          $ pytest tests/test_config.py
3241          $ pytest tests/test_config.py -k test_pkgset_mismatch_repos
3242
3243       In the tests/ directory there is a shell  script  test_compose.sh  that
3244       you  can  use  to try and create a miniature compose on dummy data. The
3245       actual data will be created by running make test-data in project root.
3246
3247          $ sudo dnf -y install rpm-build createrepo_c isomd5sum genisoimage syslinux
3248
3249          # Activate virtualenv (the one created by tox could be used)
3250          $ source .tox/py3/bin/activate
3251
3252          $ python setup.py develop
3253          $ make test-data
3254          $ make test-compose
3255
3256       This testing compose does not actually use all phases that  are  avail‐
3257       able,  and  there  is  no  checking that the result is correct. It only
3258       tells you whether it crashed or not.
3259
3260       NOTE:
3261          Even when it finishes successfully, it may print  errors  about  re‐
3262          poclosure on Server-Gluster.x86_64 in test phase. This is not a bug.
3263
3264   Documenting
3265       You  must  write  documentation  for  any  new  features and functional
3266       changes.  Any code without sufficient documentation may not be merged.
3267
3268       To generate the documentation, run make doc in project root.
3269

TESTING PUNGI

3271   Test Data
3272       Tests require test data and not all of it is  available  in  git.   You
3273       must create test repositories before running the tests:
3274
3275          make test-data
3276
3277       Requirements: createrepo_c, rpmbuild
3278
3279   Unit Tests
3280       Unit  tests  cover  functionality of Pungi python modules.  You can run
3281       all of them at once:
3282
3283          make test
3284
3285       which is shortcut to:
3286
3287          python2 setup.py test
3288          python3 setup.py test
3289
3290       You can alternatively run individual tests:
3291
3292          cd tests
3293          ./<test>.py [<class>[.<test>]]
3294
3295   Functional Tests
3296       Because compose is quite complex process and not everything is  covered
3297       with  unit  tests  yet, the easiest way how to test if your changes did
3298       not break anything badly is to start a compose on  a  relatively  small
3299       and well defined package set:
3300
3301          cd tests
3302          ./test_compose.sh
3303

MANAGING COMPOSE FROM MULTIPLE PARTS

3305       There  may  be  cases  where it makes sense to split a big compose into
3306       separate parts, but create a compose output that links all output  into
3307       one familiar structure.
3308
3309       The pungi-orchestrate tools allows that.
3310
3311       It  works  with  an INI-style configuration file. The [general] section
3312       contains information about identity of the main compose. Other sections
3313       define individual parts.
3314
3315       The  parts are scheduled to run in parallel, with the minimal amount of
3316       serialization. The final compose directory will contain  hard-links  to
3317       the files.
3318
3319   General settings
3320       target Path to directory where the final compose should be created.
3321
3322       compose_type
3323              Type of compose to make.
3324
3325       release_name
3326              Name of the product for the final compose.
3327
3328       release_short
3329              Short name of the product for the final compose.
3330
3331       release_version
3332              Version of the product for the final compose.
3333
3334       release_type
3335              Type of the product for the final compose.
3336
3337       extra_args
3338              Additional arguments that will be passed to the child Pungi pro‐
3339              cesses.
3340
3341       koji_profile
3342              If specified, a current event will be retrieved  from  the  Koji
3343              instance and used for all parts.
3344
3345       kerberos
3346              If  set  to yes, a kerberos ticket will be automatically created
3347              at the start.  Set keytab and principal as well.
3348
3349       kerberos_keytab
3350              Path to keytab file used to create the kerberos ticket.
3351
3352       kerberos_principal
3353              Kerberos principal for the ticket
3354
3355       pre_compose_script
3356              Commands to execute before first part is  started.  Can  contain
3357              multiple commands on separate lines.
3358
3359       post_compose_script
3360              Commands  to execute after the last part finishes and final sta‐
3361              tus is updated. Can contain multiple commands on separate lines.
3362
3363                 post_compose_script =
3364                     compose-latest-symlink $COMPOSE_PATH
3365                     custom-post-compose-script.sh
3366
3367              Multiple environment variables are defined for the scripts:
3368
3369COMPOSE_PATH
3370
3371COMPOSE_ID
3372
3373COMPOSE_DATE
3374
3375COMPOSE_TYPE
3376
3377COMPOSE_RESPIN
3378
3379COMPOSE_LABEL
3380
3381RELEASE_ID
3382
3383RELEASE_NAME
3384
3385RELEASE_SHORT
3386
3387RELEASE_VERSION
3388
3389RELEASE_TYPE
3390
3391RELEASE_IS_LAYERED YES for layered products, empty other‐
3392                   wise
3393
3394BASE_PRODUCT_NAME – only set for layered products
3395
3396BASE_PRODUCT_SHORT – only set for layered products
3397
3398BASE_PRODUCT_VERSION – only set for layered products
3399
3400BASE_PRODUCT_TYPE – only set for layered products
3401
3402       notification_script
3403              Executable  name (or path to a script) that will be used to send
3404              a message once the compose is finished. In order for a valid URL
3405              to  be included in the message, at least one part must configure
3406              path translation that would apply to location of main compose.
3407
3408              Only two messages will be sent, one for start and one for finish
3409              (either successful or not).
3410
3411   Partial compose settings
3412       Each part should have a separate section in the config file.
3413
3414       It can specify these options:
3415
3416       config Path  to  configuration  file that describes this part. If rela‐
3417              tive, it is resolved relative to the file with parts  configura‐
3418              tion.
3419
3420       just_phase, skip_phase
3421              Customize which phases should run for this part.
3422
3423       depends_on
3424              A  comma separated list of other parts that must be finished be‐
3425              fore this part starts.
3426
3427       failable
3428              A boolean toggle to mark a part as failable. A failure  in  such
3429              part  will  mark the final compose as incomplete, but still suc‐
3430              cessful.
3431

AUTHOR

3433       Daniel Mach
3434
3436       2021, Red Hat, Inc.
3437
3438
3439
3440
34414.3                              Nov 15, 2021                         PUNGI(1)
Impressum